webapi: parser insertions into the document notify mutation observers

Fixes "parser insertion mutations" in WPT
/dom/nodes/MutationObserver-document.html (1/4 -> 2/4): a script running
during the initial document parse can observe the document with
{subtree, childList} and must receive records for the nodes the parser
inserts after it. We suppressed all notifications for main-document
parser insertions.

Parser insertions now notify per inserted node. Fragment parses
(innerHTML et al.) stay silent, since Node.setHTML queues a single
combined "replace all" record. There is no overhead in the common case:
notifyChildInserted is gated on any observer existing, which is never
true during a parse unless an earlier script registered one.

The remaining two subtests need synchronous execution of scripts
inserted by other scripts during parsing (record batching across the
two) and parser insertions into a parent removed mid-parse; both are
script-scheduling semantics, not observer plumbing.

Coverage: /dom/nodes/MutationObserver-document.html 1/4 -> 2/4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Francis Bouvier
2026-07-11 21:44:39 +02:00
parent 01e930c73b
commit 31273fe89a

View File

@@ -2590,13 +2590,16 @@ pub fn _insertNodeRelative(self: *Frame, comptime from_parser: bool, parent: *No
}
}
// The parser path does its own (limited) connected-callback work, then
// returns.
// The parser path does its own (limited) notification and
// connected-callback work, then returns.
if (comptime from_parser) {
// No mutation records from parser insertions: the initial document
// parse never notifies, and fragment parses (innerHTML et al.) queue
// one combined "replace all" record at the call site (Node.setHTML)
// instead of one per inserted child.
// Main-document parser insertions notify per node: scripts running
// during parsing can observe the document. Fragment parses
// (innerHTML et al.) stay silent; Node.setHTML queues one combined
// "replace all" record instead.
if (self._parse_mode != .fragment) {
self.notifyChildInserted(parent, child);
}
if (child.is(Element)) |el| {
// Invoke connectedCallback for custom elements during parsing.