summaryrefslogtreecommitdiffstats
path: root/comm/mail/base/content/globalOverlay.js
blob: b31751a49095370c00efdbfce7232af1170fad5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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");
    }
  }
}