Sprint 23: Script-Tags im DOM — parentNode/currentScript für deferred & recaptcha #85
Labels
No labels
bug
docs
feature
housekeeping
html-spec
performance
react-compat
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
glow-all/true-headless-browser#85
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problembeschreibung
Aktuell werden ALLE
<script>Tags aus dem HTML gestrippt, bevor es an Happy DOM übergeben wird (parser.ts Zeile 82). Dadurch:document.querySelector('script[src=...]')selbst findendocument.currentScriptzeigt auf ein Fake-Element ohne echten parentNodes.parentNode.insertBefore()verwendet (recaptcha, spotify boot) crashtBetroffene Sites:
spotify.com— 19.5KB DOM statt 3MB+ Appqwik.dev— deferred Scripts crashen (177KB DOM trotzdem weil main bundle läuft)Fehlerbild Crawl:
Aktuelle Architektur (parser.ts)
Problem: In Schritt 3-4 feuert Happy DOM's
connectedToDocumentfür jedes<script>. Aber scripts wurden gestrippt → nichts passiert. ABER: die Scripts sind auch nicht im DOM →querySelector('script[src=...]')findet nix.Option A: Scripts im DOM lassen + early guard (empfohlen)
Erklärung: In Schritt 4 feuert
connectedToDocumentfür jedes<script>. Der DynamicScriptHandler checkt:_parserHandledScripts === true→ skippe inline scriptsloadedUrls.has(url)→ skippe pre-scanned externe scriptsVorteile:
document.querySelector('script[src=...]')findet alle Scriptsdocument.currentScript.parentNodeexistiert im DOMRisiken:
Option B: Placeholder-Elemente
Ersetze
<script>mit<span data-thb-script="true" style="display:none"></span>.Scripts können Platzhalter finden, aber Happy DOM evaluiert sie nicht.
Abgelehnt —
querySelector('script[src=...]')findet placeholder nicht (falscher nodeName).Option C: MutationObserver-block && dann DOM-Injection
Während des HTML-Parsens das MutationObserver-Processing pausieren, dann scripts laden und nachträglich ins DOM injecten.
Abgelehnt — zu komplex, Browserspezifikation sagt Scripts sind während loading im DOM.
Akzeptanzkriterien
document.querySelector('script[src=...]')findet MAIN scriptss.parentNode.insertBefore(x, s)crasht nicht (recaptcha)Betroffene Dateien
src/dom/parser.tssrc/js/dynamic-scripts.tssrc/js/execution-realm.tstests/...Testplan
document.currentScript.parentNodeexistiert während execution✅ Issue #85 — Geschlossen (Sprint 19)
Commit:
bc0c26bWas geändert wurde
<script>Tags aus HTML gestrippt vordocument.write()<script>Tags an Happy DOMquerySelector('script[src=...]')→ nullcurrentScript.parentNode→ undefineds.parentNode.insertBefore()→TypeErrordocument.write()Neue Architektur
Wie connectedToDocument blockt
disableEvaluation=true, skip_execInlineScript✅disableEvaluation=true, skip0 Regression
1519 pass / 4 pre-existing fail