<!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/1235'>
<link rel='help' href='https://github.com/whatwg/html/pull/10069'>
<link rel='help' href='https://github.com/whatwg/dom/pull/1246'>
<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) => {
t.add_cleanup(() => {
multiple1.remove();
multiple2.remove();
});
let shadow = multiple1.shadowRoot;
assert_true(!!shadow,'Remaining shadow root should be open');
assert_equals(shadow.textContent,"Open");
assert_equals(multiple1.childElementCount, 1);
assert_equals(multiple1.firstElementChild.shadowRootMode, "closed");
shadow = multiple2.shadowRoot;
assert_false(!!shadow,'Remaining shadow root should be closed');
assert_equals(multiple2.childElementCount, 1);
assert_equals(multiple2.firstElementChild.shadowRootMode, "open");
},'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 mode 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 mode');
</script>
<div id=open2>
<template shadowrootmode=open shadowrootdelegatesfocus shadowrootclonable shadowrootserializable>
Open, delegates focus (not the default), clonable (not the default)
serializable (not the default), named slot assignment (the default)
</template>
</div>
<script>
test((t) => {
t.add_cleanup(() => open2.remove());
assert_true(!!open2.shadowRoot);
// Changing the mode should throw.
assert_throws_dom("NotSupportedError",() => {
open2.attachShadow({mode: "closed"});
},'Mismatched shadow root mode should throw');
assert_throws_dom("NotSupportedError",() => {
open2.attachShadow({mode: "closed", delegatesFocus: true, slotAssignment: "named", clonable: true, serializable: true});
},'Mismatched shadow root mode should throw (explicit args)');
// Changing other things should not throw, and should not change the shadow root's settings
const initialShadow = open2.shadowRoot;
assert_equals(initialShadow.delegatesFocus,true);
assert_equals(initialShadow.slotAssignment,"named");
assert_true(initialShadow.clonable);
assert_true(initialShadow.serializable);
let newShadow = open2.attachShadow({mode: "open", delegatesFocus: false, slotAssignment: "manual", clonable: false, serializable: false});
assert_equals(newShadow,initialShadow,'Same shadow should be returned');
assert_equals(newShadow.textContent,'','Shadow should be empty');
assert_equals(newShadow.delegatesFocus,true);
assert_equals(newShadow.slotAssignment,"named");
assert_true(newShadow.clonable);
assert_true(newShadow.serializable);
assert_throws_dom("NotSupportedError",() => {
open2.attachShadow({mode: "open"});
},'Invoking attachShadow() on a non-declarative shadow root should throw');
},'Calling attachShadow() on declarative shadow root must match all parameters');
</script>