From 75216182c9a04741b2f773eb2f26ceb7a96bfbba Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sun, 14 Jul 2024 12:31:50 +0100 Subject: [PATCH] LibWeb: Implement DOMStringList --- .../Userland/Libraries/LibWeb/HTML/BUILD.gn | 1 + .../Userland/Libraries/LibWeb/idl_files.gni | 1 + .../Text/expected/all-window-properties.txt | 1 + Userland/Libraries/LibWeb/CMakeLists.txt | 1 + Userland/Libraries/LibWeb/Forward.h | 1 + .../Libraries/LibWeb/HTML/DOMStringList.cpp | 74 +++++++++++++++++++ .../Libraries/LibWeb/HTML/DOMStringList.h | 36 +++++++++ .../Libraries/LibWeb/HTML/DOMStringList.idl | 7 ++ Userland/Libraries/LibWeb/idl_files.cmake | 1 + 9 files changed, 123 insertions(+) create mode 100644 Userland/Libraries/LibWeb/HTML/DOMStringList.cpp create mode 100644 Userland/Libraries/LibWeb/HTML/DOMStringList.h create mode 100644 Userland/Libraries/LibWeb/HTML/DOMStringList.idl diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/HTML/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWeb/HTML/BUILD.gn index 0901a1e7f9a..18fc3c9dd9a 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/HTML/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/HTML/BUILD.gn @@ -26,6 +26,7 @@ source_set("HTML") { "CloseWatcher.cpp", "CloseWatcherManager.cpp", "DOMParser.cpp", + "DOMStringList.cpp", "DOMStringMap.cpp", "DataTransfer.cpp", "Dates.cpp", diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni index 5277694584d..f9b4b5fc4b8 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni @@ -119,6 +119,7 @@ standard_idl_files = [ "//Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.idl", "//Userland/Libraries/LibWeb/HTML/DataTransfer.idl", "//Userland/Libraries/LibWeb/HTML/DOMParser.idl", + "//Userland/Libraries/LibWeb/HTML/DOMStringList.idl", "//Userland/Libraries/LibWeb/HTML/DOMStringMap.idl", "//Userland/Libraries/LibWeb/HTML/ElementInternals.idl", "//Userland/Libraries/LibWeb/HTML/ErrorEvent.idl", diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index dc6d14cbce6..d83c69f63ff 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -70,6 +70,7 @@ DOMQuad DOMRect DOMRectList DOMRectReadOnly +DOMStringList DOMStringMap DOMTokenList DataTransfer diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 049dfb4ac4a..9dc0d3fa22a 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -280,6 +280,7 @@ set(SOURCES HTML/DedicatedWorkerGlobalScope.cpp HTML/DocumentState.cpp HTML/DOMParser.cpp + HTML/DOMStringList.cpp HTML/DOMStringMap.cpp HTML/DragEvent.cpp HTML/ElementInternals.cpp diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 82a8255eecc..fc6ca353f73 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -360,6 +360,7 @@ class CustomElementRegistry; class DecodedImageData; class DocumentState; class DOMParser; +class DOMStringList; class DOMStringMap; class DragEvent; class ElementInternals; diff --git a/Userland/Libraries/LibWeb/HTML/DOMStringList.cpp b/Userland/Libraries/LibWeb/HTML/DOMStringList.cpp new file mode 100644 index 00000000000..7427c45934e --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/DOMStringList.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024, Jamie Mansfield + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::HTML { + +JS_DEFINE_ALLOCATOR(DOMStringList); + +JS::NonnullGCPtr DOMStringList::create(JS::Realm& realm, Vector list) +{ + return realm.heap().allocate(realm, realm, list); +} + +DOMStringList::DOMStringList(JS::Realm& realm, Vector list) + : Bindings::PlatformObject(realm) + , m_list(move(list)) +{ + m_legacy_platform_object_flags = LegacyPlatformObjectFlags { .supports_indexed_properties = true }; +} + +void DOMStringList::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + WEB_SET_PROTOTYPE_FOR_INTERFACE(DOMStringList); +} + +// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-domstringlist-length +u32 DOMStringList::length() const +{ + // The length getter steps are to return this's associated list's size. + return m_list.size(); +} + +// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-domstringlist-item +Optional DOMStringList::item(u32 index) const +{ + // The item(index) method steps are to return the indexth item in this's associated list, or null if index plus one + // is greater than this's associated list's size. + if (index + 1 > m_list.size()) + return {}; + + return m_list.at(index); +} + +// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-domstringlist-contains +bool DOMStringList::contains(StringView string) +{ + // The contains(string) method steps are to return true if this's associated list contains string, and false otherwise. + return m_list.contains_slow(string); +} + +bool DOMStringList::is_supported_property_index(u32 index) const +{ + // The DOMStringList interface supports indexed properties. The supported property indices are the indices of this's + // associated list. + return index < m_list.size(); +} + +WebIDL::ExceptionOr DOMStringList::item_value(size_t index) const +{ + if (index + 1 > m_list.size()) + return JS::js_undefined(); + + return JS::PrimitiveString::create(vm(), m_list.at(index)); +} + +} diff --git a/Userland/Libraries/LibWeb/HTML/DOMStringList.h b/Userland/Libraries/LibWeb/HTML/DOMStringList.h new file mode 100644 index 00000000000..6da66cf514f --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/DOMStringList.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024, Jamie Mansfield + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::HTML { + +class DOMStringList final : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(DOMStringList, Bindings::PlatformObject); + JS_DECLARE_ALLOCATOR(DOMStringList); + +public: + static JS::NonnullGCPtr create(JS::Realm&, Vector); + + u32 length() const; + Optional item(u32 index) const; + bool contains(StringView string); + + virtual bool is_supported_property_index(u32) const override; + virtual WebIDL::ExceptionOr item_value(size_t index) const override; + +private: + explicit DOMStringList(JS::Realm&, Vector); + + virtual void initialize(JS::Realm&) override; + + Vector m_list; +}; + +} diff --git a/Userland/Libraries/LibWeb/HTML/DOMStringList.idl b/Userland/Libraries/LibWeb/HTML/DOMStringList.idl new file mode 100644 index 00000000000..bc45e19a98d --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/DOMStringList.idl @@ -0,0 +1,7 @@ +// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#domstringlist +[Exposed=(Window,Worker)] +interface DOMStringList { + readonly attribute unsigned long length; + getter DOMString? item(unsigned long index); + boolean contains(DOMString string); +}; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 2d4d61b7572..cab7aef9449 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -104,6 +104,7 @@ libweb_js_bindings(HTML/CustomElements/CustomElementRegistry) libweb_js_bindings(HTML/DataTransfer) libweb_js_bindings(HTML/DedicatedWorkerGlobalScope GLOBAL) libweb_js_bindings(HTML/DOMParser) +libweb_js_bindings(HTML/DOMStringList) libweb_js_bindings(HTML/DOMStringMap) libweb_js_bindings(HTML/DragEvent) libweb_js_bindings(HTML/ElementInternals)