snabbdom / snabbdom

A virtual DOM library with focus on simplicity, modularity, powerful features and performance.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.