LibWeb: Don't rely on SHTQ::process() in process_the_iframe_attributes

`HTMLIFrameElement::inserted()` does following:
1. Init a new navigable. This step appends a task on session history
   traversal queue (SHTQ) that creates a new nested history.
2. Process iframe's attributes

Processing of iframe's attributes might result in synchronous
navigation that fails to get active SHE if SHTQ task that creates
new nested history is not yet completed.

Before this change, a workaround involved forcing the processing of
SHTQ, which was terrible hack because it could occur in the middle of
another SHTQ task.

This change removes the need for "force SHTQ processing" by ensuring
that the processing of iframe's attributes is always executed after
the iframe's navigable nested history has been created.
This commit is contained in:
Aliaksandr Kalenik 2024-04-04 18:49:40 +02:00 committed by Alexander Kalenik
commit 11011cf250
Notes: sideshowbarker 2024-07-17 07:35:03 +09:00
4 changed files with 21 additions and 8 deletions

View file

@ -59,7 +59,7 @@ JS::GCPtr<NavigableContainer> NavigableContainer::navigable_container_with_conte
}
// https://html.spec.whatwg.org/multipage/document-sequences.html#create-a-new-child-navigable
WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable()
WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable(JS::SafeFunction<void()> afterSessionHistoryUpdate)
{
// 1. Let parentNavigable be element's node navigable.
auto parent_navigable = navigable();
@ -110,7 +110,7 @@ WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable()
auto traversable = parent_navigable->traversable_navigable();
// 12. Append the following session history traversal steps to traversable:
traversable->append_session_history_traversal_steps([traversable, navigable, parent_navigable, history_entry] {
traversable->append_session_history_traversal_steps([traversable, navigable, parent_navigable, history_entry, afterSessionHistoryUpdate = move(afterSessionHistoryUpdate)] {
// 1. Let parentDocState be parentNavigable's active session history entry's document state.
auto parent_doc_state = parent_navigable->active_session_history_entry()->document_state();
@ -137,6 +137,10 @@ WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable()
// 6. Update for navigable creation/destruction given traversable
traversable->update_for_navigable_creation_or_destruction();
if (afterSessionHistoryUpdate) {
afterSessionHistoryUpdate();
}
});
return {};
@ -300,6 +304,9 @@ void NavigableContainer::destroy_the_child_navigable()
// https://html.spec.whatwg.org/multipage/iframe-embed-object.html#potentially-delays-the-load-event
bool NavigableContainer::currently_delays_the_load_event() const
{
if (!m_content_navigable_initialized)
return true;
if (!m_potentially_delays_the_load_event)
return false;