From 8adae51b35b5bf64935dcfcc21346f501c856bad Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 25 Jun 2019 19:46:01 +0200 Subject: [PATCH] LibHTML: Add a simple TreeNode template for making trees. We'll be making a lot of trees here, so let's share code during bootstrap. Eventually some of these classes are gonna want custom trees but for now we can just fit them all into the same clothes. --- LibHTML/DOM/Document.cpp | 4 +-- LibHTML/DOM/Node.cpp | 13 -------- LibHTML/DOM/Node.h | 24 ++------------ LibHTML/DOM/ParentNode.cpp | 9 ------ LibHTML/DOM/ParentNode.h | 11 ------- LibHTML/Layout/LayoutNode.cpp | 23 ------------- LibHTML/Layout/LayoutNode.h | 32 ++---------------- LibHTML/TreeNode.h | 61 +++++++++++++++++++++++++++++++++++ 8 files changed, 68 insertions(+), 109 deletions(-) create mode 100644 LibHTML/TreeNode.h diff --git a/LibHTML/DOM/Document.cpp b/LibHTML/DOM/Document.cpp index f642ad55c4..95bf199f0a 100644 --- a/LibHTML/DOM/Document.cpp +++ b/LibHTML/DOM/Document.cpp @@ -21,8 +21,8 @@ static void create_layout_tree_for_node(Node& node) printf("created layout node for <%s>, parent is %p, parent ln is %p\n", static_cast(node).tag_name().characters(), node.parent_node(), node.parent_node()->layout_node()); } #endif - if (node.parent_node() && node.parent_node()->layout_node()) - node.parent_node()->layout_node()->append_child(*layout_node); + if (node.parent() && node.parent()->layout_node()) + node.parent()->layout_node()->append_child(*layout_node); } if (node.is_parent_node()) { static_cast(node).for_each_child([&](auto& child) { diff --git a/LibHTML/DOM/Node.cpp b/LibHTML/DOM/Node.cpp index cdf160797e..b8d2007da1 100644 --- a/LibHTML/DOM/Node.cpp +++ b/LibHTML/DOM/Node.cpp @@ -10,19 +10,6 @@ Node::~Node() { } -void Node::ref() -{ - ASSERT(m_retain_count); - ++m_retain_count; -} - -void Node::deref() -{ - ASSERT(m_retain_count); - if (!--m_retain_count) - delete this; -} - RefPtr Node::create_layout_node() { return nullptr; diff --git a/LibHTML/DOM/Node.h b/LibHTML/DOM/Node.h index 482891b6e2..73008fcaab 100644 --- a/LibHTML/DOM/Node.h +++ b/LibHTML/DOM/Node.h @@ -3,6 +3,7 @@ #include #include #include +#include enum class NodeType : unsigned { INVALID = 0, @@ -14,33 +15,16 @@ enum class NodeType : unsigned { class LayoutNode; class ParentNode; -class Node { +class Node : public TreeNode { public: virtual ~Node(); - void ref(); - void deref(); - int ref_count() const { return m_retain_count; } - - ParentNode* parent_node() { return m_parent_node; } - const ParentNode* parent_node() const { return m_parent_node; } - - void set_parent_node(Badge, ParentNode* parent_node) { m_parent_node = parent_node; } - NodeType type() const { return m_type; } bool is_element() const { return type() == NodeType::ELEMENT_NODE; } bool is_text() const { return type() == NodeType::TEXT_NODE; } bool is_document() const { return type() == NodeType::DOCUMENT_NODE; } bool is_parent_node() const { return is_element() || is_document(); } - Node* next_sibling() { return m_next_sibling; } - Node* previous_sibling() { return m_previous_sibling; } - const Node* next_sibling() const { return m_next_sibling; } - const Node* previous_sibling() const { return m_previous_sibling; } - - void set_next_sibling(Node* node) { m_next_sibling = node; } - void set_previous_sibling(Node* node) { m_previous_sibling = node; } - virtual RefPtr create_layout_node(); const LayoutNode* layout_node() const { return m_layout_node; } @@ -51,10 +35,6 @@ public: protected: explicit Node(NodeType); - int m_retain_count { 1 }; NodeType m_type { NodeType::INVALID }; - ParentNode* m_parent_node { nullptr }; - Node* m_next_sibling { nullptr }; - Node* m_previous_sibling { nullptr }; RefPtr m_layout_node; }; diff --git a/LibHTML/DOM/ParentNode.cpp b/LibHTML/DOM/ParentNode.cpp index 278e7a4c07..cd835d4627 100644 --- a/LibHTML/DOM/ParentNode.cpp +++ b/LibHTML/DOM/ParentNode.cpp @@ -1,11 +1,2 @@ #include -void ParentNode::append_child(NonnullRefPtr node) -{ - if (m_last_child) - m_last_child->set_next_sibling(node.ptr()); - node->set_parent_node({}, this); - m_last_child = &node.leak_ref(); - if (!m_first_child) - m_first_child = m_last_child; -} diff --git a/LibHTML/DOM/ParentNode.h b/LibHTML/DOM/ParentNode.h index 8bcd59adda..9773cb31a2 100644 --- a/LibHTML/DOM/ParentNode.h +++ b/LibHTML/DOM/ParentNode.h @@ -4,13 +4,6 @@ class ParentNode : public Node { public: - void append_child(NonnullRefPtr); - - Node* first_child() { return m_first_child; } - Node* last_child() { return m_last_child; } - const Node* first_child() const { return m_first_child; } - const Node* last_child() const { return m_last_child; } - template void for_each_child(F) const; template void for_each_child(F); @@ -19,10 +12,6 @@ protected: : Node(type) { } - -private: - Node* m_first_child { nullptr }; - Node* m_last_child { nullptr }; }; template diff --git a/LibHTML/Layout/LayoutNode.cpp b/LibHTML/Layout/LayoutNode.cpp index 6e36a971ee..22ba3097aa 100644 --- a/LibHTML/Layout/LayoutNode.cpp +++ b/LibHTML/Layout/LayoutNode.cpp @@ -9,29 +9,6 @@ LayoutNode::~LayoutNode() { } -void LayoutNode::ref() -{ - ASSERT(m_retain_count); - ++m_retain_count; -} - -void LayoutNode::deref() -{ - ASSERT(m_retain_count); - if (!--m_retain_count) - delete this; -} - -void LayoutNode::append_child(NonnullRefPtr node) -{ - if (m_last_child) - m_last_child->set_next_sibling(node.ptr()); - node->m_parent_node = this; - m_last_child = &node.leak_ref(); - if (!m_first_child) - m_first_child = m_last_child; -} - void LayoutNode::layout() { for_each_child([](auto& child) { diff --git a/LibHTML/Layout/LayoutNode.h b/LibHTML/Layout/LayoutNode.h index 89c30c63d7..9c665bf3f7 100644 --- a/LibHTML/Layout/LayoutNode.h +++ b/LibHTML/Layout/LayoutNode.h @@ -3,18 +3,15 @@ #include #include #include +#include #include class Node; -class LayoutNode { +class LayoutNode : public TreeNode { public: virtual ~LayoutNode(); - void ref(); - void deref(); - int ref_count() const { return m_retain_count; } - const Rect& rect() const { return m_rect; } Rect& rect() { return m_rect; } void set_rect(const Rect& rect) { m_rect = rect; } @@ -25,24 +22,6 @@ public: bool is_anonymous() const { return !m_node; } const Node* node() const { return m_node; } - const LayoutNode* parent_layout_node() const { return m_parent_node; } - - LayoutNode* next_sibling() { return m_next_sibling; } - LayoutNode* previous_sibling() { return m_previous_sibling; } - LayoutNode* first_child() { return m_first_child; } - LayoutNode* last_child() { return m_last_child; } - const LayoutNode* next_sibling() const { return m_next_sibling; } - const LayoutNode* previous_sibling() const { return m_previous_sibling; } - const LayoutNode* first_child() const { return m_first_child; } - const LayoutNode* last_child() const { return m_last_child; } - - bool has_children() const { return m_first_child; } - - void append_child(NonnullRefPtr); - - void set_next_sibling(LayoutNode* node) { m_next_sibling = node; } - void set_previous_sibling(LayoutNode* node) { m_previous_sibling = node; } - template inline void for_each_child(Callback callback) const { @@ -66,13 +45,8 @@ protected: explicit LayoutNode(const Node*); private: - int m_retain_count { 1 }; const Node* m_node { nullptr }; - LayoutNode* m_parent_node { nullptr }; - LayoutNode* m_first_child { nullptr }; - LayoutNode* m_last_child { nullptr }; - LayoutNode* m_next_sibling { nullptr }; - LayoutNode* m_previous_sibling { nullptr }; + LayoutStyle m_style; Rect m_rect; }; diff --git a/LibHTML/TreeNode.h b/LibHTML/TreeNode.h new file mode 100644 index 0000000000..df3b67cdf7 --- /dev/null +++ b/LibHTML/TreeNode.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +template +class TreeNode { +public: + void ref() + { + ASSERT(m_ref_count); + ++m_ref_count; + } + + void deref() + { + ASSERT(m_ref_count); + if (!--m_ref_count) + delete static_cast(this); + } + int ref_count() const { return m_ref_count; } + + T* parent() { return m_parent; } + const T* parent() const { return m_parent; } + + bool has_children() const { return m_first_child; } + T* next_sibling() { return m_next_sibling; } + T* previous_sibling() { return m_previous_sibling; } + T* first_child() { return m_first_child; } + T* last_child() { return m_last_child; } + const T* next_sibling() const { return m_next_sibling; } + const T* previous_sibling() const { return m_previous_sibling; } + const T* first_child() const { return m_first_child; } + const T* last_child() const { return m_last_child; } + + void append_child(NonnullRefPtr node); + +protected: + TreeNode() { } + +private: + int m_ref_count { 1 }; + T* m_parent { nullptr }; + T* m_first_child { nullptr }; + T* m_last_child { nullptr }; + T* m_next_sibling { nullptr }; + T* m_previous_sibling { nullptr }; +}; + +template +inline void TreeNode::append_child(NonnullRefPtr node) +{ + ASSERT(!node->m_parent); + if (m_last_child) + m_last_child->m_next_sibling = node.ptr(); + node->m_previous_sibling = m_last_child; + node->m_parent = static_cast(this); + m_last_child = &node.leak_ref(); + if (!m_first_child) + m_first_child = m_last_child; +}