diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index dd53caf084..7c9d0f0a81 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -47,8 +47,10 @@ class HTMLImageElement; class HTMLScriptElement; class PageView; class ImageData; +class LayoutBlock; class LayoutDocument; class LayoutNode; +class LayoutNodeWithStyle; class LoadRequest; class MouseEvent; class Node; 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 #include #include +#include #include #include #include @@ -38,14 +39,51 @@ namespace Web { -class Document; -class Element; -class LayoutBlock; -class LayoutDocument; -class LayoutNode; -class LayoutNodeWithStyle; -class LineBoxFragment; -class Node; +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 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); +} struct HitTestResult { RefPtr layout_node; @@ -82,6 +120,26 @@ public: callback(*node); } + template + inline void for_each_child_of_type(Callback callback) + { + for (auto* node = first_child(); node; node = node->next_sibling()) { + if (!is(node)) + continue; + callback(to(*node)); + } + } + + template + inline void for_each_child_of_type(Callback callback) const + { + for (auto* node = first_child(); node; node = node->next_sibling()) { + if (!is(node)) + continue; + callback(to(*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 U* next_sibling_of_type(); + template + const U* previous_sibling_of_type() const; + + template + U* previous_sibling_of_type(); + template const T* first_child_of_type() const; @@ -225,58 +289,6 @@ inline LayoutNodeWithStyle* LayoutNode::parent() 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); -} - template inline const T* LayoutNode::next_sibling_of_type() const { @@ -297,6 +309,26 @@ inline T* LayoutNode::next_sibling_of_type() return nullptr; } +template +inline const T* LayoutNode::previous_sibling_of_type() const +{ + for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) { + if (is(*sibling)) + return &to(*sibling); + } + return nullptr; +} + +template +inline T* LayoutNode::previous_sibling_of_type() +{ + for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) { + if (is(*sibling)) + return &to(*sibling); + } + return nullptr; +} + template inline const T* LayoutNode::first_child_of_type() const { @@ -337,4 +369,10 @@ inline T* LayoutNode::first_ancestor_of_type() return nullptr; } +template<> +inline bool is(const LayoutNode& node) +{ + return node.has_style(); +} + }