summaryrefslogtreecommitdiffstats
path: root/comm/mail/base/content/globalOverlay.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/base/content/globalOverlay.js')
-rw-r--r--comm/mail/base/content/globalOverlay.js122
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");
+ }
+ }
+}