[whatwg/dom] replaceNode() has odd mutation observer behavior after #754 (#814)

After implementing #754 in jsdom, we are no longer passing [wpt/dom/nodes/MutatioObserver-childList.html](https://github.com/web-platform-tests/wpt/blob/878422d33b13cf46ec0d4f4201536426137ecc62/dom/nodes/MutationObserver-childList.html#L277-L297) due to the following test:

```html
<p id='n52'><span>NO </span><span>CHANGED</span></p>
<p id='n53'><span>text content</span></p>
```
```diff
   var n52 = document.getElementById('n52');
   runMutationTest(n52,
                   {"childList":true},
                   [{type: "childList",
-                    removedNodes: [n52.lastChild],
-                    previousSibling: n52.firstChild},
+                    removedNodes: [n52.lastChild]},
                    {type: "childList",
                     removedNodes: [n52.firstChild],
                     addedNodes: [n52.lastChild]}],
                   function() { n52.replaceChild(n52.lastChild, n52.firstChild); },
                   "childList Node.replaceChild: internal replacement mutation");
 
   var n53 = document.getElementById('n53');
   runMutationTest(n53,
                   {"childList":true},
                   [{type: "childList",
-                    removedNodes: [n53.firstChild]},
-                   {type: "childList",
-                    addedNodes: [n53.firstChild]}],
+                    addedNodes: [n53.firstChild],
+                    removedNodes: [n53.firstChild]}],
                   function() { n53.replaceChild(n53.firstChild, n53.firstChild); },
                   "childList Node.replaceChild: self internal replacement mutation");
```
(`-` is the previous expected result; `+` is what #754 gives.)

While the n53 change looks fine if in need of an update, n52 is perhaps more problematic.

Prior to #754, `n52.lastChild` first gets removed as part of adoption process in [replace](https://dom.spec.whatwg.org/#concept-node-replace), between steps 9 and 10, leading to a mutation record. At the time of its removal, `n52.firstChild` is still in place, so it's recorded as `previousSibling` in the record.

After #754, however, the explicit adoption process was removed. So `n52.firstChild` first gets removed silently at step 11, and then `n52.lastChild` is removed as part of the adoption process in insert in step 13, leading to a mutation record – when `n52.firstChild` is no longer present in the document.

Looking only at the list of mutation records, the post-#754 flow of event is weird. Even though the removal of `n52.lastChild` is shown as the first event, the silent removal of `n52.firstChild` had already happened – and all this is observable through `previousSibling`. Another way to put this is that the events seem to no longer be atomic, as the second event happens both before and after the first.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/814

Received on Tuesday, 31 December 2019 13:42:55 UTC