Replies: 4 comments 5 replies
-
Update. I was able to get the rendering problem resolved by having my "one off extension" return all of the elements I modified in it in an array. I haven't really found any comprehensive documentation on writing extensions. Looking at the examples and the source hasn't been terribly fruitful so far. So the only outstanding question I have at the moment is my first one. |
Beta Was this translation helpful? Give feedback.
-
Another update. It's worth noting to anyone who may be trying to update SVGs that htmx currently doesn't properly support SVG in that if you try to replace SVG nodes they will appear in the DOM but not actually work correctly. This is due to the fact that SVG nodes use a different namespaceURI than the html nodes do. Htmx currently parses all content assuming it's text/html. When the parser it uses does this, all nodes get the namespaceURI for html regardless of any namespace provided in the elements. For now I have modified my copy of htmx in the makeFragment function to include support for a few SVG elements I'm using for hx-swap-oob elements. I also slightly modified the parseHTML function to take some additional arguments to support this. |
Beta Was this translation helpful? Give feedback.
-
I thought yesterday I'd learn HTMX so I can make a UI without learning JS. Good luck with that. My solution so far is below. It's minimally tested, and I might send a patch some time later, but leaving it here for whomever might need it (in case I don't). I modified <svg hx-parsing-context-only=true>
<g fill="red" hx-post="/api/handle/red" hx-swap="outerHTML">
<polygon points="87,50 87,-50 0,-100 -87,-50 -87,50 -0,100"></polygon>
</g>
</svg>
<div id="log" hx-swap-oob="true">Blue was clicked!</div> Note that the update has both: html oob swap, and svh/xml in place swap. function parseHTML(resp, depth) {
var parser = new DOMParser();
var responseDoc = parser.parseFromString(resp, "text/html");
/** @type {Element} */
var responseNode = responseDoc.body;
while (depth > 0) {
depth--;
// @ts-ignore
responseNode = responseNode.firstChild;
}
if (responseNode == null) {
// @ts-ignore
responseNode = getDocument().createDocumentFragment();
}
// The `hx-parsing-context-only` attribute can be used to send any set of tags wrapped in another tag.
// The original motivation is to allow sending SVG elements without the <svg> tag.
// It should allow the same flexibility for MathML tags, without the <math> tag.
//
// Even though SVG tags are allowed in an HTML document, they are not HTML tags.
// The <svg> tag is special. Inside the <svg> context, parser generates SVG-elements instead of HTML-elements.
//
// Normally, svg elements can only be sent inside <svg>, to trigger DOMParser context switch.
// The hx-parsing-context-only attribute allows sending a top level <svg> wrapper that is removed after parsing.
//
// More context:
// - https://github.com/bigskysoftware/htmx/discussions/1888
// - https://stackoverflow.com/questions/27489143/dynamic-svg-element-added-by-javascript-doesnt-work
// - https://stackoverflow.com/questions/3642035/jquerys-append-not-working-with-svg-element
forEach(responseNode.childNodes, function (element) {
let shouldUnwrap = !!getRawAttribute(element, "hx-parsing-context-only");
if (htmx.logger) {
// @ts-ignore
htmx.logger(element, "htmx:parsing-context", {
"shouldUnwrap": shouldUnwrap,
"objectType": Object.prototype.toString.call(responseNode)
});
}
if (shouldUnwrap) {
element.replaceWith(...element.childNodes);
}
})
return responseNode;
} |
Beta Was this translation helpful? Give feedback.
-
I made an svg extension for this. https://github.com/Fflath/svg-ext |
Beta Was this translation helpful? Give feedback.
-
I'm attempting to load an SVG graph in parts over time by rendering polyline nodes and appending to the points attribute of them from htmx polling requests. I have two questions:
First, is there a means already available to append to values within attributes in this way in htmx? I could not find one. I made a one off extension to achieve that effect for the time being.
Secondly, at the moment whenever my SVG is updated the browser is not re-rendering the SVG with the new content. The browser debugging tools show the new content is present however. A potentially important detail is that the SVG I'm updating is nested within another one which is the "topmost" SVG in the tree before it hits other html nodes. On each request I see the browser (chrome) "flash" the inner SVG node to indicate it changed in some way but the topmost SVG is not flashing. I don't know if that's relevant.
Thanks in advance.
Beta Was this translation helpful? Give feedback.
All reactions