1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:47:44 +00:00

LibHTML: Add TreeNode::for_each_in_subtree_of_type<T>()

This allows you to iterate a subtree and get a callback for every node
where is<T>(node) == true. This makes for quite pleasant DOM traversal.
This commit is contained in:
Andreas Kling 2019-12-18 21:34:03 +01:00
parent 54bd322881
commit 1aea8f116b
5 changed files with 56 additions and 25 deletions

View file

@ -177,9 +177,9 @@ void Document::layout()
void Document::update_style()
{
for_each_in_subtree([&](Node& node) {
if (node.needs_style_update())
to<Element>(node).recompute_style();
for_each_in_subtree_of_type<Element>([&](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<Element>(node) && to<Element>(node).attribute("id") == id) {
element = &to<Element>(node);
const Element* found_element = nullptr;
for_each_in_subtree_of_type<Element>([&](auto& element) {
if (element.attribute("id") == id) {
found_element = &element;
return IterationDecision::Break;
}
return IterationDecision::Continue;
});
return element;
return found_element;
}
Vector<const Element*> Document::get_elements_by_name(const String& name) const
{
Vector<const Element*> elements;
for_each_in_subtree([&](auto& node) {
if (is<Element>(node) && to<Element>(node).attribute("name") == name)
elements.append(&to<Element>(node));
for_each_in_subtree_of_type<Element>([&](auto& element) {
if (element.attribute("name") == name)
elements.append(&element);
return IterationDecision::Continue;
});
return elements;

View file

@ -34,12 +34,10 @@ void HTMLFormElement::submit()
Vector<NameAndValue> parameters;
for_each_in_subtree([&](auto& node) {
if (is<HTMLInputElement>(node)) {
auto& input = to<HTMLInputElement>(node);
if (!input.name().is_null())
parameters.append({ input.name(), input.value() });
}
for_each_in_subtree_of_type<HTMLInputElement>([&](auto& node) {
auto& input = to<HTMLInputElement>(node);
if (!input.name().is_null())
parameters.append({ input.name(), input.value() });
return IterationDecision::Continue;
});

View file

@ -74,9 +74,8 @@ RefPtr<LayoutNode> Node::create_layout_node(const StyleProperties*) const
void Node::invalidate_style()
{
for_each_in_subtree([&](auto& node) {
if (is<Element>(node))
node.set_needs_style_update(true);
for_each_in_subtree_of_type<Element>([&](auto& element) {
element.set_needs_style_update(true);
return IterationDecision::Continue;
});
document().schedule_style_update();