skip to Main Content
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
const div = document.createElement('div')
div.innerHTML = '<!-- -- -->'
foreignObject.appendChild(div)
svg.appendChild(foreignObject);
const img = document.createElement('img')
img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(new XMLSerializer().serializeToString(svg))}`
document.body.appendChild(img)

the <!-- -- --> makes the img load error,change to <!-- a --> is fine.
and the original comment node like this <!--a id="TwitterLink" title="Share on Twitter"> <img id="TwitterImg" /></a> <a-- id="FacebookLink" title="Share on Facebook"> <img id="FacebookImg" /></a--> here is a <a-- inside the comment node

what cause this problem? please help

2

Answers


  1. According to the HTML 5 specification, -- is not permitted inside a comment

    Comments must start with the four character sequence U+003C LESS-THAN
    SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS, U+002D
    HYPHEN-MINUS (<!–). Following this sequence, the comment may have
    text, with the additional restriction that the text must not start
    with a single U+003E GREATER-THAN SIGN (‘>’) character, nor start with
    a U+002D HYPHEN-MINUS (-) character followed by a U+003E GREATER-THAN
    SIGN (‘>’) character, nor contain two consecutive U+002D
    HYPHEN-MINUS (-) characters
    , nor end with a U+002D HYPHEN-MINUS (-)
    character. Finally, the comment must be ended by the three character
    sequence U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN
    SIGN (–>).

    https://www.w3.org/TR/2008/WD-html5-20080610/syntax.html#comments:~:text=nor%20contain%20two%20consecutive%20U%2B002D%20HYPHEN%2DMINUS%20(%2D)%20characters

    Login or Signup to reply.
  2. You are in an XML document (SVG is a subset of XML), and even the foreign content must abide to the XML syntax. In XML, contrarily to HTML, comments can’t contain the sequence --.

    Now, how come XMLSerializer#serializeToString(). doesn’t produce a valid XML markup? No clue, but they indeed set the require well-formed flag to false, so you don’t get any error here.

    You can still get the error earlier through the use of a DOMParser:

    const markup = new XMLSerializer().serializeToString(new Comment(" -- "));
    console.log({ markup });
    const isInvalid = !!new DOMParser().parseFromString(markup, "application/xml").querySelector("parsererror");
    console.log({ isInvalid });

    But this is just the first step for you.
    Fixing that error isn’t trivial, and maybe the best for you, since your goal is to display that SVG, would be to remove all the comment nodes from the input DOM:

    function removeComments(input) {
      const tree = input.cloneNode(true);
      const walker = document.createTreeWalker(tree);
      while(walker.nextNode()) {
        if (walker.currentNode.nodeType === 8) {
          walker.currentNode.remove();
        }
      }
      return tree;
    }
    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
    const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
    const div = document.createElement('div')
    div.innerHTML = '<!-- -- -->'
    foreignObject.appendChild(div)
    svg.appendChild(foreignObject);
    const img = document.createElement('img')
    img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(new XMLSerializer().serializeToString(removeComments(svg)))}`
    document.body.appendChild(img)
    img.onload = (evt) => console.log("loaded fine");

    But other XML errors could still be present, so you might need the first test, and another fix for these.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search