Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /shadow-dom/focus/click-focus-delegatesFocus-click.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<meta charset="utf-8">
<title>HTML Test: click on shadow host with delegatesFocus</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/shadow-utils.js"></script>
<body>
<div id="host">
<div id="slotted">slotted</div>
</div>
<div id="outside">outside</div>
</body>
<script>
const host = document.getElementById("host");
const slotted = document.getElementById("slotted");
const shadowRoot = host.attachShadow({ mode: "open", delegatesFocus: true });
const aboveSlot = document.createElement("div");
aboveSlot.innerText = "aboveSlot";
const slot = document.createElement("slot");
shadowRoot.appendChild(aboveSlot);
shadowRoot.appendChild(slot);
const elementsInFlatTreeOrder = [host, aboveSlot, slot, slotted, outside];
// Final structure:
// <div #host> (delegatesFocus=true)
// #shadowRoot
// <div #aboveSlot>
// <slot #slot>
// (slotted) <div #slotted>
// <div #outside>
function setAllTabIndex(value) {
setTabIndex(elementsInFlatTreeOrder, value);
}
function removeAllTabIndex() {
removeTabIndex(elementsInFlatTreeOrder);
}
function resetTabIndexAndFocus() {
removeAllTabIndex();
resetFocus(document);
resetFocus(shadowRoot);
}
test(() => {
resetTabIndexAndFocus();
setAllTabIndex(0);
host.click();
assert_equals(shadowRoot.activeElement, null);
assert_equals(document.activeElement, document.body);
}, "call click() on host with delegatesFocus, all tabindex=0");
test(() => {
resetTabIndexAndFocus();
setAllTabIndex(0);
slotted.click();
assert_equals(shadowRoot.activeElement, null);
assert_equals(document.activeElement, document.body);
}, "call click() on slotted element in delegatesFocus shadow tree, all tabindex=0");
function createNestedHosts(outerDelegatesFocus, innerDelegatesFocus) {
// Structure:
// <div> outerHost
// <input> outerLightChild
// #shadowRoot outerShadow delegatesFocus=true
// <div> spacer
// <span> innerHost
// #shadowRoot innerShadow delegatesFocus=true/false
// <input> innerShadowChild
// <input> outerShadowChild
const outerHost = document.createElement('div');
const outerLightChild = document.createElement('input');
outerHost.appendChild(outerLightChild);
const innerHost = document.createElement('span');
const outerShadow = outerHost.attachShadow({mode: 'closed', delegatesFocus:outerDelegatesFocus});
const spacer = document.createElement("div");
spacer.style = "height: 1000px;";
outerShadow.appendChild(spacer);
outerShadow.appendChild(innerHost);
const outerShadowChild = document.createElement('input');
outerShadow.appendChild(outerShadowChild);
const innerShadow = innerHost.attachShadow({mode: 'closed', delegatesFocus:innerDelegatesFocus});
const innerShadowChild = document.createElement('input');
innerShadow.appendChild(innerShadowChild);
document.body.insertBefore(outerHost, document.body.firstChild);
return {outerHost: outerHost,
outerLightChild: outerLightChild,
outerShadow: outerShadow,
outerShadowChild: outerShadowChild,
innerHost: innerHost,
innerShadow: innerShadow,
innerShadowChild: innerShadowChild};
}
promise_test(async function() {
const dom = createNestedHosts(true, true);
await test_driver.click(dom.outerHost);
assert_equals(document.activeElement, dom.outerHost);
assert_equals(dom.outerShadow.activeElement, dom.innerHost);
assert_equals(dom.innerShadow.activeElement, dom.innerShadowChild);
}, "click on the host with delegatesFocus with another host with delegatesFocus and a focusable child");
promise_test(async function() {
const dom = createNestedHosts(true, false);
await test_driver.click(dom.outerHost);
assert_equals(document.activeElement, dom.outerHost);
assert_equals(dom.outerShadow.activeElement, dom.outerShadowChild);
assert_equals(dom.innerShadow.activeElement, null);
}, "click on the host with delegatesFocus with another host with no delegatesFocus and a focusable child");
promise_test(async function() {
const dom = createNestedHosts(false, true);
await test_driver.click(dom.outerHost);
assert_equals(document.activeElement, document.body);
assert_equals(dom.outerShadow.activeElement, null);
assert_equals(dom.innerShadow.activeElement, null);
}, "click on the host with no delegatesFocus with another host with delegatesFocus and a focusable child");
promise_test(async function() {
const dom = createNestedHosts(false, false);
await test_driver.click(dom.outerHost);
assert_equals(document.activeElement, document.body);
assert_equals(dom.outerShadow.activeElement, null);
assert_equals(dom.innerShadow.activeElement, null);
}, "click on the host with no delegatesFocus with another host with no delegatesFocus and a focusable child");
</script>