Browse Source

LibWeb: Implement "consume history-action user activation"

Jamie Mansfield 1 year ago
parent
commit
a741f68eb9

+ 26 - 1
Userland/Libraries/LibWeb/HTML/Navigation.cpp

@@ -909,6 +909,29 @@ void Navigation::notify_about_the_committed_to_entry(JS::NonnullGCPtr<Navigation
     WebIDL::resolve_promise(realm, api_method_tracker->committed_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<JS::GCPtr<Window>> 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())

+ 1 - 0
Userland/Libraries/LibWeb/HTML/Navigation.h

@@ -150,6 +150,7 @@ private:
     void reject_the_finished_promise(JS::NonnullGCPtr<NavigationAPIMethodTracker>, JS::Value exception);
     void clean_up(JS::NonnullGCPtr<NavigationAPIMethodTracker>);
     void notify_about_the_committed_to_entry(JS::NonnullGCPtr<NavigationAPIMethodTracker>, JS::NonnullGCPtr<NavigationHistoryEntry>);
+    void consume_history_action_user_activation(Window& window);
 
     bool inner_navigate_event_firing_algorithm(
         Bindings::NavigationType,

+ 6 - 0
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<double> };
 
+    // https://html.spec.whatwg.org/multipage/interaction.html#last-history-action-activation-timestamp
+    HighResolutionTime::DOMHighResTimeStamp m_last_history_action_activation_timestamp { AK::Infinity<double> };
+
     // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
     JS::GCPtr<WebIDL::CallbackType> m_count_queuing_strategy_size_function;