Skip to content

Commit

Permalink
Disallow multiple declarative roots and mismatched imperative ones
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mfreed7 authored and chromium-wpt-export-bot committed Jan 12, 2024
1 parent 51c87dc commit 8ee47e8
Showing 1 changed file with 70 additions and 0 deletions.
70 changes: 70 additions & 0 deletions shadow-dom/declarative/declarative-shadow-dom-repeats.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!DOCTYPE html>
<title>Declarative Shadow DOM Element Attachment</title>
<link rel='author' href='mailto:[email protected]'>
<link rel='help' href='https://github.com/whatwg/dom/issues/831'>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='../../html/resources/common.js'></script>
<script src="support/helpers.js"></script>

<div id=multiple1>
<template shadowrootmode=open>Open</template>
<template shadowrootmode=closed>Closed</template>
</div>

<div id=multiple2>
<template shadowrootmode=closed>Closed</template>
<template shadowrootmode=open>Open</template>
</div>

<script>
test((t) => {
let shadow = multiple1.shadowRoot;
assert_true(!!shadow,'Remaining shadow root should be open');
assert_equals(shadow.textContent,"Open");
shadow = multiple2.shadowRoot;
assert_false(!!shadow,'Remaining shadow root should be closed');
multiple1.remove(); // Cleanup
multiple2.remove();
},'Repeated declarative shadow roots keep only the first');
</script>

<div id=open1>
<template shadowrootmode=open>Open</template>
</div>

<script>
test((t) => {
assert_throws_dom("NotSupportedError",() => {
open1.attachShadow({mode: "closed"});
},'Mismatched shadow root type should throw');
const initialShadow = open1.shadowRoot;
const shadow = open1.attachShadow({mode: "open"}); // Shouldn't throw
assert_equals(shadow,initialShadow,'Same shadow should be returned');
assert_equals(shadow.textContent,'','Shadow should be empty');
},'Calling attachShadow() on declarative shadow root must match type');
</script>

<div id=open2>
<template shadowrootmode=open shadowrootdelegatesfocus>
Open, delegates focus (not the default), named slot assignment (the default)
</template>
</div>

<script>
test((t) => {
assert_throws_dom("NotSupportedError",() => {
open2.attachShadow({mode: "closed", delegatesFocus: true, slotAssignment: "named"});
},'Mismatched shadow root type should throw');
assert_throws_dom("NotSupportedError",() => {
open2.attachShadow({mode: "open", delegatesFocus: false, slotAssignment: "named"});
},'Mismatched shadow root delegatesFocus should throw');
assert_throws_dom("NotSupportedError",() => {
open2.attachShadow({mode: "open", delegatesFocus: true, slotAssignment: "manual"});
},'Mismatched shadow root slotAssignment should throw');
const initialShadow = open2.shadowRoot;
const shadow = open2.attachShadow({mode: "open", delegatesFocus: true, slotAssignment: "named"}); // Shouldn't throw
assert_equals(shadow,initialShadow,'Same shadow should be returned');
assert_equals(shadow.textContent,'','Shadow should be empty');
},'Calling attachShadow() on declarative shadow root must match all parameters');
</script>

0 comments on commit 8ee47e8

Please sign in to comment.