diff --git a/Libraries/LibHTML/DOM/Document.cpp b/Libraries/LibHTML/DOM/Document.cpp index 4856a71739..c0d1c524a4 100644 --- a/Libraries/LibHTML/DOM/Document.cpp +++ b/Libraries/LibHTML/DOM/Document.cpp @@ -193,9 +193,9 @@ void Document::layout() void Document::update_style() { for_each_in_subtree([&](Node& node) { - if (!node.needs_style_update()) - return; - to(node).recompute_style(); + if (node.needs_style_update()) + to(node).recompute_style(); + return IterationDecision::Continue; }); update_layout(); } @@ -242,3 +242,27 @@ void Document::set_hovered_node(Node* node) invalidate_style(); } + +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); + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + return 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)); + return IterationDecision::Continue; + }); + return elements; +} diff --git a/Libraries/LibHTML/DOM/Document.h b/Libraries/LibHTML/DOM/Document.h index dc3c6c625e..c7c7541748 100644 --- a/Libraries/LibHTML/DOM/Document.h +++ b/Libraries/LibHTML/DOM/Document.h @@ -80,6 +80,9 @@ public: void schedule_style_update(); + const Element* get_element_by_id(const String&) const; + Vector get_elements_by_name(const String&) const; + private: virtual RefPtr create_layout_node(const StyleProperties* parent_style) const override; diff --git a/Libraries/LibHTML/DOM/Node.cpp b/Libraries/LibHTML/DOM/Node.cpp index 8995a3e689..bebf6b23be 100644 --- a/Libraries/LibHTML/DOM/Node.cpp +++ b/Libraries/LibHTML/DOM/Node.cpp @@ -77,6 +77,7 @@ void Node::invalidate_style() for_each_in_subtree([&](auto& node) { if (is(node)) node.set_needs_style_update(true); + return IterationDecision::Continue; }); document().schedule_style_update(); } diff --git a/Libraries/LibHTML/HtmlView.cpp b/Libraries/LibHTML/HtmlView.cpp index 4b755180e3..66eb4462d7 100644 --- a/Libraries/LibHTML/HtmlView.cpp +++ b/Libraries/LibHTML/HtmlView.cpp @@ -321,11 +321,14 @@ void HtmlView::scroll_to_anchor(const StringView& name) HTMLAnchorElement* element = nullptr; document()->for_each_in_subtree([&](auto& node) { - if (!is(node)) - return; - auto& anchor_element = to(node); - if (anchor_element.name() == name) - element = &anchor_element; + if (is(node)) { + auto& anchor_element = to(node); + if (anchor_element.name() == name) { + element = &anchor_element; + return IterationDecision::Break; + } + } + return IterationDecision::Continue; }); if (!element) { diff --git a/Libraries/LibHTML/TreeNode.h b/Libraries/LibHTML/TreeNode.h index 229b07c4e2..d368b6c347 100644 --- a/Libraries/LibHTML/TreeNode.h +++ b/Libraries/LibHTML/TreeNode.h @@ -54,12 +54,27 @@ public: bool is_child_allowed(const T&) const { return true; } template - void for_each_in_subtree(Callback callback) + IterationDecision for_each_in_subtree(Callback callback) const { - callback(static_cast(*this)); + if (callback(static_cast(*this)) == IterationDecision::Break) + return IterationDecision::Break; for (auto* child = first_child(); child; child = child->next_sibling()) { - child->for_each_in_subtree(callback); + if (child->for_each_in_subtree(callback) == IterationDecision::Break) + return IterationDecision::Break; } + return IterationDecision::Continue; + } + + template + IterationDecision for_each_in_subtree(Callback callback) + { + if (callback(static_cast(*this)) == IterationDecision::Break) + return IterationDecision::Break; + for (auto* child = first_child(); child; child = child->next_sibling()) { + if (child->for_each_in_subtree(callback) == IterationDecision::Break) + return IterationDecision::Break; + } + return IterationDecision::Continue; } protected: