Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML: Handle shadow host with delegatesFocus=true in Element.focus(), click and sequential focus navigation #18035

Merged
merged 9 commits into from
Oct 16, 2019
67 changes: 67 additions & 0 deletions shadow-dom/focus/click-focus-delegatesFocus-click-method.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!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");
</script>
68 changes: 68 additions & 0 deletions shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!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");
// Add an unfocusable spacer, because test_driver.click will click on the
// center point of #host, and we don't want the click to land on #aboveSlot
// or #slot.
const spacer = document.createElement("div");
spacer.style = "height: 1000px;";
shadowRoot.appendChild(spacer);
shadowRoot.appendChild(aboveSlot);
shadowRoot.appendChild(slot);

const elementsInFlatTreeOrder = [host, aboveSlot, spacer, slot, slotted, outside];

// Final structure:
// <div #host> (delegatesFocus=true)
// #shadowRoot
// <div #spacer>
// <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);
}

promise_test(async () => {
resetTabIndexAndFocus();
setTabIndex([aboveSlot], 2);
setTabIndex([slot, slotted], 1);
await test_driver.click(host);
assert_equals(shadowRoot.activeElement, aboveSlot);
assert_equals(document.activeElement, host);
}, "click on host with delegatesFocus, #aboveSlot tabindex = 2, #slot and #slotted tabindex = 1");

</script>
68 changes: 68 additions & 0 deletions shadow-dom/focus/click-focus-delegatesFocus-tabindex-zero.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!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");
// Add an unfocusable spacer, because test_driver.click will click on the
// center point of #host, and we don't want the click to land on #aboveSlot
// or #slot.
const spacer = document.createElement("div");
spacer.style = "height: 1000px;";
shadowRoot.appendChild(spacer);
shadowRoot.appendChild(aboveSlot);
shadowRoot.appendChild(slot);

const elementsInFlatTreeOrder = [host, aboveSlot, spacer, slot, slotted, outside];

// Final structure:
// <div #host> (delegatesFocus=true)
// #shadowRoot
// <div #spacer>
// <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);
}

promise_test(async () => {
resetTabIndexAndFocus();
setAllTabIndex(0);
removeTabIndex([spacer]);
await test_driver.click(host);
assert_equals(shadowRoot.activeElement, aboveSlot);
assert_equals(document.activeElement, host);
}, "click on host with delegatesFocus, all tabindex=0 except spacer");

</script>
Loading