diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 4225636f73e..e3cef337dd2 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index 0490d079a25..29c9647d597 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -30,10 +31,33 @@ namespace Web::DOM { +static IDAllocator s_node_id_allocator; +static HashMap s_node_directory; + +static i32 allocate_node_id(Node* node) +{ + i32 id = s_node_id_allocator.allocate(); + s_node_directory.set(id, node); + return id; +} + +static void deallocate_node_id(i32 node_id) +{ + if (!s_node_directory.remove(node_id)) + VERIFY_NOT_REACHED(); + s_node_id_allocator.deallocate(node_id); +} + +Node* Node::from_id(i32 node_id) +{ + return s_node_directory.get(node_id).value_or(nullptr); +} + Node::Node(Document& document, NodeType type) : EventTarget(static_cast(document)) , m_document(&document) , m_type(type) + , m_id(allocate_node_id(this)) { if (!is_document()) m_document->ref_from_node({}); @@ -47,6 +71,8 @@ Node::~Node() if (!is_document()) m_document->unref_from_node({}); + + deallocate_node_id(m_id); } const HTML::HTMLAnchorElement* Node::enclosing_link_element() const @@ -477,6 +503,7 @@ void Node::set_document(Badge, Document& document) { if (m_document == &document) return; + document.ref_from_node({}); m_document->unref_from_node({}); m_document = &document; diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h index 5907e061b7c..81a389401ff 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.h +++ b/Userland/Libraries/LibWeb/DOM/Node.h @@ -179,6 +179,9 @@ public: bool is_shadow_including_ancestor_of(Node const&) const; bool is_shadow_including_inclusive_ancestor_of(Node const&) const; + i32 id() const { return m_id; } + static Node* from_id(i32 node_id); + protected: Node(Document&, NodeType); @@ -187,6 +190,8 @@ protected: NodeType m_type { NodeType::INVALID }; bool m_needs_style_update { false }; bool m_child_needs_style_update { false }; + + i32 m_id; }; }