mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibWeb: Move non-DOM-related methods from DOM::Node to TreeNode
Motivated by wanting to do `is_before()` on a Layout::Node, and thought I might as well move as many as possible while I was at it.
This commit is contained in:
parent
5fad6b1938
commit
ea33bdc975
Notes:
github-actions[bot]
2025-06-07 14:51:50 +00:00
Author: https://github.com/AtkinsSJ
Commit: ea33bdc975
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5022
3 changed files with 154 additions and 156 deletions
|
@ -575,17 +575,6 @@ String Node::child_text_content() const
|
|||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-tree-root
|
||||
Node& Node::root()
|
||||
{
|
||||
// The root of an object is itself, if its parent is null, or else it is the root of its parent.
|
||||
// The root of a tree is any object participating in that tree whose parent is null.
|
||||
Node* root = this;
|
||||
while (root->parent())
|
||||
root = root->parent();
|
||||
return *root;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-shadow-including-root
|
||||
Node& Node::shadow_including_root()
|
||||
{
|
||||
|
@ -1977,13 +1966,6 @@ bool Node::is_scripting_disabled() const
|
|||
return !is_scripting_enabled();
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-node-contains
|
||||
bool Node::contains(GC::Ptr<Node> other) const
|
||||
{
|
||||
// The contains(other) method steps are to return true if other is an inclusive descendant of this; otherwise false (including when other is null).
|
||||
return other && other->is_inclusive_descendant_of(*this);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-shadow-including-descendant
|
||||
bool Node::is_shadow_including_descendant_of(Node const& other) const
|
||||
{
|
||||
|
@ -2588,28 +2570,6 @@ void Node::remove_child_impl(GC::Ref<Node> node)
|
|||
TreeNode::remove_child(node);
|
||||
}
|
||||
|
||||
bool Node::is_descendant_of(Node const& other) const
|
||||
{
|
||||
return other.is_ancestor_of(*this);
|
||||
}
|
||||
|
||||
bool Node::is_inclusive_descendant_of(Node const& other) const
|
||||
{
|
||||
return other.is_inclusive_ancestor_of(*this);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-tree-following
|
||||
bool Node::is_following(Node const& other) const
|
||||
{
|
||||
// An object A is following an object B if A and B are in the same tree and A comes after B in tree order.
|
||||
for (auto* node = previous_in_pre_order(); node; node = node->previous_in_pre_order()) {
|
||||
if (node == &other)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Node::build_accessibility_tree(AccessibilityTreeNode& parent)
|
||||
{
|
||||
if (is_uninteresting_whitespace_node())
|
||||
|
|
|
@ -280,12 +280,6 @@ public:
|
|||
|
||||
String child_text_content() const;
|
||||
|
||||
Node& root();
|
||||
Node const& root() const
|
||||
{
|
||||
return const_cast<Node*>(this)->root();
|
||||
}
|
||||
|
||||
Node& shadow_including_root();
|
||||
Node const& shadow_including_root() const
|
||||
{
|
||||
|
@ -376,8 +370,6 @@ public:
|
|||
bool is_scripting_enabled() const;
|
||||
bool is_scripting_disabled() const;
|
||||
|
||||
bool contains(GC::Ptr<Node>) const;
|
||||
|
||||
// Used for dumping the DOM Tree
|
||||
void serialize_tree_as_json(JsonObjectSerializer<StringBuilder>&) const;
|
||||
|
||||
|
@ -424,98 +416,6 @@ public:
|
|||
|
||||
Slottable as_slottable();
|
||||
|
||||
size_t child_count() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling())
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
Node* child_at_index(int index)
|
||||
{
|
||||
int count = 0;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (count == index)
|
||||
return child;
|
||||
++count;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node const* child_at_index(int index) const
|
||||
{
|
||||
return const_cast<Node*>(this)->child_at_index(index);
|
||||
}
|
||||
|
||||
bool is_descendant_of(Node const&) const;
|
||||
bool is_inclusive_descendant_of(Node const&) const;
|
||||
|
||||
bool is_following(Node const&) const;
|
||||
|
||||
bool is_before(Node const& other) const
|
||||
{
|
||||
if (this == &other)
|
||||
return false;
|
||||
for (auto* node = this; node; node = node->next_in_pre_order()) {
|
||||
if (node == &other)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-tree-preceding (Object A is 'typename U' and Object B is 'this')
|
||||
template<typename U>
|
||||
bool has_preceding_node_of_type_in_tree_order() const
|
||||
{
|
||||
for (auto* node = previous_in_pre_order(); node; node = node->previous_in_pre_order()) {
|
||||
if (is<U>(node))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-tree-following (Object A is 'typename U' and Object B is 'this')
|
||||
template<typename U>
|
||||
bool has_following_node_of_type_in_tree_order() const
|
||||
{
|
||||
for (auto* node = next_in_pre_order(); node; node = node->next_in_pre_order()) {
|
||||
if (is<U>(node))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_ancestor(Callback callback) const
|
||||
{
|
||||
return const_cast<Node*>(this)->for_each_ancestor(move(callback));
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_ancestor(Callback callback)
|
||||
{
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (callback(*ancestor) == IterationDecision::Break)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_inclusive_ancestor(Callback callback) const
|
||||
{
|
||||
return const_cast<Node*>(this)->for_each_inclusive_ancestor(move(callback));
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_inclusive_ancestor(Callback callback)
|
||||
{
|
||||
for (auto* ancestor = this; ancestor; ancestor = ancestor->parent()) {
|
||||
if (callback(*ancestor) == IterationDecision::Break)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U, typename Callback>
|
||||
WebIDL::ExceptionOr<void> for_each_child_of_type_fallible(Callback callback)
|
||||
{
|
||||
|
@ -527,13 +427,6 @@ public:
|
|||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool has_child_of_type() const
|
||||
{
|
||||
return first_child_of_type<U>() != nullptr;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
U const* shadow_including_first_ancestor_of_type() const
|
||||
{
|
||||
|
@ -543,15 +436,6 @@ public:
|
|||
template<typename U>
|
||||
U* shadow_including_first_ancestor_of_type();
|
||||
|
||||
bool is_parent_of(Node const& other) const
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (&other == child)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ErrorOr<String> accessible_name(Document const&, ShouldComputeRole = ShouldComputeRole::Yes) const;
|
||||
ErrorOr<String> accessible_description(Document const&) const;
|
||||
|
||||
|
|
|
@ -72,8 +72,57 @@ public:
|
|||
return index;
|
||||
}
|
||||
|
||||
// // https://dom.spec.whatwg.org/#concept-tree-root
|
||||
T& root()
|
||||
{
|
||||
// The root of an object is itself, if its parent is null, or else it is the root of its parent.
|
||||
// The root of a tree is any object participating in that tree whose parent is null.
|
||||
T* root = static_cast<T*>(this);
|
||||
while (root->parent())
|
||||
root = root->parent();
|
||||
return *root;
|
||||
}
|
||||
T const& root() const { return const_cast<TreeNode*>(this)->root(); }
|
||||
|
||||
bool is_ancestor_of(TreeNode const&) const;
|
||||
bool is_inclusive_ancestor_of(TreeNode const&) const;
|
||||
bool contains(GC::Ptr<T>) const;
|
||||
bool is_descendant_of(TreeNode const&) const;
|
||||
bool is_inclusive_descendant_of(TreeNode const&) const;
|
||||
|
||||
bool is_following(TreeNode const&) const;
|
||||
bool is_before(TreeNode const&) const;
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-tree-preceding (Object A is 'typename U' and Object B is 'this')
|
||||
template<typename U>
|
||||
bool has_preceding_node_of_type_in_tree_order() const
|
||||
{
|
||||
for (auto* node = previous_in_pre_order(); node; node = node->previous_in_pre_order()) {
|
||||
if (is<U>(node))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-tree-following (Object A is 'typename U' and Object B is 'this')
|
||||
template<typename U>
|
||||
bool has_following_node_of_type_in_tree_order() const
|
||||
{
|
||||
for (auto* node = next_in_pre_order(); node; node = node->next_in_pre_order()) {
|
||||
if (is<U>(node))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_parent_of(TreeNode const& other) const
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (&other == child)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void append_child(GC::Ref<T> node);
|
||||
void prepend_child(GC::Ref<T> node);
|
||||
|
@ -87,6 +136,30 @@ public:
|
|||
m_parent->remove_child(*static_cast<T*>(this));
|
||||
}
|
||||
|
||||
size_t child_count() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling())
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
T* child_at_index(int index)
|
||||
{
|
||||
int count = 0;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (count == index)
|
||||
return child;
|
||||
++count;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
T const* child_at_index(int index) const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->child_at_index(index);
|
||||
}
|
||||
|
||||
T* next_in_pre_order()
|
||||
{
|
||||
if (first_child())
|
||||
|
@ -280,6 +353,12 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool has_child_of_type() const
|
||||
{
|
||||
return first_child_of_type<U>() != nullptr;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
U const* first_child_of_type() const
|
||||
{
|
||||
|
@ -328,6 +407,36 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_ancestor(Callback callback) const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->for_each_ancestor(move(callback));
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_ancestor(Callback callback)
|
||||
{
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (callback(static_cast<T&>(*ancestor)) == IterationDecision::Break)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_inclusive_ancestor(Callback callback) const
|
||||
{
|
||||
return const_cast<TreeNode*>(this)->for_each_inclusive_ancestor(move(callback));
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_inclusive_ancestor(Callback callback)
|
||||
{
|
||||
for (auto* ancestor = this; ancestor; ancestor = ancestor->parent()) {
|
||||
if (callback(static_cast<T&>(*ancestor)) == IterationDecision::Break)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
~TreeNode() = default;
|
||||
|
||||
protected:
|
||||
|
@ -464,4 +573,49 @@ inline bool TreeNode<T>::is_inclusive_ancestor_of(TreeNode<T> const& other) cons
|
|||
return &other == this || is_ancestor_of(other);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-node-contains
|
||||
template<typename T>
|
||||
inline bool TreeNode<T>::contains(GC::Ptr<T> other) const
|
||||
{
|
||||
// The contains(other) method steps are to return true if other is an inclusive descendant of this; otherwise false (including when other is null).
|
||||
return other && other->is_inclusive_descendant_of(*this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool TreeNode<T>::is_descendant_of(TreeNode<T> const& other) const
|
||||
{
|
||||
return other.is_ancestor_of(*this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool TreeNode<T>::is_inclusive_descendant_of(TreeNode<T> const& other) const
|
||||
{
|
||||
return other.is_inclusive_ancestor_of(*this);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-tree-following
|
||||
template<typename T>
|
||||
inline bool TreeNode<T>::is_following(TreeNode const& other) const
|
||||
{
|
||||
// An object A is following an object B if A and B are in the same tree and A comes after B in tree order.
|
||||
for (auto* node = previous_in_pre_order(); node; node = node->previous_in_pre_order()) {
|
||||
if (node == &other)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool TreeNode<T>::is_before(TreeNode const& other) const
|
||||
{
|
||||
if (this == &other)
|
||||
return false;
|
||||
for (auto* node = this; node; node = node->next_in_pre_order()) {
|
||||
if (node == &other)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue