Open AsherWright opened 8 months ago
After checking the namespaceURI
of each element, I do think it might be the problem. For the existing SVG circle, it's 'http://www.w3.org/2000/svg'
and for the circle that the turbo stream adds it's 'http://www.w3.org/1999/xhtml'
The append action uses document.append
under the hood which by default adheres to the XHTML namespace http://www.w3.org/1999/xhtml
and has very strict rules about it, you can get around this by using a custom turbo stream action that implements document.insertAdjacentHTML
on 'beforeend'
to get the same append behavior but more flexibility with namespaces.
This is an example of a custom action to handle this that I've tested
import { StreamActions } from "@hotwired/turbo"
StreamActions.appendSvgCircle = function() {
this.removeDuplicateTargetChildren()
this.targetElements.forEach((targetElement) => {
let div = document.createElement('div');
div.appendChild(this.templateContent.cloneNode(true));
targetElement.insertAdjacentHTML('beforeend', div.innerHTML);
})
}
Overview
I'd like to edit SVG elements with turbo streams. One problem is that when I try to add an element via a turbo_stream, it isn't rendered. For instance, appending a
<circle>
inside of an SVG.Code example
Showing the code for a rails app, but the idea would be the same with another framework:
html page:
Turbo stream event:
After the event fires, we see it in the browser's inspect, and it's in the right spot. But it's not visible:
We can "fix" it by wrapping the
<circle>
in its own<svg>
, but then there's a bunch of unneeded SVGs.My uninformed hypothesis is that it has to do with element namespaces? And that SVGs may require the namespace when adding elements?