svgdotjs / svg.js

The lightweight library for manipulating and animating SVG
https://svgjs.dev
Other
11.04k stars 1.07k forks source link

Redeclared prefix xmlns:svgjs="http://svgjs.com/svgjs" #1081

Closed AnReZa closed 4 years ago

AnReZa commented 4 years ago

In my project (still with version 2.7.x), the user can add SVG annotations to a picture and save them to the server. However, after reloading the stored SVG node from the server and applying the SVG method to the node again, it redundandly adds the xmlns:svgjs attribute, so I end up with this:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" id="ap-canvas" class="bg-raster" version="1.1" xmlns:svgjs="http://svgjs.com/svgjs">
    <image xlink:href="/Diagnosis/LK-2001161/Photos/67" data-bind="attr: { 'xlink:href': modeData.imgSrc, href: modeData.imgSrc }" x="0" y="0" width="1920" height="847" href="/Diagnosis/LK-2001161/Photos/67"></image>
    <rect id="SvgjsRect1008" width="100" height="100" stroke-opacity="0.5" stroke="#00338e" stroke-width="3" fill-opacity="0.5" fill="#8cb5ff" x="881" y="102"></rect>
    <defs id="SvgjsDefs1006"></defs>
</svg>

Here's an extract from my knockout binding, which adds the node to the DOM:

    <!-- ko html: modeData.annotations -->
    <!-- /ko -->
    <!-- ko if: modeData.annotations() === null -->
    <svg id="ap-canvas" class="bg-raster" version="2.0" xmlns="http://www.w3.org/2000/svg">
        <image xlink:href="" data-bind="attr: { 'xlink:href': modeData.imgSrc, href: modeData.imgSrc }" x="0" y="0" width="100%" height="100%"></image>
    </svg>
    <!-- /ko -->
let canvas = document.getElementById('ap-canvas');
let img = SVG(canvas);

If there is no stored node yet, it adds the template. Otherwise it will load the node stored on the server. If it is stored on the server, it will contain a single occurance of the xmlns:svgjs="http://svgjs.com/svgjs" declaration. So after calling SVG() on this node again, it will duplicate the declaration.

Is that a bug, or is there any way to prevent that?

AnReZa commented 4 years ago

Might be a duplicate of #709, but no solution there.

Fuzzyma commented 4 years ago

My best guess is, that the imported svg has nodes created in the wrong namespace and when we add the correct ones, its not counted as the same. But thats really a hard guess.

Importing in 2.x was implemented in a bad way. Unfortunately changing it would be a major break. Thats why I suggest using 3.0 instead

AnReZa commented 4 years ago

@Fuzzyma I actually tried to upgrade to 3.x, but I get some strange errors there (see https://github.com/svgdotjs/svg.select.js/issues/59). And, as far as I'm concerned, the svg.select.js extension is still not ported to 3.x, or is it?

Fuzzyma commented 4 years ago

No unfortunately it is not. There is only a branch with (not so) ongoing development for the next version that would be compatible.