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('input', {'id': 'younger-input-B-0', 'tabindex': 0}), // The last node in the focusScope
44 createDOM('input', {'id': 'younger-input-B-1', 'tabindex': 1})),
45 createDOM('input', {'id': 'light-child-selected-0', 'tabindex': 0}),
46 createDOM('input', {'id': 'light-child-selected-1', 'tabindex': 1}),
47 createDOM('input', {'id': 'light-child-non-selected-1', 'tabindex': 1})),
48 createDOM('input', {'id': 'input-D-1', 'tabindex': 1}),
49 createDOM('input', {'id': 'input-C-0', 'tabindex': 0}),
50 createDOM('div', {'id': 'host-C', 'tabindex': -1},
52 createDOM('input', {'tabindex': -1}))),
53 createDOM('input', {'id': 'input-D-0', 'tabindex': 0}),
55 createDOM('div', {'id': 'host-D', 'tabindex': 0},
57 createDOM('input', {'id': 'input-E-0', 'tabindex': 0})));
62 if (window.testRunner)
63 testRunner.dumpAsText();
65 if (!window.eventSender) {
70 prepareDOMTree(document.body);
72 // FIXME: Output inserted comments in this array to expected.txt for readability of the result.
73 var elementsInFocusNavigationOrder = [
74 'input-A-1', 'input-B-1',
75 // Traverse elements which have tabindex=1.
76 // Should skip every elements, even though they have the same tabindex, in the non-focusable shadow host (id=host-A)
77 // since a non-focusable shadow host should act as if they were assinged to tabindex=0 so it was skipped in this turn.
80 // Traverse a focusable shadow host.
83 // Enter the focus scope of the youngest shadow root in the shadow host and travese the first focusable node in the shadow DOM navigation.
84 'host-B//younger-input-A-1',
85 'host-B//younger-input-B-1',
86 'host-B//younger-input-A-0',
88 // Visits a shadow insertion point. Entering the focus scope of the older shadow root.
89 'host-B/older-input-A-1',
90 'host-B/older-input-B-1',
91 'host-B/older-input-A-0',
92 'host-B/older-input-B-0',
94 // Exits the focus scope of the older sahdow root. Visits the next focusable element which follows the shadow insertion point.
95 'host-B//younger-input-B-0',
97 // Exits the focus scope of the youngest sahdow root.
98 'light-child-selected-1',
100 // 'light-child-non-selected-1' should be skipped since it doesn't participate in the composed tree.
103 // All elements with tabindex=1 had been traversed in the outermost scope.
104 // So traverse elements with tabindex=0 in next.
107 // // A non-focusable shadow host (id=host-A) will be "replaced" with its shadow DOM navigation.
110 'host-A/nested-host',
112 // Enter a nested focus scope inside of a shadow host (id=nested-host).
113 'host-A/nested-host/input-15',
114 'host-A/nested-host/input-25',
116 // Exit a nested shadow host.
119 'light-child-selected-0',
123 // A non-focusable shadow host (id=host-C), which does not have focusable elements, should be skipped entirely.
128 // Wraps to the first element in the outermost focus scope.
132 testFocusNavigationFowrad(elementsInFocusNavigationOrder);
133 elementsInFocusNavigationOrder.reverse();
134 testFocusNavigationBackward(elementsInFocusNavigationOrder);
136 debug('Test finished.');