4 <script src="../../../resources/js-test.js"></script>
5 <script src="resources/shadow-dom.js"></script>
8 <p>This tests that pressing Tab key should traverse into shadow DOM subtrees, and pressing Shift-Tab should reverse the order.</p>
9 <pre id="console"></pre>
12 function prepareDOMTree(parent)
15 // FIXME: Use more descriptive ids for each elements.
16 createDOM('div', {'id': 'top-div'},
17 createDOM('input', {'id': 'input-A-1', 'tabindex': 1}),
18 createDOM('input', {'id': 'input-B-1', 'tabindex': 1}),
19 createDOM('div'), // Should not be selected.
20 createDOM('input', {'id': 'input-A-0', 'tabindex': 0}),
21 createDOM('div', {'id': 'host-A', 'tabindex': -1},
23 createDOM('input', {'id': 'input-1', 'tabindex': 1}),
24 createDOM('div', {'id': 'nested-host', 'tabindex': 30},
26 createDOM('input', {'tabindex': -1}),
27 createDOM('input', {'id': 'input-15', 'tabindex': 15}),
28 createDOM('input', {'id': 'input-25', 'tabindex': 25}))),
29 createDOM('input', {'id': 'input-20', 'tabindex': 20}))),
30 createDOM('input', {'id': 'input-C-1', 'tabindex': 1}),
31 createDOM('input', {'id': 'input-B-0', 'tabindex': 0}),
32 createDOM('div', {'id': 'host-B', 'tabindex': 1},
34 createDOM('input', {'id': 'older-input-A-0', 'tabindex': 0}),
35 createDOM('input', {'id': 'older-input-A-1', 'tabindex': 1}),
36 createDOM('content', {'select': '#light-child-selected-0, #light-child-selected-1'}),
37 createDOM('input', {'id': 'older-input-B-0', 'tabindex': 0}),
38 createDOM('input', {'id': 'older-input-B-1', 'tabindex': 1})),
40 createDOM('input', {'id': 'younger-input-A-0', 'tabindex': 0}),
41 createDOM('input', {'id': 'younger-input-A-1', 'tabindex': 1}), // The first node in the focusScope
42 createDOM('shadow', {},
43 createDOM('content', {})),
44 createDOM('input', {'id': 'younger-input-B-0', 'tabindex': 0}), // The last node in the focusScope
45 createDOM('input', {'id': 'younger-input-B-1', 'tabindex': 1})),
46 createDOM('input', {'id': 'light-child-selected-0', 'tabindex': 0}),
47 createDOM('input', {'id': 'light-child-selected-1', 'tabindex': 1}),
48 createDOM('input', {'id': 'light-child-non-selected-1', 'tabindex': 1})),
49 createDOM('input', {'id': 'input-D-1', 'tabindex': 1}),
50 createDOM('input', {'id': 'input-C-0', 'tabindex': 0}),
51 createDOM('div', {'id': 'host-C', 'tabindex': -1},
53 createDOM('input', {'tabindex': -1}))),
54 createDOM('input', {'id': 'input-D-0', 'tabindex': 0}),
56 createDOM('div', {'id': 'host-D', 'tabindex': 0},
58 createDOM('input', {'id': 'input-E-0', 'tabindex': 0})));
63 if (window.testRunner)
64 testRunner.dumpAsText();
66 if (!window.eventSender) {
71 prepareDOMTree(document.body);
73 // FIXME: Output inserted comments in this array to expected.txt for readability of the result.
74 var elementsInFocusNavigationOrder = [
75 'input-A-1', 'input-B-1',
76 // Traverse elements which have tabindex=1.
77 // Should skip every elements, even though they have the same tabindex, in the non-focusable shadow host (id=host-A)
78 // since a non-focusable shadow host should act as if they were assinged to tabindex=0 so it was skipped in this turn.
81 // Traverse a focusable shadow host.
84 // Enter the focus scope of the youngest shadow root in the shadow host and travese the first focusable node in the shadow DOM navigation.
85 'host-B//younger-input-A-1',
86 'host-B//younger-input-B-1',
87 'host-B//younger-input-A-0',
89 // Visits a shadow insertion point. Entering the focus scope of the older shadow root.
90 'host-B/older-input-A-1',
91 'host-B/older-input-B-1',
92 'host-B/older-input-A-0',
93 'host-B/older-input-B-0',
95 // Exits the focus scope of the older sahdow root. Visits the next focusable element which follows the shadow insertion point.
96 'host-B//younger-input-B-0',
98 // Exits the focus scope of the youngest sahdow root.
99 'light-child-selected-1',
101 // 'light-child-non-selected-1' should be skipped since it doesn't participate in the composed tree.
104 // All elements with tabindex=1 had been traversed in the outermost scope.
105 // So traverse elements with tabindex=0 in next.
108 // // A non-focusable shadow host (id=host-A) will be "replaced" with its shadow DOM navigation.
111 'host-A/nested-host',
113 // Enter a nested focus scope inside of a shadow host (id=nested-host).
114 'host-A/nested-host/input-15',
115 'host-A/nested-host/input-25',
117 // Exit a nested shadow host.
120 'light-child-selected-0',
124 // A non-focusable shadow host (id=host-C), which does not have focusable elements, should be skipped entirely.
129 // Wraps to the first element in the outermost focus scope.
133 testFocusNavigationFowrad(elementsInFocusNavigationOrder);
134 elementsInFocusNavigationOrder.reverse();
135 testFocusNavigationBackward(elementsInFocusNavigationOrder);
137 debug('Test finished.');