6

I got this error in safari while trying to convert svg to base64 url via code:

$svgCopy = $('svg').clone()
html = $('<div>').append($svgCopy).html()
imgSrc = 'data:image/svg+xml;base64,' + btoa(html)
imgEl.src = imgSrc

The problem is that when you set attribute with NS (setAttributeNS) safari sets NS\d+ namespace and do not sets xmlns:NS\d+ attribute in svg, so it looks like

<use NS1:href="#source" />

When you copy such svg in Chrome - you have not such problem because this svg element will look like this:

<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#source" />

And in result (on svg copy) we getting invalid file.

UPD: @Robert with setAttributeNS all is ok:

el.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#source')

Without proper call it won't work in Chrome.

extempl
  • 2,987
  • 1
  • 26
  • 38

1 Answers1

6

I did not find a better solution than to simply replace those occurrences with:

html = html.replace(/NS\d+:href/gi, 'xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href')

Now it works well.

EDIT: Firefox requires xmlns:xlink="http://www.w3.org/1999/xlink at the root, and Safari likes that, so now I'm adding this attribute to the Root:

draw.canvas.setAttributeNS('http://www.w3.org/2000/svg', 'xlink', 'http://www.w3.org/1999/xlink') 

...and correcting HTML of the SVG copy for further use in base64:

// Firefox, Safari root NS issue fix
html = html.replace('xlink=', 'xmlns:xlink=')
// Safari xlink NS issue fix
html = html.replace(/NS\d+:href/gi, 'xlink:href')
montrealist
  • 5,593
  • 12
  • 46
  • 68
extempl
  • 2,987
  • 1
  • 26
  • 38
  • 1
    FWIW in Safari 9.1.2 with what I'm doing I was getting `ns1` (lowercase) and added a case-insensitive `i` to the NS replace: `html = html.replace(/NS\d+:href/gi, 'xlink:href')`. Works like a charm, thanks so much @extempl! – Michael Thompson Aug 15 '16 at 05:41