bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
38.19k stars 1.3k forks source link

Swapping via SSE not working when the content has the same id #295

Closed zilti closed 1 year ago

zilti commented 3 years ago

I assumed the smooth transition HTMX does would also work for SSE. So I made a minimal page with a simple, absolutely-positioned div that gets replaced via an SSE. That works fine when the div doesn't have an id - and falls apart completely as soon as it does. With the id attribute, the content will never get swapped. Minimal webpage showing it does not work:

<html><body>
<div>
<script src="https://unpkg.com/htmx.org@1.0.2"></script>
<div hx-sse="connect:/sse swap:demo">
<div id="anidemo" style="position: absolute; top: 50px; left: 50px;">X</div></div></div></body></html>

SSE body:

<div id="anidemo" style="position: absolute; top: 500px; left: 500px;">X</div>

Removing the id="anidemo" from both will make it work (but, obviously, without transition). Tested in Firefox 84.0.

benpate commented 3 years ago

Hey @zilti thanks for the report. I did some of the work on SSE, but am now a maintainer on the project itself. Right now, SSE uses some of the swapping logic that a regular hx-get would use, but not all of it. And, I'm pretty sure that the transitions (sometimes called swizzling) would not be a part of that. It's something that I'm hoping we'll be able to implement, but would have taken more work than we could do for 1.0.

When you run your demo, does anything outright break? Or is it just the transitions that are not behaving the way you'd expect?

zilti commented 3 years ago

It does break, yes. The SSE gets completely ignored when the id attribute is there. There are no errors shown in the browser console though.

benpate commented 3 years ago

Thanks for the insight. I'm AFK for a while, but I'll try to take a look at this soon.

1cg commented 3 years ago

@benpate I'll defer this one to you, but I'm happy to help if needed.

benpate commented 3 years ago

Hey @zilti I took another look at this, and I have some dumb questions to ask you. I've gotten a very close replica of your code working on my machine, using my own SSE generator. I'm still not getting the "animations" to appear correctly, so that is odd. However, the content itself is showing up correctly.

The first thing I can think of, and want to check with you, is that your SSE engine is generating each message using the demo event type. Each SSE message can include a unique event type, and that is what the swap: command is looking for. If your engine does not generate a message type, you can use the default swap:message to match the empty type. It's the one peculiar part of using SSEs that is not very intuitive, and we have no way to work around it from Javascript.

Like I said, I'm going to keep digging for a bit, but thought I'd check in with you on this before I continue.

benpate commented 3 years ago

@1cg -- there is something funny going on. Here's what I'm seeing. If I include the id attribute in both the original HTML or in the SSE message, then some parts don't seem to be swapped correctly. The innerHTML still changes for me with each message, but the style and class of the node do not. This means (using @zilti 's code above) that the DIV stays pinned to top:50, left:50, instead of moving to top:500, left:500 as it seems like it should.

I think there's some deep magic happening in the selectAndSwap function that I'm afraid to dig into. Could you please take a look?

zilti commented 3 years ago

The innerHTML still changes for me with each message, but the style and class of the node do not.

Hmm yes, these two are the only attributes I changed. So I guess it is safe to assume that the innerHTML actually did get changed anyway in my case.

zilti commented 3 years ago

As of 1.3.3, it has become completely impossible to swap in div elements using SSE.

benpate commented 3 years ago

Hey @zilti -- sorry I've been slow getting back to you on this. I just ran a quick test using my SSE placeholder demo app, and everything is working correctly for me.

I'm pretty sure nothing has changed with this set of code for a while, so if something IS broken, it's likely because of something new that was introduced in 1.3.3. Here's the diff on the source code between 1.3.2 and 1.3.3. It doesn't look like anything relative to SSE or swapping has been touched.

Are you able to provide some demo code, or any error messages? This might be tough to track down otherwise.

tk-png commented 1 year ago

I'm swapping in a div from SSE with an id tag and the standard animation works fine. On Chrome 118, htmx 1.9.6.