New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error when inserting node during render: "Failed to execute 'insertBefore' on 'Node'" #2128
Comments
Great catch, thanks a lot. I hadn't thought of that scenario. Your analysis seems pretty good, but it's getting too late here for me to think it through. More tomorrow. |
So: For 1) I think that we could set the DOM to I'm almost certain that 2) is a bug in its own right and that |
Thanks for the feedback. Looks like changing I tried the changes and some of the tests fail, including this one: mithril.js/render/tests/test-component.js Lines 162 to 176 in ec43ca0
The fragment children are rendering out of order. Code snippet of the test. |
I'm starting to get the hang of it... There's a similar bug when using the map-based diff part of the loop. PR coming soon. |
Fix proposal in #2130 |
Thanks @pygy! I tested the proposed fixes in my project and everything works so far. Previous errors are gone. |
Expected Behavior
When rendering there should be no errors and all the elements should be rendered in the correct order.
Current Behavior
When inserting a node during the render process, if
nextSibling
is not a proper child ofparent
then the following error occurs:This happens in the following situations that I have found. In all cases
nextSibling.parentNode
becomes null:updateNodes
when the keys between the compared nodes match while traversing the nodes backwards.nextSibling
is assigned too.dom
of the element that got updated.o.dom
can be removed from the dom if the tags are different, causingo.dom.parentNode
to be null.nextSibling
is set too.dom
causing the error ifinsertNode
is eventually called with the samenextSibling
.mithril.js/render/render.js
Lines 314 to 318 in ec43ca0
mithril.js/render/render.js
Lines 322 to 328 in ec43ca0
updateNode
the next sibling is determined by callinggetNextSibling
with the old nodes. If an old node exists but was removed it could return that node which would be set tonextSibling
.mithril.js/render/render.js
Lines 462 to 467 in ec43ca0
updateNodes
when keys do not match between compared nodes while traversing backwards:nextSibling
is set to the node that gets created.mithril.js/render/render.js
Lines 328 to 330 in ec43ca0
But that node can be a fragment and
parentNode
for a fragment is also null.mithril.js/render/render.js
Lines 92 to 102 in ec43ca0
Those are the only cases where
nextSibling
is set to a value without a parent as far as I could tell.This commit: 02aab65 removed the check for
nextSibling.parentNode
insideinsertNode
. This is causing the underlying issues to not be hidden. Whereas before the commit the error wasn't present, there still was issues with ordering of the rendered elements since the check causedappendChild
to be called instead ofinsertBefore
.Possible Solution
In the first case above the old element
o.dom
was removed. Then it's assigned tonextSibling
. Instead I thinkv.dom
should be the next sibling since it is the element that is on the dom.getNextSibling
should be updated to not return a dom element if it doesn't have a parent. That way it doesn't setnextSibling
to a removed node.And for the second case the created fragment is set to
nextSibling
. Insteadv.dom
should be used since the fragment itself isn't a part of the dom.v.dom
is already set to the first child of the fragment.I did some testing with the above changes and it appears to fix the error successfully and keep the correct order of elements. But I'm not too familiar with the code so I'm looking for some feedback.
I'd be happy to create the PR with these fixes if they're correct.
Steps to Reproduce (for bugs)
Simple steps to reproduce the first case:
Code snippet: Flems
Your Environment
next
. Error doesn't occur in v1.1.6 or below because it doesn't include mentioned commit.The text was updated successfully, but these errors were encountered: