diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.cpp b/Userland/Libraries/LibWeb/HTML/Navigation.cpp index ba03ee6fbfd..fc1d3ab0ac6 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigation.cpp @@ -909,6 +909,29 @@ void Navigation::notify_about_the_committed_to_entry(JS::NonnullGCPtrcommitted_promise, nhe); } +// https://html.spec.whatwg.org/multipage/interaction.html#consume-history-action-user-activation +void Navigation::consume_history_action_user_activation(Window& w) +{ + // 1. If W's navigable is null, then return. + if (!w.navigable()) + return; + + // 2. Let top be W's navigable's top-level traversable. + auto top = w.navigable()->top_level_traversable(); + + // 3. Let navigables be the inclusive descendant navigables of top's active document. + auto navigables = top->active_document()->inclusive_descendant_navigables(); + + // 4. Let windows be the list of Window objects constructed by taking the active window of each item in navigables. + Vector> windows; + for (auto& navigable : navigables) + windows.append(navigable->active_window()); + + // 5. For each window in windows, set window's last history-action activation timestamp to window's last activation timestamp. + for (auto& window : windows) + window->set_last_history_action_activation_timestamp(window->get_last_activation_timestamp()); +} + // https://html.spec.whatwg.org/multipage/nav-history-apis.html#inner-navigate-event-firing-algorithm bool Navigation::inner_navigate_event_firing_algorithm( Bindings::NavigationType navigation_type, @@ -1070,7 +1093,9 @@ bool Navigation::inner_navigate_event_firing_algorithm( // 29. If dispatchResult is false: if (!dispatch_result) { - // FIXME: 1. If navigationType is "traverse", then consume history-action user activation. + // 1. If navigationType is "traverse", then consume history-action user activation. + if (navigation_type == Bindings::NavigationType::Traverse) + consume_history_action_user_activation(relevant_global_object); // 2. If event's abort controller's signal is not aborted, then abort the ongoing navigation given navigation. if (!event->abort_controller()->signal()->aborted()) diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.h b/Userland/Libraries/LibWeb/HTML/Navigation.h index 25319147e18..fbd0e66900f 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.h +++ b/Userland/Libraries/LibWeb/HTML/Navigation.h @@ -150,6 +150,7 @@ private: void reject_the_finished_promise(JS::NonnullGCPtr, JS::Value exception); void clean_up(JS::NonnullGCPtr); void notify_about_the_committed_to_entry(JS::NonnullGCPtr, JS::NonnullGCPtr); + void consume_history_action_user_activation(Window& window); bool inner_navigate_event_firing_algorithm( Bindings::NavigationType, diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index d1860189382..2ca57ef6061 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -214,6 +214,9 @@ public: HighResolutionTime::DOMHighResTimeStamp get_last_activation_timestamp() const { return m_last_activation_timestamp; } void set_last_activation_timestamp(HighResolutionTime::DOMHighResTimeStamp timestamp) { m_last_activation_timestamp = timestamp; } + HighResolutionTime::DOMHighResTimeStamp get_last_history_action_activation_timestamp() const { return m_last_history_action_activation_timestamp; } + void set_last_history_action_activation_timestamp(HighResolutionTime::DOMHighResTimeStamp timestamp) { m_last_history_action_activation_timestamp = timestamp; } + static void set_inspector_object_exposed(bool); static void set_internals_object_exposed(bool); @@ -288,6 +291,9 @@ private: // https://html.spec.whatwg.org/multipage/interaction.html#user-activation-data-model HighResolutionTime::DOMHighResTimeStamp m_last_activation_timestamp { AK::Infinity }; + // https://html.spec.whatwg.org/multipage/interaction.html#last-history-action-activation-timestamp + HighResolutionTime::DOMHighResTimeStamp m_last_history_action_activation_timestamp { AK::Infinity }; + // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function JS::GCPtr m_count_queuing_strategy_size_function;