Open Lubrsi opened 1 year ago
Does this mean DOMParser currently permits forcing arbitrary queued microtasks to be flushed “synchronously” (from the POV of the flush-inducing code) at will? I’d have expected (naively, anyway — I may not be picturing this right) the microtask checkpoint algorithm to be a noop any time user code is already on the execution stack.
Just wondering, is it possible that there is something "that delays the load event" here? If I'm not mistaken, scripting is disabled by lack of a browsing context, so I guess the two first lists of scripts from step 5 and step 7 should always already be empty, but I'm not quite sure about this step 8, though it seems that most requests are also blocked because the Document is not "fully active".
Asking because this reminds me of https://github.com/whatwg/html/issues/6230 where it was already spotted that browsers apparently don't really spin the event loop when the condition is already met. I guess the same could be happening here (assuming in your tests you don't have the microtask-checkpoint). Note: I agree that a strict reading of the specs indeed would ask for it to be visited, and incur a microtask-checkpoint, and it also seems true that most of this "the end" seems off for these parsers.
When the HTML parser stops parsing, it performs one conditional event loop spin on step 5.1 and two unconditional event loop spins on step 7 and 8. Spinning the event loop performs a microtask checkpoint on step 5.
However, this causes microtasks to execute at the wrong time. Take this example with custom elements:
This affects YouTube, which sets innerHTML of a
<template>
element in some custom element constructors before setting up class attributes, causing unhandled exceptions in connectedCallback when it tries to use the attributes it assumes were setup in the constructor.It appears WebKit and Blink skip most of
the end
for parsing fragments, roughly doing steps 2 and 4. It doesn't appear they skip any steps for DOMParser, as they don't usecreateFragmentForInnerOuterHTML
orcreateFragmentForMarkup
for DOMParser.WebKit: https://github.com/WebKit/WebKit/blob/44374328f96d4c74b57ce233a54d72406492774b/Source/WebCore/html/parser/HTMLDocumentParser.cpp#L140-L142
https://github.com/WebKit/WebKit/blob/46837e56d6f57f7e52bf92c9534cc7683909eee5/Source/WebCore/html/parser/HTMLTreeBuilder.cpp#L3024
https://github.com/WebKit/WebKit/blob/a36f6efecc490ae267d0a2103e86f1f0db533c62/Source/WebCore/xml/DOMParser.cpp#L41
Blink: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/parser/html_document_parser.cc;l=553-555;drc=f9ebf0deab3efad7c0db6843af187bb36f0ccb4c?q=html_document_parser&ss=chromium%2Fchromium%2Fsrc
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/parser/html_tree_builder.cc;l=2950;drc=f9ebf0deab3efad7c0db6843af187bb36f0ccb4c?q=html_tree_bui&ss=chromium%2Fchromium%2Fsrc
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/xml/dom_parser.cc;l=32;drc=f9ebf0deab3efad7c0db6843af187bb36f0ccb4c?q=dom_parser.cc&ss=chromium%2Fchromium%2Fsrc
I have not looked into what Gecko does for this.
There are other issues with
the end
in these cases, such as unnecessary events likereadystatechange
,DOMContentLoaded
andload
which are not observable and the WebDriver steps assuming Document's browsing context is non-null. However, I focused on spinning the event loop as it is observable by user code.