Fix insertBefore leaving the previous sibling pointing past the inserted node#622
Open
airhorns wants to merge 1 commit into
Open
Fix insertBefore leaving the previous sibling pointing past the inserted node#622airhorns wants to merge 1 commit into
airhorns wants to merge 1 commit into
Conversation
…ted 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 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
ParentNode.insertInto(child, before)relinks the new child'sNEXT/PREVand the reference node'sPREV, but only repoints the previous sibling'sNEXTwhen the reference node is the first child:Insert before any later child and the forward sibling chain skips the new node.
That chain is exactly what
querySelector/querySelectorAllrecurse through (within[CHILD], then[CHILD]/[NEXT]), and whatfirstChild+nextSiblingtraversal walks. So an affected node becomes unreachable from every selector query and sibling walk — whilechildNodes(a spliced array),parentNode,previousSibling,isConnected, and the host mirror (built from theinsertChild(parent, child, index)hook) all still report it as present.The node renders correctly on the host and is invisible to the remote environment's own lookups, with no error raised.
replaceChild(removeChild+insertInto(new, next)),prependof more than one node, andChildNode.afteron a non-last child all route through the same branch and were affected too.The divergence, on
main, from a hand-rolled host mirror fed by the realinsertChildhook:querySelector('s-modal')[s-page, style]❌[s-page, s-modal, style]null❌[s-page, s-modal, style]✅[s-page, s-modal, style]s-modal✅Why it matters
This is easy to hit whenever a framework renders ahead of existing content. A remote environment that appends a
<style>element to the body and then lets Preact render into it gets every root inserted before that style element — mid-list. Code as ordinary as this then silently does nothing:It also looks non-deterministic, because it tracks whether a
<style>element happens to be present: with no style block the roots insert at the front,before[PREV] === null, and that is the one case the buggy branch got right.The fix
Hoist the reference node's previous sibling and link it forward to the new child, keeping the insert-at-front case: