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");
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");
opener.is(lastFocusTarget, shadowDate, "Should have focused date element with a calendar button in shadow DOM. (3)");
let canTabMoveFocusToRootElement =
!SpecialPowers.getBoolPref("dom.disable_tab_focus_to_root_element");
if (canTabMoveFocusToRootElement) {
synthesizeKey("KEY_Tab");
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");
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});
opener.is(shadowIframe.contentDocument.activeElement,
shadowIframe.contentDocument.body.firstChild, "Should have focused input element in shadow iframe. (4)");
if (canTabMoveFocusToRootElement) {
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});
opener.is(lastFocusTarget, shadowDate, "Should have focused date element with a calendar button 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});
opener.is(lastFocusTarget, shadowDate, "Should have focused date element in shadow DOM. (4)");
synthesizeKey("KEY_Tab", {shiftKey: true});
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 hiddenShadowButton = document.createElement("button");
hiddenShadowButton.setAttribute("style", "display: none;");
sr.appendChild(hiddenShadowButton);
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)");
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);
varh1 = sr0.getElementById("h1"); var sr1 = h1.attachShadow({mode: "open"});
sr1.innerHTML = "h1 "; 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 "; 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)");
host.remove();
}
function testTabbingThroughDisplayContentsHost() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (1)");
// 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)");
host.remove();
host1.remove();
}
function testTabbingThroughLightDOMShadowDOMLightDOM() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, host, "Should have focused host.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
host.remove();
p.remove();
}
function testShiftTabbingThroughFocusableHost() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, host, "Should have focused host element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowButton, "Should have focused button element in shadow DOM. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input, "Should have focused input element. (4)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowInput, "Should have focused input element in shadow DOM. (5)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, shadowButton, "Should have focused button element in shadow DOM. (6)");
synthesizeKey("KEY_Tab", {shiftKey: true});
// focus is already on host
opener.is(sr.activeElement, null, "Focus should have left button element in shadow DOM. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
host.remove(); input.remove();
}
function testTabbingThroughNestedSlot() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
var host0 = document.createElement("div"); var sr0 = host0.attachShadow({mode: "open"});
sr0.innerHTML = "";
document.body.appendChild(host0);
// focusable var host00 = document.createElement("div"); var sr00 = host00.attachShadow({mode: "open"}); var div00 = document.createElement("div");
div00.tabIndex = 0;
div00.onfocus = focusLogger;
sr00.appendChild(div00);
host0.appendChild(host00);
// not focusable var host01 = document.createElement("div"); var sr01 = host01.attachShadow({mode: "open"});
sr01.innerHTML = "";
host0.appendChild(host01);
// focusable var host02 = document.createElement("div"); var sr02 = host02.attachShadow({mode: "open"}); var div02 = document.createElement("div");
div02.tabIndex = 0;
div02.onfocus = focusLogger;
sr02.appendChild(div02);
host0.appendChild(host02);
var host1 = document.createElement("div"); var sr1 = host1.attachShadow({mode: "open"});
sr1.innerHTML = "";
document.body.appendChild(host1);
var host10 = document.createElement("div"); var sr10 = host10.attachShadow({mode: "open"});
sr10.innerHTML = "";
host1.appendChild(host10);
var input10 = document.createElement("input");
input10.onfocus = focusLogger;
host10.appendChild(input10);
var host11 = document.createElement("div"); var sr11 = host11.attachShadow({mode: "open"});
sr11.innerHTML = "";
host1.appendChild(host11);
var input11 = document.createElement("input");
input11.onfocus = focusLogger;
host11.appendChild(input11);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, div00, "Should have focused div element in shadow DOM. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, div02, "Should have focused div element in shadow DOM. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input10, "Should have focused input element in shadow DOM. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input11, "Should have focused button element in shadow DOM. (4)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input10, "Should have focused input element in shadow DOM. (5)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, div02, "Should have focused input element in shadow DOM. (6)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, div00, "Should have focused input element in shadow DOM. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
host0.remove();
host1.remove();
}
function testTabbingThroughSlotInLightDOM() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
var input0 = document.createElement("input");
input0.onfocus = focusLogger;
document.body.appendChild(input0);
var slot1 = document.createElement("slot");
document.body.appendChild(slot1);
var input10 = document.createElement("input");
input10.onfocus = focusLogger;
slot1.appendChild(input10);
var input11 = document.createElement("input");
input11.onfocus = focusLogger;
slot1.appendChild(input11);
var input2 = document.createElement("input");
input2.onfocus = focusLogger;
document.body.appendChild(input2);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input0, "Should have focused input element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input10, "Should have focused input element in slot. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input11, "Should have focused input element in slot. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input2, "Should have focused input element. (4)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input11, "Should have focused input element in slot. (5)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input10, "Should have focused input element in slot. (6)");
function testTabbingThroughFocusableSlotInLightDOM() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
slot0.remove();
input1.remove();
}
function testTabbingThroughScrollableShadowDOM() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
var input1 = document.createElement("input");
input1.onfocus = focusLogger;
document.body.appendChild(input1);
document.body.offsetLeft;
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, host0, "Should have focused shadow host element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input00, "Should have focused input element in shadow dom. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, container01, "Should have focused scrollable element in shadow dom. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input010, "Should have focused input element in shadow dom. (4)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input011, "Should have focused input element in shadow dom. (5)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, slot02, "Should have focused slot element in shadow dom. (6)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input020, "Should have focused input element in slot. (7)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input021, "Should have focused input element in slot. (8)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, input1, "Should have focused input element in light dom. (9)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input021, "Should have focused input element in slot. (10)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input020, "Should have focused input element in slot. (11)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, slot02, "Should have focused slot element in shadow dom. (12)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input011, "Should have focused input element in shadow dom. (13)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input010, "Should have focused input element in shadow dom. (14)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, container01, "Should have focused scrollable element in shadow dom. (15)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, input00, "Should have focused input element in shadow dom. (16)");
synthesizeKey("KEY_Tab", {shiftKey: true});
// focus is already on host
opener.is(sr0.activeElement, null, "Focus should have left input element in shadow DOM. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
host0.remove();
input1.remove();
}
// Bug 1604140
function testTabbingThroughScrollableShadowHost() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, aboveFirstHost, "Should have focused div above first host element. (1)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, divInFirstShadow, "Should have focused div in first shadow dom. (2)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, aboveSecondHost, "Should have focused div above second host element. (3)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, secondHost, "Should have focused second host element. (4)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, divInSecondShadow, "Should have focused div in second shadow dom. (5)");
synthesizeKey("KEY_Tab");
opener.is(lastFocusTarget, belowSecondHost, "Should have focused div below second host. (6)");
// Backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, divInSecondShadow, "Should have focused div in second shadow dom. (7)");
synthesizeKey("KEY_Tab", {shiftKey: true});
// focus is already on second host, so lastFocusTarget won't get updated.
opener.is(document.activeElement, secondHost, "Should have focused second host element. (8)");
opener.is(secondShadow.activeElement, null, "Focus should have left div in second shadow dom. (8)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, aboveSecondHost, "Should have focused div above second host element. (9)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, divInFirstShadow, "Should have focused div in first shadow dom. (10)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(lastFocusTarget, aboveFirstHost, "Should have focused div above first host element. (11)");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
function testDeeplyNestedShadowTree() {
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus."); var host1 = document.createElement("test-node"); var lastHost = host1;
for (var i = 0; i < 20; ++i) {
lastHost.appendChild(document.createElement("test-node"));
lastHost = lastHost.firstChild;
}
// Test shadow tree which doesn't have anything tab-focusable.
host1.shadowRoot.querySelector("div").focus();
synthesizeKey("KEY_Tab");
is(document.activeElement, input, "Should have focused input element.");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus.");
// Same test but with focusable elements in the tree... var input2 = document.createElement("input"); var host2 = host1.firstChild; var host3 = host2.firstChild;
host2.insertBefore(input2, host3); var input3 = document.createElement("input");
lastHost.appendChild(input3);
document.body.offsetLeft;
host3.shadowRoot.querySelector("div").focus();
synthesizeKey("KEY_Tab");
is(document.activeElement, input3, "Should have focused input3 element.");
first.focus();
opener.is(document.activeElement, first, "First light div should have focus");
synthesizeKey("KEY_Tab");
opener.is(document.activeElement, host, "Host should be focused");
synthesizeKey("KEY_Tab");
opener.is(document.activeElement, second, "Second light div should be focused");
// Now backwards
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, host, "Focus should return to host");
synthesizeKey("KEY_Tab", {shiftKey: true});
opener.is(document.activeElement, first, "Focus should return to first light div");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.