Bug 1880914 - Move browser/tab closing functions. r=Gijs,perftest-reviewers,devtools-reviewers,fxview-reviewers,sessionstore-reviewers,sfoster,kshampur
authorYi Xiong Wong <johnmax2468@gmail.com>
Mon, 08 Apr 2024 17:21:01 +0000 (15 months ago)
changeset 734376 71c30fc6409ced6fb56420aa74650e4f4adb94b3
parent 734375 e4d2936852d95ea5d1e600f319a768df43dc8e3e
child 734377 64d268bc8eddb5d596f3ed2a200ac05cc1a0e4c6
push id41717
push usersstanca@mozilla.com
push dateMon, 08 Apr 2024 21:52:59 +0000 (15 months ago)
treeherdermozilla-central@79551503d77c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, perftest-reviewers, devtools-reviewers, fxview-reviewers, sessionstore-reviewers, sfoster, kshampur
bugs1880914
milestone126.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1880914 - Move browser/tab closing functions. r=Gijs,perftest-reviewers,devtools-reviewers,fxview-reviewers,sessionstore-reviewers,sfoster,kshampur Differential Revision: https://phabricator.services.mozilla.com/D206197
browser/base/content/browser-commands.js
browser/base/content/browser-sets.inc
browser/base/content/browser.js
browser/base/content/browser.js.globals
browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js
browser/base/content/test/general/browser_private_no_prompt.js
browser/base/content/test/popups/browser_popup_close_main_window.js
browser/components/firefoxview/tests/browser/browser_tab_on_close_warning.js
browser/components/sessionstore/test/browser_354894_perwindowpb.js
browser/components/sessionstore/test/browser_580512.js
browser/components/sessionstore/test/browser_589246.js
devtools/client/framework/test/browser_toolbox_screenshot_tool.js
devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js
devtools/shared/commands/resource/tests/browser_resources_last_private_context_exit.js
devtools/startup/tests/browser/browser_shim_disable_devtools.js
testing/talos/talos/tests/tart/addon/content/tart.js
--- a/browser/base/content/browser-commands.js
+++ b/browser/base/content/browser-commands.js
@@ -373,9 +373,45 @@ var BrowserCommands = {
           nsIFilePicker.filterXML |
           nsIFilePicker.filterHTML |
           nsIFilePicker.filterPDF
       );
       fp.displayDirectory = gLastOpenDirectory.path;
       fp.open(fpCallback);
     } catch (ex) {}
   },
+
+  closeTabOrWindow(event) {
+    // If we're not a browser window, just close the window.
+    if (window.location.href != AppConstants.BROWSER_CHROME_URL) {
+      closeWindow(true);
+      return;
+    }
+
+    // In a multi-select context, close all selected tabs
+    if (gBrowser.multiSelectedTabsCount) {
+      gBrowser.removeMultiSelectedTabs();
+      return;
+    }
+
+    // Keyboard shortcuts that would close a tab that is pinned select the first
+    // unpinned tab instead.
+    if (
+      event &&
+      (event.ctrlKey || event.metaKey || event.altKey) &&
+      gBrowser.selectedTab.pinned
+    ) {
+      if (gBrowser.visibleTabs.length > gBrowser._numPinnedTabs) {
+        gBrowser.tabContainer.selectedIndex = gBrowser._numPinnedTabs;
+      }
+      return;
+    }
+
+    // If the current tab is the last one, this will close the window.
+    gBrowser.removeCurrentTab({ animate: true });
+  },
+
+  tryToCloseWindow(event) {
+    if (WindowIsClosing(event)) {
+      window.close();
+    } // WindowIsClosing does all the necessary checks
+  },
 };
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -27,18 +27,18 @@
     <command id="Browser:SendLink"
              oncommand="MailIntegration.sendLinkForBrowser(gBrowser.selectedBrowser);"/>
 
     <command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
     <command id="cmd_print" oncommand="PrintUtils.startPrintWindow(gBrowser.selectedBrowser.browsingContext);"/>
     <command id="cmd_printPreviewToggle" oncommand="PrintUtils.togglePrintPreview(gBrowser.selectedBrowser.browsingContext);"/>
     <command id="cmd_file_importFromAnotherBrowser" oncommand="MigrationUtils.showMigrationWizard(window, { entrypoint: MigrationUtils.MIGRATION_ENTRYPOINTS.FILE_MENU });"/>
     <command id="cmd_help_importFromAnotherBrowser" oncommand="MigrationUtils.showMigrationWizard(window, { entrypoint: MigrationUtils.MIGRATION_ENTRYPOINTS.HELP_MENU });"/>
-    <command id="cmd_close" oncommand="BrowserCloseTabOrWindow(event);"/>
-    <command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow(event)"/>
+    <command id="cmd_close" oncommand="BrowserCommands.closeTabOrWindow(event);"/>
+    <command id="cmd_closeWindow" oncommand="BrowserCommands.tryToCloseWindow(event)"/>
     <command id="cmd_toggleMute" oncommand="gBrowser.toggleMuteAudioOnMultiSelectedTabs(gBrowser.selectedTab)"/>
     <command id="cmd_CustomizeToolbars" oncommand="gCustomizeMode.enter()"/>
     <command id="cmd_toggleOfflineStatus" oncommand="BrowserOffline.toggleOfflineStatus();"/>
     <command id="cmd_quitApplication" oncommand="goQuitApplication(event)"/>
 
     <command id="View:AboutProcesses" oncommand="switchToTabHavingURI('about:processes', true)"/>
     <command id="View:PageSource" oncommand="BrowserViewSource(window.gBrowser.selectedBrowser);"/>
     <command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2645,17 +2645,17 @@ function HandleAppCommandEvent(evt) {
       break;
     case "Home":
       BrowserCommands.home();
       break;
     case "New":
       BrowserCommands.openTab();
       break;
     case "Close":
-      BrowserCloseTabOrWindow();
+      BrowserCommands.closeTabOrWindow();
       break;
     case "Find":
       gLazyFindCommand("onFindCommand");
       break;
     case "Help":
       openHelpLink("firefox-help");
       break;
     case "Open":
@@ -2760,52 +2760,16 @@ var gLastOpenDirectory = {
       );
     }
   },
   reset() {
     this._lastDir = null;
   },
 };
 
-function BrowserCloseTabOrWindow(event) {
-  // If we're not a browser window, just close the window.
-  if (window.location.href != AppConstants.BROWSER_CHROME_URL) {
-    closeWindow(true);
-    return;
-  }
-
-  // In a multi-select context, close all selected tabs
-  if (gBrowser.multiSelectedTabsCount) {
-    gBrowser.removeMultiSelectedTabs();
-    return;
-  }
-
-  // Keyboard shortcuts that would close a tab that is pinned select the first
-  // unpinned tab instead.
-  if (
-    event &&
-    (event.ctrlKey || event.metaKey || event.altKey) &&
-    gBrowser.selectedTab.pinned
-  ) {
-    if (gBrowser.visibleTabs.length > gBrowser._numPinnedTabs) {
-      gBrowser.tabContainer.selectedIndex = gBrowser._numPinnedTabs;
-    }
-    return;
-  }
-
-  // If the current tab is the last one, this will close the window.
-  gBrowser.removeCurrentTab({ animate: true });
-}
-
-function BrowserTryToCloseWindow(event) {
-  if (WindowIsClosing(event)) {
-    window.close();
-  } // WindowIsClosing does all the necessary checks
-}
-
 function getLoadContext() {
   return window.docShell.QueryInterface(Ci.nsILoadContext);
 }
 
 function readFromClipboard() {
   var url;
 
   try {
--- a/browser/base/content/browser.js.globals
+++ b/browser/base/content/browser.js.globals
@@ -32,18 +32,16 @@
   "delayedStartupPromise",
   "gBrowserInit",
   "HandleAppCommandEvent",
   "BrowserCommands",
   "kSkipCacheFlags",
   "loadOneOrMoreURIs",
   "openLocation",
   "gLastOpenDirectory",
-  "BrowserCloseTabOrWindow",
-  "BrowserTryToCloseWindow",
   "getLoadContext",
   "readFromClipboard",
   "BrowserViewSourceOfDocument",
   "BrowserViewSource",
   "BrowserPageInfo",
   "UpdateUrlbarSearchSplitterState",
   "UpdatePopupNotificationsVisibility",
   "PageProxyClickHandler",
--- a/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js
+++ b/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js
@@ -52,17 +52,17 @@ add_task(async function closeWindowWithM
   await promiseTabLoadEvent(firstTab, TEST_PAGE);
   await promiseTabLoadEvent(
     BrowserTestUtils.addTab(newWin.gBrowser),
     // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     "http://example.com/"
   );
   let windowClosedPromise = BrowserTestUtils.domWindowClosed(newWin);
   expectingDialog = true;
-  newWin.BrowserTryToCloseWindow();
+  newWin.BrowserCommands.tryToCloseWindow();
   await windowClosedPromise;
   ok(!expectingDialog, "There should have been a dialog.");
   ok(newWin.closed, "Window should be closed.");
   Services.prefs.clearUserPref("browser.tabs.warnOnClose");
 });
 
 add_task(async function closeWindoWithSingleTabTwice() {
   let newWin = await promiseOpenAndLoadWindow({}, true);
--- a/browser/base/content/test/general/browser_private_no_prompt.js
+++ b/browser/base/content/test/general/browser_private_no_prompt.js
@@ -1,12 +1,12 @@
 function test() {
   waitForExplicitFinish();
   var privateWin = OpenBrowserWindow({ private: true });
 
   whenDelayedStartupFinished(privateWin, function () {
     privateWin.BrowserCommands.openTab();
-    privateWin.BrowserTryToCloseWindow();
+    privateWin.BrowserCommands.tryToCloseWindow();
     ok(true, "didn't prompt");
 
     executeSoon(finish);
   });
 }
--- a/browser/base/content/test/popups/browser_popup_close_main_window.js
+++ b/browser/base/content/test/popups/browser_popup_close_main_window.js
@@ -32,17 +32,17 @@ add_task(async function closing_last_win
 
   let observed = 0;
   function obs() {
     observed++;
   }
   Services.obs.addObserver(obs, "browser-lastwindow-close-requested");
   let newWin = await BrowserTestUtils.openNewBrowserWindow();
   let closedPromise = BrowserTestUtils.windowClosed(newWin);
-  newWin.BrowserTryToCloseWindow();
+  newWin.BrowserCommands.tryToCloseWindow();
   await closedPromise;
   is(observed, 1, "Got a notification for closing the normal window.");
   Services.obs.removeObserver(obs, "browser-lastwindow-close-requested");
 });
 
 /**
  * Check that if we close the 1 remaining window and also have a popup open,
  * we don't treat it as quitting.
@@ -63,22 +63,22 @@ add_task(async function closing_last_win
   Services.obs.addObserver(obs, "browser-lastwindow-close-requested");
   let newWin = await BrowserTestUtils.openNewBrowserWindow();
   let popupPromise = BrowserTestUtils.waitForNewWindow("https://example.com/");
   SpecialPowers.spawn(newWin.gBrowser.selectedBrowser, [], function () {
     content.open("https://example.com/", "_blank", "height=500");
   });
   let popupWin = await popupPromise;
   let closedPromise = BrowserTestUtils.windowClosed(newWin);
-  newWin.BrowserTryToCloseWindow();
+  newWin.BrowserCommands.tryToCloseWindow();
   await closedPromise;
   is(observed, 0, "Got no notification for closing the normal window.");
 
   closedPromise = BrowserTestUtils.windowClosed(popupWin);
-  popupWin.BrowserTryToCloseWindow();
+  popupWin.BrowserCommands.tryToCloseWindow();
   await closedPromise;
   is(
     observed,
     0,
     "Got no notification now that we're closing the last window, as it's a popup."
   );
   Services.obs.removeObserver(obs, "browser-lastwindow-close-requested");
 });
--- a/browser/components/firefoxview/tests/browser/browser_tab_on_close_warning.js
+++ b/browser/components/firefoxview/tests/browser/browser_tab_on_close_warning.js
@@ -26,17 +26,17 @@ add_task(
     await SpecialPowers.pushPrefEnv({
       set: [["browser.tabs.warnOnClose", true]],
     });
     info("Opening window...");
     const win = await BrowserTestUtils.openNewBrowserWindow();
     info("Opening Firefox View tab...");
     await openFirefoxViewTab(win);
     info("Trigger warnAboutClosingWindow()");
-    win.BrowserTryToCloseWindow();
+    win.BrowserCommands.tryToCloseWindow();
     await BrowserTestUtils.closeWindow(win);
     ok(!dialogObserver.wasOpened, "Dialog was not opened");
     dialogObserver.cleanup();
   }
 );
 
 add_task(
   async function on_close_warning_should_not_show_for_firefox_view_tab_non_macos() {
--- a/browser/components/sessionstore/test/browser_354894_perwindowpb.js
+++ b/browser/components/sessionstore/test/browser_354894_perwindowpb.js
@@ -16,17 +16,17 @@
  * attribute modified so that it's not considered a browser window any longer.
  * This is crucial, because otherwise there would be two browser windows around,
  * said main test window and the one opened by the tests, and hence the new
  * logic wouldn't be executed at all.
  * @note Mac only tests the new notifications, as restoring the last window is
  * not enabled on that platform (platform shim; the application is kept running
  * although there are no windows left)
  * @note There is a difference when closing a browser window with
- * BrowserTryToCloseWindow() as opposed to close(). The former will make
+ * BrowserCommands.tryToCloseWindow() as opposed to close(). The former will make
  * nsSessionStore restore a window next time it gets a chance and will post
  * notifications. The latter won't.
  */
 
 // The rejection "BrowserWindowTracker.getTopWindow(...) is null" is left
 // unhandled in some cases. This bug should be fixed, but for the moment this
 // file allows a class of rejections.
 //
@@ -177,30 +177,30 @@ let setupTest = async function (options,
 function injectTestTabs(win) {
   let promises = TEST_URLS.map(url =>
     BrowserTestUtils.addTab(win.gBrowser, url)
   ).map(tab => BrowserTestUtils.browserLoaded(tab.linkedBrowser));
   return Promise.all(promises);
 }
 
 /**
- * Attempts to close a window via BrowserTryToCloseWindow so that
+ * Attempts to close a window via BrowserCommands.tryToCloseWindow so that
  * we get the browser-lastwindow-close-requested and
  * browser-lastwindow-close-granted observer notifications.
  *
  * @param win (Window)
  *        The window to try to close
  * @returns Promise
  *        Resolves to true if the window closed, or false if the window
  *        was denied the ability to close.
  */
 function closeWindowForRestoration(win) {
   return new Promise(resolve => {
     let closePromise = BrowserTestUtils.windowClosed(win);
-    win.BrowserTryToCloseWindow();
+    win.BrowserCommands.tryToCloseWindow();
     if (!win.closed) {
       resolve(false);
       return;
     }
 
     closePromise.then(() => {
       resolve(true);
     });
--- a/browser/components/sessionstore/test/browser_580512.js
+++ b/browser/components/sessionstore/test/browser_580512.js
@@ -27,20 +27,20 @@ function test() {
   openWinWithCb(closeFirstWin, URIS_PINNED.concat(URIS_NORMAL_A));
 }
 
 function closeFirstWin(win) {
   win.gBrowser.pinTab(win.gBrowser.tabs[0]);
   win.gBrowser.pinTab(win.gBrowser.tabs[1]);
 
   let winClosed = BrowserTestUtils.windowClosed(win);
-  // We need to call BrowserTryToCloseWindow in order to trigger
+  // We need to call BrowserCommands.tryToCloseWindow in order to trigger
   // the machinery that chooses whether or not to save the session
   // for the last window.
-  win.BrowserTryToCloseWindow();
+  win.BrowserCommands.tryToCloseWindow();
   ok(win.closed, "window closed");
 
   winClosed.then(() => {
     openWinWithCb(
       checkSecondWin,
       URIS_NORMAL_B,
       URIS_PINNED.concat(URIS_NORMAL_B)
     );
--- a/browser/components/sessionstore/test/browser_589246.js
+++ b/browser/components/sessionstore/test/browser_589246.js
@@ -211,22 +211,22 @@ function onStateRestored() {
             "load",
             function () {
               if (shouldCloseTab == "one") {
                 newWin.gBrowser.removeTab(newTab2);
               } else if (shouldCloseTab == "both") {
                 newWin.gBrowser.removeTab(newTab);
                 newWin.gBrowser.removeTab(newTab2);
               }
-              newWin.BrowserTryToCloseWindow();
+              newWin.BrowserCommands.tryToCloseWindow();
             },
             { capture: true, once: true }
           );
         } else {
-          newWin.BrowserTryToCloseWindow();
+          newWin.BrowserCommands.tryToCloseWindow();
         }
       });
     },
     { once: true }
   );
 }
 
 // This will be called before the window is actually closed
--- a/devtools/client/framework/test/browser_toolbox_screenshot_tool.js
+++ b/devtools/client/framework/test/browser_toolbox_screenshot_tool.js
@@ -116,11 +116,11 @@ add_task(async function () {
 
   // Remove the downloaded screenshot file
   await IOUtils.remove(privateScreenshotFilePath);
 
   // cleanup the downloads
   await resetDownloads();
 
   const closePromise = BrowserTestUtils.windowClosed(privateWindow);
-  privateWindow.BrowserTryToCloseWindow();
+  privateWindow.BrowserCommands.tryToCloseWindow();
   await closePromise;
 });
--- a/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js
+++ b/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js
@@ -136,17 +136,17 @@ add_task(async function () {
   info("Wait for private log message");
   await onBrowserConsolePrivateLogMessage;
   info("Wait for private error message");
   await onBrowserConsolePrivateErrorMessage;
   ok(true, "Messages are displayed as expected");
 
   info("close the private window and check if private messages are removed");
   const onPrivateMessagesCleared = hud.ui.once("private-messages-cleared");
-  privateWindow.BrowserTryToCloseWindow();
+  privateWindow.BrowserCommands.tryToCloseWindow();
   await onPrivateMessagesCleared;
 
   ok(
     findConsoleAPIMessage(hud, NON_PRIVATE_MESSAGE),
     "non-private messages are still shown after private window closed"
   );
   assertNoPrivateMessages(hud);
 
--- a/devtools/shared/commands/resource/tests/browser_resources_last_private_context_exit.js
+++ b/devtools/shared/commands/resource/tests/browser_resources_last_private_context_exit.js
@@ -61,31 +61,31 @@ add_task(async function () {
   );
 
   info("Open a second private browsing window");
   const secondPrivateWindow = await BrowserTestUtils.openNewBrowserWindow({
     private: true,
   });
 
   info("Close the second private window");
-  secondPrivateWindow.BrowserTryToCloseWindow();
+  secondPrivateWindow.BrowserCommands.tryToCloseWindow();
 
   // Let a chance to an unexpected async event to be fired
   await wait(1000);
 
   is(
     availableResources.length,
     0,
     "We do not get any LAST_PRIVATE_CONTEXT_EXIT when closing the second private window only"
   );
 
   info(
     "close the private window and check if LAST_PRIVATE_CONTEXT_EXIT resource is sent"
   );
-  privateWindow.BrowserTryToCloseWindow();
+  privateWindow.BrowserCommands.tryToCloseWindow();
 
   info("Wait for LAST_PRIVATE_CONTEXT_EXIT");
   await waitFor(() => availableResources.length == 1);
   is(
     availableResources.length,
     1,
     "We get one LAST_PRIVATE_CONTEXT_EXIT when closing the last opened private window"
   );
--- a/devtools/startup/tests/browser/browser_shim_disable_devtools.js
+++ b/devtools/startup/tests/browser/browser_shim_disable_devtools.js
@@ -129,17 +129,17 @@ add_task(async function () {
   info("Close out the menu popups");
   await simulateMenuClosed(subMenu);
   await simulateMenuClosed(toolsMenuPopup);
 
   win.gBrowser.removeTab(tab);
 
   info("Close the test window");
   const winClosed = BrowserTestUtils.windowClosed(win);
-  win.BrowserTryToCloseWindow();
+  win.BrowserCommands.tryToCloseWindow();
   await winClosed;
 });
 
 function waitForDelayedStartupFinished(win) {
   return new Promise(resolve => {
     Services.obs.addObserver(function observer(subject) {
       if (win == subject) {
         Services.obs.removeObserver(
--- a/testing/talos/talos/tests/tart/addon/content/tart.js
+++ b/testing/talos/talos/tests/tart/addon/content/tart.js
@@ -141,17 +141,17 @@ Tart.prototype = {
     // --> many-tabs case which requires modified max-width will not go into v1. No need for now.
     // this._win.gBrowser.selectedTab.style.minWidth = "1px"; // Prevent overflow regrdless of DPI scale.
 
     return this._win.gBrowser.selectedTab;
   },
 
   clickCloseCurrentTab() {
     this._endDetection = this.tabDetector;
-    this._win.BrowserCloseTabOrWindow();
+    this._win.BrowserCommands.closeTabOrWindow();
     return this._win.gBrowser.selectedTab;
   },
 
   fadeOutCurrentTab() {
     this._endDetection = this.tabDetector;
     this._win.gBrowser.selectedTab.removeAttribute("fadein");
   },