1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
<!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>
|