diff --git a/shadow-dom/slots-imperative-api-slotchange.tentative.html b/shadow-dom/imperative-slot-api-slotchange.html
similarity index 98%
rename from shadow-dom/slots-imperative-api-slotchange.tentative.html
rename to shadow-dom/imperative-slot-api-slotchange.html
index 43627a246cce9d9..dd9ebbd3f849b32 100644
--- a/shadow-dom/slots-imperative-api-slotchange.tentative.html
+++ b/shadow-dom/imperative-slot-api-slotchange.html
@@ -107,7 +107,7 @@
let tTree = setupShadowDOM(test_slotchange, test, data);
let [s1Promise, s2Promise] = monitorSlots(data);
- assert_throws_dom('NotAllowedError', () => { tTree.s1.assign([tTree.c4]); });
+ tTree.s1.assign([]);;
tTree.s2.assign([]);
tTree.host.insertBefore(tTree.c4, tTree.c1);
@@ -135,7 +135,7 @@
[s1Promise] = monitorSlots(data);
tTree.s1.assign([tTree.c1, tTree.c2]);
- tTree.s1.assign([tTree.c2, tTree.c1, tTree.c1, tTree.c2, tTree.c2]);
+ tTree.s1.assign([tTree.c1, tTree.c2, tTree.c1, tTree.c2, tTree.c2]);
s1Promise.then(test.step_func_done(() => {
assert_equals(data.s1EventCount, 1);
diff --git a/shadow-dom/slots-imperative-slot-api.tentative.html b/shadow-dom/imperative-slot-api.html
similarity index 71%
rename from shadow-dom/slots-imperative-slot-api.tentative.html
rename to shadow-dom/imperative-slot-api.html
index 2ffb08fba1b70e1..54b22632d11547f 100644
--- a/shadow-dom/slots-imperative-slot-api.tentative.html
+++ b/shadow-dom/imperative-slot-api.html
@@ -15,7 +15,7 @@
let tTree = createTestTree(test_basic);
assert_not_equals(tTree.host1.attachShadow({ mode: 'open', slotAssignment: 'manual'}),
null, 'slot assignment manual should work');
- assert_not_equals(tTree.host2.attachShadow({ mode: 'open', slotAssignment: 'name'}),
+ assert_not_equals(tTree.host2.attachShadow({ mode: 'open', slotAssignment: 'named'}),
null, 'slot assignment auto should work');
assert_throws_js(TypeError, () => {
tTree.host3.attachShadow({ mode: 'open', slotAssignment: 'exceptional' })},
@@ -23,39 +23,6 @@
}, 'attachShadow can take slotAssignment parameter.');
-
@@ -155,34 +122,31 @@
let tTree = createTestTree(test_assign);
// tTree.c4 is invalid for tTree.host slot assignment.
- try {
- tTree.s1.assign([tTree.c1, tTree.c2, tTree.c4]);
- assert_unreached('assign() should have failed) ');
- } catch (err) {
- assert_equals(err.name, 'NotAllowedError');
- }
+ // No exception should be thrown here.
+ tTree.s1.assign([tTree.c1, tTree.c4, tTree.c2]);
- assert_array_equals(tTree.s1.assignedNodes(), []);
- assert_equals(tTree.c1.assignedSlot, null);
- assert_equals(tTree.c2.assignedSlot, null);
+ // All observable assignments should skip c4.
+ assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2]);
+ assert_equals(tTree.c1.assignedSlot, tTree.s1);
+ assert_equals(tTree.c2.assignedSlot, tTree.s1);
assert_equals(tTree.c4.assignedSlot, null);
- tTree.s1.assign([tTree.c2, tTree.c3, tTree.c1]);
- assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c3, tTree.c1]);
-
- try {
- tTree.s1.assign([tTree.c4]);
- assert_unreached('assign() should have failed) ');
- } catch (err) {
- assert_equals(err.name, 'NotAllowedError');
- }
-
- // Previous state is preserved.
- assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c3, tTree.c1]);
+ // Moving c4 into place should reveal the assignment.
+ tTree.host.append(tTree.c4);
+ assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c4, tTree.c2]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
assert_equals(tTree.c2.assignedSlot, tTree.s1);
- assert_equals(tTree.c3.assignedSlot, tTree.s1);
-}, 'Assigning invalid nodes causes exception and slot returns to its previous state.');
+ assert_equals(tTree.c4.assignedSlot, tTree.s1);
+
+ // Moving c4 into a different shadow host and back should
+ // also not break the assignment.
+ tTree.host4.append(tTree.c4)
+ assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2]);
+ assert_equals(tTree.c4.assignedSlot, null);
+ tTree.host.append(tTree.c4);
+ assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c4, tTree.c2]);
+ assert_equals(tTree.c4.assignedSlot, tTree.s1);
+}, 'Assigning invalid nodes should be allowed.');
test(() => {
let tTree = createTestTree(test_assign);
@@ -227,21 +191,6 @@
assert_equals(tTree.c1.assignedSlot, tTree.s4);
}, 'Appending slottable to different host, it loses slot assignment. It can be re-assigned within a new host.');
-test(() => {
- let tTree = createTestTree(test_assign);
-
- tTree.s1.assign([tTree.c1]);
- assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1]);
-
- tTree.shadow_root4.insertBefore(tTree.s1, tTree.s4);
- assert_array_equals(tTree.s1.assignedNodes(), []);
- // Don't trigger slot assignment on previous shadow root.
- // assert_array_equals(tTree.s2.assignedNodes(), []);
-
- tTree.shadow_root.insertBefore(tTree.s1, tTree.s2);
- assert_array_equals(tTree.s1.assignedNodes(), []);
-}, 'Previously assigned node should not be assigned if slot moved to a new shadow root. The slot remains empty when moved back, no trigger recalc.');
-
test(() => {
let tTree = createTestTree(test_assign);
@@ -264,8 +213,8 @@
assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1]);
tTree.s1.assign([tTree.c1, tTree.c1, tTree.c2, tTree.c2, tTree.c1]);
- assert_array_equals(tTree.s1.assignedNodes(), [tTree.c2, tTree.c1]);
-}, 'Assignment with the same node in parameters should be ignored, last one wins.');
+ assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2]);
+}, 'Assignment with the same node in parameters should be ignored, first one wins.');
test(() => {
let tTree = createTestTree(test_assign);
@@ -281,25 +230,45 @@
test(() => {
let tTree = createTestTree(test_assign);
- tTree.s1.assign([tTree.c1]);
- tTree.s2.assign([tTree.c2]);
- tTree.s3.assign([tTree.c3]);
- tTree.shadow_root.insertBefore(tTree.s2, tTree.s1);
- tTree.shadow_root.insertBefore(tTree.s3, tTree.s1);
+ const isolatedDocNode = document.implementation.createHTMLDocument("").body;
+ isolatedDocNode.appendChild(tTree.c1);
+ const isolatedDocNode2 = document.implementation.createHTMLDocument("").body;
+ isolatedDocNode2.appendChild(tTree.s1);
- assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1]);
- assert_array_equals(tTree.s2.assignedNodes(), []);
- assert_array_equals(tTree.s3.assignedNodes(), []);
- assert_equals(tTree.c1.assignedSlot, tTree.s1);
+ tTree.s1.assign([tTree.c1, tTree.c2]);
+ assert_array_equals(tTree.s1.assignedNodes(), [], 's1 not inside shadow root');
+ assert_equals(tTree.c1.assignedSlot, null);
assert_equals(tTree.c2.assignedSlot, null);
- assert_equals(tTree.c3.assignedSlot, null);
- tTree.s2.remove();
+ tTree.shadow_root.appendChild(tTree.s1);
+ tTree.host.appendChild(tTree.c1);
+ assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2]);
+ assert_equals(tTree.c1.assignedSlot, tTree.s1);
+ assert_equals(tTree.c2.assignedSlot, tTree.s1);
+}, 'Nodes can be assigned even if slots or nodes aren\'t in the same tree.');
- assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1]);
- assert_array_equals(tTree.s3.assignedNodes(), []);
+test(() => {
+ let tTree = createTestTree(test_assign);
+
+ tTree.s1.assign([tTree.c1, tTree.c2]);
+ assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2]);
assert_equals(tTree.c1.assignedSlot, tTree.s1);
+ assert_equals(tTree.c2.assignedSlot, tTree.s1);
+
+ const isolatedDocNode = document.implementation.createHTMLDocument("").body;
+ isolatedDocNode.appendChild(tTree.c1);
+ const isolatedDocNode2 = document.implementation.createHTMLDocument("").body;
+ isolatedDocNode2.appendChild(tTree.s1);
+
+ assert_array_equals(tTree.s1.assignedNodes(), [], 's1 not inside shadow root');
+ assert_equals(tTree.c1.assignedSlot, null);
assert_equals(tTree.c2.assignedSlot, null);
- assert_equals(tTree.c3.assignedSlot, null);
-}, 'A slot should be cleared of assigned nodes even if it\'s re-inserted into the same shadow root.');
+
+ tTree.shadow_root.appendChild(tTree.s1);
+ tTree.host.appendChild(tTree.c1);
+ assert_array_equals(tTree.s1.assignedNodes(), [tTree.c1, tTree.c2]);
+ assert_equals(tTree.c1.assignedSlot, tTree.s1);
+ assert_equals(tTree.c2.assignedSlot, tTree.s1);
+}, 'Removing a node from the document does not break manually assigned slot linkage.');
+