mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-25 19:25:43 +00:00
Bug 1570852: Trap focus in delete confirmation dialog. r=jaws
Differential Revision: https://phabricator.services.mozilla.com/D43717 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
1c1704fdbb
commit
8f7faa78fb
@ -45,7 +45,28 @@ export default class ConfirmationDialog extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
setKeyboardAccessForElementsExternalToDialog(enableTabbingOutsideDialog) {
|
||||
const pageElements = document.querySelectorAll(
|
||||
"login-item, login-list, menu-button, login-filter, fxaccounts-button, [tabindex]"
|
||||
);
|
||||
|
||||
pageElements.forEach(el => {
|
||||
if (!enableTabbingOutsideDialog) {
|
||||
if (el.tabIndex > -1) {
|
||||
el.dataset.oldTabIndex = el.tabIndex;
|
||||
}
|
||||
el.tabIndex = "-1";
|
||||
} else if (el.dataset.oldTabIndex) {
|
||||
el.tabIndex = el.dataset.oldTabIndex;
|
||||
delete el.dataset.oldTabIndex;
|
||||
} else {
|
||||
el.removeAttribute("tabindex");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.setKeyboardAccessForElementsExternalToDialog(true);
|
||||
this._cancelButton.removeEventListener("click", this);
|
||||
this._confirmButton.removeEventListener("click", this);
|
||||
this._dismissButton.removeEventListener("click", this);
|
||||
@ -56,6 +77,7 @@ export default class ConfirmationDialog extends HTMLElement {
|
||||
}
|
||||
|
||||
show({ title, message, confirmButtonLabel }) {
|
||||
this.setKeyboardAccessForElementsExternalToDialog(false);
|
||||
this.hidden = false;
|
||||
|
||||
document.l10n.setAttributes(this._title, title);
|
||||
|
@ -95,6 +95,33 @@ add_task(async function test_enter_key_to_confirm() {
|
||||
ok(false, "The dialog Promise should not reject after hitting Return with the confirm button focused");
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_dialog_focus_trap() {
|
||||
let displayEl = document.getElementById("display");
|
||||
let displayElChildSpan = document.createElement("span");
|
||||
displayElChildSpan.tabIndex = 0;
|
||||
displayElChildSpan.id = "display-child";
|
||||
displayEl.appendChild(displayElChildSpan);
|
||||
|
||||
gConfirmationDialog.show(options);
|
||||
|
||||
ok(!gConfirmationDialog.hidden, "The dialog should be visible");
|
||||
ok(displayElChildSpan.tabIndex === -1, "The tabIndex value for elements with a hardcoded tabIndex attribute should be reset to '-1'.")
|
||||
ok(displayElChildSpan.dataset.oldTabIndex === "0", "Existing tabIndex values should be stored in `dataset.oldTabIndex`.")
|
||||
|
||||
const isActiveElemDialogOrHTML = (elemTagName) => {
|
||||
return (["HTML", "CONFIRMATION-DIALOG"].includes(elemTagName));
|
||||
}
|
||||
|
||||
let iterator = 0;
|
||||
while(iterator < 20) {
|
||||
sendKey("TAB");
|
||||
isnot(document.activeElement.id, "display-child", "The display-child element should not gain focus when the dialog is showing");
|
||||
is(isActiveElemDialogOrHTML(document.activeElement.tagName), true, "The confirmation-dialog should always have focus when the dialog is showing");
|
||||
iterator++;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user