From e63d81b36ecd43af54847f6ea6290af65966ea87 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 3 Jul 2025 17:32:10 +0100 Subject: [PATCH] LibWeb: Add CustomStateSet IDL type --- Libraries/LibWeb/CMakeLists.txt | 1 + Libraries/LibWeb/DOM/Node.h | 1 + Libraries/LibWeb/Forward.h | 1 + .../HTML/CustomElements/CustomStateSet.cpp | 53 +++++++++++++++++++ .../HTML/CustomElements/CustomStateSet.h | 40 ++++++++++++++ .../HTML/CustomElements/CustomStateSet.idl | 5 ++ Libraries/LibWeb/idl_files.cmake | 1 + .../BindingsGenerator/IDLGenerators.cpp | 1 + .../Text/expected/all-window-properties.txt | 1 + 9 files changed, 104 insertions(+) create mode 100644 Libraries/LibWeb/HTML/CustomElements/CustomStateSet.cpp create mode 100644 Libraries/LibWeb/HTML/CustomElements/CustomStateSet.h create mode 100644 Libraries/LibWeb/HTML/CustomElements/CustomStateSet.idl diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 3393d65d4d4..8e9464fab89 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -362,6 +362,7 @@ set(SOURCES HTML/CustomElements/CustomElementName.cpp HTML/CustomElements/CustomElementReactionNames.cpp HTML/CustomElements/CustomElementRegistry.cpp + HTML/CustomElements/CustomStateSet.cpp HTML/DataTransfer.cpp HTML/DataTransferItem.cpp HTML/DataTransferItemList.cpp diff --git a/Libraries/LibWeb/DOM/Node.h b/Libraries/LibWeb/DOM/Node.h index e364f4971a0..c455c71db06 100644 --- a/Libraries/LibWeb/DOM/Node.h +++ b/Libraries/LibWeb/DOM/Node.h @@ -56,6 +56,7 @@ enum class ShouldComputeRole { X(CSSStylePropertiesSetProperty) \ X(CSSStylePropertiesTextChange) \ X(CustomElementStateChange) \ + X(CustomStateSetChange) \ X(DidLoseFocus) \ X(DidReceiveFocus) \ X(EditingInsertion) \ diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 7c22074ac85..6025efa8a3e 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -507,6 +507,7 @@ class CloseWatcher; class CloseWatcherManager; class CustomElementDefinition; class CustomElementRegistry; +class CustomStateSet; class DataTransfer; class DataTransferItem; class DataTransferItemList; diff --git a/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.cpp b/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.cpp new file mode 100644 index 00000000000..ea4d8d3d2c4 --- /dev/null +++ b/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +namespace Web::HTML { + +GC_DEFINE_ALLOCATOR(CustomStateSet); + +GC::Ref CustomStateSet::create(JS::Realm& realm, GC::Ref element) +{ + return realm.create(realm, element); +} + +CustomStateSet::CustomStateSet(JS::Realm& realm, GC::Ref element) + : Bindings::PlatformObject(realm) + , m_set_entries(JS::Set::create(realm)) + , m_element(element) +{ +} + +void CustomStateSet::initialize(JS::Realm& realm) +{ + WEB_SET_PROTOTYPE_FOR_INTERFACE(CustomStateSet); + Base::initialize(realm); +} + +void CustomStateSet::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_set_entries); + visitor.visit(m_element); +} + +bool CustomStateSet::has_state(FlyString const& state) const +{ + return m_set_entries->set_has(JS::PrimitiveString::create(realm().vm(), state)); +} + +void CustomStateSet::on_set_modified_from_js(Badge) +{ + m_element->invalidate_style(DOM::StyleInvalidationReason::CustomStateSetChange); +} + +} diff --git a/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.h b/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.h new file mode 100644 index 00000000000..316319a2c9f --- /dev/null +++ b/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Web::HTML { + +// https://html.spec.whatwg.org/multipage/custom-elements.html#customstateset +class CustomStateSet final : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(CustomStateSet, Bindings::PlatformObject); + GC_DECLARE_ALLOCATOR(CustomStateSet); + +public: + [[nodiscard]] static GC::Ref create(JS::Realm&, GC::Ref); + virtual ~CustomStateSet() override = default; + + GC::Ref set_entries() const { return m_set_entries; } + bool has_state(FlyString const&) const; + + void on_set_modified_from_js(Badge); + +private: + CustomStateSet(JS::Realm&, GC::Ref); + + virtual void initialize(JS::Realm&) override; + virtual void visit_edges(Cell::Visitor&) override; + + GC::Ref m_set_entries; + GC::Ref m_element; +}; + +} diff --git a/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.idl b/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.idl new file mode 100644 index 00000000000..a07190e2cf8 --- /dev/null +++ b/Libraries/LibWeb/HTML/CustomElements/CustomStateSet.idl @@ -0,0 +1,5 @@ +// https://html.spec.whatwg.org/multipage/custom-elements.html#customstateset +[Exposed=Window] +interface CustomStateSet { + setlike; +}; diff --git a/Libraries/LibWeb/idl_files.cmake b/Libraries/LibWeb/idl_files.cmake index c4249ba1a7d..6a4146065d3 100644 --- a/Libraries/LibWeb/idl_files.cmake +++ b/Libraries/LibWeb/idl_files.cmake @@ -128,6 +128,7 @@ libweb_js_bindings(HTML/CloseEvent) libweb_js_bindings(HTML/CloseWatcher) libweb_js_bindings(HTML/CommandEvent) libweb_js_bindings(HTML/CustomElements/CustomElementRegistry) +libweb_js_bindings(HTML/CustomElements/CustomStateSet) libweb_js_bindings(HTML/DataTransfer) libweb_js_bindings(HTML/DataTransferItem) libweb_js_bindings(HTML/DataTransferItemList) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index a11351f5387..5fc303ac756 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -54,6 +54,7 @@ static bool is_platform_object(Type const& type) "Credential"sv, "CredentialsContainer"sv, "CryptoKey"sv, + "CustomStateSet"sv, "DataTransfer"sv, "Document"sv, "DocumentType"sv, diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index 863431fbd00..b686224203c 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -85,6 +85,7 @@ Crypto CryptoKey CustomElementRegistry CustomEvent +CustomStateSet DOMException DOMImplementation DOMMatrix