Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespace prefix NS1 for href on %tagElement% is not defined, setAttributeNS

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.

like image 327
extempl Avatar asked May 16 '15 09:05

extempl


People also ask

How to define namespace in XML?

XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".

Why namespace is used in XML?

An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.

What is a namespace URI?

A namespace name is a uniform resource identifier (URI). Typically, the URI chosen for the namespace of a given XML vocabulary describes a resource under the control of the author or organization defining the vocabulary, such as a URL for the author's Web server.


1 Answers

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')
like image 125
extempl Avatar answered Oct 16 '22 03:10

extempl