fix(platform-browser): avoid false NG05106 errors on insertBefore - #70423
Open
lazerg wants to merge 1 commit into
Open
fix(platform-browser): avoid false NG05106 errors on insertBefore#70423lazerg wants to merge 1 commit into
lazerg wants to merge 1 commit into
Conversation
lazerg
force-pushed
the
fix/issue-70418-insert-before-parent-identity
branch
from
August 27, 2026 08:16
80b6011 to
8f4d9fa
Compare
arturovt
reviewed
Aug 27, 2026
| parent.appendChild(refChild); | ||
|
|
||
| // some DOM implementations hand out more than one object for the same element | ||
| const wrappedParent = new Proxy(parent, { |
Contributor
There was a problem hiding this comment.
The proxy trap is heavier to read, looking at the implementation we only need to pass an object who's shape would go against === comparison, I think this should work (haven't checked locally):
it('inserts a child even when refChild.parentNode is not the passed-in parent object', () => {
// some DOM implementations hand out more than one object for the same element
const realParent = document.createElement('div');
const refChild = document.createElement('span');
const newChild = document.createElement('div');
realParent.appendChild(refChild);
const parentAlias = {
tagName: 'DIV',
insertBefore: (n: Node, r: Node) => realParent.insertBefore(n, r),
};
renderer.insertBefore(parentAlias, newChild, refChild);
expect(newChild.parentNode).toBe(realParent);
expect(newChild.nextSibling).toBe(refChild);
});
Contributor
Author
There was a problem hiding this comment.
Thanks, applied in cbc65b9. I ran it locally first: it fails on the old code with NG05106 and passes with the fix, on both Chromium and Firefox. It is also the stricter check, since a plain object breaks loudly if the renderer ever reads more than insertBefore off the parent.
arturovt
approved these changes
Aug 27, 2026
arturovt
left a comment
Contributor
There was a problem hiding this comment.
@JeanMeche LGTM for me overall, left a comment to simplify the unit test.
The guard added for NG05106 compares `refChild.parentNode` with the target parent by object identity, but `parentNode` is only specified to return the parent node, not one particular object for it. DOM implementations that hand out more than one object per element then hit the guard on inserts the native call would have completed. Run the native call first and describe the failure only once it actually throws.
lazerg
force-pushed
the
fix/issue-70418-insert-before-parent-identity
branch
from
August 27, 2026 13:02
8f4d9fa to
cbc65b9
Compare
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.
DefaultDomRenderer2.insertBeforechecks thatrefChild.parentNodeis the parent it is about to insert into and throws NG05106 when it is not.parentNodeonly guarantees the parent node itself though, not one particular object for it, so an implementation may hand out more than one wrapper for the same element. happy-dom does that for<form>and<select>, whose constructors return aProxywhile children attached before the element was connected keep a reference to the raw instance. A component whose template root is a form then throws on insertions the native call would have completed.Run the native call first and inspect the reference node only after it throws, so the descriptive error still replaces the opaque
NotFoundErrorin both cases the guard was written for.Fixes #70418