replaceChild method
Implementation
@override
Node? replaceChild(Node newNode, Node oldNode) {
// https://dom.spec.whatwg.org/#concept-node-replace
// Step 2 to 6 are already done at C++ side.
bool isOldChildConnected = oldNode.isConnected;
// 7. Let reference child be child’s next sibling.
Node? next = oldNode.nextSibling;
// 8. If reference child is node, set it to node’s next sibling.
if (next == newNode) next = newNode.nextSibling;
// 10. Adopt node into parent’s node document.
// Though the following CollectChildrenAndRemoveFromOldParent() also calls
// RemoveChild(), we'd like to call RemoveChild() here to make a separated
// MutationRecord.
ContainerNode? newChildParent = newNode.parentNode;
if (newChildParent != null) {
newChildParent.removeChild(newNode);
}
// 9. Let previousSibling be child’s previous sibling.
// 11. Let removedNodes be the empty list.
// 15. Queue a mutation record of "childList" for target parent with
// addedNodes nodes, removedNodes removedNodes, nextSibling reference child,
// and previousSibling previousSibling.
// 12. If child’s parent is not null, run these substeps:
// 1. Set removedNodes to a list solely containing child.
// 2. Remove child from its parent with the suppress observers flag set.
ContainerNode? oldChildParent = oldNode.parentNode;
if (oldChildParent != null) {
oldChildParent.removeChild(oldNode);
}
List<Node> targets = [];
// 13. Let nodes be node’s children if node is a DocumentFragment node, and
// a list containing solely node otherwise.
if (!collectChildrenAndRemoveFromOldParent(newNode, targets)) return oldNode;
// 10. Adopt node into parent’s node document.
// 14. Insert node into parent before reference child with the suppress
// observers flag set.
if (next != null) {
_insertNode(targets, next, _adoptAndInsertBefore);
} else {
_insertNode(targets, null, _adoptAndAppendChild);
}
if (isOldChildConnected) {
oldNode.disconnectedCallback();
newNode.connectedCallback();
}
didInsertNode(targets, next);
return oldNode;
}