LibWeb: Parse srcdoc documents synchronously during activation

Bypass the async body-reading pipeline for about:srcdoc iframes whose
body bytes are already in memory. Set up a deferred parser at document
load time and run the post-activation update synchronously, so the body
element exists before parent script can observe the new document via
contentDocument. This matches Chrome and Firefox behavior for srcdoc
iframes and fixes the flaky test
`set-innerHTML-inside-iframe-srcdoc-document.html` that relied on body
being non-null.

Co-authored-by: Tim Ledbetter <tim.ledbetter@ladybird.org>
This commit is contained in:
Jelle Raaijmakers
2026-04-16 00:26:13 +02:00
committed by Tim Ledbetter
parent 732063aca9
commit a5e1c33743
Notes: github-actions[bot] 2026-04-22 12:28:50 +00:00
3 changed files with 32 additions and 0 deletions

View File

@@ -942,6 +942,15 @@ void ApplyHistoryStepState::process_continuations()
if (target_entry->document_state()->document_id() == displayed_document_id) {
update_document();
}
// AD-HOC: When the document already has its parser pre-loaded with in-memory data (currently set up
// only for about:srcdoc), perform updateDocument synchronously instead of queueing it.
// updateDocument calls Document::set_ready_to_run_scripts(), which kicks off the deferred
// parser. Running it in the same task as activation guarantees the body element exists before
// script in the parent navigable can observe the new document — matching Chrome and Firefox
// behavior for srcdoc iframes.
else if (resolved_document->has_deferred_parser_start()) {
update_document();
}
// 5. Otherwise, queue a global task on the navigation and traversal task source given targetEntry's document's relevant global object to perform updateDocument
else {
queue_global_task(Task::Source::NavigationAndTraversal, relevant_global_object(*resolved_document), GC::create_function(heap(), move(update_document)));