Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions src/widgets/Dialogs.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ define(function (require, exports, module) {
DIALOG_ID_EXT_CHANGED = "ext-changed-dialog",
DIALOG_ID_EXT_DELETED = "ext-deleted-dialog",
DIALOG_ID_LIVE_DEVELOPMENT = "live-development-error-dialog";

/**
* A stack of keydown event handler functions that corresponds to the
* current stack of modal dialogs.
*
* @type {Array.<Function>}
*/
var _keydownListeners = [];

function _dismissDialog(dlg, buttonId) {
dlg.data("buttonId", buttonId);
Expand All @@ -71,7 +79,9 @@ define(function (require, exports, module) {
var inFormField = ($(e.target).filter(":input").length > 0),
inTextArea = (e.target.tagName === "TEXTAREA");

if (e.which === KeyEvent.DOM_VK_RETURN && !inTextArea) { // enter key in single-line text input still dismisses
if (e.which === KeyEvent.DOM_VK_ESCAPE) {
buttonId = DIALOG_BTN_CANCEL;
} else if (e.which === KeyEvent.DOM_VK_RETURN && !inTextArea) { // enter key in single-line text input still dismisses
// Click primary button
primaryBtn.click();
} else if (e.which === KeyEvent.DOM_VK_SPACE) {
Expand Down Expand Up @@ -177,7 +187,22 @@ define(function (require, exports, module) {

// Remove keydown event handler
window.document.body.removeEventListener("keydown", handleKeyDown, true);
KeyBindingManager.setEnabled(true);

// Remove this dialog's listener from the stack of listeners. (It
// might not be on the top of the stack if the dialogs are somehow
// dismissed out of order.)
_keydownListeners = _keydownListeners.filter(function (listener) {
return listener !== handleKeyDown;
});

// Restore the previous listener if there was one; otherwise return
// control to the KeyBindingManager.
if (_keydownListeners.length > 0) {
var previousListener = _keydownListeners[_keydownListeners.length - 1];
window.document.body.addEventListener("keydown", previousListener, true);
} else {
KeyBindingManager.setEnabled(true);
}
}).one("shown", function () {
// Set focus to the default button
var primaryBtn = $dlg.find(".primary");
Expand All @@ -186,9 +211,18 @@ define(function (require, exports, module) {
primaryBtn.focus();
}

// Listen for dialog keyboard shortcuts
// If this is the only dialog then also disable the KeyBindingManager;
// otherwise, remove and the previous dialog's listener before installing the new one.
if (_keydownListeners.length > 0) {
var previousListener = _keydownListeners[_keydownListeners.length - 1];
window.document.body.removeEventListener("keydown", previousListener, true);
} else {
KeyBindingManager.setEnabled(false);
}
_keydownListeners.push(handleKeyDown);

// Handle this dialog's keyboard events with the current listener
window.document.body.addEventListener("keydown", handleKeyDown, true);
KeyBindingManager.setEnabled(false);
});

// Click handler for buttons
Expand All @@ -202,7 +236,7 @@ define(function (require, exports, module) {
$dlg.modal({
backdrop: "static",
show: true,
keyboard: autoDismiss
keyboard: false // handle the ESC key ourselves so we can deal with nested dialogs
});

return promise;
Expand Down