Fix sequential script loading in webtrees.load()#5359
Fix sequential script loading in webtrees.load()#5359magicsunday wants to merge 1 commit intofisharebest:mainfrom
Conversation
The webtrees.load() function injects scripts dynamically via appendChild, but external scripts (with src) load asynchronously. Subsequent inline scripts execute immediately before the external script has finished loading, causing "not a constructor" errors for any module that uses separate script tags for library loading and initialization. Replace forEach with a Promise chain that waits for each external script's onload event before appending the next script element.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5359 +/- ##
=========================================
Coverage 35.37% 35.37%
Complexity 11196 11196
=========================================
Files 1166 1166
Lines 48031 48031
=========================================
Hits 16990 16990
Misses 31041 31041 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
For reference, this regression was introduced in commit a3ca8e1 ("Convert jQuery code to VanillaJS"). The previous jQuery This affects all custom modules that use the common two-block pattern ( |
Replace two separate View::push('javascript') blocks with a single
<script type="module"> block using dynamic import(). The import()
promise waits for the external script to load before initializing,
avoiding the race condition in webtrees.load() (PR fisharebest/webtrees#5359).
Replace two separate View::push('javascript') blocks with a single
<script type="module"> block using dynamic import(). The import()
promise waits for the external script to load before initializing,
avoiding the race condition in webtrees.load() (PR fisharebest/webtrees#5359).
|
Our modules no longer trigger this race condition — we switched to dynamic Keeping this PR open since the fix in |
Summary
webtrees.load()where inline scripts execute before external scripts have finished loadingforEachwith aPromisechain that waits for each external script'sonloadevent before appending the next scriptProblem
The
webtrees.load()function (which replaced jQuery's.load()) dynamically injects<script>elements viaappendChild. External scripts (withsrc) load asynchronously by default, but theforEachloop immediately appends the next script without waiting. This causes inline scripts that depend on a preceding external library to fail with errors like:This affects any custom module that uses the common pattern of pushing an external script tag followed by an inline initialization script via
View::push('javascript').Fix
Scripts are now loaded sequentially using a
Promisechain. External scripts wait for theironloadevent before the next script in the chain is appended to the DOM.Test plan
View::push('javascript')with separate external and inline script blocks load correctly