mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-28 12:18:56 +00:00
LibWeb: Use TraversalDecision
for multi level Node traversal methods
This adds the `SkipChildrenAndContinue` option, where traversal continues but child nodes are not included.
This commit is contained in:
parent
c57d395a48
commit
398bf10b92
Notes:
sideshowbarker
2024-07-17 08:59:18 +09:00
Author: https://github.com/tcl3
Commit: 398bf10b92
Pull-request: https://github.com/SerenityOS/serenity/pull/24207
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/AtkinsSJ
Reviewed-by: https://github.com/shannonbooth ✅
33 changed files with 229 additions and 215 deletions
|
@ -751,7 +751,7 @@ JS::GCPtr<HTML::HTMLTitleElement> Document::title_element()
|
|||
|
||||
for_each_in_subtree_of_type<HTML::HTMLTitleElement>([&](auto& title_element_in_tree) {
|
||||
title_element = title_element_in_tree;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
});
|
||||
|
||||
return title_element;
|
||||
|
@ -931,10 +931,10 @@ void Document::update_base_element(Badge<HTML::HTMLBaseElement>)
|
|||
for_each_in_subtree_of_type<HTML::HTMLBaseElement>([&base_element](HTML::HTMLBaseElement const& base_element_in_tree) {
|
||||
if (base_element_in_tree.has_attribute(HTML::AttributeNames::href)) {
|
||||
base_element = &base_element_in_tree;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
m_first_base_element_with_href_in_tree_order = base_element;
|
||||
|
@ -1757,7 +1757,7 @@ void Document::adopt_node(Node& node)
|
|||
|
||||
// FIXME: 2. If inclusiveDescendant is an element, then set the node document of each attribute in inclusiveDescendant’s
|
||||
// attribute list to document.
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// 2. For each inclusiveDescendant in node’s shadow-including inclusive descendants that is custom,
|
||||
|
@ -1765,7 +1765,7 @@ void Document::adopt_node(Node& node)
|
|||
// and an argument list containing oldDocument and document.
|
||||
node.for_each_shadow_including_inclusive_descendant([&](DOM::Node& inclusive_descendant) {
|
||||
if (!is<DOM::Element>(inclusive_descendant))
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
|
||||
auto& element = static_cast<DOM::Element&>(inclusive_descendant);
|
||||
if (element.is_custom()) {
|
||||
|
@ -1778,14 +1778,14 @@ void Document::adopt_node(Node& node)
|
|||
element.enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::adoptedCallback, move(arguments));
|
||||
}
|
||||
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// 3. For each inclusiveDescendant in node’s shadow-including inclusive descendants, in shadow-including tree order,
|
||||
// run the adopting steps with inclusiveDescendant and oldDocument.
|
||||
node.for_each_shadow_including_inclusive_descendant([&](auto& inclusive_descendant) {
|
||||
inclusive_descendant.adopted_from(old_document);
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// Transfer NodeIterators rooted at `node` from old_document to this document.
|
||||
|
@ -1951,9 +1951,9 @@ Element* Document::find_a_potential_indicated_element(FlyString const& fragment)
|
|||
root().for_each_in_subtree_of_type<Element>([&](Element const& element) {
|
||||
if (element.name() == fragment) {
|
||||
element_with_name = const_cast<Element*>(&element);
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
if (element_with_name)
|
||||
return element_with_name;
|
||||
|
@ -2959,12 +2959,12 @@ Vector<JS::Handle<HTML::Navigable>> Document::descendant_navigables()
|
|||
auto& navigable_container = static_cast<HTML::NavigableContainer&>(node);
|
||||
// 1. If navigableContainer's content navigable is null, then continue.
|
||||
if (!navigable_container.content_navigable())
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
|
||||
// 2. Extend navigables with navigableContainer's content navigable's active document's inclusive descendant navigables.
|
||||
navigables.extend(navigable_container.content_navigable()->active_document()->inclusive_descendant_navigables());
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// 4. Return navigables.
|
||||
|
@ -3041,10 +3041,10 @@ Vector<JS::Handle<HTML::Navigable>> Document::document_tree_child_navigables()
|
|||
for_each_in_subtree_of_type<HTML::NavigableContainer>([&](HTML::NavigableContainer& navigable_container) {
|
||||
// 1. If navigableContainer's content navigable is null, then continue.
|
||||
if (!navigable_container.content_navigable())
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
// 2. Append navigableContainer's content navigable to navigables.
|
||||
navigables.append(*navigable_container.content_navigable());
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// 5. Return navigables.
|
||||
|
@ -4509,9 +4509,9 @@ Element const* Document::element_from_point(double x, double y)
|
|||
auto* dom_node = result.dom_node();
|
||||
if (dom_node && dom_node->is_element()) {
|
||||
hit_test_result = result;
|
||||
return Painting::TraversalDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return Painting::TraversalDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
if (hit_test_result.has_value())
|
||||
|
@ -4551,7 +4551,7 @@ Vector<JS::NonnullGCPtr<Element>> Document::elements_from_point(double x, double
|
|||
auto* dom_node = result.dom_node();
|
||||
if (dom_node && dom_node->is_element())
|
||||
sequence.append(*static_cast<Element*>(dom_node));
|
||||
return Painting::TraversalDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2290,11 +2290,11 @@ Element::Directionality Element::directionality() const
|
|||
// Discard not-allowed ancestors
|
||||
for (auto* ancestor = text_node.parent(); ancestor && ancestor != this; ancestor = ancestor->parent()) {
|
||||
if (is<HTML::HTMLScriptElement>(*ancestor) || is<HTML::HTMLStyleElement>(*ancestor) || is<HTML::HTMLTextAreaElement>(*ancestor))
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
if (ancestor->is_element()) {
|
||||
auto ancestor_element = static_cast<Element const*>(ancestor);
|
||||
if (ancestor_element->dir().has_value())
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2304,11 +2304,11 @@ Element::Directionality Element::directionality() const
|
|||
if (first_is_one_of(bidi_class, bidirectional_class_L, bidirectional_class_AL, bidirectional_class_R)) {
|
||||
found_character = code_point;
|
||||
found_character_bidi_class = bidi_class;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
}
|
||||
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// If such a character is found and it is of bidirectional character type AL or R,
|
||||
|
|
|
@ -61,7 +61,7 @@ void HTMLCollection::update_cache_if_needed() const
|
|||
m_root->for_each_in_subtree_of_type<Element>([&](auto& element) {
|
||||
if (m_filter(element))
|
||||
m_cached_elements.append(element);
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
} else {
|
||||
m_root->for_each_child_of_type<Element>([&](auto& element) {
|
||||
|
|
|
@ -42,7 +42,7 @@ JS::MarkedVector<Node*> LiveNodeList::collection() const
|
|||
m_root->for_each_in_subtree([&](auto& node) {
|
||||
if (m_filter(node))
|
||||
nodes.append(const_cast<Node*>(&node));
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
} else {
|
||||
m_root->for_each_child([&](auto& node) {
|
||||
|
@ -61,9 +61,9 @@ Node* LiveNodeList::first_matching(Function<bool(Node const&)> const& filter) co
|
|||
m_root->for_each_in_subtree([&](auto& node) {
|
||||
if (m_filter(node) && filter(node)) {
|
||||
matched_node = const_cast<Node*>(&node);
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
} else {
|
||||
m_root->for_each_child([&](auto& node) {
|
||||
|
|
|
@ -149,7 +149,7 @@ String Node::descendant_text_content() const
|
|||
StringBuilder builder;
|
||||
for_each_in_subtree_of_type<Text>([&](auto& text_node) {
|
||||
builder.append(text_node.data());
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
return builder.to_string_without_validation();
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ void Node::invalidate_style()
|
|||
if (shadow_root->has_children())
|
||||
shadow_root->m_child_needs_style_update = true;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
for (auto* ancestor = parent_or_shadow_host(); ancestor; ancestor = ancestor->parent_or_shadow_host())
|
||||
ancestor->m_child_needs_style_update = true;
|
||||
|
@ -507,7 +507,7 @@ void Node::insert_before(JS::NonnullGCPtr<Node> node, JS::GCPtr<Node> child, boo
|
|||
}
|
||||
}
|
||||
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -646,7 +646,7 @@ void Node::remove(bool suppress_observers)
|
|||
|
||||
for_each_in_inclusive_subtree_of_type<HTML::HTMLSlotElement>([&](auto const&) {
|
||||
has_descendent_slot = true;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
});
|
||||
|
||||
if (has_descendent_slot) {
|
||||
|
@ -692,7 +692,7 @@ void Node::remove(bool suppress_observers)
|
|||
}
|
||||
}
|
||||
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// 19. For each inclusive ancestor inclusiveAncestor of parent, and then for each registered of inclusiveAncestor’s registered observer list,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/DOM/Slottable.h>
|
||||
#include <LibWeb/DOMParsing/XMLSerializer.h>
|
||||
#include <LibWeb/TraversalDecision.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
@ -274,11 +275,11 @@ public:
|
|||
|
||||
// https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_shadow_including_inclusive_descendant(Callback);
|
||||
TraversalDecision for_each_shadow_including_inclusive_descendant(Callback);
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-shadow-including-descendant
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_shadow_including_descendant(Callback);
|
||||
TraversalDecision for_each_shadow_including_descendant(Callback);
|
||||
|
||||
Slottable as_slottable();
|
||||
|
||||
|
@ -460,95 +461,95 @@ public:
|
|||
}
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_in_inclusive_subtree(Callback callback) const
|
||||
TraversalDecision for_each_in_inclusive_subtree(Callback callback) const
|
||||
{
|
||||
if (callback(static_cast<Node const&>(*this)) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (auto decision = callback(static_cast<Node const&>(*this)); decision != TraversalDecision::Continue)
|
||||
return decision;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->for_each_in_inclusive_subtree(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_in_inclusive_subtree(Callback callback)
|
||||
TraversalDecision for_each_in_inclusive_subtree(Callback callback)
|
||||
{
|
||||
if (callback(static_cast<Node&>(*this)) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (auto decision = callback(static_cast<Node&>(*this)); decision != TraversalDecision::Continue)
|
||||
return decision;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->for_each_in_inclusive_subtree(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename U, typename Callback>
|
||||
IterationDecision for_each_in_inclusive_subtree_of_type(Callback callback)
|
||||
TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback)
|
||||
{
|
||||
if (is<U>(static_cast<Node&>(*this))) {
|
||||
if (callback(static_cast<U&>(*this)) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (auto decision = callback(static_cast<U&>(*this)); decision != TraversalDecision::Continue)
|
||||
return decision;
|
||||
}
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename U, typename Callback>
|
||||
IterationDecision for_each_in_inclusive_subtree_of_type(Callback callback) const
|
||||
TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback) const
|
||||
{
|
||||
if (is<U>(static_cast<Node const&>(*this))) {
|
||||
if (callback(static_cast<U const&>(*this)) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (auto decision = callback(static_cast<U const&>(*this)); decision != TraversalDecision::Continue)
|
||||
return decision;
|
||||
}
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_in_subtree(Callback callback) const
|
||||
TraversalDecision for_each_in_subtree(Callback callback) const
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->for_each_in_inclusive_subtree(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_in_subtree(Callback callback)
|
||||
TraversalDecision for_each_in_subtree(Callback callback)
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->for_each_in_inclusive_subtree(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename U, typename Callback>
|
||||
IterationDecision for_each_in_subtree_of_type(Callback callback)
|
||||
TraversalDecision for_each_in_subtree_of_type(Callback callback)
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename U, typename Callback>
|
||||
IterationDecision for_each_in_subtree_of_type(Callback callback) const
|
||||
TraversalDecision for_each_in_subtree_of_type(Callback callback) const
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
|
|
|
@ -24,9 +24,9 @@ public:
|
|||
static_cast<NodeType const*>(this)->template for_each_in_inclusive_subtree_of_type<Element>([&](auto& element) {
|
||||
if (element.id() == id) {
|
||||
found_element = &element;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
return found_element;
|
||||
}
|
||||
|
@ -37,9 +37,9 @@ public:
|
|||
static_cast<NodeType*>(this)->template for_each_in_inclusive_subtree_of_type<Element>([&](auto& element) {
|
||||
if (element.id() == id) {
|
||||
found_element = &element;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
return found_element;
|
||||
}
|
||||
|
|
|
@ -45,10 +45,10 @@ WebIDL::ExceptionOr<JS::GCPtr<Element>> ParentNode::query_selector(StringView se
|
|||
for (auto& selector : selectors) {
|
||||
if (SelectorEngine::matches(selector, {}, element, {}, this)) {
|
||||
result = &element;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
return result;
|
||||
|
@ -79,7 +79,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<NodeList>> ParentNode::query_selector_all(S
|
|||
elements.append(&element);
|
||||
}
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
return StaticNodeList::create(realm(), move(elements));
|
||||
|
|
|
@ -1225,7 +1225,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> Range::create_contextual
|
|||
fragment_node->for_each_in_subtree_of_type<HTML::HTMLScriptElement>([&](HTML::HTMLScriptElement& script_element) {
|
||||
script_element.unmark_as_already_started({});
|
||||
script_element.unmark_as_parser_inserted({});
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// 5. Return the value of fragment node.
|
||||
|
|
|
@ -71,37 +71,37 @@ template<>
|
|||
inline bool Node::fast_is<ShadowRoot>() const { return node_type() == to_underlying(NodeType::DOCUMENT_FRAGMENT_NODE) && is_shadow_root(); }
|
||||
|
||||
template<typename Callback>
|
||||
inline IterationDecision Node::for_each_shadow_including_inclusive_descendant(Callback callback)
|
||||
inline TraversalDecision Node::for_each_shadow_including_inclusive_descendant(Callback callback)
|
||||
{
|
||||
if (callback(*this) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (callback(*this) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->is_element()) {
|
||||
if (JS::GCPtr<ShadowRoot> shadow_root = static_cast<Element*>(child)->shadow_root_internal()) {
|
||||
if (shadow_root->for_each_shadow_including_inclusive_descendant(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (shadow_root->for_each_shadow_including_inclusive_descendant(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
}
|
||||
if (child->for_each_shadow_including_inclusive_descendant(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->for_each_shadow_including_inclusive_descendant(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
inline IterationDecision Node::for_each_shadow_including_descendant(Callback callback)
|
||||
inline TraversalDecision Node::for_each_shadow_including_descendant(Callback callback)
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (child->is_element()) {
|
||||
if (JS::GCPtr<ShadowRoot> shadow_root = static_cast<Element*>(child)->shadow_root()) {
|
||||
if (shadow_root->for_each_shadow_including_inclusive_descendant(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (shadow_root->for_each_shadow_including_inclusive_descendant(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
}
|
||||
if (child->for_each_shadow_including_inclusive_descendant(callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (child->for_each_shadow_including_inclusive_descendant(callback) == TraversalDecision::Break)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,10 +78,10 @@ JS::GCPtr<HTML::HTMLSlotElement> find_a_slot(Slottable const& slottable, OpenFla
|
|||
|
||||
shadow->for_each_in_subtree_of_type<HTML::HTMLSlotElement>([&](auto& child) {
|
||||
if (!child.manually_assigned_nodes().contains_slow(slottable))
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
|
||||
slot = child;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
});
|
||||
|
||||
return slot;
|
||||
|
@ -93,10 +93,10 @@ JS::GCPtr<HTML::HTMLSlotElement> find_a_slot(Slottable const& slottable, OpenFla
|
|||
|
||||
shadow->for_each_in_subtree_of_type<HTML::HTMLSlotElement>([&](auto& child) {
|
||||
if (child.slot_name() != slottable_name)
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
|
||||
slot = child;
|
||||
return IterationDecision::Break;
|
||||
return TraversalDecision::Break;
|
||||
});
|
||||
|
||||
return slot;
|
||||
|
@ -188,7 +188,7 @@ void assign_slottables_for_a_tree(JS::NonnullGCPtr<Node> root)
|
|||
// descendants, in tree order.
|
||||
root->for_each_in_inclusive_subtree_of_type<HTML::HTMLSlotElement>([](auto& slot) {
|
||||
assign_slottables(slot);
|
||||
return IterationDecision::Continue;
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue