From adcc3905e5f1ba0dc7375b839141bfc09b82cc8c Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Fri, 5 Apr 2024 16:02:52 +0200 Subject: [PATCH] LibWeb: Pass SynchronousNavigation flag into "apply the history step" Workaround spec bug by explicitly carrying information whether navigation is sync (History api, fragment change) or not. See for more details https://github.com/whatwg/html/issues/10232 --- Userland/Libraries/LibWeb/HTML/Navigable.cpp | 2 +- .../LibWeb/HTML/TraversableNavigable.cpp | 17 +++++++++-------- .../LibWeb/HTML/TraversableNavigable.h | 9 +++++++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp index 43c6ed04a4..d09f6b45a6 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp @@ -1866,7 +1866,7 @@ void finalize_a_cross_document_navigation(JS::NonnullGCPtr navigable, } // 10. Apply the push/replace history step targetStep to traversable. - traversable->apply_the_push_or_replace_history_step(target_step, history_handling); + traversable->apply_the_push_or_replace_history_step(target_step, history_handling, TraversableNavigable::SynchronousNavigation::No); } // https://html.spec.whatwg.org/multipage/browsing-the-web.html#url-and-history-update-steps diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp index 77600f7581..9e6b94ca3b 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp @@ -384,7 +384,8 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ Optional source_snapshot_params, JS::GCPtr initiator_to_check, Optional user_involvement_for_navigate_events, - Optional navigation_type) + Optional navigation_type, + SynchronousNavigation synchronous_navigation) { auto& vm = this->vm(); // FIXME: 1. Assert: This is running within traversable's session history traversal queue. @@ -474,7 +475,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ }; // 4. If displayedEntry is targetEntry and targetEntry's document state's reload pending is false, then: - if (displayed_entry == target_entry && !target_entry->document_state()->reload_pending()) { + if (synchronous_navigation == SynchronousNavigation::Yes && !target_entry->document_state()->reload_pending()) { // 1. Set changingNavigableContinuation's update-only to true. changing_navigable_continuation.update_only = true; @@ -907,7 +908,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::update_for_navigab auto step = current_session_history_step(); // 2. Return the result of applying the history step to traversable given false, null, null, null, and null. - return apply_the_history_step(step, false, {}, {}, {}, {}); + return apply_the_history_step(step, false, {}, {}, {}, {}, SynchronousNavigation::No); } // https://html.spec.whatwg.org/multipage/browsing-the-web.html#apply-the-reload-history-step @@ -917,20 +918,20 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_reload_h auto step = current_session_history_step(); // 2. Return the result of applying the history step step to traversable given true, null, null, null, and "reload". - return apply_the_history_step(step, true, {}, {}, {}, Bindings::NavigationType::Reload); + return apply_the_history_step(step, true, {}, {}, {}, Bindings::NavigationType::Reload, SynchronousNavigation::No); } -TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_push_or_replace_history_step(int step, HistoryHandlingBehavior history_handling) +TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_push_or_replace_history_step(int step, HistoryHandlingBehavior history_handling, SynchronousNavigation synchronous_navigation) { // 1. Return the result of applying the history step step to traversable given false, null, null, null, and historyHandling. auto navigation_type = history_handling == HistoryHandlingBehavior::Replace ? Bindings::NavigationType::Replace : Bindings::NavigationType::Push; - return apply_the_history_step(step, false, {}, {}, {}, navigation_type); + return apply_the_history_step(step, false, {}, {}, {}, navigation_type, synchronous_navigation); } TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_traverse_history_step(int step, Optional source_snapshot_params, JS::GCPtr initiator_to_check, UserNavigationInvolvement user_involvement) { // 1. Return the result of applying the history step step to traversable given true, sourceSnapshotParams, initiatorToCheck, userInvolvement, and "traverse". - return apply_the_history_step(step, true, move(source_snapshot_params), initiator_to_check, user_involvement, Bindings::NavigationType::Traverse); + return apply_the_history_step(step, true, move(source_snapshot_params), initiator_to_check, user_involvement, Bindings::NavigationType::Traverse, SynchronousNavigation::No); } // https://html.spec.whatwg.org/multipage/document-sequences.html#close-a-top-level-traversable @@ -1034,7 +1035,7 @@ void finalize_a_same_document_navigation(JS::NonnullGCPtr } // 6. Apply the push/replace history step targetStep to traversable given historyHandling. - traversable->apply_the_push_or_replace_history_step(*target_step, history_handling); + traversable->apply_the_push_or_replace_history_step(*target_step, history_handling, TraversableNavigable::SynchronousNavigation::Yes); } // https://html.spec.whatwg.org/multipage/interaction.html#system-visibility-state diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h index 494ec7fe31..f065cfb4de 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h @@ -50,7 +50,11 @@ public: HistoryStepResult apply_the_traverse_history_step(int, Optional, JS::GCPtr, UserNavigationInvolvement); HistoryStepResult apply_the_reload_history_step(); - HistoryStepResult apply_the_push_or_replace_history_step(int step, HistoryHandlingBehavior history_handling); + enum class SynchronousNavigation : bool { + Yes, + No, + }; + HistoryStepResult apply_the_push_or_replace_history_step(int step, HistoryHandlingBehavior history_handling, SynchronousNavigation); HistoryStepResult update_for_navigable_creation_or_destruction(); int get_the_used_step(int step) const; @@ -98,7 +102,8 @@ private: Optional, JS::GCPtr initiator_to_check, Optional user_involvement_for_navigate_events, - Optional navigation_type); + Optional navigation_type, + SynchronousNavigation); Vector> get_session_history_entries_for_the_navigation_api(JS::NonnullGCPtr, int);