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

Templates don't work with SVG #2598

Open
gburca opened this issue Aug 30, 2022 · 2 comments
Open

Templates don't work with SVG #2598

gburca opened this issue Aug 30, 2022 · 2 comments

Comments

@gburca
Copy link

gburca commented Aug 30, 2022

See: http://jsfiddle.net/gburca/hwb92esf/33/

The generated HTML looks identical, yet the 1st SVG drawing is not displaying the circles (even though they're in the generated HTML). The 2nd drawing (which doesn't use templates) displays them properly.

@wilson0x4d
Copy link

wilson0x4d commented Sep 28, 2022

so, not exactly a solution, but might get someone one step closer to implementing a fix:

https://jsfiddle.net/wzsy8p5j/1/

specifically, if you have an element and you use createElement('circle') and append the result to the svg, it does not render. surprise! this is consistent in every browser i tested, and is not knockout-specific behavior but occurs with plain-old-javascript as well.

if you instead use createElementNS('http://www.w3.org/2000/svg', 'circle') and append the result to the svg, the circle renders just fine. surprise again!

i suspect this is a very old quirk present from when SVGs were namespace-aware (i checked multiple browsers), and suggests "magic" is performed when an SVG fragment is loaded (where the xmlns is implied for all elements within the fragment, historically SVGs were encapsulated within <script> blocks or loaded as separate documents, each having an xmlns assigned to them.) however, when createElement() is used and the element is appended it is not properly namespaced and so gets ignored (and this appears to be the expected behavior dating back to at least 2009, from what I could find.)

i tried to use knockout to set the xmlns attribute on the templated circle elements and this did not work, apparently they can't be specified on the element itself when createElement is being used (lame.)

most likely as a "fix" for this we would need a new binding that allows the specification of an xmlns for element creation via createElementNS(...) -- i wouldn't know the best way to get it implemented, probably a property needs to be added to the binding context that can be checked anywhere createElement would be called (since you'd only want this performed on a subset of nodes in the view) and then you could apply it as part of your svg/g element/tag (similar to how you leverage with or using bindings).

for example, a new binding cleverly named 'xmlns' might be obvious enough, giving us something like this:

<svg data-bind="xmlns: 'http://www.w3.org/2000/svg'">

or, given your fiddle, you could do this:

<g data-bind="xmlns: 'http://www.w3.org/2000/svg', template: { name: 'Dot', foreach: dots }"></g>

but that's going to require someone to update the source code, add tests, and get a PR merged @SteveSanderson @mbest i'd be more than happy to work with someone on this. if someone wants to collab, hit me up on discord wilson0x4d#4327 i can do the heavy lifting.

@brianmhunt
Copy link
Member

@wilson0x4d your suspicion is correct, this is a relic of the early browser era.

These commits in knockout/tko that give TKO support of SVGs in JSX may give some illumination, and in any case I think you're on the right path:

❯ git log --oneline | grep -i xmlns 
70a41319 jsx) Avoid error when setting `xmlns` on an `svg` node.
aecbf1e4 jsx) Fix misapplying of the xmlns namespace when updating attributes
5870086d jsx) Detect SVG and support other `xmlns` attributes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants