-
Notifications
You must be signed in to change notification settings - Fork 212
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
Remove duplicate xmlns property from svg creation #338
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm.
I have an issue with this PR, but can't write it up just now. I will post later as soon as I get the chance. |
Sorry for taking so long to get to this. (I've just started by to teaching for the fall term, and things are always a bit hectic the first week.) Here are my concerns. First, I am not able to reproduce the issue that you describe. If I take one of MathJax's svg elements and use Second, if the Here is a code snippet that shows the output of
The results for me are:
Note that both are the same, with no duplicate
where the
I'm not sure if you are suggesting that one should set the
I get the error
So I'm not sure how to make the attribute available for If you could give a more explicit description of what you are doing to get the duplicates, that might help. Thanks. |
Also, as an aside for the future, it would be best to start an issue for the problem that you have seen, and then make a pull request that resolves that issue. Then we can use the issue tracker to discuss the problem itself (how to reproduce, potential alternative solutions), and save the comments here for actual review of your code that resolves the problem. |
Firstly apologies for not creating a full reproduction of the issue, I'll do that week. I did think that this would be a straightforward fix, as it's quite clear that The examples below aren't using MathJax, but might be useful as an illustration:
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
new XMLSerializer().serializeToString(svg);
// <svg xmlns="http://www.w3.org/2000/svg"/>
const svg = document.createElement('svg');
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
new XMLSerializer().serializeToString(svg);
// Chrome: <svg xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/2000/svg"></svg>
// Firefox: <a0:svg xmlns:a0="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/2000/svg"></a0:svg>
// Safari: <svg xmlns="http://www.w3.org/2000/svg"></svg> (the latter example isn't showing everything, because manually setting the |
Thanks for the new information. But note the following:
If you are getting different results, can you say what OS and browser versions you are using? If you are able to reproduce this with actual MathJax output, can you give a working example of that? What do you get for the example document I included above (which does use MathJax output directly)? |
It seems that the issue appears when using The output of serializing the TeX input <svg xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="1.131ex" height="1.507ex" role="img" focusable="false" viewBox="0 -666 500 666" style="vertical-align: 0px;"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="matrix(1 0 0 -1 0 0)"><g data-mml-node="math"><g data-mml-node="mn"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"/></g></g></g></svg> Setting the If there's a bug in the serialization, I'll file an issue with the |
I think this serialization is correct, as the namespace is optional on the HTML5 serialization of SVG: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg
|
Another route to serialize SVG with the xmlns attribute would be to create it as a standalone SVG document:
|
I've created an issue on |
At least one other DOM library (slimdom) throws an error when trying to set the import { Document, serializeToWellFormedString } from 'slimdom'
const document = new Document()
const element = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
element.setAttribute('xmlns', 'http://www.w3.org/2000/svg') // "InvalidStateError: The serialization of this attr would not be a well-formed attribute"
console.log(serializeToWellFormedString(element)) Which isn't to say that setting an xmlns attribute shouldn't be allowed in an HTML context, but it does point towards it being problematic. |
Thanks for the additional comments and examples. It has turned out to be more subtle than I originally thought. I will make a few comments in response to some of yours, and then suggest a potential resolution.
I think there is a technicality that is confusing the issue a bit. Creating a node in a namespace does not actually set the
the both
I agree. That is because the
Thanks, I was unaware of that. On the other hand, the handling of the created elements in MathJax is all mediated through MathJax's DOM adaptors, so that MathJax can work with structures that are not full (our even actual) DOM implementations (like its own
For me the error comes when I try to serialize, not when the attribute is set, but, yes, I do see that too. The documentation for it does reference the DOM-parsing draft recommendation, and although it is only a draft currently, it does seem to indicate (in the topic called "XML serialization of the attributes", item 3, subitem 8) that when the 'require well-formed' flag is set, So that leads me to the suggestion for how to proceed. I think the best solution for MathJax would be to have an option for the SVG output jax that tells it whether to add the An alternative would be to subclass the HTMLadaptor and modify its to skip the In any case, I think we can come to a resolution that will work for both your needs and the needs of others, either with an option or a different adaptor. |
It seems like there are two possible "correct" solutions:
I can see why both of those are potentially tricky given the reasoning you've outlined above, so I'll have a look at subclassing |
While your number 2 looks attractive from the standpoint of serialization, the results also have to be able to be inserted into an HTML document, which this can't (at least not without extra work). So I think that won't be practical. The current If you want to subclass the
or in the
The originals are in Typescript, but I remove the types here. See here and here. Since your code sandbox example used |
Subclassing |
This removes the duplicate
xmlns
property set when creating an svg element, because:a) The SVG namespace is already set when creating the svg element: https://github.com/mathjax/MathJax-src/blob/master/ts/output/svg.ts#L311
b) Setting an attribute called
xmlns
without thehttp://www.w3.org/2000/xmlns/
namespace leads to a duplicatexmlns
attribute being created when the node is serialized to XML.