diff options
author | Andreas Kling <kling@serenityos.org> | 2020-06-09 20:42:11 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-09 21:13:16 +0200 |
commit | b4d4d6b32a0e4d0326b6679d32cd9aa9a663f394 (patch) | |
tree | 42e428954d8bde12e72580f18dd9e9ab55e744c1 /Libraries/LibWeb/Layout | |
parent | f2d40ac2b28b7919853b899c80877f7dc1bc8255 (diff) | |
download | serenity-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.h | 150 |
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(); +} + } |