consider namespaces
Yo!
I've got some problems with namespaces on Firefox (v45.9.0). Some of them were not recognized, some prefixes were stripped, ... such things. So I've forked and enhanced your code in a way this will work for me.
If you want to use it, feel free to merge. If you think "Woah! Do not ever do this!" and you can provide a solution to me, please inform me ;-)
Thanks for the PR. Two things:
- As far as I can see the namespaces are collected forever, so repeated calls could hypothetically inherit values from previous ones. That means we leak state across independent invocations, probably not what users would expect.
- For the change to be merged, I'd like to see test cases that document that changed behaviour. We want to make sure this doesn't break in the future!
Yeah you're right. I've changed my code, so the "namespaces"-Variable will be reset, everytime a new serialization starts. And I've created a testcase as you wished ;-)
Hi thanks, the test case helps me much more to understand what you are facing.
As far as I understand though you might be able to get the missing namespace information from the attribute's prefix value, that both parse5 and the browser's parser seem to give you:
> p = require('parse5')
> d = p.parse('<svg id="svgContainer" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="/foo/bar.jpg"/></svg>')
> d.childNodes[0].childNodes[1].childNodes[0].childNodes[0].attrs[0]
{ name: 'href',
value: '/foo/bar.jpg',
prefix: 'xlink',
namespace: 'http://www.w3.org/1999/xlink' }
and in Firefox
> d = (new DOMParser()).parseFromString('<svg id="svgContainer" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="/foo/bar.jpg"/></svg>', 'text/xml')
> d.childNodes[0].childNodes[0].attributes[0].prefix
"xlink"
Can you verify whether that's enough to solve your problem?
Mhhh. The direction of this thoughts are right. If I parse the given svg-string in the tests, I get two issues.
First:
The xlink-prefix will be stripped from the attribute, so "href" is that, what remains.
But I want "xlink:href" as output.
In my current project, Firefox won't display the image, if the prefix "xlink" on href is missing. (Other browsers are working, even Edge and IE11)
Second:
Namespace for the "cn"-prefix is not recognized.
The parser don't recognize cn:first-attribute as an attribute "first-attribute" from namespace "cn", but as a primitive attribute "cn:first-attribute".
Strange, because xlink:href is recognized as attribute "href" from namespace "xlink".
What you are describing seems to be specific to output from parse5. If you play around a bit you'll see that parse5 assumes a few things, depending on the namespace identifier:
> d = p.parse('<svg><image xlink:href="/foo/bar.jpg"/></svg>')
> d.childNodes[0].childNodes[1].childNodes[0].childNodes[0].attrs
[ { name: 'href',
value: '/foo/bar.jpg',
prefix: 'xlink',
namespace: 'http://www.w3.org/1999/xlink' } ]
vs.
> d = p.parse('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:blabla="http://www.w3.org/1999/xlink"><image blabla:href="/foo/bar.jpg"/></svg>')
> d.childNodes[0].childNodes[1].childNodes[0].childNodes[0].attrs
[ { name: 'blabla:href', value: '/foo/bar.jpg' } ]
I'd say the first one is guessing that 'xlink' namespace is wanted, although it's never declared - and for the second one I try declaring the http://www.w3.org/1999/xlink namespace, however it is not recognised. Now, parse5 is an html5 parser, not an xml parser, so this might be by the spec. After all Firefox behaves pretty similarly.
Long story short, we should maybe be looking at the parser, not the serializer.
One wild guess for xlink:href being swallowed by parse5, would be https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href. Also maybe https://stackoverflow.com/questions/18467982/are-svg-parameters-such-as-xmlns-and-version-needed.