Temporary DOM elements somewhere cached

Hi folks,

We have a nasty bug in our new SVG-node. Found at last where it is located and found a solution. But I don't understand the problem, don't know why the fix solves it and don't know if the fix will work on all browsers. So if anybody has a better solution, that would be nice!

The users can enter an SVG string. But let's assume they use a file path to a local image (which cannot be accessed by our Javascript code running in a browser):

<svg .../>
 <image xlink:href="file://c:/temp/unaccessible_image.jpg"/>
</svg>

At some point in our node, we convert this SVG string to (temporary) DOM elements:

function someFunction(svgString) {
   var svgElement = $(svgStr)[0];
   ...

This allows us to search through the SVG easily, and we can even manipulate it. And this works fine!!
Once someFunction is completed, we don't need the temporary DOM elements anymore...

However quite some time after this function has finished (somewhere up in the call stack), an error occurs in my Chrome console log:

Not allowed to load local resource..."

So for some reason it seems that these (temporary) SVG elements are stored somewhere in memory, but I couldn't pinpoint where and why that error was raised. :worried: This also means I cannot give a code snippet here to reproduce the problem ...

So I tried some alternatives (to convert the SVG string into DOM elements):

  • Have tried to do $(svgStr).empty() and $(svgStr).detach() and $(svgStr).remove() since I read somewhere that jQuery caches those objects. But nothing helped...

  • So tried to do it in Vanilla Javascript:

    var svgElement = document.createElement('div');
    svgElement.innerHTML = svgStr;
    

    But same error. Even when I did svgElement.innerHTML = "" afterwards, the problem still occured...

  • At the end I tried it with the DOMParser:

    var svgElement = new DOMParser().parseFromString(svgStr, "image/svg+xml");
    

    Now the error is gone!!! But to be honest I have no clue why this solution is better (without me cleaning up anything). Moreover from the compatibility chart it is not clear to me whether Safari iOs supports SVG in DOMParser...

Summarized the DOMParser is my only solution...

Thanks!!
Bart

Perhaps the issue is relate to missing xmlns attribute ?

1 Like

Morning Andrei (@Andrei),
Thanks! My SVG string above is a bit simplified, but at the 3 dots I have all the required namespaces...

But the error that Chrome logs is entirely correct: the image path in the SVG string refers to a local file, to which the browser has no access. But I don't expect that error to occur somewhere AFTER my function has ended. This means that the SVG element keeps being stored somewhere (and being validated). But I just want the (temporary) svg elements to be deleted/detached/removed/emptied/... at the end if my function, so it cannot be validated anymore afterwards...
Bart

It sounds like this ?

However, using the use xlink:href mechanism results in a non-exposed cloned DOM tree,

From: 5 Gotchas You’re Gonna Face Getting Inline SVG Into Production

Hey @bakman2,

Perhaps it might be something like this. But that link is referring to the SVG shadow DOM tree.

In SVG you can reuse (groups of) shapes, via defintions or symbols. For example I create a symbol and I want to draw that symbol twice in my drawing. To avoid having to repeat everthing twice, you can easily use that symbol twice:

<symbol id="my-icon" viewBox="0 0 30 30">
	<!-- icon content / shapes here -->
</symbol>

<use xlink:href="#my-icon" x="100" y="100" />
<use xlink:href="#my-icon" x="200" y="100" />

Then indeed two extra shadow DOM trees will be created (one for every 'use') to let each 'use' element have its own cloned symbol shapes, as you can see in the screenshot in my link above:

image

But I don't think that is happening here, because I don't use anything: I simply have an image referring to some local file path...

[EDIT] And I have nowhere appended these SVG elements to my DOM tree, so I thought it should be removed then automatically when I leave my function?