Merge pull request #1318 from lightpanda-io/node-self-replace

handle Node self replacement in insertBefore
This commit is contained in:
Karl Seguin
2026-01-06 17:23:12 +08:00
committed by GitHub

View File

@@ -457,6 +457,21 @@ pub fn insertBefore(self: *Node, new_node: *Node, ref_node_: ?*Node, page: *Page
return self.appendChild(new_node, page); return self.appendChild(new_node, page);
}; };
// special case: if nodes are the same, ignore the change.
if (new_node == ref_node_) {
page.domChanged();
if (page.hasMutationObservers()) {
const parent = new_node._parent.?;
const previous_sibling = new_node.previousSibling();
const next_sibling = new_node.nextSibling();
const replaced = [_]*Node{new_node};
page.childListChange(parent, &replaced, &replaced, previous_sibling, next_sibling);
}
return new_node;
}
if (ref_node._parent == null or ref_node._parent.? != self) { if (ref_node._parent == null or ref_node._parent.? != self) {
return error.NotFound; return error.NotFound;
} }
@@ -500,23 +515,14 @@ pub fn replaceChild(self: *Node, new_child: *Node, old_child: *Node, page: *Page
try validateNodeInsertion(self, new_child); try validateNodeInsertion(self, new_child);
// special case: we replace a node by itself _ = try self.insertBefore(new_child, old_child, page);
if (new_child == old_child) {
page.domChanged();
if (page.hasMutationObservers()) { // Special case: if we replace a node by itself, we don't remove it.
const parent = new_child._parent.?; // insertBefore is an noop in this case.
const previous_sibling = new_child.previousSibling(); if (new_child != old_child) {
const next_sibling = new_child.nextSibling(); page.removeNode(self, old_child, .{ .will_be_reconnected = false });
const replaced = [_]*Node{new_child};
page.childListChange(parent, &replaced, &replaced, previous_sibling, next_sibling);
}
return old_child;
} }
_ = try self.insertBefore(new_child, old_child, page);
page.removeNode(self, old_child, .{ .will_be_reconnected = false });
return old_child; return old_child;
} }