snabbdom: Snabbdom tries to remove a node that is already detached, throws exception
Changing the content of an element from an array of children to some innerHTML content currently produces the following exception:
Uncaught DOMException: Node.removeChild: The node to be removed is not a child of this node
This bug can be reproduced as such:
var patch = snabbdom.init([
snabbdom.propsModule
]);
var el = document.createElement('div');
document.body.appendChild(el);
var vdom = patch(el, snabbdom.h('p', {}, ["Text"]));
patch(vdom, snabbdom.h('p', {props: {innerHTML: "Eh?"}}, []));
In other words:
- Snabbdom renders an element with
TextNodechildren - Snabbdom reuses the element for a new vnode that has no children, but instead sets
innerHTML - Snabbdom calls on the properties module to update the node first, causing it to set innerHTML
- Snabbdom attempts to remove the old
TextNodefrom the DOM - The
TextNodeis no longer attached to the DOM; Snabbdom encounters an exception
It can happen when trying to remove elements as well:
var vdom = patch(el, snabbdom.h('p', {}, [snabbdom.h('span', {}, ['LUL'])]));
patch(vdom, snabbdom.h('p', {props: {innerHTML: "Eh?"}}, []));
This time it fails in a different place.
I could provide a PR, but I’m not sure what the preferred fix is. It seems to me that the way Snabbdom allows its modules to “do anything” to a node is somewhat at odds with its assumptions that all DOM operations are safe. My suggestion for a fix is to ensure that the node being removed in DOMAPI.removeChild is still attached to the DOM (in the position expected by Snabbdom), before attempting to remove it:
function removeChild(node: Node, child: Node): void {
if (child.parentNode === node) {
node.removeChild(child);
}
}
I’m not intimately familiar with the implementation or guiding principles in it, so this may not be your preferred solution.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 4
- Comments: 26 (10 by maintainers)
Commits related to this issue
- Temporarily bundle snabbdom with a fix for snabbdom/snabbdom#970 — committed to cjohansen/dumdom by cjohansen 3 years ago
- Temporarily bundle snabbdom with a fix for snabbdom/snabbdom#970 — committed to cjohansen/dumdom by cjohansen 3 years ago
I’ve been using my down-time to make little Snabbdom PRs and resolve various issues. Because there are many opened issues and PRs, I did not read this great discussion until tonight. @cjohansen it is enjoyable to read your clear input and analysis in all issues and particularly this one.
It seems dumdom continues to be developed and to use Snabbdom despite annoying issues you found and carefully reported which were never resolved,
Would you tell, from a high-level, what is your view of Snabbdom at this time? Has Snabbdom been a good vdom package for you, despite above listed issues? Have you encountered slowness issues like the ones described by @aranchelk? How do you think Snabbdom compares with Inferno and react-dom at this time? Are innerHTML issues the most serious short-coming with Snabbdom? (nice suggestion to support legacy and new core innerHTML implementations)
Also, sharing these recent PRs which might resolve some issues you reported,