LibWeb: Style invalidation for DOM node removal needs to happen earlier

We can't invalidate after the removal has taken effect, since that means
invalidation won't be able to find potentially affected siblings and
ancestors by traversing from the invalidation target.
This commit is contained in:
Andreas Kling 2024-11-06 17:24:39 +01:00 committed by Andreas Kling
commit 1045000c28
Notes: github-actions[bot] 2024-11-06 20:44:01 +00:00
6 changed files with 23 additions and 27 deletions

View file

@ -748,9 +748,6 @@ 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();
bool had_layout_node = layout_node();
// 1. Let parent be nodes parent
auto* parent = this->parent();
@ -795,6 +792,18 @@ void Node::remove(bool suppress_observers)
// 10. Let oldNextSibling be nodes next sibling.
JS::GCPtr<Node> old_next_sibling = next_sibling();
if (is_connected()) {
// Since the tree structure is about to change, 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.
invalidate_style(StyleInvalidationReason::NodeRemove);
// NOTE: If we didn't have a layout node before, rebuilding the layout tree isn't gonna give us one
// after we've been removed from the DOM.
if (layout_node()) {
document().invalidate_layout_tree();
}
}
// 11. Remove node from its parents children.
parent->remove_child_impl(*this);
@ -887,19 +896,6 @@ 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.
invalidate_style(StyleInvalidationReason::NodeRemove);
// NOTE: If we didn't have a layout node before, rebuilding the layout tree isn't gonna give us one
// after we've been removed from the DOM.
if (had_layout_node) {
document().invalidate_layout_tree();
}
}
document().bump_dom_tree_version();
}