LibWeb: Fix queuing mutation records for node removal

Step 19 of node removal was missing, which allows the mutations of the
descendants of the removed node to still be observed by the parent.

Step 20 of node removal queued the mutation record for the removed
node instead of it's parent. Since queuing takes place after the node
is removed from the tree, the mutation record would be lost as the only
inclusive ancestor of the node at this point is only the node itself.
This commit is contained in:
Luke Wilde 2022-07-17 18:14:22 +01:00 committed by Linus Groh
parent 9b46091f38
commit aa9f7cc597
Notes: sideshowbarker 2024-07-17 08:52:12 +09:00

View File

@ -563,15 +563,23 @@ void Node::remove(bool suppress_observers)
return IterationDecision::Continue;
});
// FIXME: 19. For each inclusive ancestor inclusiveAncestor of parent, and then for each registered of inclusiveAncestors registered observer list,
// if registereds options["subtree"] is true, then append a new transient registered observer
// whose observer is registereds observer, options is registereds options, and source is registered to nodes registered observer list.
// 19. For each inclusive ancestor inclusiveAncestor of parent, and then for each registered of inclusiveAncestors registered observer list,
// if registereds options["subtree"] is true, then append a new transient registered observer
// whose observer is registereds observer, options is registereds options, and source is registered to nodes registered observer list.
for (auto* inclusive_ancestor = parent; inclusive_ancestor; inclusive_ancestor = inclusive_ancestor->parent()) {
for (auto& registered : inclusive_ancestor->m_registered_observer_list) {
if (registered.options.subtree) {
auto transient_observer = TransientRegisteredObserver::create(registered.observer, registered.options, registered);
m_registered_observer_list.append(move(transient_observer));
}
}
}
// 20. If suppress observers flag is unset, then queue a tree mutation record for parent with « », « node », oldPreviousSibling, and oldNextSibling.
if (!suppress_observers) {
NonnullRefPtrVector<Node> removed_nodes;
removed_nodes.append(*this);
queue_tree_mutation_record(StaticNodeList::create({}), StaticNodeList::create(move(removed_nodes)), old_previous_sibling, old_next_sibling);
parent->queue_tree_mutation_record(StaticNodeList::create({}), StaticNodeList::create(move(removed_nodes)), old_previous_sibling, old_next_sibling);
}
// 21. Run the children changed steps for parent.