diff --git a/Libraries/LibHTML/Layout/LayoutBlock.h b/Libraries/LibHTML/Layout/LayoutBlock.h
index dc10c36752..91b21c8e60 100644
--- a/Libraries/LibHTML/Layout/LayoutBlock.h
+++ b/Libraries/LibHTML/Layout/LayoutBlock.h
@@ -53,3 +53,9 @@ void LayoutNode::for_each_fragment_of_this(Callback callback)
}
}
}
+
+template<>
+inline bool is(const LayoutNode& node)
+{
+ return node.is_block();
+}
diff --git a/Libraries/LibHTML/Layout/LayoutNode.cpp b/Libraries/LibHTML/Layout/LayoutNode.cpp
index 6516c47cae..22efbde750 100644
--- a/Libraries/LibHTML/Layout/LayoutNode.cpp
+++ b/Libraries/LibHTML/Layout/LayoutNode.cpp
@@ -31,8 +31,8 @@ void LayoutNode::layout()
const LayoutBlock* LayoutNode::containing_block() const
{
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
- if (ancestor->is_block())
- return static_cast(ancestor);
+ if (is(*ancestor))
+ return to(ancestor);
}
return nullptr;
}
diff --git a/Libraries/LibHTML/Layout/LayoutNode.h b/Libraries/LibHTML/Layout/LayoutNode.h
index 19c4c50127..1318f634c6 100644
--- a/Libraries/LibHTML/Layout/LayoutNode.h
+++ b/Libraries/LibHTML/Layout/LayoutNode.h
@@ -63,6 +63,7 @@ public:
virtual bool is_text() const { return false; }
virtual bool is_block() const { return false; }
virtual bool is_replaced() const { return false; }
+ bool has_style() const { return m_has_style; }
bool is_inline() const { return m_inline; }
void set_inline(bool b) { m_inline = b; }
@@ -136,3 +137,55 @@ inline const LayoutNodeWithStyle* LayoutNode::parent() const
{
return static_cast(TreeNode::parent());
}
+
+template
+inline bool is(const LayoutNode&)
+{
+ return false;
+}
+
+template
+inline bool is(const LayoutNode* node)
+{
+ return node && is(*node);
+}
+
+template<>
+inline bool is(const LayoutNode&)
+{
+ return true;
+}
+
+template<>
+inline bool is(const LayoutNode& node)
+{
+ return node.has_style();
+}
+
+template
+inline const T& to(const LayoutNode& node)
+{
+ ASSERT(is(node));
+ return static_cast(node);
+}
+
+template
+inline T* to(LayoutNode* node)
+{
+ ASSERT(is(node));
+ return static_cast(node);
+}
+
+template
+inline const T* to(const LayoutNode* node)
+{
+ ASSERT(is(node));
+ return static_cast(node);
+}
+
+template
+inline T& to(LayoutNode& node)
+{
+ ASSERT(is(node));
+ return static_cast(node);
+}
diff --git a/Libraries/LibHTML/Layout/LayoutReplaced.h b/Libraries/LibHTML/Layout/LayoutReplaced.h
index 719da0b465..a3392997ec 100644
--- a/Libraries/LibHTML/Layout/LayoutReplaced.h
+++ b/Libraries/LibHTML/Layout/LayoutReplaced.h
@@ -15,3 +15,9 @@ private:
virtual void split_into_lines(LayoutBlock& container) override;
};
+
+template<>
+inline bool is(const LayoutNode& node)
+{
+ return node.is_replaced();
+}
diff --git a/Libraries/LibHTML/Layout/LayoutText.h b/Libraries/LibHTML/Layout/LayoutText.h
index afa3a808c7..bae226c11a 100644
--- a/Libraries/LibHTML/Layout/LayoutText.h
+++ b/Libraries/LibHTML/Layout/LayoutText.h
@@ -31,3 +31,9 @@ private:
String m_text_for_rendering;
};
+
+template<>
+inline bool is(const LayoutNode& node)
+{
+ return node.is_text();
+}
diff --git a/Libraries/LibHTML/Layout/LineBoxFragment.cpp b/Libraries/LibHTML/Layout/LineBoxFragment.cpp
index 4f64c93481..01def67e5b 100644
--- a/Libraries/LibHTML/Layout/LineBoxFragment.cpp
+++ b/Libraries/LibHTML/Layout/LineBoxFragment.cpp
@@ -10,8 +10,7 @@ void LineBoxFragment::render(RenderingContext& context)
return;
}
- if (layout_node().is_text()) {
- auto& layout_text = static_cast(layout_node());
- layout_text.render_fragment(context, *this);
+ if (is(layout_node())) {
+ to(layout_node()).render_fragment(context, *this);
}
}