summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb/Layout
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-06-09 20:42:11 +0200
committerAndreas Kling <kling@serenityos.org>2020-06-09 21:13:16 +0200
commitb4d4d6b32a0e4d0326b6679d32cd9aa9a663f394 (patch)
tree42e428954d8bde12e72580f18dd9e9ab55e744c1 /Libraries/LibWeb/Layout
parentf2d40ac2b28b7919853b899c80877f7dc1bc8255 (diff)
downloadserenity-b4d4d6b32a0e4d0326b6679d32cd9aa9a663f394.zip
LibWeb: Add some iteration helpers to LayoutNode
- for_each_child_of_type<T> - previous_sibling_of_type<T>
Diffstat (limited to 'Libraries/LibWeb/Layout')
-rw-r--r--Libraries/LibWeb/Layout/LayoutNode.h150
1 files changed, 94 insertions, 56 deletions
diff --git a/Libraries/LibWeb/Layout/LayoutNode.h b/Libraries/LibWeb/Layout/LayoutNode.h
index adcd160d81..e34332f9b2 100644
--- a/Libraries/LibWeb/Layout/LayoutNode.h
+++ b/Libraries/LibWeb/Layout/LayoutNode.h
@@ -31,6 +31,7 @@
#include <LibGfx/FloatRect.h>
#include <LibGfx/Rect.h>
#include <LibWeb/CSS/StyleProperties.h>
+#include <LibWeb/Forward.h>
#include <LibWeb/Layout/BoxModelMetrics.h>
#include <LibWeb/Layout/LayoutPosition.h>
#include <LibWeb/RenderingContext.h>
@@ -38,14 +39,51 @@
namespace Web {
-class Document;
-class Element;
-class LayoutBlock;
-class LayoutDocument;
-class LayoutNode;
-class LayoutNodeWithStyle;
-class LineBoxFragment;
-class Node;
+template<typename T>
+inline bool is(const LayoutNode&)
+{
+ return false;
+}
+
+template<typename T>
+inline bool is(const LayoutNode* node)
+{
+ return !node || is<T>(*node);
+}
+
+template<>
+inline bool is<LayoutNode>(const LayoutNode&)
+{
+ return true;
+}
+
+template<typename T>
+inline const T& to(const LayoutNode& node)
+{
+ ASSERT(is<T>(node));
+ return static_cast<const T&>(node);
+}
+
+template<typename T>
+inline T* to(LayoutNode* node)
+{
+ ASSERT(is<T>(node));
+ return static_cast<T*>(node);
+}
+
+template<typename T>
+inline const T* to(const LayoutNode* node)
+{
+ ASSERT(is<T>(node));
+ return static_cast<const T*>(node);
+}
+
+template<typename T>
+inline T& to(LayoutNode& node)
+{
+ ASSERT(is<T>(node));
+ return static_cast<T&>(node);
+}
struct HitTestResult {
RefPtr<LayoutNode> layout_node;
@@ -82,6 +120,26 @@ public:
callback(*node);
}
+ template<typename T, typename Callback>
+ inline void for_each_child_of_type(Callback callback)
+ {
+ for (auto* node = first_child(); node; node = node->next_sibling()) {
+ if (!is<T>(node))
+ continue;
+ callback(to<T>(*node));
+ }
+ }
+
+ template<typename T, typename Callback>
+ inline void for_each_child_of_type(Callback callback) const
+ {
+ for (auto* node = first_child(); node; node = node->next_sibling()) {
+ if (!is<T>(node))
+ continue;
+ callback(to<T>(*node));
+ }
+ }
+
virtual const char* class_name() const = 0;
virtual bool is_root() const { return false; }
virtual bool is_text() const { return false; }
@@ -144,6 +202,12 @@ public:
template<typename U>
U* next_sibling_of_type();
+ template<typename U>
+ const U* previous_sibling_of_type() const;
+
+ template<typename U>
+ U* previous_sibling_of_type();
+
template<typename T>
const T* first_child_of_type() const;
@@ -226,61 +290,29 @@ inline LayoutNodeWithStyle* LayoutNode::parent()
}
template<typename T>
-inline bool is(const LayoutNode&)
-{
- return false;
-}
-
-template<typename T>
-inline bool is(const LayoutNode* node)
-{
- return !node || is<T>(*node);
-}
-
-template<>
-inline bool is<LayoutNode>(const LayoutNode&)
-{
- return true;
-}
-
-template<>
-inline bool is<LayoutNodeWithStyle>(const LayoutNode& node)
-{
- return node.has_style();
-}
-
-template<typename T>
-inline const T& to(const LayoutNode& node)
-{
- ASSERT(is<T>(node));
- return static_cast<const T&>(node);
-}
-
-template<typename T>
-inline T* to(LayoutNode* node)
-{
- ASSERT(is<T>(node));
- return static_cast<T*>(node);
-}
-
-template<typename T>
-inline const T* to(const LayoutNode* node)
+inline const T* LayoutNode::next_sibling_of_type() const
{
- ASSERT(is<T>(node));
- return static_cast<const T*>(node);
+ for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
+ if (is<T>(*sibling))
+ return &to<T>(*sibling);
+ }
+ return nullptr;
}
template<typename T>
-inline T& to(LayoutNode& node)
+inline T* LayoutNode::next_sibling_of_type()
{
- ASSERT(is<T>(node));
- return static_cast<T&>(node);
+ for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
+ if (is<T>(*sibling))
+ return &to<T>(*sibling);
+ }
+ return nullptr;
}
template<typename T>
-inline const T* LayoutNode::next_sibling_of_type() const
+inline const T* LayoutNode::previous_sibling_of_type() const
{
- for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
+ for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) {
if (is<T>(*sibling))
return &to<T>(*sibling);
}
@@ -288,9 +320,9 @@ inline const T* LayoutNode::next_sibling_of_type() const
}
template<typename T>
-inline T* LayoutNode::next_sibling_of_type()
+inline T* LayoutNode::previous_sibling_of_type()
{
- for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
+ for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) {
if (is<T>(*sibling))
return &to<T>(*sibling);
}
@@ -337,4 +369,10 @@ inline T* LayoutNode::first_ancestor_of_type()
return nullptr;
}
+template<>
+inline bool is<LayoutNodeWithStyle>(const LayoutNode& node)
+{
+ return node.has_style();
+}
+
}