mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:07:36 +00:00
LibWeb: Add some iteration helpers to LayoutNode
- for_each_child_of_type<T> - previous_sibling_of_type<T>
This commit is contained in:
parent
f2d40ac2b2
commit
b4d4d6b32a
2 changed files with 100 additions and 60 deletions
|
@ -47,8 +47,10 @@ class HTMLImageElement;
|
||||||
class HTMLScriptElement;
|
class HTMLScriptElement;
|
||||||
class PageView;
|
class PageView;
|
||||||
class ImageData;
|
class ImageData;
|
||||||
|
class LayoutBlock;
|
||||||
class LayoutDocument;
|
class LayoutDocument;
|
||||||
class LayoutNode;
|
class LayoutNode;
|
||||||
|
class LayoutNodeWithStyle;
|
||||||
class LoadRequest;
|
class LoadRequest;
|
||||||
class MouseEvent;
|
class MouseEvent;
|
||||||
class Node;
|
class Node;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <LibGfx/FloatRect.h>
|
#include <LibGfx/FloatRect.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
#include <LibWeb/CSS/StyleProperties.h>
|
#include <LibWeb/CSS/StyleProperties.h>
|
||||||
|
#include <LibWeb/Forward.h>
|
||||||
#include <LibWeb/Layout/BoxModelMetrics.h>
|
#include <LibWeb/Layout/BoxModelMetrics.h>
|
||||||
#include <LibWeb/Layout/LayoutPosition.h>
|
#include <LibWeb/Layout/LayoutPosition.h>
|
||||||
#include <LibWeb/RenderingContext.h>
|
#include <LibWeb/RenderingContext.h>
|
||||||
|
@ -38,14 +39,51 @@
|
||||||
|
|
||||||
namespace Web {
|
namespace Web {
|
||||||
|
|
||||||
class Document;
|
template<typename T>
|
||||||
class Element;
|
inline bool is(const LayoutNode&)
|
||||||
class LayoutBlock;
|
{
|
||||||
class LayoutDocument;
|
return false;
|
||||||
class LayoutNode;
|
}
|
||||||
class LayoutNodeWithStyle;
|
|
||||||
class LineBoxFragment;
|
template<typename T>
|
||||||
class Node;
|
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 {
|
struct HitTestResult {
|
||||||
RefPtr<LayoutNode> layout_node;
|
RefPtr<LayoutNode> layout_node;
|
||||||
|
@ -82,6 +120,26 @@ public:
|
||||||
callback(*node);
|
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 const char* class_name() const = 0;
|
||||||
virtual bool is_root() const { return false; }
|
virtual bool is_root() const { return false; }
|
||||||
virtual bool is_text() const { return false; }
|
virtual bool is_text() const { return false; }
|
||||||
|
@ -144,6 +202,12 @@ public:
|
||||||
template<typename U>
|
template<typename U>
|
||||||
U* next_sibling_of_type();
|
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>
|
template<typename T>
|
||||||
const T* first_child_of_type() const;
|
const T* first_child_of_type() const;
|
||||||
|
|
||||||
|
@ -225,58 +289,6 @@ inline LayoutNodeWithStyle* LayoutNode::parent()
|
||||||
return static_cast<LayoutNodeWithStyle*>(TreeNode<LayoutNode>::parent());
|
return static_cast<LayoutNodeWithStyle*>(TreeNode<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)
|
|
||||||
{
|
|
||||||
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>
|
template<typename T>
|
||||||
inline const T* LayoutNode::next_sibling_of_type() const
|
inline const T* LayoutNode::next_sibling_of_type() const
|
||||||
{
|
{
|
||||||
|
@ -297,6 +309,26 @@ inline T* LayoutNode::next_sibling_of_type()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline const T* LayoutNode::previous_sibling_of_type() const
|
||||||
|
{
|
||||||
|
for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) {
|
||||||
|
if (is<T>(*sibling))
|
||||||
|
return &to<T>(*sibling);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T* LayoutNode::previous_sibling_of_type()
|
||||||
|
{
|
||||||
|
for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) {
|
||||||
|
if (is<T>(*sibling))
|
||||||
|
return &to<T>(*sibling);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline const T* LayoutNode::first_child_of_type() const
|
inline const T* LayoutNode::first_child_of_type() const
|
||||||
{
|
{
|
||||||
|
@ -337,4 +369,10 @@ inline T* LayoutNode::first_ancestor_of_type()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline bool is<LayoutNodeWithStyle>(const LayoutNode& node)
|
||||||
|
{
|
||||||
|
return node.has_style();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue