Bug 1412028 - open toolbox after completing about:devtools;r=ochameau draft
authorJulian Descottes <jdescottes@mozilla.com>
Fri, 27 Oct 2017 17:04:30 +0200
changeset 687710 c0627e37a1acdc474cda1e6abacb765bbb189738
parent 687708 b8768451b78cdb8aa941a858697deb6685dd8403
child 737718 50751ea4de0c179d12d7aca23778d162937f7bdd
push id86576
push userjdescottes@mozilla.com
push dateFri, 27 Oct 2017 16:22:17 +0000
reviewersochameau
bugs1412028
milestone58.0a1
Bug 1412028 - open toolbox after completing about:devtools;r=ochameau MozReview-Commit-ID: HTgWEOp9Caj
devtools/shim/DevToolsShim.jsm
devtools/shim/aboutdevtools/aboutdevtools.js
devtools/shim/devtools-startup.js
--- a/devtools/shim/DevToolsShim.jsm
+++ b/devtools/shim/DevToolsShim.jsm
@@ -174,17 +174,19 @@ this.DevToolsShim = {
    *        An array of CSS selectors to find the target node. Several selectors can be
    *        needed if the element is nested in frames and not directly in the root
    *        document.
    * @return {Promise} a promise that resolves when the node is selected in the inspector
    *         markup view or that resolves immediately if DevTools are not installed.
    */
   inspectNode: function (tab, selectors) {
     if (!this.isEnabled()) {
-      DevtoolsStartup.openInstallPage("ContextMenu");
+      // Pass the inspector keyshortcut id in order to open the inspector after the user
+      // has completed the installation.
+      DevtoolsStartup.openInstallPage("ContextMenu", "inspector");
       return Promise.resolve();
     }
 
     // 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 `DevtoolsStartup.initDevTools` into account.
     let { performance } = Services.appShell.hiddenDOMWindow;
     let startTime = performance.now();
--- a/devtools/shim/aboutdevtools/aboutdevtools.js
+++ b/devtools/shim/aboutdevtools/aboutdevtools.js
@@ -1,48 +1,56 @@
 /* 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/. */
 
 "use strict";
 
-const { utils: Cu } = Components;
+const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
 const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
+const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
+XPCOMUtils.defineLazyGetter(this, "DevtoolsStartup", () => {
+  return Cc["@mozilla.org/devtools/startup-clh;1"]
+            .getService(Ci.nsICommandLineHandler)
+            .wrappedJSObject;
+});
+
 const DEVTOOLS_ENABLED_PREF = "devtools.enabled";
 
 const MESSAGES = {
   AboutDebugging: "about-debugging-message",
   ContextMenu: "inspect-element-message",
   HamburgerMenu: "menu-message",
   KeyShortcut: "key-shortcut-message",
   SystemMenu: "menu-message",
 };
 
 // URL constructor doesn't support about: scheme,
 // we have to use http in order to have working searchParams.
 let url = new URL(window.location.href.replace("about:", "http://"));
 let reason = url.searchParams.get("reason");
+let keyid = url.searchParams.get("keyid");
 let tabid = parseInt(url.searchParams.get("tabid"), 10);
 
 function getToolboxShortcut() {
   const bundleUrl = "chrome://devtools-shim/locale/key-shortcuts.properties";
   const bundle = Services.strings.createBundle(bundleUrl);
   const modifier = Services.appinfo.OS == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+";
   return modifier + bundle.GetStringFromName("toggleToolbox.commandkey");
 }
 
 function onInstallButtonClick() {
-  Services.prefs.setBoolPref("devtools.enabled", true);
+  Services.prefs.setBoolPref(DEVTOOLS_ENABLED_PREF, true);
 }
 
 function updatePage() {
   const installPage = document.getElementById("install-page");
   const welcomePage = document.getElementById("welcome-page");
-  const isEnabled = Services.prefs.getBoolPref("devtools.enabled");
+  const isEnabled = Services.prefs.getBoolPref(DEVTOOLS_ENABLED_PREF);
   if (isEnabled) {
     installPage.setAttribute("hidden", "true");
     welcomePage.removeAttribute("hidden");
   } else {
     welcomePage.setAttribute("hidden", "true");
     installPage.removeAttribute("hidden");
   }
 }
@@ -73,26 +81,34 @@ window.addEventListener("load", function
   installButton.addEventListener("click", onInstallButtonClick);
 
   // Update the current page based on the current value of DEVTOOLS_ENABLED_PREF.
   updatePage();
 }, { once: true });
 
 window.addEventListener("beforeunload", function () {
   // Focus the originator tab.
-  let { gBrowser } = Services.wm.getMostRecentWindow("navigator:browser");
+  let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+  let { gBrowser } = browserWindow;
   if (gBrowser.selectedTab.linkedBrowser.contentWindow !== window) {
     // Only try to focus the correct tab if the current tab is the about:devtools page.
     return;
   }
 
   for (let tab of gBrowser.tabs) {
     let outerWindowID = tab.linkedBrowser.outerWindowID;
     if (outerWindowID === tabid) {
       gBrowser.selectedTab = tab;
+
+      // If DevTools are enabled and a keyid was passed to the install page, execute the
+      // user action after selecting the original tab.
+      const isEnabled = Services.prefs.getBoolPref(DEVTOOLS_ENABLED_PREF);
+      if (keyid && isEnabled) {
+        DevtoolsStartup.executeKey(keyid, browserWindow);
+      }
     }
   }
 }, {once: true});
 
 window.addEventListener("unload", function () {
   let installButton = document.getElementById("install");
   installButton.removeEventListener("click", onInstallButtonClick);
   Services.prefs.removeObserver(DEVTOOLS_ENABLED_PREF, updatePage);
--- a/devtools/shim/devtools-startup.js
+++ b/devtools/shim/devtools-startup.js
@@ -462,24 +462,24 @@ DevToolsStartup.prototype = {
    *
    * @param {String} keyId
    *        id or toolId for the DevTools key shortcut to execute (see KeyShortcuts).
    * @param {Window} window
    *        the window where the command should be executed (command will most likely
    *        apply to the selected tab).
    */
   executeKey(keyId, window) {
-    // 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.
+    if (!Services.prefs.getBoolPref(DEVTOOLS_ENABLED_PREF)) {
+      this.openInstallPage("KeyShortcut", keyId);
+    } else {
+      // 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");
       let { gDevToolsBrowser } = require("devtools/client/framework/devtools-browser");
       let key = KeyShortcuts.find(k => keyId === (k.toolId || k.id));
       gDevToolsBrowser.onKeyShortcut(window, key, startTime);
     }
   },
 
   // Create a <xul:key> DOM Element
   createKey(doc, { id, toolId, shortcut, modifiers: mod }, oncommand) {
@@ -499,22 +499,16 @@ DevToolsStartup.prototype = {
     // Bug 371900: command event is fired only if "oncommand" attribute is set.
     k.setAttribute("oncommand", ";");
     k.addEventListener("command", oncommand);
 
     return k;
   },
 
   initDevTools: function (reason) {
-    // If an entry point is fired and tools are not enabled open the installation page
-    if (!Services.prefs.getBoolPref(DEVTOOLS_ENABLED_PREF)) {
-      this.openInstallPage(reason);
-      return null;
-    }
-
     if (reason && !this.recorded) {
       // Only save the first call for each firefox run as next call
       // won't necessarely start the tool. For example key shortcuts may
       // only change the currently selected tool.
       try {
         Services.telemetry.getHistogramById("DEVTOOLS_ENTRY_POINT")
                           .add(reason);
       } catch (e) {
@@ -526,17 +520,17 @@ DevToolsStartup.prototype = {
     this.initialized = true;
     let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
     // 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) {
+  openInstallPage: function (reason, keyId) {
     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") &&
@@ -554,16 +548,20 @@ DevToolsStartup.prototype = {
       params.push("reason=" + encodeURIComponent(reason));
     }
 
     let selectedTab = gBrowser.selectedTab;
     if (selectedTab) {
       params.push("tabid=" + selectedTab.linkedBrowser.outerWindowID);
     }
 
+    if (keyId) {
+      params.push("keyid=" + keyId);
+    }
+
     if (params.length > 0) {
       url += "?" + params.join("&");
     }
 
     // Set relatedToCurrent: true to open the tab next to the current one.
     gBrowser.selectedTab = gBrowser.addTab(url, {relatedToCurrent: true});
   },