diff options
-rw-r--r-- | components/script/dom/element.rs | 1 | ||||
-rw-r--r-- | components/script/dom/node.rs | 28 | ||||
-rw-r--r-- | tests/wpt/meta/MANIFEST.json | 2 | ||||
-rw-r--r-- | tests/wpt/tests/dom/nodes/Node-mutation-adoptNode.html | 14 |
4 files changed, 38 insertions, 7 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 58a4d26a6a5..17e1549c64d 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -160,6 +160,7 @@ use crate::task::TaskOnce; // and when the element enters or leaves a browsing context container. // https://html.spec.whatwg.org/multipage/#selector-focus +/// <https://dom.spec.whatwg.org/#element> #[dom_struct] pub(crate) struct Element { node: Node, diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 1f991d3b715..e37e8df1c55 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -1886,30 +1886,46 @@ impl Node { pub(crate) fn adopt(node: &Node, document: &Document) { document.add_script_and_layout_blocker(); - // Step 1. + // Step 1. Let oldDocument be node’s node document. let old_doc = node.owner_doc(); old_doc.add_script_and_layout_blocker(); - // Step 2. + + // Step 2. If node’s parent is non-null, then remove node. node.remove_self(); - // Step 3. + + // Step 3. If document is not oldDocument: if &*old_doc != document { - // Step 3.1. + // Step 3.1. For each inclusiveDescendant in node’s shadow-including inclusive descendants: for descendant in node.traverse_preorder(ShadowIncluding::Yes) { + // Step 3.1.1 Set inclusiveDescendant’s node document to document. descendant.set_owner_doc(document); + + // Step 3.1.2 If inclusiveDescendant is an element, then set the node document of each + // attribute in inclusiveDescendant’s attribute list to document. + if let Some(element) = descendant.downcast::<Element>() { + for attribute in element.attrs().iter() { + attribute.upcast::<Node>().set_owner_doc(document); + } + } } + + // Step 3.2 For each inclusiveDescendant in node’s shadow-including inclusive descendants + // that is custom, enqueue a custom element callback reaction with inclusiveDescendant, + // callback name "adoptedCallback", and « oldDocument, document ». for descendant in node .traverse_preorder(ShadowIncluding::Yes) .filter_map(|d| d.as_custom_element()) { - // Step 3.2. ScriptThread::enqueue_callback_reaction( &descendant, CallbackReaction::Adopted(old_doc.clone(), DomRoot::from_ref(document)), None, ); } + + // Step 3.3 For each inclusiveDescendant in node’s shadow-including inclusive descendants, + // in shadow-including tree order, run the adopting steps with inclusiveDescendant and oldDocument. for descendant in node.traverse_preorder(ShadowIncluding::Yes) { - // Step 3.3. vtable_for(&descendant).adopting_steps(&old_doc); } } diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 01012a8b8b1..59a503639f5 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -606523,7 +606523,7 @@ ] ], "Node-mutation-adoptNode.html": [ - "9c9594c07b22a4ac94b3703f8ab1711b41a759e4", + "812a2e4d3af326c1e73115c6fc50726bc4fc4b23", [ null, {} diff --git a/tests/wpt/tests/dom/nodes/Node-mutation-adoptNode.html b/tests/wpt/tests/dom/nodes/Node-mutation-adoptNode.html index 9c9594c07b2..812a2e4d3af 100644 --- a/tests/wpt/tests/dom/nodes/Node-mutation-adoptNode.html +++ b/tests/wpt/tests/dom/nodes/Node-mutation-adoptNode.html @@ -20,4 +20,18 @@ test(() => { assert_equals(div.firstChild.ownerDocument, document); }, "simple append of foreign div with text"); +test(function() { + var div = document.createElement("div"); + div.id = "foobar"; + + assert_equals(div.ownerDocument, document); + assert_equals(div.attributes[0].ownerDocument, document); + + var other_doc = document.implementation.createHTMLDocument(); + other_doc.body.appendChild(div); + + assert_equals(div.ownerDocument, other_doc); + assert_equals(div.attributes[0].ownerDocument, other_doc); +}, "Adopting an element into a different document update's the element's owner doc as well as the owner docs of it's attributes") + </script> |