Open TimothyGu opened 4 years ago
The thing I don't understand is that previousSibling goes away as we do store that in a variable upfront before any mutations have happened. So how could it disappear?
child's previous sibling is saved, but not node's. The first mutation event results from step 13 of replace
Insert node into parent before referenceChild with the suppress observers flag set.
which eventually goes to step 7.1 of insert
Adopt node into parent’s node document.
which goes to step 2 of adopt
If node’s parent is non-null, then remove node.
which fires a mutation event. At that time, node's previous sibling has already been removed (in step 11.2 of replace), so the fired mutation event does not contain a previousSibling.
The second mutation event in the array is a result of "queue a tree mutation record" in replace itself. That works fine.
Thanks. Sigh this is hard.
So would reverting work, but then changing "adopt" in two ways:
If "do it anyway" is false and node is a DocumentFragment whose host is non-null, then continue.
Note: This checks node and not inclusiveDescendant as ShadowRoot nodes are to be adopted, unless they are passed directly to adopt.
Then in the template
element's adoption steps, we invoke "adopt" with "do it anyway" set to true.
cc @smaug---- @rniwa
@TimothyGu thoughts on the above? Does jsdom also have all the relevant tests imported? In that case I suppose I could play around with that too, it'd be nice to find a solution here.
@annevk Yes, definitely feel free to play around. Tests are all there, and you can change test exceptions in the to-run.yml file (look for 754 and 813) for a list.
Here's the patch for what you described above:
You could apply it and run tests through yarn test
.
Edit: It looks like this change made html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy.html
pass, but not either custom-elements/adopted-callback.html
or dom/nodes/adoption.window.js
that were changed in web-platform-tests/wpt#16348.
For custom-elements/adopted-callback.html
we have:
Failed in "Moving the shadow host's shadow of a custom element from the owner document into * must enqueue and invoke adoptedCallback":
assert_array_equals: expected array ["disconnected", "adopted", Document node with 2 children, Document node with 1 child, "connected"]
got ["adopted", Document node with 2 children, Document node with 1 child, "disconnected", "connected"])
(but the "moving the <template>
's content of a custom element" test works fine)
For dom/nodes/adoption.window.js
we have:
Failed in "adoptNode() and DocumentFragment with host":
assert_equals: expected Document node with 0 children but got Document node with 2 children
Failed in "adoptNode() and DocumentFragment":
assert_equals: expected Document node with 2 children but got Document node with 0 children
Sorry, it looks like I have gotten myself confused. The correct patch should be the following:
In terms of tests, template-element/template-content-hierarcy.html
works, custom-elements/adopted-callback.html
has the same result as before, and dom/nodes/adoption.window.js
has:
Failed in "appendChild() and DocumentFragment with host":
assert_equals: expected Document node with 2 children but got Document node with 0 children
Failed in "appendChild() and DocumentFragment":
assert_equals: expected Document node with 0 children but got Document node with 2 children
Failed in "appendChild() and ShadowRoot":
assert_equals: expected Document node with 2 children but got Document node with 0 children
I worked a bit more on this and put up https://github.com/jsdom/jsdom/pull/2925, #819, and https://github.com/web-platform-tests/wpt/pull/22504. I'll clean that all up for wider review soonish, but early feedback appreciated.
After implementing #754 in jsdom, we are no longer passing wpt/dom/nodes/MutatioObserver-childList.html due to the following test:
(
-
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, 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 aspreviousSibling
in the record.After #754, however, the explicit adoption process was removed. So
n52.firstChild
first gets removed silently at step 11, and thenn52.lastChild
is removed as part of the adoption process in insert in step 13, leading to a mutation record – whenn52.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 ofn52.firstChild
had already happened – and all this is observable throughpreviousSibling
. 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.