diff options
Diffstat (limited to 'comm/mail/base/content/globalOverlay.js')
-rw-r--r-- | comm/mail/base/content/globalOverlay.js | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/comm/mail/base/content/globalOverlay.js b/comm/mail/base/content/globalOverlay.js new file mode 100644 index 0000000000..b31751a490 --- /dev/null +++ b/comm/mail/base/content/globalOverlay.js @@ -0,0 +1,122 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Notifies observers that quitting has been requested. + * + * @returns {boolean} - True if an observer prevented quitting, false otherwise. + */ +function canQuitApplication() { + try { + let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance( + Ci.nsISupportsPRBool + ); + Services.obs.notifyObservers(cancelQuit, "quit-application-requested"); + + // Something aborted the quit process. + if (cancelQuit.data) { + return false; + } + } catch (ex) {} + return true; +} + +/** + * Quit the application if no `quit-application-requested` observer prevents it. + */ +function goQuitApplication() { + if (!canQuitApplication()) { + return false; + } + + Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit); + return true; +} + +/** + * Gets the first registered controller that returns true for both + * `supportsCommand` and `isCommandEnabled`, or null if no controllers + * return true for both. + * + * @param {string} command - The command name to pass to controllers. + * @returns {nsIController|null} + */ +function getEnabledControllerForCommand(command) { + // The first controller for which `supportsCommand` returns true. + let controllerA = + top.document.commandDispatcher.getControllerForCommand(command); + if (controllerA?.isCommandEnabled(command)) { + return controllerA; + } + + // Didn't find a controller, or `isCommandEnabled` returned false? + // Try the other controllers. Note this isn't exactly the same set + // of controllers as `commandDispatcher` has. + for (let i = 0; i < top.controllers.getControllerCount(); i++) { + let controllerB = top.controllers.getControllerAt(i); + if ( + controllerB !== controllerA && + controllerB.supportsCommand(command) && + controllerB.isCommandEnabled(command) + ) { + return controllerB; + } + } + + return null; +} + +/** + * Updates the enabled state of the element with the ID `command`. The command + * is considered enabled if at least one controller returns true for both + * `supportsCommand` and `isCommandEnabled`. + * + * @param {string} command - The command name to pass to controllers. + */ +function goUpdateCommand(command) { + try { + goSetCommandEnabled(command, !!getEnabledControllerForCommand(command)); + } catch (e) { + console.error(`An error occurred updating the ${command} command: ${e}`); + } +} + +/** + * Calls `doCommand` on the first controller that returns true for both + * `supportsCommand` and `isCommandEnabled`. + * + * @param {string} command - The command name to pass to controllers. + * @param {any[]} args - Any number of arguments to pass to the chosen + * controller. Note that passing arguments is not part of the `nsIController` + * interface and only possible for JS controllers. + */ +function goDoCommand(command, ...args) { + try { + let controller = getEnabledControllerForCommand(command); + if (controller) { + controller = controller.wrappedJSObject ?? controller; + controller.doCommand(command, ...args); + } + } catch (e) { + console.error(`An error occurred executing the ${command} command: ${e}`); + } +} + +/** + * Updates the enabled state of the element with the ID `id`. + * + * @param {string} id + * @param {boolean} enabled + */ +function goSetCommandEnabled(id, enabled) { + let node = document.getElementById(id); + + if (node) { + if (enabled) { + node.removeAttribute("disabled"); + } else { + node.setAttribute("disabled", "true"); + } + } +} |