Bug 1495944: Enable/Disable devtools menu items and the shortcut key. r=jdescottes
☠☠ backed out by f93fc53741db ☠ ☠
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Fri, 18 Jan 2019 10:26:53 +0000
changeset 514412 9418ac4c2fa1a57fb1d7ffe005381c16ce8f4de8
parent 514411 69d19e1214f7a30cb342cadd03584098a80db52f
child 514413 be64b571b600b15ab290ab162b66318048b5b3df
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [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,56 @@ 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) {
+    if (isEnabled) {
+      menuItem.removeAttribute("hidden");
+    } else {
+      menuItem.setAttribute("hidden", true);
+    }
+  }
+}
+
+/**
+ * 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.