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;
+}