Bug 1495944: Enable/Disable devtools menu items and the shortcut key. r=jdescottes
☠☠ backed out by fd6b8be34aed ☠ ☠
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Thu, 17 Jan 2019 23:12:29 +0000
changeset 511473 85f355a22192c5ccba2a05c8684e2f04cc7b988e
parent 511472 0e2384b8497dbe5af4db59a7b8be7241caf7266d
child 511474 f78876cf49e649cd99dbe806a01225e2f856924d
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1495944
milestone66.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 1495944: Enable/Disable devtools menu items and the shortcut key. r=jdescottes Differential Revision: https://phabricator.services.mozilla.com/D16684
devtools/client/framework/browser-menus.js
devtools/client/framework/devtools-browser.js
--- a/devtools/client/framework/browser-menus.js
+++ b/devtools/client/framework/browser-menus.js
@@ -294,8 +294,52 @@ exports.addMenus = function(doc) {
  * @param {XULDocument} doc
  *        The document to which menus are to be removed.
  */
 exports.removeMenus = function(doc) {
   // We only remove top level entries. Per-tool entries are removed while
   // unregistering each tool.
   removeTopLevelItems(doc);
 };
+
+/**
+ * This is used for about:devtools-toolbox and that we are hiding the main toolbox toggle
+ * menu item, as well as all the tool items displayed on the menu. But we keep the
+ * non-toolbox menu items such as Scratchpad, Browser Console etc.
+ *
+ * @param {XULDocument} doc
+ * @param {boolean} isEnabled
+ */
+function setDevtoolsMenuItemsEnabled(doc, isEnabled) {
+  setMenuItemEnabled(doc, "menu_devToolbox", isEnabled);
+
+  for (const toolDefinition of gDevTools.getToolDefinitionArray()) {
+    if (!toolDefinition.inMenu) {
+      continue;
+    }
+    setMenuItemEnabled(doc, "menuitem_" + toolDefinition.id, isEnabled);
+  }
+}
+
+function setMenuItemEnabled(doc, menuItemId, isEnabled) {
+  const menuItem = doc.getElementById(menuItemId);
+  if (menuItem) {
+    menuItem.setAttribute("hidden", !isEnabled);
+  }
+}
+
+/**
+ * Enable all devtools menu items.
+ *
+ * @param {XULDocument} doc
+ */
+exports.enableDevtoolsMenuItems = function(doc) {
+  setDevtoolsMenuItemsEnabled(doc, true);
+};
+
+/**
+ * Disable all devtools menu items.
+ *
+ * @param {XULDocument} doc
+ */
+exports.disableDevtoolsMenuItems = function(doc) {
+  setDevtoolsMenuItemsEnabled(doc, false);
+};
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -237,16 +237,26 @@ var gDevToolsBrowser = exports.gDevTools
    *         - `toolId` used to identify a toolbox's panel like inspector or webconsole,
    *         - `id` used to identify any other key shortcuts like scratchpad or
    *         about:debugging
    * @param {Number} startTime
    *        Optional, indicates the time at which the key event fired. This is a
    *        `Cu.now()` timing.
    */
   async onKeyShortcut(window, key, startTime) {
+    // Avoid to open devtools when the about:devtools-toolbox page is showing
+    // on the window now.
+    if (gDevToolsBrowser._isAboutDevtoolsToolbox(window) &&
+        (key.toolId ||
+         key.id === "toggleToolbox" ||
+         key.id === "toggleToolboxF12" ||
+         key.id === "inspectorMac")) {
+      return;
+    }
+
     // If this is a toolbox's panel key shortcut, delegate to selectToolCommand
     if (key.toolId) {
       await gDevToolsBrowser.selectToolCommand(window.gBrowser, key.toolId, startTime);
       return;
     }
     // Otherwise implement all other key shortcuts individually here
     switch (key.id) {
       case "toggleToolbox":
@@ -584,16 +594,20 @@ var gDevToolsBrowser = exports.gDevTools
       if (def === toolDefinition) {
         break;
       }
       prevDef = def;
     }
 
     for (const win of gDevToolsBrowser._trackedBrowserWindows) {
       BrowserMenus.insertToolMenuElements(win.document, toolDefinition, prevDef);
+      // If we are on a page where devtools menu items are hidden such as
+      // about:devtools-toolbox, we need to call _updateMenuItems to update the
+      // visibility of the newly created menu item.
+      gDevToolsBrowser._updateMenuItems(win);
     }
 
     if (toolDefinition.id === "jsdebugger") {
       gDevToolsBrowser.setSlowScriptDebugHandler();
     }
   },
 
   hasToolboxOpened(win) {
@@ -602,33 +616,61 @@ var gDevToolsBrowser = exports.gDevTools
       if (target.tab == tab) {
         return true;
       }
     }
     return false;
   },
 
   /**
-   * Update the "Toggle Tools" checkbox in the developer tools menu. This is
+   * Update developer tools menu items and the "Toggle Tools" checkbox. This is
    * called when a toolbox is created or destroyed.
    */
-  _updateMenuCheckbox() {
+  _updateMenu() {
     for (const win of gDevToolsBrowser._trackedBrowserWindows) {
-      const hasToolbox = gDevToolsBrowser.hasToolboxOpened(win);
+      gDevToolsBrowser._updateMenuItems(win);
+    }
+  },
+
+  /**
+   * Update developer tools menu items and the "Toggle Tools" checkbox of XULWindow.
+   *
+   * @param {XULWindow} win
+   */
+  _updateMenuItems(win) {
+    if (gDevToolsBrowser._isAboutDevtoolsToolbox(win)) {
+      BrowserMenus.disableDevtoolsMenuItems(win.document);
+      return;
+    }
+
+    BrowserMenus.enableDevtoolsMenuItems(win.document);
 
-      const menu = win.document.getElementById("menu_devToolbox");
-      if (hasToolbox) {
-        menu.setAttribute("checked", "true");
-      } else {
-        menu.removeAttribute("checked");
-      }
+    const hasToolbox = gDevToolsBrowser.hasToolboxOpened(win);
+
+    const menu = win.document.getElementById("menu_devToolbox");
+    if (hasToolbox) {
+      menu.setAttribute("checked", "true");
+    } else {
+      menu.removeAttribute("checked");
     }
   },
 
   /**
+   * Check whether the window is showing about:devtools-toolbox page or not.
+   *
+   * @param {XULWindow} win
+   * @return {boolean} true: about:devtools-toolbox is showing
+   *                   false: otherwise
+   */
+  _isAboutDevtoolsToolbox(win) {
+    const currentURI = win.gBrowser.currentURI;
+    return currentURI.scheme === "about" && currentURI.filePath === "devtools-toolbox";
+  },
+
+  /**
    * Remove the menuitem for a tool to all open browser windows.
    *
    * @param {string} toolId
    *        id of the tool to remove
    */
   _removeToolFromWindows(toolId) {
     for (const win of gDevToolsBrowser._trackedBrowserWindows) {
       BrowserMenus.removeToolFromMenu(toolId, win.document);
@@ -670,17 +712,17 @@ var gDevToolsBrowser = exports.gDevTools
 
     const tabContainer = win.gBrowser.tabContainer;
     tabContainer.removeEventListener("TabSelect", this);
   },
 
   handleEvent(event) {
     switch (event.type) {
       case "TabSelect":
-        gDevToolsBrowser._updateMenuCheckbox();
+        gDevToolsBrowser._updateMenu();
         break;
       case "unload":
         // top-level browser window unload
         gDevToolsBrowser._forgetBrowserWindow(event.target.defaultView);
         break;
     }
   },
 
@@ -722,18 +764,18 @@ gDevTools.on("tool-registered", function
     gDevToolsBrowser._addToolToWindows(toolDefinition);
   }
 });
 
 gDevTools.on("tool-unregistered", function(toolId) {
   gDevToolsBrowser._removeToolFromWindows(toolId);
 });
 
-gDevTools.on("toolbox-ready", gDevToolsBrowser._updateMenuCheckbox);
-gDevTools.on("toolbox-destroyed", gDevToolsBrowser._updateMenuCheckbox);
+gDevTools.on("toolbox-ready", gDevToolsBrowser._updateMenu);
+gDevTools.on("toolbox-destroyed", gDevToolsBrowser._updateMenu);
 
 Services.obs.addObserver(gDevToolsBrowser, "quit-application");
 Services.obs.addObserver(gDevToolsBrowser, "browser-delayed-startup-finished");
 // Watch for module loader unload. Fires when the tools are reloaded.
 Services.obs.addObserver(gDevToolsBrowser, "devtools:loader:destroy");
 
 // Fake end of browser window load event for all already opened windows
 // that is already fully loaded.