-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
htmx 2.0.0 breaks <template> elements inside Web Components #2702
Comments
Why: - Fixes lazy loading the territory-list-map. htmx 2.0.0 breaks web components which contain <template> elements: the template element isn't added to DOM. This leads to the map showing no data. See bigskysoftware/htmx#2702
Does htmx create some of its own templates and use them for oob swap? It seems dangerous to find and remove arbitrary template elements, instead of just those that htmx has created for a specific purpose. Maybe the oob swap templates could be tagged with a custom class or attribute for identification, and only delete those? |
Continuing the discussion with more investigation The following function seems to be taking care of OOB elements: findAndSwapOobElements(fragment, settleInfo) function findAndSwapOobElements(fragment, settleInfo) {
forEach(findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]'), function(oobElement) {
if (htmx.config.allowNestedOobSwaps || oobElement.parentElement === null) {
const oobValue = getAttributeValue(oobElement, 'hx-swap-oob')
if (oobValue != null) {
oobSwap(oobValue, oobElement, settleInfo)
}
} else {
oobElement.removeAttribute('hx-swap-oob')
oobElement.removeAttribute('data-hx-swap-oob')
}
})
} Now back to oob swaps again: // oob swaps
findAndSwapOobElements(fragment, settleInfo)
forEach(findAll(fragment, 'template'), /** @param {HTMLTemplateElement} template */function(template) {
findAndSwapOobElements(template.content, settleInfo)
if (template.content.childElementCount === 0) {
// Avoid polluting the DOM with empty templates that were only used to encapsulate oob swap
template.remove()
}
}) We are looping through each occurance of the fragment 'template' from the response of the findAll function (see htmx official doc) so it seems htmx is indeed looping through all elements of some type: Maybe if the findAndSwapOobElements() is assigned to a variable to introduce a second check (if HTMX modified the template) before removing the OOB template, that would help? forEach(findAll(fragment, 'template'), /** @param {HTMLTemplateElement} template */function(template) {
let wasModified = findAndSwapOobElements(template.content, settleInfo)
if (wasModified && template.content.childNodes.length === 0) {
// Only remove if HTMX modified it and it's completely empty
template.remove()
}
}) But then... I think this is starting a different discussion that maybe needs a new issue opened. So it seems we are back to the initial workaround or "fix": 🚧 Workaround: don't leave plaintext inside <template> |
Should I tag someone from the maintainers team? Or should I directly start PR to kickoff a discussion inside? I'm new to this whole open source contributing thing. 🥲 |
Hello @kubeden, haven't had much time lately to investigate issues, a bugfix PR would be very welcome as per our contribution guidelines:
So if you feel like it, sure go for it! |
When a htmx response contains
<template>
elements inside a Web Component element, htmx 1.9.12 adds them to the DOM, but htmx 2.0.0 removes them. This breaks web components which use that method to receive data from the server.Example app
server.py
Open the app at http://127.0.0.1:5000/
Open the JavaScript console and see what is printed there on page load
Expected result
template: <template>…</template> Lazy loaded content
Actual result
template: null undefined
The text was updated successfully, but these errors were encountered: