LibWeb: Move tree iteration helpers from Node/LayoutNode to TreeNode
Since these are generally useful in our trees, let's just keep them in TreeNode instead of duplicating the helpers in subclasses.
This commit is contained in:
parent
62ea2c5437
commit
eaf7e68408
Notes:
sideshowbarker
2024-07-19 04:04:06 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/eaf7e684080
3 changed files with 92 additions and 164 deletions
|
@ -106,12 +106,6 @@ public:
|
|||
Element* parent_element();
|
||||
const Element* parent_element() const;
|
||||
|
||||
template<typename T>
|
||||
const T* first_child_of_type() const;
|
||||
|
||||
template<typename T>
|
||||
const T* first_ancestor_of_type() const;
|
||||
|
||||
virtual void inserted_into(Node&) { }
|
||||
virtual void removed_from(Node&) { }
|
||||
virtual void children_changed() { }
|
||||
|
@ -144,24 +138,4 @@ protected:
|
|||
bool m_needs_style_update { true };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline const T* Node::first_child_of_type() const
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (is<T>(*child))
|
||||
return downcast<T>(child);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const T* Node::first_ancestor_of_type() const
|
||||
{
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (is<T>(*ancestor))
|
||||
return downcast<T>(ancestor);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -69,40 +69,6 @@ public:
|
|||
const LayoutDocument& root() const;
|
||||
LayoutDocument& root();
|
||||
|
||||
template<typename Callback>
|
||||
inline void for_each_child(Callback callback) const
|
||||
{
|
||||
for (auto* node = first_child(); node; node = node->next_sibling())
|
||||
callback(*node);
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
inline void for_each_child(Callback callback)
|
||||
{
|
||||
for (auto* node = first_child(); node; node = node->next_sibling())
|
||||
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(downcast<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(downcast<T>(*node));
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char* class_name() const = 0;
|
||||
virtual bool is_root() const { return false; }
|
||||
virtual bool is_text() const { return false; }
|
||||
|
@ -171,30 +137,6 @@ public:
|
|||
bool children_are_inline() const { return m_children_are_inline; }
|
||||
void set_children_are_inline(bool value) { m_children_are_inline = value; }
|
||||
|
||||
template<typename U>
|
||||
const U* next_sibling_of_type() const;
|
||||
|
||||
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;
|
||||
|
||||
template<typename T>
|
||||
T* first_child_of_type();
|
||||
|
||||
template<typename T>
|
||||
const T* first_ancestor_of_type() const;
|
||||
|
||||
template<typename T>
|
||||
T* first_ancestor_of_type();
|
||||
|
||||
Gfx::FloatPoint box_type_agnostic_position() const;
|
||||
|
||||
float font_size() const;
|
||||
|
@ -275,86 +217,6 @@ inline LayoutNodeWithStyle* LayoutNode::parent()
|
|||
return static_cast<LayoutNodeWithStyle*>(TreeNode<LayoutNode>::parent());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const T* LayoutNode::next_sibling_of_type() const
|
||||
{
|
||||
for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
|
||||
if (is<T>(*sibling))
|
||||
return &downcast<T>(*sibling);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T* LayoutNode::next_sibling_of_type()
|
||||
{
|
||||
for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
|
||||
if (is<T>(*sibling))
|
||||
return &downcast<T>(*sibling);
|
||||
}
|
||||
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 &downcast<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 &downcast<T>(*sibling);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const T* LayoutNode::first_child_of_type() const
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (is<T>(*child))
|
||||
return &downcast<T>(*child);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T* LayoutNode::first_child_of_type()
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (is<T>(*child))
|
||||
return &downcast<T>(*child);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const T* LayoutNode::first_ancestor_of_type() const
|
||||
{
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (is<T>(*ancestor))
|
||||
return &downcast<T>(*ancestor);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T* LayoutNode::first_ancestor_of_type()
|
||||
{
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (is<T>(*ancestor))
|
||||
return &downcast<T>(*ancestor);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AK_BEGIN_TYPE_TRAITS(Web::LayoutNodeWithStyle)
|
||||
|
|
|
@ -191,6 +191,98 @@ public:
|
|||
return IterationDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_child(Callback callback) const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->template for_each_child(move(callback));
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_child(Callback callback)
|
||||
{
|
||||
for (auto* node = first_child(); node; node = node->next_sibling())
|
||||
callback(*node);
|
||||
}
|
||||
|
||||
template<typename U, typename Callback>
|
||||
void for_each_child_of_type(Callback callback)
|
||||
{
|
||||
for (auto* node = first_child(); node; node = node->next_sibling()) {
|
||||
if (is<U>(node))
|
||||
callback(downcast<U>(*node));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U, typename Callback>
|
||||
void for_each_child_of_type(Callback callback) const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->template for_each_child_of_type<U>(move(callback));
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
const U* next_sibling_of_type() const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->template next_sibling_of_type<U>();
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
inline U* next_sibling_of_type()
|
||||
{
|
||||
for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
|
||||
if (is<U>(*sibling))
|
||||
return &downcast<U>(*sibling);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
const U* previous_sibling_of_type() const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->template previous_sibling_of_type<U>();
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
U* previous_sibling_of_type()
|
||||
{
|
||||
for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) {
|
||||
if (is<U>(*sibling))
|
||||
return &downcast<U>(*sibling);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
const U* first_child_of_type() const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->template first_child_of_type<U>();
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
U* first_child_of_type()
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (is<U>(*child))
|
||||
return &downcast<U>(*child);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
const U* first_ancestor_of_type() const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->template first_ancestor_of_type<U>();
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
U* first_ancestor_of_type()
|
||||
{
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (is<U>(*ancestor))
|
||||
return &downcast<U>(*ancestor);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
TreeNode() { }
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue