Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes in namespace handling breaks scripts in SVG #2737

Closed
klpn opened this issue Feb 14, 2016 · 3 comments
Closed

Changes in namespace handling breaks scripts in SVG #2737

klpn opened this issue Feb 14, 2016 · 3 comments

Comments

@klpn
Copy link

klpn commented Feb 14, 2016

The changes in namespace handling in this commit breaks the functionality of SVGs with embedded Javascript like this one. The script is supposed to dynamically create tooltips showing information when the mouse is moved over a datapoint. It works if I use a version of D3 before the commit was merged, or if the SVG and Javascript code are embedded into a HTML document. Apparently, the namespace-aware createElementNS, rather than createElement, has to be used in order for the script to work.

@mbostock
Copy link
Member

You can fix the code by specifying an SVG namespace when appending elements. For example, replace:

selection.append("g");

With:

selection.append("svg:g");

If you specify an explicit namespace, then createElementNS is always used. If you do not specify an explicit namespace, then createElementNS is used if the element to be appended has a different namespace than the document; otherwise, createElement is used.

Here, because you are appending an SVG element in an SVG document, createElement is used rather than createElementNS.

Unfortunately, createElement isn’t very reasonable in non-HTML documents: it creates elements with a null namespace. In HTML documents—and XUL, and perhaps other namespaces to be determined—it creates elements in the namespace of the document (e.g., XHTML).

We could make the logic HTML-specific:

var document = this.ownerDocument,
    documentNamespace = document.documentElement.namespaceURI,
    namespace = this.namespaceURI;
return namespace && namespace !== documentNamespace && documentNamespace === "http://www.w3.org/1999/xhtml"
    ? document.createElementNS(namespace, name)
    : document.createElement(name);

But, that would mean using createElementNS to create XUL elements inside an XUL document, when it could reasonable use createElement. Though I’m unsure if there’s a difference in behavior in the XUL case—at least in HTML there is, hence #2722.

I’m somewhat inclined to keep the namespace resolution logic as simple as possible… That means if you want to create an SVG element in an SVG document, you would need to specify the SVG namespace explicitly. But if there were a way to test whether document.createElement created an element of the same namespace as the document element (other than hard-coding the test for HTML), that might be reasonable.

@mbostock
Copy link
Member

The specification for createElement is HTML-specific, so it seems reasonable to make our logic HTML-specific, too.

@mbostock
Copy link
Member

Fixed in 3.5.16.

mbostock added a commit to d3/d3-selection that referenced this issue Feb 18, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants