blob: b82b1c0e7be1c5b5140b7c5bc949ca897d106284 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test.js"></script>
<script src="resources/shadow-dom.js"></script>
</head>
<body>
<p>This tests that pressing Tab key should traverse into shadow DOM subtrees, and pressing Shift-Tab should reverse the order.</p>
<pre id="console"></pre>
<script>
function prepareDOMTree(parent)
{
parent.appendChild(
// FIXME: Use more descriptive ids for each elements.
createDOM('div', {'id': 'top-div'},
createDOM('input', {'id': 'input-A-1', 'tabindex': 1}),
createDOM('input', {'id': 'input-B-1', 'tabindex': 1}),
createDOM('div'), // Should not be selected.
createDOM('input', {'id': 'input-A-0', 'tabindex': 0}),
createDOM('div', {'id': 'host-A', 'tabindex': -1},
createShadowRoot(
createDOM('input', {'id': 'input-1', 'tabindex': 1}),
createDOM('div', {'tabindex': 2, 'style': 'visibility:hidden;'},
createShadowRoot()),
createDOM('input', {'tabindex': 3, 'type': 'date', 'disabled': ''}),
createDOM('select', {'tabindex': 4, 'multiple': '', 'disabled': ''}),
createDOM('div', {'id': 'nested-host', 'tabindex': 30},
createShadowRoot(
createDOM('input', {'tabindex': -1}),
createDOM('input', {'id': 'input-15', 'tabindex': 15}),
createDOM('input', {'id': 'input-25', 'tabindex': 25}))),
createDOM('input', {'id': 'input-20', 'tabindex': 20}))),
createDOM('input', {'id': 'input-C-1', 'tabindex': 1}),
createDOM('input', {'id': 'input-B-0', 'tabindex': 0}),
createDOM('div', {'id': 'host-B', 'tabindex': 1},
createShadowRoot(
createDOM('input', {'id': 'older-input-A-0', 'tabindex': 0}),
createDOM('input', {'id': 'older-input-A-1', 'tabindex': 1}),
createDOM('content', {'select': '#light-child-selected-0, #light-child-selected-1'}),
createDOM('input', {'id': 'older-input-B-0', 'tabindex': 0}),
createDOM('input', {'id': 'older-input-B-1', 'tabindex': 1})),
createShadowRoot(
createDOM('input', {'id': 'younger-input-A-0', 'tabindex': 0}),
createDOM('input', {'id': 'younger-input-A-1', 'tabindex': 1}), // The first node in the focusScope
createDOM('shadow', {}),
createDOM('input', {'id': 'younger-input-B-0', 'tabindex': 0}), // The last node in the focusScope
createDOM('input', {'id': 'younger-input-B-1', 'tabindex': 1})),
createDOM('input', {'id': 'light-child-selected-0', 'tabindex': 0}),
createDOM('input', {'id': 'light-child-selected-1', 'tabindex': 1}),
createDOM('input', {'id': 'light-child-non-selected-1', 'tabindex': 1})),
createDOM('input', {'id': 'input-D-1', 'tabindex': 1}),
createDOM('input', {'id': 'input-C-0', 'tabindex': 0}),
createDOM('div', {'id': 'host-C', 'tabindex': -1},
createShadowRoot(
createDOM('input', {'tabindex': -1}))),
createDOM('input', {'id': 'input-D-0', 'tabindex': 0}),
createDOM('div', {},
createDOM('div', {'id': 'host-D', 'tabindex': 0},
createShadowRoot())),
createDOM('input', {'id': 'input-E-0', 'tabindex': 0})));
parent.offsetLeft;
}
function test() {
if (!window.eventSender) {
testFailed('');
return;
}
prepareDOMTree(document.body);
// FIXME: Output inserted comments in this array to expected.txt for readability of the result.
var elementsInFocusNavigationOrder = [
'input-A-1', 'input-B-1',
// Traverse elements which have tabindex=1.
// Should skip every elements, even though they have the same tabindex, in the non-focusable shadow host (id=host-A)
// since a non-focusable shadow host should act as if they were assinged to tabindex=0 so it was skipped in this turn.
'input-C-1',
// Traverse a focusable shadow host.
'host-B',
// Enter the focus scope of the youngest shadow root in the shadow host and travese the first focusable node in the shadow DOM navigation.
'host-B//younger-input-A-1',
'host-B//younger-input-B-1',
'host-B//younger-input-A-0',
// Visits a shadow insertion point. Entering the focus scope of the older shadow root.
'host-B/older-input-A-1',
'host-B/older-input-B-1',
'host-B/older-input-A-0',
'host-B/older-input-B-0',
// Exits the focus scope of the older sahdow root. Visits the next focusable element which follows the shadow insertion point.
'host-B//younger-input-B-0',
// Exits the focus scope of the youngest sahdow root.
'light-child-selected-1',
// 'light-child-non-selected-1' should be skipped since it doesn't participate in the flat tree.
'input-D-1',
// All elements with tabindex=1 had been traversed in the outermost scope.
// So traverse elements with tabindex=0 in next.
'input-A-0',
// // A non-focusable shadow host (id=host-A) will be "replaced" with its shadow DOM navigation.
'host-A/input-1',
'host-A/input-20',
'host-A/nested-host',
// Enter a nested focus scope inside of a shadow host (id=nested-host).
'host-A/nested-host/input-15',
'host-A/nested-host/input-25',
// Exit a nested shadow host.
'input-B-0',
'light-child-selected-0',
'input-C-0',
// A non-focusable shadow host (id=host-C), which does not have focusable elements, should be skipped entirely.
'input-D-0',
'host-D',
'input-E-0',
// Wraps to the first element in the outermost focus scope.
'input-A-1',
];
testFocusNavigationForward(elementsInFocusNavigationOrder);
elementsInFocusNavigationOrder.reverse();
testFocusNavigationBackward(elementsInFocusNavigationOrder);
debug('Test finished.');
}
test();
</script>
</body>
</html>