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:
Andreas Kling 2020-08-10 13:52:49 +02:00
parent 62ea2c5437
commit eaf7e68408
Notes: sideshowbarker 2024-07-19 04:04:06 +09:00
3 changed files with 92 additions and 164 deletions

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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() { }