Full Happy DOM Replacement: Eigenes DOM System + Fragment Parser #104
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#104
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?
#101 — Full Happy DOM Replacement: Eigenes DOM System + Fragment Parser
Problembeschreibung
Happy DOM ist aktuell noch für drei Kernbereiche verantwortlich, die zunehmend als Pain Points wirken:
1. DOM Tree + Elemente (~35.000 Zeilen Happy DOM)
PropertySymbol-Struktur verursacht Workarounds in Shadow DOM, innerHTML und Custom Elementsinstanceof HTMLDivElementetc. laufen nur innerhalb des Happy DOM Window-Kontexts — bei Proxy-Umwegen brechen siedocument.createElement()/appendChild()geht2. HTML Parsing (über
element.innerHTML = ...)el.innerHTML = '<div>'landet im Initial-Mode statt InBody3. Event System
Aktuelle Architektur
Lösungsansätze
Option A — Fragment-Modus im Custom Parser (2 Tage, ~300 Zeilen)
Idee: Dem TreeBuilder einen Fragment-Modus geben. Statt Initial→BeforeHTML→BeforeHead→BeforeBody → direkt InBody starten.
Vorteile:
Nachteile:
Option B — Fragment + eigenes Event System (1-2 Wochen, ~1.500 Zeilen)
Wie A, plus: Eigenes
EventTarget+dispatchEventvon Grund:Vorteile:
Nachteile:
Option C — Full Replacement: Eigenes DOM System (2-4 Wochen, ~8.000 Zeilen Kern + ~2.000 HTML Elements)
Alles neu:
nwsapi-Enginenwsapiodercss-selectals externe Lib — ~100 Zeilen WrapperGesamt: ~3.500-4.000 Zeilen Kern (ohne HTML Elements) + ~2.000 Zeilen HTML Elements = ~5.500-6.000 Zeilen.
Vorteile:
Nachteile:
querySelectorAllbraucht eine externe Lib (nwsapi) — das ist aber stabilEntscheidung: Option C — Full Replacement
Begründung:
Akzeptanzkriterien
Phase 1: DOM Core + Parser Integration (~1 Woche)
Phase 2: Events + Query (~3 Tage)
Phase 3: HTML Elements (~1 Woche)
Phase 4: MutationObserver (~2 Tage)
Phase 5: Integration + Migration (~2 Tage)
new HappyWindow()→ ersetzt durchnew OwnDocument()Window-Objekt ist ein eigenes Window (location, navigator, setTimeout delegiert an Bun/EventLoop)EventSystemnicht mehr von Happy DOM → dispatchEvent, addEventListener komplett eigenMutationObservereigenimport { Window } from "happy-dom"mehr irgendwoimport type { Window } from "happy-dom"mehr irgendwofake-indexeddb/autoals einzige externe Browser LibBetroffene Dateien
Neu
src/dom/node.tssrc/dom/element.tssrc/dom/text.tssrc/dom/comment.tssrc/dom/document.tssrc/dom/document-fragment.tssrc/dom/attr.tssrc/dom/event-target.tssrc/dom/event.tssrc/dom/events.ts(alle Event-Klassen)src/dom/css-style-declaration.tssrc/dom/query.ts(Selector Wrapper für nwsapi)src/dom/mutation-observer.tssrc/dom/html-elements.ts(alle 25 HTML Elements)src/dom/serializer.ts(innerHTML Serialisierung)src/dom/window.tssrc/dom/index.tsÄndern
src/dom/parser.tsIncrementalParsernutzt eigenen DOM statt Happy DOMsrc/html/DOMBuilder.tsdocument.createElement()src/runtime-isolation.tsnew OwnDocument()stattnew Window()aus Happy DOMsrc/shadow-dom/shadow-root.tssrc/shadow-dom/event-retargeting.tssrc/forms/form-action.tssrc/custom-elements/shim.tsLöschen
package.json→"happy-dom"Dependency"fake-indexeddb"Abhängigkeiten
→ package.json Dependency Change:
"happy-dom"raus,"nwsapi"reinRisiken
Performance-Impact
Testplan
happy-domin imports → 0 TrefferGesamt: ~130 neue Tests.
Phasen-Implementierung (Reihenfolge)
Jede Phase wird als eigenständiger Commit/Push ausgeliefert. Phasen 1-2 sind pre-requisite für Phase 3. Phase 5 läuft erst nach erfolgreichem Abschluss aller vorherigen Phasen.
Frühester Switch-Punkt (Phase 1 fertig):
Nach Phase 1 kann der Custom Parser bereits eigene Nodes bauen und
innerHTMLsteuern. Happy DOM wird dann nur noch für Events + HTML Elements + MutationObserver gebraucht — und fallbackt sofort bei Problemen.Querverweise
✅ Phase 1 implementiert: DOM Core + Parser Integration
Commit:
f1659e1Neu erstellte Dateien
src/dom/node.tssrc/dom/serializer.tssrc/dom/factory.tssrc/dom/index.tstests/unit/dom-phase1.test.tsGeanderte Dateien
src/html/HTMLParser.tssrc/html/tree-construction.tsAkzeptanzkriterien erreicht
✅ Happy DOM Replacement — Vollstandig integriert (Commit
752554b)useOwnDom: truein createIsolatedContext() ist jetzt einsatzbereit.Was funktioniert:
Noch offen (Phase 3/4 fur nachstes Sprint):
Phase 3/4 Plan — Non-Visual-DOM-Optimizations
Basierend auf
references/non-visual-dom-opti.md— 10 Optimierungs-Protokolle fur perfektes DOM-Verhalten ohne visuelles Rendering.Neue Issues (erstellt)
Non-Visual-DOM-Protokoll (10 Regeln)
Kernprinzip: Frameworks prufen DOM-CORRECTNESS (instanceof, > 0, !== null) nicht VISUAL-ACCURACY (Pixel-genaue Werte).