Snap.svg
Snap.svg copied to clipboard
Unwanted Empty SVG Elements getting added underneath Snap(Snap.deurl(value)) in getattr.fill handler
Hello,
I'm making something where I'm loading up fragments of SVG that have been saved from illustrator and using them as data to interpolate between. I'm running in to issues with the fill color interpolation where the event handler for "snap.util.getattr.fill" seems not to be very well behaved.
Everything works perfectly if I change the line 4516
return Snap(Snap.deurl(value)) || value;
to simply return value
though I would not want to suggest that as a pull request since presumably the "Snap(Snap.deurl(value))" part is there for a reason, though it's not relevant to my use case.
The bad behaviour is inside the function Snap(w,h)
The behaviour is different between versions 0.50 and 0.51. I was using npm to get Snap, and despite having "snapsvg": "^0.5.1"
in my package.json file i was ending up with a copy of Snap.svg.js that said version 0.50 at the top. (Perhaps this is a separate issue that you want to address, does this mean that someone uploaded the wrong source to npm somehow?)
Under the version 0.50 from npm, the code underneath function Snap(w,h)
, in the if (h==null)
branch had a commented-out try-catch. Called from underneath the getattr.fill event handler, this function is getting a "w" value which is a string like "rgb(214, 202, 176)". The glob.doc.querySelector(String(w))
call was resulting in an exception since that's not a valid selector string.
Version 0.51 (which i got directly from the SnapSVG website rather than npm) seems to have reinstated the commented out try-catch, which means that the bad selector value no longer results in an uncaught exception. However the new bad behaviour under 0.51 is that empty extra
Using a Chrome DOM breakpoint I tracked the addition of these unwanted SVG elements down to a callstack that was underneath this same eve.on("snap.util.getattr.fill"...
event handler.
Underneath that the callstack looks like
Paper snap.svg.js:2373
wrap (line 2403)
make (line2354)
Paper (line 2385)
Snap (line 910)
(anon) (line 4516) --> snap.util.getattr.fill handler
When going awry, the problem is that the value="" in the line
return Snap(Snap.deurl(value)) || value;
In my use case it is getting an empty string sometimes from this line
var value = eve("snap.util.getattr.fill", this, true).firstDefined();
In which case the call to Snap(w,h)
skips the if(w)
condition (because empty strings are "falsey") but then ends up calling new Paper("", 100%)
w = w == null ? "100%" : w;
h = h == null ? "100%" : h;
return new Paper(w, h);
Inside of the Paper(w,h)
function it is falling in to this block of code
res = make("svg", glob.doc.body);
$(res.node, {
height: h,
version: 1.1,
width: w,
xmlns: xmlns
});
Unfortunately I don't have a simple repro case that I can send you. I have a large unwieldy thing that exhibits the problem which I cannot send, and in any attempt to boil it down to a simpler example I could not get the event handler to have the empty string for a value. (my simpler cases always got a "rgb(n,n,n)" string instead of empty string, so it's not clear where the empty string comes from)
It seems fairly dangerous to me that the Snap(w,h) constructor-like-function is being overridden for so many different purposes, from grabbing elements from the DOM to making new "Paper's". Would it not be better to isolate the different cases into different uniquely named functions?
thanks a lot. this is a huge bug. all my animations were not working until I saw your solution.
Thanks for commenting, though since it has been two weeks since posting this issue it doesn't seem that anyone else thinks this is a critical issue to fix.
I have the same issue. Took me a while to figure it out but it is the same issue. On firefox it works fine but in chrome every second or so 4 to 6 svg elements get added to the body, eventually lagging my game to a grind. This is also in a larger project but I could share it if needed.