From 29029de83901847ba97a5994c870ef2fa6b2e9b9 Mon Sep 17 00:00:00 2001 From: stelar7 Date: Wed, 31 May 2023 00:13:56 +0200 Subject: LibWeb: Set `last activation timestamp` on the window --- Userland/Libraries/LibWeb/DOM/EventTarget.cpp | 50 +++++++++++++++++++++++++++ Userland/Libraries/LibWeb/HTML/Window.h | 6 ++++ 2 files changed, 56 insertions(+) diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp index ce1c7fa08e..06d345687a 100644 --- a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp +++ b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -30,7 +31,9 @@ #include #include #include +#include #include +#include #include namespace Web::DOM { @@ -751,6 +754,53 @@ void EventTarget::element_event_handler_attribute_changed(FlyString const& local bool EventTarget::dispatch_event(Event& event) { + // https://html.spec.whatwg.org/multipage/interaction.html#activation-triggering-input-event + auto is_activation_triggering_input_event = [&]() -> bool { + // An activation triggering input event is any event whose isTrusted attribute is true and whose type is one of: + if (!event.is_trusted()) + return false; + + // keydown, provided the key is neither the Esc key nor a shortcut key reserved by the user agent. + if (event.type() == UIEvents::EventNames::keydown) + return static_cast(&event)->key_code() != KeyCode::Key_Escape; + + // mousedown. + if (event.type() == UIEvents::EventNames::mousedown) + return true; + + // FIXME: + // pointerdown, provided the event's pointerType is "mouse". + // pointerup, provided the event's pointerType is not "mouse". + // touchend. + + return false; + }; + + // https://html.spec.whatwg.org/multipage/interaction.html#user-activation-processing-model + // When a user interaction causes firing of an activation triggering input event in a Document document, + // the user agent must perform the following activation notification steps before dispatching the event: + + // FIXME: 1. Assert: document is fully active. + // FIXME: 2. Let windows be « document's relevant global object ». + // FIXME: 3. Extend windows with the active window of each of document's ancestor navigables. + // FIXME: 4. Extend windows with the active window of each of document's descendant navigables, + // filtered to include only those navigables whose active document's origin is same origin with document's origin. + // FIXME: 5. For each window in windows, set window's last activation timestamp to the current high resolution time. + + // FIXME: This is ad-hoc, but works for now. + if (is_activation_triggering_input_event()) { + auto unsafe_shared_time = HighResolutionTime::unsafe_shared_current_time(); + auto current_time = HighResolutionTime::relative_high_resolution_time(unsafe_shared_time, realm().global_object()); + + if (is(this)) { + static_cast(this)->set_last_activation_timestamp(current_time); + } else if (is(this)) { + auto const* element = static_cast(this); + auto& window = element->document().window(); + window.set_last_activation_timestamp(current_time); + } + } + return EventDispatcher::dispatch(*this, event); } diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index a764fcdc87..659ee7de91 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -184,6 +184,9 @@ public: WebIDL::ExceptionOr> custom_elements(); + 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; } + private: explicit Window(JS::Realm&); @@ -235,6 +238,9 @@ private: // [[CrossOriginPropertyDescriptorMap]], https://html.spec.whatwg.org/multipage/browsers.html#crossoriginpropertydescriptormap CrossOriginPropertyDescriptorMap m_cross_origin_property_descriptor_map; + + // https://html.spec.whatwg.org/multipage/interaction.html#user-activation-data-model + HighResolutionTime::DOMHighResTimeStamp m_last_activation_timestamp { NumericLimits::max() }; }; void run_animation_frame_callbacks(DOM::Document&, double now); -- cgit v1.2.3