diff --git a/Libraries/LibHTML/DOM/Document.cpp b/Libraries/LibHTML/DOM/Document.cpp index 5d1eaf19c5d..fb631bd1410 100644 --- a/Libraries/LibHTML/DOM/Document.cpp +++ b/Libraries/LibHTML/DOM/Document.cpp @@ -177,9 +177,9 @@ void Document::layout() void Document::update_style() { - for_each_in_subtree([&](Node& node) { - if (node.needs_style_update()) - to(node).recompute_style(); + for_each_in_subtree_of_type([&](auto& element) { + if (element.needs_style_update()) + element.recompute_style(); return IterationDecision::Continue; }); update_layout(); @@ -252,23 +252,23 @@ void Document::set_hovered_node(Node* node) const Element* Document::get_element_by_id(const String& id) const { - const Element* element = nullptr; - for_each_in_subtree([&](auto& node) { - if (is(node) && to(node).attribute("id") == id) { - element = &to(node); + const Element* found_element = nullptr; + for_each_in_subtree_of_type([&](auto& element) { + if (element.attribute("id") == id) { + found_element = &element; return IterationDecision::Break; } return IterationDecision::Continue; }); - return element; + return found_element; } Vector Document::get_elements_by_name(const String& name) const { Vector elements; - for_each_in_subtree([&](auto& node) { - if (is(node) && to(node).attribute("name") == name) - elements.append(&to(node)); + for_each_in_subtree_of_type([&](auto& element) { + if (element.attribute("name") == name) + elements.append(&element); return IterationDecision::Continue; }); return elements; diff --git a/Libraries/LibHTML/DOM/HTMLFormElement.cpp b/Libraries/LibHTML/DOM/HTMLFormElement.cpp index 1e0f047533e..a6fb478f07b 100644 --- a/Libraries/LibHTML/DOM/HTMLFormElement.cpp +++ b/Libraries/LibHTML/DOM/HTMLFormElement.cpp @@ -34,12 +34,10 @@ void HTMLFormElement::submit() Vector parameters; - for_each_in_subtree([&](auto& node) { - if (is(node)) { - auto& input = to(node); - if (!input.name().is_null()) - parameters.append({ input.name(), input.value() }); - } + for_each_in_subtree_of_type([&](auto& node) { + auto& input = to(node); + if (!input.name().is_null()) + parameters.append({ input.name(), input.value() }); return IterationDecision::Continue; }); diff --git a/Libraries/LibHTML/DOM/Node.cpp b/Libraries/LibHTML/DOM/Node.cpp index bebf6b23be6..78ccf41ad11 100644 --- a/Libraries/LibHTML/DOM/Node.cpp +++ b/Libraries/LibHTML/DOM/Node.cpp @@ -74,9 +74,8 @@ RefPtr Node::create_layout_node(const StyleProperties*) const void Node::invalidate_style() { - for_each_in_subtree([&](auto& node) { - if (is(node)) - node.set_needs_style_update(true); + for_each_in_subtree_of_type([&](auto& element) { + element.set_needs_style_update(true); return IterationDecision::Continue; }); document().schedule_style_update(); diff --git a/Libraries/LibHTML/Layout/LayoutDocument.cpp b/Libraries/LibHTML/Layout/LayoutDocument.cpp index 279fb810cbf..9ff55e20745 100644 --- a/Libraries/LibHTML/Layout/LayoutDocument.cpp +++ b/Libraries/LibHTML/Layout/LayoutDocument.cpp @@ -34,11 +34,8 @@ void LayoutDocument::layout() void LayoutDocument::did_set_viewport_rect(Badge, const Rect& a_viewport_rect) { FloatRect viewport_rect(a_viewport_rect.x(), a_viewport_rect.y(), a_viewport_rect.width(), a_viewport_rect.height()); - for_each_in_subtree([&](auto& layout_node) { - if (is(layout_node)) { - auto& image = to(layout_node); - const_cast(image.node()).set_volatile({}, !viewport_rect.intersects(image.rect())); - } + for_each_in_subtree_of_type([&](auto& layout_image) { + const_cast(layout_image.node()).set_volatile({}, !viewport_rect.intersects(layout_image.rect())); return IterationDecision::Continue; }); } diff --git a/Libraries/LibHTML/TreeNode.h b/Libraries/LibHTML/TreeNode.h index d87b8e0a6f1..5ad07f8daf5 100644 --- a/Libraries/LibHTML/TreeNode.h +++ b/Libraries/LibHTML/TreeNode.h @@ -4,6 +4,15 @@ #include #include +// FIXME: I wish I didn't have to forward declare these, but I can't seem to avoid +// it if I still want to have for_each_in_subtree_of_type inline here. +class Node; +class LayoutNode; +template +bool is(const Node&); +template +bool is(const LayoutNode&); + template class TreeNode : public Weakable { public: @@ -122,6 +131,34 @@ public: return IterationDecision::Continue; } + template + IterationDecision for_each_in_subtree_of_type(Callback callback) + { + if (is(static_cast(*this))) { + if (callback(static_cast(*this)) == IterationDecision::Break) + return IterationDecision::Break; + } + for (auto* child = first_child(); child; child = child->next_sibling()) { + if (child->template for_each_in_subtree_of_type(callback) == IterationDecision::Break) + return IterationDecision::Break; + } + return IterationDecision::Continue; + } + + template + IterationDecision for_each_in_subtree_of_type(Callback callback) const + { + if (is(static_cast(*this))) { + if (callback(static_cast(*this)) == IterationDecision::Break) + return IterationDecision::Break; + } + for (auto* child = first_child(); child; child = child->next_sibling()) { + if (child->template for_each_in_subtree_of_type(callback) == IterationDecision::Break) + return IterationDecision::Break; + } + return IterationDecision::Continue; + } + protected: TreeNode() {}