From 31273fe89a64a5c519f42607bf29bbadf7bbbcfb Mon Sep 17 00:00:00 2001 From: Francis Bouvier Date: Sat, 11 Jul 2026 21:44:39 +0200 Subject: [PATCH] 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 --- src/browser/Frame.zig | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/browser/Frame.zig b/src/browser/Frame.zig index fa0482e69..3483b4b6e 100644 --- a/src/browser/Frame.zig +++ b/src/browser/Frame.zig @@ -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.