bigskysoftware / idiomorph

A DOM-merging algorithm
BSD 2-Clause "Simplified" License
693 stars 33 forks source link

`hx-swap="morph:outerHTML` being treated as `innerHTML` #8

Open Hades32 opened 1 year ago

Hades32 commented 1 year ago

Hey @1cg, when I use a hidden inner element to auto-refresh a component, I get infinitely nested elements. It seems like either the target is ignored or the modifier. Any thoughts?

<button
    id="mod-button"
    hx-get=/mod-queue'
    hx-trigger="click"
    hx-target="#root-container"
>
    {/* auto-refresh */}
    <span className="hidden" 
        hx-get="/components/my-button" 
        hx-target="closest button" 
        hx-swap="morph:outerHTML" 
        hx-trigger="every 5s"></span>

When I change it to hx-swap="outerHTML" it works as expected

mossblaser commented 1 year ago

Can confirm I've encountered this issue too!

1cg commented 1 year ago

what content is being returned by /components/my-button?

mossblaser commented 1 year ago

Ah-ha! I suspect I've found the issue here -- and its a simple documentation issue. To use idiomorph with htmx you need to use the version of the library which also includes a htmx extension binding not found in the default JS file on unpkg listed in the README. Instead you need to use: https://unpkg.com/idiomorph/dist/idiomorph-ext.min.js. It would be great to include this detail somewhere in the README since I'm sure plenty of folks will be coming to this repo looking to use this with htmx.

Aside: Unfortunately, htmx does not emit a warning when you hx-ext an undefined extension nor when you use a hx-swap. Instead htmx falls back on using the default swap mode (innerHTML) resulting in the apparently broken behaviour seen in this issue above. Perhaps this unlucky pair of 'sharp edges' are worth of fixing in htmx?

Skinner927 commented 5 months ago

Just to add to @mossblaser 's great answer, you'll want to set hx-ext="morph".