2018-04-22 14:25:38 +03:00
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>Test for Bug 1453693</title>
|
|
|
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
|
|
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
|
|
|
<script>
|
|
|
|
|
|
|
|
var lastFocusTarget;
|
|
|
|
function focusLogger(event) {
|
|
|
|
lastFocusTarget = event.target;
|
|
|
|
console.log(event.target + " under " + event.target.parentNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
function testTabbingThroughShadowDOMWithTabIndexes() {
|
|
|
|
var anchor = document.createElement("a");
|
|
|
|
anchor.onfocus = focusLogger;
|
|
|
|
anchor.href = "#";
|
|
|
|
anchor.textContent = "in light DOM";
|
|
|
|
document.body.appendChild(anchor);
|
|
|
|
|
|
|
|
var host = document.createElement("div");
|
|
|
|
document.body.appendChild(host);
|
|
|
|
|
|
|
|
var sr = host.attachShadow({mode: "open"});
|
|
|
|
var shadowAnchor = anchor.cloneNode(false);
|
|
|
|
shadowAnchor.onfocus = focusLogger;
|
|
|
|
shadowAnchor.textContent = "in shadow DOM";
|
|
|
|
sr.appendChild(shadowAnchor);
|
|
|
|
var shadowInput = document.createElement("input");
|
|
|
|
shadowInput.onfocus = focusLogger;
|
|
|
|
shadowInput.tabIndex = 1;
|
|
|
|
sr.appendChild(shadowInput);
|
|
|
|
|
2018-04-27 12:37:43 +03:00
|
|
|
var shadowDate = document.createElement("input");
|
|
|
|
shadowDate.type = "date";
|
|
|
|
shadowDate.onfocus = focusLogger;
|
|
|
|
shadowDate.tabIndex = 1;
|
|
|
|
sr.appendChild(shadowDate);
|
|
|
|
|
2018-04-28 16:07:06 +03:00
|
|
|
var shadowIframe = document.createElement("iframe");
|
|
|
|
shadowIframe.tabIndex = 1;
|
|
|
|
sr.appendChild(shadowIframe);
|
|
|
|
shadowIframe.contentDocument.body.innerHTML = "<input>";
|
|
|
|
|
2018-04-22 14:25:38 +03:00
|
|
|
var input = document.createElement("input");
|
|
|
|
input.onfocus = focusLogger;
|
|
|
|
input.tabIndex = 1;
|
|
|
|
document.body.appendChild(input);
|
|
|
|
|
|
|
|
var input2 = document.createElement("input");
|
|
|
|
input2.onfocus = focusLogger;
|
|
|
|
document.body.appendChild(input2);
|
|
|
|
|
|
|
|
document.body.offsetLeft;
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, input, "Should have focused input element. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, anchor, "Should have focused anchor element. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
2018-04-27 12:37:43 +03:00
|
|
|
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
2018-04-28 16:07:06 +03:00
|
|
|
opener.is(shadowIframe.contentDocument.activeElement,
|
|
|
|
shadowIframe.contentDocument.documentElement,
|
|
|
|
"Should have focused document element in shadow iframe. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(shadowIframe.contentDocument.activeElement,
|
|
|
|
shadowIframe.contentDocument.body.firstChild,
|
|
|
|
"Should have focused input element in shadow iframe. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
2018-04-22 14:25:38 +03:00
|
|
|
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM. (3)");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, input2, "Should have focused input[2] element. (3)");
|
|
|
|
|
|
|
|
// Backwards
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM. (4)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
2018-04-28 16:07:06 +03:00
|
|
|
opener.is(shadowIframe.contentDocument.activeElement,
|
|
|
|
shadowIframe.contentDocument.body.firstChild,
|
|
|
|
"Should have focused input element in shadow iframe. (4)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(shadowIframe.contentDocument.activeElement,
|
|
|
|
shadowIframe.contentDocument.documentElement,
|
|
|
|
"Should have focused document element in shadow iframe. (4)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
2018-04-27 12:37:43 +03:00
|
|
|
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (4)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (4)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (4)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
2018-04-22 14:25:38 +03:00
|
|
|
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (4)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, anchor, "Should have focused anchor element. (4)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, input, "Should have focused input element. (4)");
|
|
|
|
|
|
|
|
document.body.innerHTML = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function testTabbingThroughSimpleShadowDOM() {
|
|
|
|
var anchor = document.createElement("a");
|
|
|
|
anchor.onfocus = focusLogger;
|
|
|
|
anchor.href = "#";
|
|
|
|
anchor.textContent = "in light DOM";
|
|
|
|
document.body.appendChild(anchor);
|
|
|
|
anchor.focus();
|
|
|
|
|
|
|
|
var host = document.createElement("div");
|
|
|
|
document.body.appendChild(host);
|
|
|
|
|
|
|
|
var sr = host.attachShadow({mode: "open"});
|
|
|
|
var shadowAnchor = anchor.cloneNode(false);
|
|
|
|
shadowAnchor.onfocus = focusLogger;
|
|
|
|
shadowAnchor.textContent = "in shadow DOM";
|
|
|
|
sr.appendChild(shadowAnchor);
|
|
|
|
var shadowInput = document.createElement("input");
|
|
|
|
shadowInput.onfocus = focusLogger;
|
|
|
|
sr.appendChild(shadowInput);
|
|
|
|
|
|
|
|
var input = document.createElement("input");
|
|
|
|
input.onfocus = focusLogger;
|
|
|
|
document.body.appendChild(input);
|
|
|
|
|
|
|
|
var input2 = document.createElement("input");
|
|
|
|
input2.onfocus = focusLogger;
|
|
|
|
document.body.appendChild(input2);
|
|
|
|
|
|
|
|
document.body.offsetLeft;
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM.");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM.");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, input, "Should have focused input element.");
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, input2, "Should have focused input[2] element.");
|
|
|
|
|
|
|
|
// Backwards
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, input, "Should have focused input element. (2)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (2)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM. (2)");
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, anchor, "Should have focused anchor element. (2)");
|
2018-07-10 01:56:42 +03:00
|
|
|
|
|
|
|
host.remove();
|
|
|
|
input.remove();
|
|
|
|
input2.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
function testTabbingThroughNestedShadowDOM() {
|
|
|
|
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (1)");
|
|
|
|
|
|
|
|
var host = document.createElement("div");
|
|
|
|
host.id = "host";
|
|
|
|
document.body.appendChild(host);
|
|
|
|
|
|
|
|
var sr0 = host.attachShadow({mode: "open"});
|
|
|
|
sr0.innerHTML = "<button id='button'>X</button><br id='br'><div id='h1'></div><div id='h2'></div>";
|
|
|
|
var button = sr0.getElementById("button");
|
|
|
|
button.onfocus = focusLogger;
|
|
|
|
|
|
|
|
var h1 = sr0.getElementById("h1");
|
|
|
|
var sr1 = h1.attachShadow({mode: "open"});
|
|
|
|
sr1.innerHTML = "h1 <input id='h11' placeholder='click me and press tab'><input id='h12' placeholder='and then tab again'>";
|
|
|
|
var input11 = sr1.getElementById("h11");
|
|
|
|
input11.onfocus = focusLogger;
|
|
|
|
var input12 = sr1.getElementById("h12");
|
|
|
|
input12.onfocus = focusLogger;
|
|
|
|
|
|
|
|
var h2 = sr0.getElementById("h2");
|
|
|
|
var sr2 = h2.attachShadow({mode: "open"});
|
|
|
|
sr2.innerHTML = "h2 <input id='h21'><input id='h22'>";
|
|
|
|
var input21 = sr2.getElementById("h21");
|
|
|
|
input21.onfocus = focusLogger;
|
|
|
|
var input22 = sr2.getElementById("h22");
|
|
|
|
input22.onfocus = focusLogger;
|
|
|
|
|
|
|
|
document.body.offsetLeft;
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, button, "[nested shadow] Should have focused button element. (1)");
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, input11, "[nested shadow] Should have focused input element. (1)");
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, input12, "[nested shadow] Should have focused input element. (2)");
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, input21, "[nested shadow] Should have focused input element. (3)");
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, input22, "[nested shadow] Should have focused input element. (4)");
|
|
|
|
|
|
|
|
// Backwards
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, input21, "[nested shadow] Should have focused input element. (5)");
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, input12, "[nested shadow] Should have focused input element. (6)");
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, input11, "[nested shadow] Should have focused input element. (7)");
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, button, "[nested shadow] Should have focused button element. (8)");
|
|
|
|
|
|
|
|
// Back to beginning, outside of Shadow DOM.
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (2)");
|
2018-07-20 19:29:52 +03:00
|
|
|
|
|
|
|
host.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
function testTabbingThroughDisplayContentsHost() {
|
|
|
|
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (1)");
|
|
|
|
|
|
|
|
var host = document.createElement("div");
|
|
|
|
host.id = "host";
|
|
|
|
host.setAttribute("style", "display: contents; border: 1px solid black;");
|
|
|
|
document.body.appendChild(host);
|
|
|
|
|
|
|
|
var sr0 = host.attachShadow({mode: "open"});
|
|
|
|
sr0.innerHTML = "<input id='shadowInput1'><input id='shadowInput2'>";
|
|
|
|
var shadowInput1 = sr0.getElementById("shadowInput1");
|
|
|
|
shadowInput1.onfocus = focusLogger;
|
|
|
|
var shadowInput2 = sr0.getElementById("shadowInput2");
|
|
|
|
shadowInput2.onfocus = focusLogger;
|
|
|
|
|
|
|
|
document.body.offsetLeft;
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, shadowInput1, "Should have focused input element. (1)");
|
|
|
|
|
|
|
|
synthesizeKey("KEY_Tab");
|
|
|
|
opener.is(lastFocusTarget, shadowInput2, "Should have focused input element. (2)");
|
|
|
|
|
|
|
|
// Backwards
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(lastFocusTarget, shadowInput1, "Should have focused input element. (3)");
|
|
|
|
|
|
|
|
// Back to beginning, outside of Shadow DOM.
|
|
|
|
synthesizeKey("KEY_Tab", {shiftKey: true});
|
|
|
|
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (2)");
|
2018-04-22 14:25:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function runTest() {
|
|
|
|
|
|
|
|
testTabbingThroughShadowDOMWithTabIndexes();
|
|
|
|
testTabbingThroughSimpleShadowDOM();
|
2018-07-10 01:56:42 +03:00
|
|
|
testTabbingThroughNestedShadowDOM();
|
2018-07-20 19:29:52 +03:00
|
|
|
testTabbingThroughDisplayContentsHost();
|
2018-04-22 14:25:38 +03:00
|
|
|
|
|
|
|
opener.didRunTests();
|
|
|
|
window.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
function init() {
|
|
|
|
SimpleTest.waitForFocus(runTest);
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
<style>
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body onload="init()">
|
|
|
|
</body>
|
|
|
|
</html>
|