Skip to content

Commit e643336

Browse files
mfreed7chromium-wpt-export-bot
authored andcommitted
Disallow multiple declarative roots and mismatched imperative ones
Two changes: 1. If two declarative shadow roots are included within a single host element, only the *first* one will remain. This is a change in behavior from before, but reached consensus [1] and hopefully won't be a breaking change for anyone. 2. If attachShadow() is used on an existing declarative shadow root, and the parameters (e.g. shadow root type, etc.) do not match, an exception is thrown. This, also, is a breaking change, but hopefully not one that gets hit. See also [1]. [1] whatwg/dom#1235 Bug: 1379513,1042130 Change-Id: Ia81088227797013f9f62f5ac90f76898663b0bc4
1 parent ec00e9f commit e643336

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

shadow-dom/declarative/declarative-shadow-dom-attachment.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@
4343
}
4444

4545
// Now, call attachShadow() and make sure we get back the same (original) shadowRoot, but empty.
46-
const oppositeMode = (mode === 'open') ? 'closed' : 'open';
47-
const newShadow = element.attachShadow({mode: oppositeMode}); // Should be no exception here
46+
const newShadow = element.attachShadow({mode: mode, delegatesFocus: delegatesFocus});
4847
if (mode === 'open') {
4948
assert_equals(element.shadowRoot, originalShadowRoot, 'The same shadow root should be returned');
5049
assert_equals(element.shadowRoot.innerHTML, '', 'Empty shadow content');
@@ -55,6 +54,7 @@
5554
element.attachShadow({mode: mode});
5655
}, 'Calling attachShadow a second time on an element with a declarative shadow fails (same mode)');
5756

57+
const oppositeMode = (mode === 'open') ? 'closed' : 'open';
5858
assert_throws_dom('NotSupportedError', () => {
5959
element.attachShadow({mode: oppositeMode});
6060
}, 'Calling attachShadow a second time on an element with a declarative shadow fails (opposite mode)');

shadow-dom/declarative/declarative-shadow-dom-basic.html

+6-2
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,14 @@
154154
<script>
155155
test(() => {
156156
const host = document.querySelector('#multi-host');
157-
assert_equals(host.querySelector('template'), null, "No leftover template nodes from either root");
157+
const leftover = host.querySelector('template');
158+
assert_true(!!leftover, "The second (duplicate) template should be left in the DOM");
159+
assert_true(leftover instanceof HTMLTemplateElement);
160+
assert_equals(leftover.getAttribute('shadowrootmode'),"closed");
161+
assert_equals(leftover.shadowRootMode,"closed");
158162
assert_true(!!host.shadowRoot,"No open shadow root found - first root should remain");
159163
const innerSpan = host.shadowRoot.querySelector('span');
160-
assert_equals(innerSpan.textContent, 'root 2', "Content should come from last declarative shadow root");
164+
assert_equals(innerSpan.textContent, 'root 1', "Content should come from first declarative shadow root");
161165
}, 'Declarative Shadow DOM: Multiple roots');
162166

163167
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<!DOCTYPE html>
2+
<title>Declarative Shadow DOM Element Attachment</title>
3+
<link rel='author' href='mailto:[email protected]'>
4+
<link rel='help' href='https://github.com/whatwg/dom/issues/831'>
5+
<script src='/resources/testharness.js'></script>
6+
<script src='/resources/testharnessreport.js'></script>
7+
<script src='../../html/resources/common.js'></script>
8+
<script src="support/helpers.js"></script>
9+
10+
<div id=multiple1>
11+
<template shadowrootmode=open>Open</template>
12+
<template shadowrootmode=closed>Closed</template>
13+
</div>
14+
15+
<div id=multiple2>
16+
<template shadowrootmode=closed>Closed</template>
17+
<template shadowrootmode=open>Open</template>
18+
</div>
19+
20+
<script>
21+
test((t) => {
22+
let shadow = multiple1.shadowRoot;
23+
assert_true(!!shadow,'Remaining shadow root should be open');
24+
assert_equals(shadow.textContent,"Open");
25+
shadow = multiple2.shadowRoot;
26+
assert_false(!!shadow,'Remaining shadow root should be closed');
27+
multiple1.remove(); // Cleanup
28+
multiple2.remove();
29+
},'Repeated declarative shadow roots keep only the first');
30+
</script>
31+
32+
<div id=open1>
33+
<template shadowrootmode=open>Open</template>
34+
</div>
35+
36+
<script>
37+
test((t) => {
38+
assert_throws_dom("NotSupportedError",() => {
39+
open1.attachShadow({mode: "closed"});
40+
},'Mismatched shadow root type should throw');
41+
const initialShadow = open1.shadowRoot;
42+
const shadow = open1.attachShadow({mode: "open"}); // Shouldn't throw
43+
assert_equals(shadow,initialShadow,'Same shadow should be returned');
44+
assert_equals(shadow.textContent,'','Shadow should be empty');
45+
},'Calling attachShadow() on declarative shadow root must match type');
46+
</script>
47+
48+
<div id=open2>
49+
<template shadowrootmode=open shadowrootdelegatesfocus>
50+
Open, delegates focus (not the default), named slot assignment (the default)
51+
</template>
52+
</div>
53+
54+
<script>
55+
test((t) => {
56+
assert_throws_dom("NotSupportedError",() => {
57+
open2.attachShadow({mode: "closed", delegatesFocus: true, slotAssignment: "named"});
58+
},'Mismatched shadow root type should throw');
59+
assert_throws_dom("NotSupportedError",() => {
60+
open2.attachShadow({mode: "open", delegatesFocus: false, slotAssignment: "named"});
61+
},'Mismatched shadow root delegatesFocus should throw');
62+
assert_throws_dom("NotSupportedError",() => {
63+
open2.attachShadow({mode: "open", delegatesFocus: true, slotAssignment: "manual"});
64+
},'Mismatched shadow root slotAssignment should throw');
65+
const initialShadow = open2.shadowRoot;
66+
const shadow = open2.attachShadow({mode: "open", delegatesFocus: true, slotAssignment: "named"}); // Shouldn't throw
67+
assert_equals(shadow,initialShadow,'Same shadow should be returned');
68+
assert_equals(shadow.textContent,'','Shadow should be empty');
69+
},'Calling attachShadow() on declarative shadow root must match all parameters');
70+
</script>

0 commit comments

Comments
 (0)