diff options
author | Andreas Kling <kling@serenityos.org> | 2022-09-01 17:13:18 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-09-06 00:27:09 +0200 |
commit | 43ec0f734f262517ab729b6dabdae43ac34774fa (patch) | |
tree | b53b91f94bfba08efa462096ff7922cc554a109b | |
parent | 48e0066371a3e4a4d5b743579747c76bf3c46ea4 (diff) | |
download | serenity-43ec0f734f262517ab729b6dabdae43ac34774fa.zip |
LibWeb: Make MutationRecord GC-allocated
-rw-r--r-- | Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/MutationObserver.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/MutationObserver.h | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/MutationRecord.cpp | 67 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/MutationRecord.h | 55 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Node.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Forward.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/idl_files.cmake | 2 |
9 files changed, 72 insertions, 71 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp index fe6edc907c..e9ec6b244c 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp @@ -149,6 +149,8 @@ static bool impl_is_wrapper(Type const& type) return true; if (type.name == "DOMStringMap"sv) return true; + if (type.name == "MutationRecord"sv) + return true; return false; } diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index a9e230b89a..9964f7c4ce 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -15,7 +15,6 @@ #include <LibWeb/Bindings/LocationObject.h> #include <LibWeb/Bindings/MainThreadVM.h> #include <LibWeb/Bindings/MutationObserverWrapper.h> -#include <LibWeb/Bindings/MutationRecordWrapper.h> #include <LibWeb/Bindings/WindowProxy.h> #include <LibWeb/DOM/Document.h> #include <LibWeb/HTML/PromiseRejectionEvent.h> @@ -378,9 +377,8 @@ void queue_mutation_observer_microtask(DOM::Document& document) auto* wrapped_records = MUST(JS::Array::create(realm, 0)); for (size_t i = 0; i < records.size(); ++i) { auto& record = records.at(i); - auto* wrapped_record = Bindings::wrap(realm, record); auto property_index = JS::PropertyKey { i }; - MUST(wrapped_records->create_data_property(property_index, wrapped_record)); + MUST(wrapped_records->create_data_property(property_index, record.ptr())); } auto* wrapped_mutation_observer = Bindings::wrap(realm, mutation_observer); diff --git a/Userland/Libraries/LibWeb/DOM/MutationObserver.cpp b/Userland/Libraries/LibWeb/DOM/MutationObserver.cpp index 7a7e9e8114..d7f5851dbc 100644 --- a/Userland/Libraries/LibWeb/DOM/MutationObserver.cpp +++ b/Userland/Libraries/LibWeb/DOM/MutationObserver.cpp @@ -108,7 +108,7 @@ void MutationObserver::disconnect() } // https://dom.spec.whatwg.org/#dom-mutationobserver-takerecords -NonnullRefPtrVector<MutationRecord> MutationObserver::take_records() +Vector<JS::Handle<MutationRecord>> MutationObserver::take_records() { // 1. Let records be a clone of this’s record queue. auto records = m_record_queue; diff --git a/Userland/Libraries/LibWeb/DOM/MutationObserver.h b/Userland/Libraries/LibWeb/DOM/MutationObserver.h index b222d9eaa4..57af34ce46 100644 --- a/Userland/Libraries/LibWeb/DOM/MutationObserver.h +++ b/Userland/Libraries/LibWeb/DOM/MutationObserver.h @@ -43,16 +43,16 @@ public: ExceptionOr<void> observe(Node& target, MutationObserverInit options = {}); void disconnect(); - NonnullRefPtrVector<MutationRecord> take_records(); + Vector<JS::Handle<MutationRecord>> take_records(); Vector<WeakPtr<Node>>& node_list() { return m_node_list; } Vector<WeakPtr<Node>> const& node_list() const { return m_node_list; } Bindings::CallbackType& callback() { return *m_callback; } - void enqueue_record(Badge<Node>, NonnullRefPtr<MutationRecord> mutation_record) + void enqueue_record(Badge<Node>, JS::NonnullGCPtr<MutationRecord> mutation_record) { - m_record_queue.append(move(mutation_record)); + m_record_queue.append(*mutation_record); } private: @@ -65,7 +65,7 @@ private: Vector<WeakPtr<Node>> m_node_list; // https://dom.spec.whatwg.org/#concept-mo-queue - NonnullRefPtrVector<MutationRecord> m_record_queue; + Vector<JS::Handle<MutationRecord>> m_record_queue; }; // https://dom.spec.whatwg.org/#registered-observer diff --git a/Userland/Libraries/LibWeb/DOM/MutationRecord.cpp b/Userland/Libraries/LibWeb/DOM/MutationRecord.cpp index 05ad9fd49d..bb66e5e5ea 100644 --- a/Userland/Libraries/LibWeb/DOM/MutationRecord.cpp +++ b/Userland/Libraries/LibWeb/DOM/MutationRecord.cpp @@ -1,57 +1,48 @@ /* * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/MutationRecordPrototype.h> #include <LibWeb/DOM/MutationRecord.h> #include <LibWeb/DOM/Node.h> #include <LibWeb/DOM/NodeList.h> +#include <LibWeb/HTML/Window.h> namespace Web::DOM { -class MutationRecordImpl final : public MutationRecord { -public: - MutationRecordImpl(FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value) - : m_type(type) - , m_target(JS::make_handle(target)) - , m_added_nodes(added_nodes) - , m_removed_nodes(removed_nodes) - , m_previous_sibling(JS::make_handle(previous_sibling)) - , m_next_sibling(JS::make_handle(next_sibling)) - , m_attribute_name(attribute_name) - , m_attribute_namespace(attribute_namespace) - , m_old_value(old_value) - { - } - - virtual ~MutationRecordImpl() override = default; +JS::NonnullGCPtr<MutationRecord> MutationRecord::create(HTML::Window& window, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value) +{ + return *window.heap().allocate<MutationRecord>(window.realm(), window, type, target, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, old_value); +} - virtual FlyString const& type() const override { return m_type; } - virtual Node const* target() const override { return m_target.ptr(); } - virtual NodeList const* added_nodes() const override { return m_added_nodes; } - virtual NodeList const* removed_nodes() const override { return m_removed_nodes; } - virtual Node const* previous_sibling() const override { return m_previous_sibling.ptr(); } - virtual Node const* next_sibling() const override { return m_next_sibling.ptr(); } - virtual String const& attribute_name() const override { return m_attribute_name; } - virtual String const& attribute_namespace() const override { return m_attribute_namespace; } - virtual String const& old_value() const override { return m_old_value; } +MutationRecord::MutationRecord(HTML::Window& window, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value) + : PlatformObject(window.realm()) + , m_type(type) + , m_target(JS::make_handle(target)) + , m_added_nodes(added_nodes) + , m_removed_nodes(removed_nodes) + , m_previous_sibling(JS::make_handle(previous_sibling)) + , m_next_sibling(JS::make_handle(next_sibling)) + , m_attribute_name(attribute_name) + , m_attribute_namespace(attribute_namespace) + , m_old_value(old_value) +{ + set_prototype(&window.ensure_web_prototype<Bindings::MutationRecordPrototype>("MutationRecord")); +} -private: - FlyString m_type; - JS::Handle<Node> m_target; - JS::Handle<NodeList> m_added_nodes; - JS::Handle<NodeList> m_removed_nodes; - JS::Handle<Node> m_previous_sibling; - JS::Handle<Node> m_next_sibling; - String m_attribute_name; - String m_attribute_namespace; - String m_old_value; -}; +MutationRecord::~MutationRecord() = default; -NonnullRefPtr<MutationRecord> MutationRecord::create(FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value) +void MutationRecord::visit_edges(Cell::Visitor& visitor) { - return adopt_ref(*new MutationRecordImpl(type, target, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, old_value)); + Base::visit_edges(visitor); + visitor.visit(m_target.ptr()); + visitor.visit(m_added_nodes.ptr()); + visitor.visit(m_removed_nodes.ptr()); + visitor.visit(m_previous_sibling.ptr()); + visitor.visit(m_next_sibling.ptr()); } } diff --git a/Userland/Libraries/LibWeb/DOM/MutationRecord.h b/Userland/Libraries/LibWeb/DOM/MutationRecord.h index 0c1b279400..e8905eb76f 100644 --- a/Userland/Libraries/LibWeb/DOM/MutationRecord.h +++ b/Userland/Libraries/LibWeb/DOM/MutationRecord.h @@ -6,33 +6,44 @@ #pragma once -#include <AK/RefCounted.h> -#include <LibWeb/Bindings/Wrappable.h> +#include <LibWeb/Bindings/PlatformObject.h> namespace Web::DOM { // https://dom.spec.whatwg.org/#mutationrecord -// NOTE: This is implemented as a pure virtual interface with the actual implementation in the CPP file to prevent this circular dependency: Node.h -> MutationRecord.h -> MutationObserver.h -> Node.h -// This is also why this uses raw pointers and references, since using (NN)RP requires us to include the templated type, even in a header specifying a function return type. -class MutationRecord - : public RefCounted<MutationRecord> - , public Bindings::Wrappable { -public: - using WrapperType = Bindings::MutationRecordWrapper; - - static NonnullRefPtr<MutationRecord> create(FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value); - - virtual ~MutationRecord() override = default; +class MutationRecord : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(MutationRecord, Bindings::PlatformObject); - virtual FlyString const& type() const = 0; - virtual Node const* target() const = 0; - virtual NodeList const* added_nodes() const = 0; - virtual NodeList const* removed_nodes() const = 0; - virtual Node const* previous_sibling() const = 0; - virtual Node const* next_sibling() const = 0; - virtual String const& attribute_name() const = 0; - virtual String const& attribute_namespace() const = 0; - virtual String const& old_value() const = 0; +public: + static JS::NonnullGCPtr<MutationRecord> create(HTML::Window&, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value); + + virtual ~MutationRecord() override; + + FlyString const& type() const { return m_type; } + Node const* target() const { return m_target; } + NodeList const* added_nodes() const { return m_added_nodes; } + NodeList const* removed_nodes() const { return m_removed_nodes; } + Node const* previous_sibling() const { return m_previous_sibling; } + Node const* next_sibling() const { return m_next_sibling; } + String const& attribute_name() const { return m_attribute_name; } + String const& attribute_namespace() const { return m_attribute_namespace; } + String const& old_value() const { return m_old_value; } + +private: + MutationRecord(HTML::Window& window, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value); + virtual void visit_edges(Cell::Visitor&) override; + + FlyString m_type; + JS::GCPtr<Node> m_target; + JS::GCPtr<NodeList> m_added_nodes; + JS::GCPtr<NodeList> m_removed_nodes; + JS::GCPtr<Node> m_previous_sibling; + JS::GCPtr<Node> m_next_sibling; + String m_attribute_name; + String m_attribute_namespace; + String m_old_value; }; } + +WRAPPER_HACK(MutationRecord, Web::DOM) diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index 24c4ba2b25..d6d05efab7 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -1368,7 +1368,7 @@ void Node::queue_mutation_record(FlyString const& type, String attribute_name, S for (auto& interested_observer : interested_observers) { // 1. Let record be a new MutationRecord object with its type set to type, target set to target, attributeName set to name, attributeNamespace set to namespace, oldValue set to mappedOldValue, // addedNodes set to addedNodes, removedNodes set to removedNodes, previousSibling set to previousSibling, and nextSibling set to nextSibling. - auto record = MutationRecord::create(type, *this, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, /* mappedOldValue */ interested_observer.value); + auto record = MutationRecord::create(window(), type, *this, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, /* mappedOldValue */ interested_observer.value); // 2. Enqueue record to observer’s record queue. interested_observer.key->enqueue_record({}, move(record)); diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index fa0d028ab4..7778d40efd 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -470,7 +470,6 @@ class IntersectionObserverWrapper; class LocationObject; class MessageChannelWrapper; class MutationObserverWrapper; -class MutationRecordWrapper; class OptionConstructor; class Path2DWrapper; class RangePrototype; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 6c0e0fc1a6..012dea5d09 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -38,7 +38,7 @@ libweb_js_wrapper(DOM/Element NO_INSTANCE) libweb_js_wrapper(DOM/Event NO_INSTANCE) libweb_js_wrapper(DOM/EventTarget NO_INSTANCE) libweb_js_wrapper(DOM/HTMLCollection) -libweb_js_wrapper(DOM/MutationRecord) +libweb_js_wrapper(DOM/MutationRecord NO_INSTANCE) libweb_js_wrapper(DOM/MutationObserver) libweb_js_wrapper(DOM/NamedNodeMap NO_INSTANCE) libweb_js_wrapper(DOM/Node NO_INSTANCE) |