aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/element.rs1
-rw-r--r--components/script/dom/node.rs28
-rw-r--r--tests/wpt/meta/MANIFEST.json2
-rw-r--r--tests/wpt/tests/dom/nodes/Node-mutation-adoptNode.html14
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>