From 0176d42f4977dc1ab21db3b172f2b5f8be3fe3e7 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 8 Aug 2022 15:19:46 +0200 Subject: LibWeb: Make DOMTokenList GC-allocated --- Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp | 20 ++++++++++++++++--- Userland/Libraries/LibWeb/DOM/DOMTokenList.h | 27 +++++++++++++------------- Userland/Libraries/LibWeb/DOM/DOMTokenList.idl | 1 + Userland/Libraries/LibWeb/DOM/Element.cpp | 10 +++++----- Userland/Libraries/LibWeb/DOM/Element.h | 4 ++-- Userland/Libraries/LibWeb/Forward.h | 1 - Userland/Libraries/LibWeb/idl_files.cmake | 2 +- 7 files changed, 39 insertions(+), 26 deletions(-) (limited to 'Userland/Libraries') diff --git a/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp b/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp index 902a12d856..4b3575920f 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp +++ b/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp @@ -1,13 +1,17 @@ /* * Copyright (c) 2021, Tim Flynn + * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include +#include +#include #include #include +#include #include namespace { @@ -50,14 +54,16 @@ inline void replace_in_ordered_set(Vector& set, StringView item, String namespace Web::DOM { -NonnullRefPtr DOMTokenList::create(Element const& associated_element, FlyString associated_attribute) +DOMTokenList* DOMTokenList::create(Element const& associated_element, FlyString associated_attribute) { - return adopt_ref(*new DOMTokenList(associated_element, move(associated_attribute))); + auto& realm = associated_element.document().preferred_window_object().realm(); + return realm.heap().allocate(realm, associated_element, move(associated_attribute)); } // https://dom.spec.whatwg.org/#ref-for-domtokenlist%E2%91%A0%E2%91%A2 DOMTokenList::DOMTokenList(Element const& associated_element, FlyString associated_attribute) - : m_associated_element(associated_element) + : Bindings::LegacyPlatformObject(associated_element.document().preferred_window_object().ensure_web_prototype("DOMTokenList")) + , m_associated_element(associated_element) , m_associated_attribute(move(associated_attribute)) { auto value = associated_element.get_attribute(m_associated_attribute); @@ -250,4 +256,12 @@ void DOMTokenList::run_update_steps() associated_element->set_attribute(m_associated_attribute, value()); } +JS::Value DOMTokenList::item_value(size_t index) const +{ + auto const& string = item(index); + if (string.is_null()) + return JS::js_undefined(); + return JS::js_string(vm(), string); +} + } diff --git a/Userland/Libraries/LibWeb/DOM/DOMTokenList.h b/Userland/Libraries/LibWeb/DOM/DOMTokenList.h index b96ae20b30..890caffbc3 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMTokenList.h +++ b/Userland/Libraries/LibWeb/DOM/DOMTokenList.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Tim Flynn + * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,29 +9,30 @@ #include #include -#include #include #include #include -#include +#include #include #include namespace Web::DOM { // https://dom.spec.whatwg.org/#domtokenlist -class DOMTokenList final - : public RefCounted - , public Bindings::Wrappable { +class DOMTokenList final : public Bindings::LegacyPlatformObject { + JS_OBJECT(DOMTokenList, Bindings::LegacyPlatformObject); public: - using WrapperType = Bindings::DOMTokenListWrapper; - - static NonnullRefPtr create(Element const& associated_element, FlyString associated_attribute); + static DOMTokenList* create(Element const& associated_element, FlyString associated_attribute); + DOMTokenList(Element const& associated_element, FlyString associated_attribute); ~DOMTokenList() = default; + DOMTokenList& impl() { return *this; } + void associated_attribute_changed(StringView value); - bool is_supported_property_index(u32 index) const; + + virtual bool is_supported_property_index(u32 index) const override; + virtual JS::Value item_value(size_t index) const override; size_t length() const { return m_token_set.size(); } String const& item(size_t index) const; @@ -44,8 +46,6 @@ public: void set_value(String value); private: - DOMTokenList(Element const& associated_element, FlyString associated_attribute); - ExceptionOr validate_token(StringView token) const; void run_update_steps(); @@ -57,7 +57,6 @@ private: } namespace Web::Bindings { - -DOMTokenListWrapper* wrap(JS::Realm&, DOM::DOMTokenList&); - +inline JS::Object* wrap(JS::Realm&, Web::DOM::DOMTokenList& object) { return &object; } +using DOMTokenListWrapper = Web::DOM::DOMTokenList; } diff --git a/Userland/Libraries/LibWeb/DOM/DOMTokenList.idl b/Userland/Libraries/LibWeb/DOM/DOMTokenList.idl index 210703da50..5bf5729401 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMTokenList.idl +++ b/Userland/Libraries/LibWeb/DOM/DOMTokenList.idl @@ -1,3 +1,4 @@ +[NoInstanceWrapper] interface DOMTokenList { readonly attribute unsigned long length; getter DOMString? item(unsigned long index); diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 94526ea7a3..89fe06ce28 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -307,7 +307,7 @@ void Element::parse_attribute(FlyString const& name, String const& value) for (auto& new_class : new_classes) { m_classes.unchecked_append(new_class); } - if (m_class_list) + if (m_class_list.cell()) m_class_list->associated_attribute_changed(value); } else if (name == HTML::AttributeNames::style) { // https://drafts.csswg.org/cssom/#ref-for-cssstyledeclaration-updating-flag @@ -412,11 +412,11 @@ NonnullRefPtr Element::resolved_css_values() return properties; } -RefPtr const& Element::class_list() +DOMTokenList* Element::class_list() { - if (!m_class_list) - m_class_list = DOMTokenList::create(*this, HTML::AttributeNames::class_); - return m_class_list; + if (!m_class_list.cell()) + m_class_list = JS::make_handle(DOMTokenList::create(*this, HTML::AttributeNames::class_)); + return m_class_list.cell(); } // https://dom.spec.whatwg.org/#dom-element-matches diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index 22979d8b72..7da6d5b849 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -62,7 +62,7 @@ public: NamedNodeMap const* attributes() const { return m_attributes.cell(); } Vector get_attribute_names() const; - RefPtr const& class_list(); + DOMTokenList* class_list(); DOM::ExceptionOr matches(StringView selectors) const; DOM::ExceptionOr closest(StringView selectors) const; @@ -157,7 +157,7 @@ private: RefPtr m_computed_css_values; HashMap m_custom_properties; - RefPtr m_class_list; + JS::Handle m_class_list; Vector m_classes; RefPtr m_shadow_root; diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 17860ad5e1..282c31f1cf 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -471,7 +471,6 @@ class DOMPointReadOnlyWrapper; class DOMRectListWrapper; class DOMRectReadOnlyWrapper; class DOMRectWrapper; -class DOMTokenListWrapper; class ElementWrapper; class ErrorEventWrapper; class EventListenerWrapper; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index e39051582c..9d8d2cf984 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -33,7 +33,7 @@ libweb_js_wrapper(DOM/DocumentFragment) libweb_js_wrapper(DOM/DocumentType) libweb_js_wrapper(DOM/DOMException) libweb_js_wrapper(DOM/DOMImplementation) -libweb_js_wrapper(DOM/DOMTokenList) +libweb_js_wrapper(DOM/DOMTokenList NO_INSTANCE) libweb_js_wrapper(DOM/Element) libweb_js_wrapper(DOM/Event) libweb_js_wrapper(DOM/EventTarget) -- cgit v1.2.3