summaryrefslogtreecommitdiffstats
path: root/toolkit/content/globalOverlay.js
blob: c021bfe74024b02a50a65781a057d11071b29bb5 (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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* 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/. */

function closeWindow(aClose, aPromptFunction, aSource) {
  let { AppConstants } = ChromeUtils.importESModule(
    "resource://gre/modules/AppConstants.sys.mjs"
  );

  // Closing the last window doesn't quit the application on OS X.
  if (AppConstants.platform != "macosx") {
    var windowCount = 0;
    for (let w of Services.wm.getEnumerator(null)) {
      if (w.closed) {
        continue;
      }
      if (++windowCount == 2) {
        break;
      }
    }

    // If we're down to the last window and someone tries to shut down, check to make sure we can!
    if (windowCount == 1 && !canQuitApplication("lastwindow", aSource)) {
      return false;
    }
    if (
      windowCount != 1 &&
      typeof aPromptFunction == "function" &&
      !aPromptFunction(aSource)
    ) {
      return false;
    }

    // If the user explicitly closes the last tabs in the window close remaining tabs. Bug 490136
    if (aClose) {
      window.SessionStore?.maybeDontRestoreTabs(window);
    }
  } else if (
    typeof aPromptFunction == "function" &&
    !aPromptFunction(aSource)
  ) {
    return false;
  }

  if (aClose) {
    window.close();
    return window.closed;
  }

  return true;
}

function canQuitApplication(aData, aSource) {
  const kCID = "@mozilla.org/browser/browserglue;1";
  if (kCID in Cc && !(aData || "").includes("restart")) {
    let BrowserGlue = Cc[kCID].getService(Ci.nsISupports).wrappedJSObject;
    BrowserGlue._registerQuitSource(aSource);
  }
  try {
    var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
      Ci.nsISupportsPRBool
    );
    Services.obs.notifyObservers(
      cancelQuit,
      "quit-application-requested",
      aData || null
    );

    // Something aborted the quit process.
    if (cancelQuit.data) {
      return false;
    }
  } catch (ex) {}
  return true;
}

function goQuitApplication(event) {
  // We can't know for sure if the user used a shortcut to trigger quit.
  // Proxy by means of checking for the shortcut modifier.
  let isMac = navigator.platform.startsWith("Mac");
  let key = isMac ? "metaKey" : "ctrlKey";
  let source = "OS";
  if (event[key]) {
    source = "shortcut";
    // Note that macOS likes pretending something came from this menu even if
    // activated by keyboard shortcut, hence checking that first.
  } else if (event.sourceEvent?.target?.id?.startsWith("menu_")) {
    source = "menuitem";
  } else if (event.sourceEvent?.target?.id?.startsWith("appMenu")) {
    source = "appmenu";
  }
  if (!canQuitApplication(undefined, source)) {
    return false;
  }

  Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
  return true;
}

//
// Command Updater functions
//
function goUpdateCommand(aCommand) {
  try {
    var controller = top.document.commandDispatcher.getControllerForCommand(
      aCommand
    );

    var enabled = false;
    if (controller) {
      enabled = controller.isCommandEnabled(aCommand);
    }

    goSetCommandEnabled(aCommand, enabled);
  } catch (e) {
    Cu.reportError(
      "An error occurred updating the " + aCommand + " command: " + e
    );
  }
}

function goDoCommand(aCommand) {
  try {
    var controller = top.document.commandDispatcher.getControllerForCommand(
      aCommand
    );
    if (controller && controller.isCommandEnabled(aCommand)) {
      controller.doCommand(aCommand);
    }
  } catch (e) {
    Cu.reportError(
      "An error occurred executing the " + aCommand + " command: " + e
    );
  }
}

function goSetCommandEnabled(aID, aEnabled) {
  var node = document.getElementById(aID);

  if (node) {
    if (aEnabled) {
      node.removeAttribute("disabled");
    } else {
      node.setAttribute("disabled", "true");
    }
  }
}