Issue with attribute.js - setAttributeNS
DHTMLGoodies opened this issue · comments
When patching HTML containing SVG such as:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 694 694" data-locate="true" style="opacity: 1; transform: translate(46.4892px, 0px);"></svg>
an error is thrown when from attributes.js when it tries to set the xmlns:xlink attribute:
VM5469:1 Uncaught DOMException: Failed to execute 'setAttributeNS' on 'Element': 'http://www.w3.org/1999/xlink' is an invalid namespace for attributes.
The problem seems to be that it calls:
elm.setAttribute("http://www.w3.org/1999/xlink", "xmlns:xlink", "http://www.w3.org/1999/xlink");
instead of the correct one:
elm.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
i.e. it always uses xlinkNS which does not seems to be correct in all cases.
For reference, see:
https://stackoverflow.com/questions/52571125/setattributens-xmlns-of-svg-for-a-general-purpose-library
A workaround for us has been to modify/patch your attributes.js with the following:
const namespaces ={
svg: 'http://www.w3.org/2000/svg',
html: 'http://www.w3.org/1999/xhtml',
xml: 'http://www.w3.org/XML/1998/namespace',
xlink: 'http://www.w3.org/1999/xlink',
xmlns: 'http://www.w3.org/2000/xmlns/' // sic for the final slash...
};
then change the if block to:
else if (key.charCodeAt(5) === colonChar) {
const type = key.split(":")[0].toLowerCase();
const namespaceUrl = namespaces[type];
if(namespaceUrl){
elm.setAttributeNS(namespaceUrl, key, cur);
}else{
elm.setAttribute(key, cur);
}
}
Hi @DHTMLGoodies. Thank you for reporting this issue and for linking to the very useful SO question. The PR #1061 is supposed to address this issue.
Fixed. Thanks to @bumblehead.