diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/HTML/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWeb/HTML/BUILD.gn index 7f27d50928f..5b8fb0c291e 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/HTML/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/HTML/BUILD.gn @@ -165,6 +165,7 @@ source_set("HTML") { "ToggleEvent.cpp", "TrackEvent.cpp", "TraversableNavigable.cpp", + "UserActivation.cpp", "VideoTrack.cpp", "VideoTrackList.cpp", "WebViewHints.cpp", diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni index 2a3785ef86c..bf0391f6754 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni @@ -225,6 +225,7 @@ standard_idl_files = [ "//Userland/Libraries/LibWeb/HTML/TimeRanges.idl", "//Userland/Libraries/LibWeb/HTML/ToggleEvent.idl", "//Userland/Libraries/LibWeb/HTML/TrackEvent.idl", + "//Userland/Libraries/LibWeb/HTML/UserActivation.idl", "//Userland/Libraries/LibWeb/HTML/VideoTrack.idl", "//Userland/Libraries/LibWeb/HTML/VideoTrackList.idl", "//Userland/Libraries/LibWeb/HTML/Worker.idl", diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 3e6532ee084..23ae9847a08 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -432,6 +432,7 @@ set(SOURCES HTML/ToggleEvent.cpp HTML/TrackEvent.cpp HTML/TraversableNavigable.cpp + HTML/UserActivation.cpp HTML/VideoTrack.cpp HTML/VideoTrackList.cpp HTML/WebViewHints.cpp diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index ab0cc5f346d..ef86b907313 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -466,6 +466,7 @@ class ToggleEvent; class TrackEvent; struct TransferDataHolder; class TraversableNavigable; +class UserActivation; class VideoTrack; class VideoTrackList; class Window; diff --git a/Userland/Libraries/LibWeb/HTML/Navigator.cpp b/Userland/Libraries/LibWeb/HTML/Navigator.cpp index 52aab8c4e7e..bbfcd70df0a 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigator.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigator.cpp @@ -62,6 +62,7 @@ void Navigator::visit_edges(Cell::Visitor& visitor) visitor.visit(m_mime_type_array); visitor.visit(m_plugin_array); visitor.visit(m_clipboard); + visitor.visit(m_user_activation); } JS::NonnullGCPtr Navigator::mime_types() @@ -85,6 +86,13 @@ JS::NonnullGCPtr Navigator::clipboard() return *m_clipboard; } +JS::NonnullGCPtr Navigator::user_activation() +{ + if (!m_user_activation) + m_user_activation = heap().allocate(realm(), realm()); + return *m_user_activation; +} + // https://w3c.github.io/pointerevents/#dom-navigator-maxtouchpoints WebIDL::Long Navigator::max_touch_points() { diff --git a/Userland/Libraries/LibWeb/HTML/Navigator.h b/Userland/Libraries/LibWeb/HTML/Navigator.h index 050ff216a06..d8a2eb03a26 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigator.h +++ b/Userland/Libraries/LibWeb/HTML/Navigator.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace Web::HTML { @@ -47,6 +48,7 @@ public: [[nodiscard]] JS::NonnullGCPtr mime_types(); [[nodiscard]] JS::NonnullGCPtr plugins(); [[nodiscard]] JS::NonnullGCPtr clipboard(); + [[nodiscard]] JS::NonnullGCPtr user_activation(); static WebIDL::Long max_touch_points(); @@ -65,6 +67,9 @@ private: // https://w3c.github.io/clipboard-apis/#dom-navigator-clipboard JS::GCPtr m_clipboard; + + // https://html.spec.whatwg.org/multipage/interaction.html#dom-navigator-useractivation + JS::GCPtr m_user_activation; }; } diff --git a/Userland/Libraries/LibWeb/HTML/Navigator.idl b/Userland/Libraries/LibWeb/HTML/Navigator.idl index f0c1ff1fb00..b2d2f7faf15 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigator.idl +++ b/Userland/Libraries/LibWeb/HTML/Navigator.idl @@ -6,6 +6,7 @@ #import #import #import +#import // https://html.spec.whatwg.org/multipage/system-state.html#navigator [Exposed=Window] @@ -17,6 +18,9 @@ interface Navigator { // https://w3c.github.io/pointerevents/#extensions-to-the-navigator-interface readonly attribute long maxTouchPoints; + + // https://html.spec.whatwg.org/multipage/interaction.html#useractivation + [SameObject] readonly attribute UserActivation userActivation; }; // NOTE: As NavigatorContentUtils, NavigatorCookies, NavigatorPlugins, and NavigatorAutomationInformation diff --git a/Userland/Libraries/LibWeb/HTML/UserActivation.cpp b/Userland/Libraries/LibWeb/HTML/UserActivation.cpp new file mode 100644 index 00000000000..719e1f4d42e --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/UserActivation.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024, Jamie Mansfield + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::HTML { + +JS_DEFINE_ALLOCATOR(UserActivation); + +WebIDL::ExceptionOr> UserActivation::construct_impl(JS::Realm& realm) +{ + return realm.heap().allocate(realm, realm); +} + +UserActivation::UserActivation(JS::Realm& realm) + : PlatformObject(realm) +{ +} + +void UserActivation::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + WEB_SET_PROTOTYPE_FOR_INTERFACE(UserActivation); +} + +// https://html.spec.whatwg.org/multipage/interaction.html#dom-useractivation-hasbeenactive +bool UserActivation::has_been_active() const +{ + // The hasBeenActive getter steps are to return true if this's relevant global object has sticky activation, and false otherwise. + return verify_cast(relevant_global_object(*this)).has_sticky_activation(); +} + +// https://html.spec.whatwg.org/multipage/interaction.html#dom-useractivation-isactive +bool UserActivation::is_active() const +{ + // The isActive getter steps are to return true if this's relevant global object has transient activation, and false otherwise. + return verify_cast(relevant_global_object(*this)).has_transient_activation(); +} + +} diff --git a/Userland/Libraries/LibWeb/HTML/UserActivation.h b/Userland/Libraries/LibWeb/HTML/UserActivation.h new file mode 100644 index 00000000000..916d6e55ca2 --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/UserActivation.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024, Jamie Mansfield + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::HTML { + +class UserActivation final : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(UserActivation, Bindings::PlatformObject); + JS_DECLARE_ALLOCATOR(UserActivation); + +public: + static WebIDL::ExceptionOr> construct_impl(JS::Realm&); + virtual ~UserActivation() override = default; + + bool has_been_active() const; + bool is_active() const; + +private: + UserActivation(JS::Realm&); + + virtual void initialize(JS::Realm&) override; +}; + +} diff --git a/Userland/Libraries/LibWeb/HTML/UserActivation.idl b/Userland/Libraries/LibWeb/HTML/UserActivation.idl new file mode 100644 index 00000000000..83b50796c5b --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/UserActivation.idl @@ -0,0 +1,6 @@ +// https://html.spec.whatwg.org/multipage/interaction.html#useractivation +[Exposed=Window] +interface UserActivation { + readonly attribute boolean hasBeenActive; + readonly attribute boolean isActive; +}; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 7a9e9c32bc4..f88ba77e9b4 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -209,6 +209,7 @@ libweb_js_bindings(HTML/TextMetrics) libweb_js_bindings(HTML/TimeRanges) libweb_js_bindings(HTML/ToggleEvent) libweb_js_bindings(HTML/TrackEvent) +libweb_js_bindings(HTML/UserActivation) libweb_js_bindings(HTML/VideoTrack) libweb_js_bindings(HTML/VideoTrackList) libweb_js_bindings(HTML/Window GLOBAL)