Fix ready state for htmx:load listeners bound on DOMContentLoaded - #2037
Fix ready state for htmx:load listeners bound on DOMContentLoaded#2037Telroshan wants to merge 1 commit into
Conversation
|
Having written the first version of it myself, I think that this bit of code is ill-advised. It was important to support modules, because those are a Native JS feature, but trying to cover ever possible permutation of when htmx might enter the DOM is a fool's errand. Because So what I propose instead is that we revert #1972, and provide an |
|
Closing this in favor of #2040, after discussion |
Description
So we introduced a commit recently to fix the ready state detection when loading htmx as an async script.
Seems we missed it at that time but we actually introduced a regression for that specific behaviour:
DOMContentLoadedvia its internalreadyfunctionDOMContentLoadedto wait for htmx to be initializedDOMContentLoadedfires, htmx initializes itselfs thanks to its initialreadylistener that has been called back, queues a setTimeout that will firehtmx:loadhtmx:loadevent usinghtmx.onLoad, which itself callshtmx.onhtmx.oninternally also calls thatreadyfunction, it now goes through that new logic we introduced in the commit mentioned above. This is where lies the problem:complete? Not yet. So the callback won't be called right awayreadyqueues the callback for bothDOMContentLoadedandreadystatechange.DOMContentLoadedhas already been fired at this point, soreadystatechangewould catch it, but not now since the page has to reach thecompletestate first (when all assets are downloaded)setTimeoutthat had been queued is executed, andhtmx:loadis fired on the bodycompletestate, thehtmx.onlistener is called back, thus the client's custom script that binds a listener function tohtmx:load. However,htmx:loadhas already been fired at this point, and this listener won't be called since it missed that initialhtmx:loadevent.Hope the description of the problem is clear, let me know!
As for the fix, this PR introduces again (that boolean variable is a mechanism we had prior to the commit mentioned above) a boolean variable, that is set to true the first time a
readycallback is called. When areadylistener is called, we know that no matter what the state of the document is, htmx is now initialized and can bind events right away. Because this variable would be set to true in the steps described above, the client'shx.onLoadcall wouldn't be bound to the document events but called right away instead. Thus, its load listener would be called when htmx fireshtmx:loadCorresponding issue: #2033
Testing
First, to reproduce the issue:
I don't know how to write a test in the test suite for it, since it really relies on this timing between
DOMContentLoadedandloadevents with the initialhtmx:loadevent, and the test suite only runs onDOMContentLoaded, by the time this test runs, thecompletestate would very likely already been reachedChecklist
masterfor website changes,devforsource changes)
approved via an issue
npm run test) and verified that it succeeded