Bug 1495944: Enable/Disable devtools menu items and the shortcut key. r=jdescottes
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Fri, 18 Jan 2019 16:20:43 +0000
changeset 511582 a93d114f9bc94b1681c08a4a496a25451b540d82
parent 511581 39e888455f3f21ef4d34b1cf32f4e1e4c78ab929
child 511583 4674df9d14e3126a0ab6644e29b666823426bb9c
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,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.