bigskysoftware / idiomorph

A DOM-merging algorithm
BSD 2-Clause "Simplified" License
631 stars 31 forks source link

Web Components don't survive hx-swap=morph #57

Open luontola opened 5 days ago

luontola commented 5 days ago

I have an htmx page with a form. Some form elements depend on other form elements, and the page has some web components which also depend on the form, so I want to swap all of them when the form is changed. I use Idiomorph to maintain form element focus.

But when I use hx-swap="morph:outerHTML", the web components stop working after the swap. None of the web components' callback methods are called when the swap happens. It seems like the original web component instance is never notified that it was removed from the DOM, and no new web component instance is initialized. With hx-swap="outerHTML" things work fine.

Example app

  1. Save this file as server.py
    
    from string import Template

from flask import Flask, request

app = Flask(name)

@app.route("/", methods=['GET', 'POST']) def home(): message = "world" if "message" in request.form: message = request.form['message'] html = Template("""

Hello $message from HTML

""").substitute(message=message) print(html) return html


2. Run the app with the commands:

pip install Flask flask --app server.py --debug run



3. Open the app at http://127.0.0.1:5000/

4. Write something to the input field

### Expected result

- The page should show the messages "Hello something from HTML" and "Hello something from Web Component"

### Actual result

- The page only shows "Hello something from HTML"
- The page source contains the element `<hello-world message="something"></hello-world>` without any of its dynamically generated child elements (it's like the web component was not re-initialized after the swap)
- The only log statements on the javascript console are "constructor" and "connectedCallback" from the original full page load (it's like the original web component instance wasn't notified that its DOM node was destroyed/recreated/updated)

## Workaround

In my app I was able to use `hx-select-oob` to update the web component portion of the page without morphing, and only morph the form which didn't contain web components.