diff --git a/Libraries/LibWeb/DOM/Node.cpp b/Libraries/LibWeb/DOM/Node.cpp index a3fc8105902..0eae54c18cd 100644 --- a/Libraries/LibWeb/DOM/Node.cpp +++ b/Libraries/LibWeb/DOM/Node.cpp @@ -107,12 +107,8 @@ void Node::finalize() void Node::visit_edges(Cell::Visitor& visitor) { Base::visit_edges(visitor); + TreeNode::visit_edges(visitor); visitor.visit(m_document); - visitor.visit(m_parent); - visitor.visit(m_first_child); - visitor.visit(m_last_child); - visitor.visit(m_next_sibling); - visitor.visit(m_previous_sibling); visitor.visit(m_child_nodes); visitor.visit(m_layout_node); @@ -2292,75 +2288,24 @@ void Node::queue_tree_mutation_record(Vector> added_nodes, Vector void Node::append_child_impl(GC::Ref node) { - VERIFY(!node->m_parent); + VERIFY(!node->parent()); if (!is_child_allowed(*node)) return; - if (m_last_child) - m_last_child->m_next_sibling = node.ptr(); - node->m_previous_sibling = m_last_child; - node->m_parent = this; - m_last_child = node.ptr(); - if (!m_first_child) - m_first_child = m_last_child; + TreeNode::append_child(node); } void Node::insert_before_impl(GC::Ref node, GC::Ptr child) { if (!child) return append_child_impl(move(node)); - - VERIFY(!node->m_parent); - VERIFY(child->parent() == this); - - node->m_previous_sibling = child->m_previous_sibling; - node->m_next_sibling = child; - - if (child->m_previous_sibling) - child->m_previous_sibling->m_next_sibling = node; - - if (m_first_child == child) - m_first_child = node; - - child->m_previous_sibling = node; - - node->m_parent = this; + TreeNode::insert_before(node, child); } void Node::remove_child_impl(GC::Ref node) { - VERIFY(node->m_parent.ptr() == this); - - if (m_first_child == node) - m_first_child = node->m_next_sibling; - - if (m_last_child == node) - m_last_child = node->m_previous_sibling; - - if (node->m_next_sibling) - node->m_next_sibling->m_previous_sibling = node->m_previous_sibling; - - if (node->m_previous_sibling) - node->m_previous_sibling->m_next_sibling = node->m_next_sibling; - - node->m_next_sibling = nullptr; - node->m_previous_sibling = nullptr; - node->m_parent = nullptr; -} - -bool Node::is_ancestor_of(Node const& other) const -{ - for (auto* ancestor = other.parent(); ancestor; ancestor = ancestor->parent()) { - if (ancestor == this) - return true; - } - return false; -} - -bool Node::is_inclusive_ancestor_of(Node const& other) const -{ - return &other == this || is_ancestor_of(other); + TreeNode::remove_child(node); } bool Node::is_descendant_of(Node const& other) const diff --git a/Libraries/LibWeb/DOM/Node.h b/Libraries/LibWeb/DOM/Node.h index b40df03731f..71cbbd9c552 100644 --- a/Libraries/LibWeb/DOM/Node.h +++ b/Libraries/LibWeb/DOM/Node.h @@ -6,12 +6,10 @@ #pragma once -#include #include #include #include #include -#include #include #include #include @@ -20,6 +18,7 @@ #include #include #include +#include #include namespace Web::DOM { @@ -104,7 +103,8 @@ enum class StyleInvalidationReason { #undef __ENUMERATE_STYLE_INVALIDATION_REASON }; -class Node : public EventTarget { +class Node : public EventTarget + , public TreeNode { WEB_PLATFORM_OBJECT(Node, EventTarget); public: @@ -381,19 +381,6 @@ public: Slottable as_slottable(); - Node* parent() { return m_parent.ptr(); } - Node const* parent() const { return m_parent.ptr(); } - - bool has_children() const { return m_first_child; } - Node* next_sibling() { return m_next_sibling.ptr(); } - Node* previous_sibling() { return m_previous_sibling.ptr(); } - Node* first_child() { return m_first_child.ptr(); } - Node* last_child() { return m_last_child.ptr(); } - Node const* next_sibling() const { return m_next_sibling.ptr(); } - Node const* previous_sibling() const { return m_previous_sibling.ptr(); } - Node const* first_child() const { return m_first_child.ptr(); } - Node const* last_child() const { return m_last_child.ptr(); } - size_t child_count() const { size_t count = 0; @@ -418,80 +405,11 @@ public: return const_cast(this)->child_at_index(index); } - // https://dom.spec.whatwg.org/#concept-tree-index - size_t index() const - { - // The index of an object is its number of preceding siblings, or 0 if it has none. - size_t index = 0; - for (auto* node = previous_sibling(); node; node = node->previous_sibling()) - ++index; - return index; - } - - bool is_ancestor_of(Node const&) const; - bool is_inclusive_ancestor_of(Node const&) const; bool is_descendant_of(Node const&) const; bool is_inclusive_descendant_of(Node const&) const; bool is_following(Node const&) const; - Node* next_in_pre_order() - { - if (first_child()) - return first_child(); - Node* node; - if (!(node = next_sibling())) { - node = parent(); - while (node && !node->next_sibling()) - node = node->parent(); - if (node) - node = node->next_sibling(); - } - return node; - } - - Node* next_in_pre_order(Node const* stay_within) - { - if (first_child()) - return first_child(); - - Node* node = static_cast(this); - Node* next = nullptr; - while (!(next = node->next_sibling())) { - node = node->parent(); - if (!node || node == stay_within) - return nullptr; - } - return next; - } - - Node const* next_in_pre_order() const - { - return const_cast(this)->next_in_pre_order(); - } - - Node const* next_in_pre_order(Node const* stay_within) const - { - return const_cast(this)->next_in_pre_order(stay_within); - } - - Node* previous_in_pre_order() - { - if (auto* node = previous_sibling()) { - while (node->last_child()) - node = node->last_child(); - - return node; - } - - return parent(); - } - - Node const* previous_in_pre_order() const - { - return const_cast(this)->previous_in_pre_order(); - } - bool is_before(Node const& other) const { if (this == &other) @@ -525,98 +443,6 @@ public: return false; } - template - TraversalDecision for_each_in_inclusive_subtree(Callback callback) const - { - if (auto decision = callback(static_cast(*this)); decision != TraversalDecision::Continue) - return decision; - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break) - return TraversalDecision::Break; - } - return TraversalDecision::Continue; - } - - template - TraversalDecision for_each_in_inclusive_subtree(Callback callback) - { - if (auto decision = callback(static_cast(*this)); decision != TraversalDecision::Continue) - return decision; - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break) - return TraversalDecision::Break; - } - return TraversalDecision::Continue; - } - - template - TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback) - { - if (auto* maybe_node_of_type = as_if(static_cast(*this))) { - if (auto decision = callback(*maybe_node_of_type); decision != TraversalDecision::Continue) - return decision; - } - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (child->template for_each_in_inclusive_subtree_of_type(callback) == TraversalDecision::Break) - return TraversalDecision::Break; - } - return TraversalDecision::Continue; - } - - template - TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback) const - { - if (auto* maybe_node_of_type = as_if(static_cast(*this))) { - if (auto decision = callback(*maybe_node_of_type); decision != TraversalDecision::Continue) - return decision; - } - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (child->template for_each_in_inclusive_subtree_of_type(callback) == TraversalDecision::Break) - return TraversalDecision::Break; - } - return TraversalDecision::Continue; - } - - template - TraversalDecision for_each_in_subtree(Callback callback) const - { - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break) - return TraversalDecision::Break; - } - return TraversalDecision::Continue; - } - - template - TraversalDecision for_each_in_subtree(Callback callback) - { - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break) - return TraversalDecision::Break; - } - return TraversalDecision::Continue; - } - - template - TraversalDecision for_each_in_subtree_of_type(Callback callback) - { - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (child->template for_each_in_inclusive_subtree_of_type(callback) == TraversalDecision::Break) - return TraversalDecision::Break; - } - return TraversalDecision::Continue; - } - - template - TraversalDecision for_each_in_subtree_of_type(Callback callback) const - { - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (child->template for_each_in_inclusive_subtree_of_type(callback) == TraversalDecision::Break) - return TraversalDecision::Break; - } - return TraversalDecision::Continue; - } - template void for_each_ancestor(Callback callback) const { @@ -647,38 +473,6 @@ public: } } - template - void for_each_child(Callback callback) const - { - return const_cast(this)->for_each_child(move(callback)); - } - - template - void for_each_child(Callback callback) - { - for (auto* node = first_child(); node; node = node->next_sibling()) { - if (callback(*node) == IterationDecision::Break) - return; - } - } - - template - void for_each_child_of_type(Callback callback) - { - for (auto* node = first_child(); node; node = node->next_sibling()) { - if (auto* maybe_child_of_type = as_if(node)) { - if (callback(*maybe_child_of_type) == IterationDecision::Break) - return; - } - } - } - - template - void for_each_child_of_type(Callback callback) const - { - return const_cast(this)->template for_each_child_of_type(move(callback)); - } - template WebIDL::ExceptionOr for_each_child_of_type_fallible(Callback callback) { @@ -691,92 +485,12 @@ public: return {}; } - template - U const* next_sibling_of_type() const - { - return const_cast(this)->template next_sibling_of_type(); - } - - template - inline U* next_sibling_of_type() - { - for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) { - if (auto* maybe_sibling_of_type = as_if(*sibling)) - return maybe_sibling_of_type; - } - return nullptr; - } - - template - U const* previous_sibling_of_type() const - { - return const_cast(this)->template previous_sibling_of_type(); - } - - template - U* previous_sibling_of_type() - { - for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) { - if (auto* maybe_sibling_of_type = as_if(*sibling)) - return maybe_sibling_of_type; - } - return nullptr; - } - - template - U const* first_child_of_type() const - { - return const_cast(this)->template first_child_of_type(); - } - - template - U const* last_child_of_type() const - { - return const_cast(this)->template last_child_of_type(); - } - - template - U* first_child_of_type() - { - for (auto* child = first_child(); child; child = child->next_sibling()) { - if (auto* maybe_child_of_type = as_if(*child)) - return maybe_child_of_type; - } - return nullptr; - } - - template - U* last_child_of_type() - { - for (auto* child = last_child(); child; child = child->previous_sibling()) { - if (auto* maybe_child_of_type = as_if(*child)) - return maybe_child_of_type; - } - return nullptr; - } - template bool has_child_of_type() const { return first_child_of_type() != nullptr; } - template - U const* first_ancestor_of_type() const - { - return const_cast(this)->template first_ancestor_of_type(); - } - - template - U* first_ancestor_of_type() - { - for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { - if (auto* maybe_ancestor_of_type = as_if(*ancestor)) - return maybe_ancestor_of_type; - } - return nullptr; - } - template U const* shadow_including_first_ancestor_of_type() const { @@ -843,12 +557,6 @@ private: static Optional first_valid_id(StringView, Document const&); - GC::Ptr m_parent; - GC::Ptr m_first_child; - GC::Ptr m_last_child; - GC::Ptr m_next_sibling; - GC::Ptr m_previous_sibling; - GC::Ptr m_child_nodes; };