LibWeb: Only invalidate style/layout on mutation for connected DOM nodes

If a DOM node isn't connected, there's no need to invalidate, since it's
not going to be visible anyway. The node will be automatically inserted
if/when it becomes connected in the future.
This commit is contained in:
Andreas Kling 2024-04-14 10:24:44 +02:00
commit 24157e4d1b
Notes: sideshowbarker 2024-07-16 20:39:14 +09:00
2 changed files with 21 additions and 13 deletions

View file

@ -205,8 +205,10 @@ void Node::set_text_content(Optional<String> const& maybe_content)
// Otherwise, do nothing.
if (is_connected()) {
document().invalidate_style();
document().invalidate_layout();
}
document().bump_dom_tree_version();
}
@ -510,10 +512,11 @@ void Node::insert_before(JS::NonnullGCPtr<Node> node, JS::GCPtr<Node> child, boo
// 9. Run the children changed steps for parent.
children_changed();
if (is_connected()) {
// FIXME: This will need to become smarter when we implement the :has() selector.
invalidate_style();
document().invalidate_layout();
}
document().bump_dom_tree_version();
}
@ -569,6 +572,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Node::append_child(JS::NonnullGCPtr<
// https://dom.spec.whatwg.org/#concept-node-remove
void Node::remove(bool suppress_observers)
{
bool was_connected = is_connected();
// 1. Let parent be nodes parent
auto* parent = this->parent();
@ -705,10 +710,12 @@ void Node::remove(bool suppress_observers)
// 21. Run the children changed steps for parent.
parent->children_changed();
if (was_connected) {
// Since the tree structure has changed, we need to invalidate both style and layout.
// In the future, we should find a way to only invalidate the parts that actually need it.
document().invalidate_style();
document().invalidate_layout();
}
document().bump_dom_tree_version();
}

View file

@ -52,9 +52,10 @@ WebIDL::ExceptionOr<void> inner_html_setter(JS::NonnullGCPtr<DOM::Node> context_
if (!is<HTML::HTMLTemplateElement>(*context_object)) {
context_object->set_needs_style_update(true);
if (context_object->is_connected()) {
// NOTE: Since the DOM has changed, we have to rebuild the layout tree.
context_object->document().invalidate_layout();
context_object->document().set_needs_layout();
}
}
return {};