From 940dfa4b9db16b6cf84b27a93586c5311879a385 Mon Sep 17 00:00:00 2001 From: Harry Brundage Date: Thu, 16 Jul 2026 11:21:07 -0400 Subject: [PATCH 1/2] Fix insertBefore leaving the previous sibling pointing past the inserted node ParentNode.insertBefore relinked the new child's NEXT/PREV and the reference node's PREV, but only repointed the previous sibling's NEXT when the reference node was the first child. Inserting before any later child therefore left the forward sibling chain skipping the new node. That chain is what querySelector, querySelectorAll, and firstChild/nextSibling traversal walk, so an affected node was unreachable from every selector query and sibling walk, while childNodes, parentNode, previousSibling, and the host mirror all still reported it as present. The node rendered correctly on the host and was invisible to the remote environment's own lookups, with no error raised. replaceChild, prepend of more than one node, and ChildNode.after all route through the same branch and were affected too. Hoist the reference node's previous sibling and link it forward to the new child, keeping the insert-at-front case that the old branch already handled. Co-Authored-By: Claude --- .../polyfill-insert-before-sibling-chain.md | 11 + packages/polyfill/source/ParentNode.ts | 6 +- .../polyfill/source/tests/ParentNode.test.ts | 189 ++++++++++++++++++ 3 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 .changeset/polyfill-insert-before-sibling-chain.md create mode 100644 packages/polyfill/source/tests/ParentNode.test.ts diff --git a/.changeset/polyfill-insert-before-sibling-chain.md b/.changeset/polyfill-insert-before-sibling-chain.md new file mode 100644 index 00000000..48c0ee33 --- /dev/null +++ b/.changeset/polyfill-insert-before-sibling-chain.md @@ -0,0 +1,11 @@ +--- +'@remote-dom/polyfill': patch +--- + +Fix `insertBefore()` leaving the previous sibling pointing past the inserted node + +`ParentNode.insertBefore()` relinked the new child's `NEXT`/`PREV` and the reference node's `PREV`, but only repointed the previous sibling's `NEXT` when the reference node was the first child. Inserting before any _later_ child therefore left the forward sibling chain skipping the new node. + +That chain is what `querySelector()`, `querySelectorAll()`, and `firstChild`/`nextSibling` traversal walk, so an affected node was unreachable from every selector query and sibling walk — while `childNodes`, `parentNode`, `previousSibling`, and the host mirror all still reported it as present. The node rendered correctly on the host and was invisible to the remote environment's own lookups, with no error raised. `replaceChild()`, `prepend()` (of more than one node), and `ChildNode.after()` all route through the same branch and were affected too. + +This is easy to hit whenever a framework renders ahead of existing content — for example inserting content before an already-appended `