Bug 1410361 - reuse existing tab of about:devtools;r=nchevobbe draft
authorJulian Descottes <jdescottes@mozilla.com>
Thu, 26 Oct 2017 15:11:51 +0200
changeset 689317 f2faf7cf176f008f25f8b4e3e972c49b48378147
parent 689309 7203df4914480faa4d901715eeedf7b023ad730d
child 689396 27c1ccd489a692e9d3189e2d2baec9aaf80fbf85
child 689412 4a694b94bc972e4be1fa1fbaa8e3f2a960e05ca2
push id86992
push userjdescottes@mozilla.com
push dateTue, 31 Oct 2017 11:15:27 +0000
reviewersnchevobbe
bugs1410361
milestone58.0a1
Bug 1410361 - reuse existing tab of about:devtools;r=nchevobbe MozReview-Commit-ID: 2cTjzmrcLYb
devtools/shim/aboutdevtools/test/browser.ini
devtools/shim/aboutdevtools/test/browser_aboutdevtools_reuse_existing.js
devtools/shim/devtools-startup.js
--- a/devtools/shim/aboutdevtools/test/browser.ini
+++ b/devtools/shim/aboutdevtools/test/browser.ini
@@ -1,7 +1,8 @@
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 support-files =
   head.js
 
 [browser_aboutdevtools_enables_devtools.js]
+[browser_aboutdevtools_reuse_existing.js]
new file mode 100644
--- /dev/null
+++ b/devtools/shim/aboutdevtools/test/browser_aboutdevtools_reuse_existing.js
@@ -0,0 +1,63 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/* eslint-env browser */
+
+/**
+ * Test that only one tab of about:devtools is used for a given window.
+ */
+add_task(async function () {
+  await pushPref("devtools.enabled", false);
+
+  info("Add an about:blank tab");
+  let tab = await addTab("about:blank");
+
+  synthesizeToggleToolboxKey();
+
+  info("Wait for the about:devtools tab to be selected");
+  await waitUntil(() => isAboutDevtoolsTab(gBrowser.selectedTab));
+
+  // Keep a reference on this tab to assert it later on.
+  let aboutDevtoolsTab = gBrowser.selectedTab;
+
+  info("Select the about:blank tab again");
+  gBrowser.selectedTab = tab;
+
+  synthesizeToggleToolboxKey();
+
+  info("Wait for the about:devtools tab to be selected");
+  await waitUntil(() => isAboutDevtoolsTab(gBrowser.selectedTab));
+
+  // filter is not available on gBrowser.tabs.
+  let aboutDevtoolsTabs = [...gBrowser.tabs].filter(isAboutDevtoolsTab);
+  ok(aboutDevtoolsTabs.length === 1, "Only one tab of about:devtools was opened.");
+  ok(aboutDevtoolsTabs[0] === aboutDevtoolsTab,
+    "The existing about:devtools tab was reused.");
+
+  await removeTab(aboutDevtoolsTab);
+  await removeTab(tab);
+});
+
+/**
+ * Helper to call the toggle devtools shortcut.
+ */
+function synthesizeToggleToolboxKey() {
+  info("Trigger the toogle toolbox shortcut");
+  if (Services.appinfo.OS == "Darwin") {
+    EventUtils.synthesizeKey("i", { accelKey: true, altKey: true });
+  } else {
+    EventUtils.synthesizeKey("i", { accelKey: true, shiftKey: true });
+  }
+}
+
+/**
+ * Helper to check if a given tab is about:devtools.
+ */
+function isAboutDevtoolsTab(tab) {
+  let browser = tab.linkedBrowser;
+  let location = browser.documentURI.spec;
+  return location.startsWith("about:devtools");
+}
--- a/devtools/shim/devtools-startup.js
+++ b/devtools/shim/devtools-startup.js
@@ -454,16 +454,17 @@ DevToolsStartup.prototype = {
     let mainKeyset = doc.getElementById("mainKeyset");
     mainKeyset.parentNode.insertBefore(keyset, mainKeyset);
   },
 
   onKey(window, key) {
     // Record the timing at which this event started in order to compute later in
     // gDevTools.showToolbox, the complete time it takes to open the toolbox.
     // i.e. especially take `initDevTools` into account.
+
     let startTime = window.performance.now();
     let require = this.initDevTools("KeyShortcut");
     if (require) {
       // require might be null if initDevTools was called while DevTools are disabled.
       let { gDevToolsBrowser } = require("devtools/client/framework/devtools-browser");
       gDevToolsBrowser.onKeyShortcut(window, key, startTime);
     }
   },
@@ -515,16 +516,30 @@ DevToolsStartup.prototype = {
     // Ensure loading main devtools module that hooks up into browser UI
     // and initialize all devtools machinery.
     require("devtools/client/framework/devtools-browser");
     return require;
   },
 
   openInstallPage: function (reason) {
     let { gBrowser } = Services.wm.getMostRecentWindow("navigator:browser");
+
+    // Focus about:devtools tab if there is already one opened in the current window.
+    for (let tab of gBrowser.tabs) {
+      let browser = tab.linkedBrowser;
+      // browser.documentURI might be undefined if the browser tab is still loading.
+      let location = browser.documentURI ? browser.documentURI.spec : "";
+      if (location.startsWith("about:devtools") &&
+          !location.startsWith("about:devtools-toolbox")) {
+        // Focus the existing about:devtools tab and bail out.
+        gBrowser.selectedTab = tab;
+        return;
+      }
+    }
+
     let url = "about:devtools";
     if (reason) {
       url += "?reason=" + encodeURIComponent(reason);
     }
     gBrowser.selectedTab = gBrowser.addTab(url);
   },
 
   handleConsoleFlag: function (cmdLine) {