Bug 1359855 - Fix the developer toggle in customize widgets. r=jdescottes draft
authorAlexandre Poirot <poirot.alex@gmail.com>
Thu, 13 Jul 2017 15:43:50 +0200
changeset 614026 d93261c33d30cdd94bd59d9de0fed26956c7d1a8
parent 614025 f7c0bd61413c249b247a4556acef52f203b68857
child 614027 d0b3ba39a442b7ce15af35ecb40730a8a25efd33
push id69893
push userbmo:poirot.alex@gmail.com
push dateSun, 23 Jul 2017 20:50:47 +0000
reviewersjdescottes
bugs1359855
milestone56.0a1
Bug 1359855 - Fix the developer toggle in customize widgets. r=jdescottes Now that devtools-browser is lazily evaluated, we have to create the widget early in devtools-startup. MozReview-Commit-ID: JanbAPalYE1
devtools/client/devtools-startup.js
devtools/client/framework/devtools-browser.js
--- a/devtools/client/devtools-startup.js
+++ b/devtools/client/devtools-startup.js
@@ -26,16 +26,20 @@ const kDebuggerPrefs = [
   "devtools.debugger.remote-enabled",
   "devtools.chrome.enabled"
 ];
 const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
                                   "resource://gre/modules/AppConstants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
+                                  "resource:///modules/CustomizableUI.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "CustomizableWidgets",
+                                  "resource:///modules/CustomizableWidgets.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "Bundle", function () {
   const kUrl = "chrome://devtools/locale/key-shortcuts.properties";
   return Services.strings.createBundle(kUrl);
 });
 
 XPCOMUtils.defineLazyGetter(this, "KeyShortcuts", function () {
   const isMac = AppConstants.platform == "macosx";
@@ -203,19 +207,96 @@ DevToolsStartup.prototype = {
     this.hookKeyShortcuts(window);
 
     // All the other hooks are only necessary if the tools aren't loaded yet.
     if (this.initialized) {
       return;
     }
 
     this.hookWebDeveloperMenu(window);
+    this.hookDeveloperToggle(window);
   },
 
   /**
+   * Dynamically register a wrench icon in the customization menu.
+   * You can use this button by right clicking on Firefox toolbar
+   * and dragging it from the customization panel to the toolbar.
+   * (i.e. this isn't displayed by default to users!)
+   *
+   * _But_, the "Web Developer" entry in the hamburger menu (the menu with
+   * 3 horizontal lines), is using this "developer-button" view to populate
+   * its menu. So we have to register this button for the menu to work.
+   *
+   * Also, this menu duplicates its own entries from the "Web Developer"
+   * menu in the system menu, under "Tools" main menu item. The system
+   * menu is being hooked by "hookWebDeveloperMenu" which ends up calling
+   * devtools/client/framework/browser-menu to create the items for real,
+   * initDevTools, from onViewShowing is also calling browser-menu.
+   */
+  hookDeveloperToggle(window) {
+    let id = "developer-button";
+    let widget = CustomizableUI.getWidget(id);
+    if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
+      return;
+    }
+    let item = {
+      id: id,
+      type: "view",
+      viewId: "PanelUI-developer",
+      shortcutId: "key_toggleToolbox",
+      tooltiptext: "developer-button.tooltiptext2",
+      defaultArea: AppConstants.MOZ_DEV_EDITION ?
+                     CustomizableUI.AREA_NAVBAR :
+                     CustomizableUI.AREA_PANEL,
+      onViewShowing: (event) => {
+        // Ensure creating the menuitems in the system menu before trying to copy them.
+        this.initDevTools();
+
+        // Populate the subview with whatever menuitems are in the developer
+        // menu. We skip menu elements, because the menu panel has no way
+        // of dealing with those right now.
+        let doc = event.target.ownerDocument;
+
+        let menu = doc.getElementById("menuWebDeveloperPopup");
+
+        let itemsToDisplay = [...menu.children];
+        // Hardcode the addition of the "work offline" menuitem at the bottom:
+        itemsToDisplay.push({localName: "menuseparator", getAttribute: () => {}});
+        itemsToDisplay.push(doc.getElementById("goOfflineMenuitem"));
+
+        let developerItems = doc.getElementById("PanelUI-developerItems");
+        // Import private helpers from CustomizableWidgets
+        let { clearSubview, fillSubviewFromMenuItems } =
+          Cu.import("resource:///modules/CustomizableWidgets.jsm", {});
+        clearSubview(developerItems);
+        fillSubviewFromMenuItems(itemsToDisplay, developerItems);
+      },
+      onInit(anchor) {
+        // Since onBeforeCreated already bails out when initialized, we can call
+        // it right away.
+        this.onBeforeCreated(anchor.ownerDocument);
+      },
+      onBeforeCreated(doc) {
+        // Bug 1223127, CUI should make this easier to do.
+        if (doc.getElementById("PanelUI-developerItems")) {
+          return;
+        }
+        let view = doc.createElement("panelview");
+        view.id = "PanelUI-developerItems";
+        let panel = doc.createElement("vbox");
+        panel.setAttribute("class", "panel-subview-body");
+        view.appendChild(panel);
+        doc.getElementById("PanelUI-multiView").appendChild(view);
+      }
+    };
+    CustomizableUI.createWidget(item);
+    CustomizableWidgets.push(item);
+  },
+
+  /*
    * We listen to the "Web Developer" system menu, which is under "Tools" main item.
    * This menu item is hardcoded empty in Firefox UI. We listen for its opening to
    * populate it lazily. Loading main DevTools module is going to populate it.
    */
   hookWebDeveloperMenu(window) {
     let menu = window.document.getElementById("webDeveloperMenu");
     menu.addEventListener("popupshowing", () => this.initDevTools(), { once: true });
   },
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -7,17 +7,17 @@
 /**
  * This is the main module loaded in Firefox desktop that handles browser
  * windows and coordinates devtools around each window.
  *
  * This module is loaded lazily by devtools-clhandler.js, once the first
  * browser window is ready (i.e. fired browser-delayed-startup-finished event)
  **/
 
-const {Cc, Ci, Cu} = require("chrome");
+const {Cc, Ci} = require("chrome");
 const Services = require("Services");
 const defer = require("devtools/shared/defer");
 const {gDevTools} = require("./devtools");
 
 // Load target and toolbox lazily as they need gDevTools to be fully initialized
 loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
 loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
@@ -414,76 +414,16 @@ var gDevToolsBrowser = exports.gDevTools
           });
     } else {
       let msg = L10N.getStr("toolbox.noContentProcessForTab.message");
       Services.prompt.alert(null, "", msg);
     }
   },
 
   /**
-   * Install Developer widget
-   */
-  installDeveloperWidget() {
-    let id = "developer-button";
-    let widget = CustomizableUI.getWidget(id);
-    if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
-      return;
-    }
-    let item = {
-      id: id,
-      type: "view",
-      viewId: "PanelUI-developer",
-      shortcutId: "key_devToolboxMenuItem",
-      tooltiptext: "developer-button.tooltiptext2",
-      defaultArea: AppConstants.MOZ_DEV_EDITION ?
-                     CustomizableUI.AREA_NAVBAR :
-                     CustomizableUI.AREA_PANEL,
-      onViewShowing(event) {
-        // Populate the subview with whatever menuitems are in the developer
-        // menu. We skip menu elements, because the menu panel has no way
-        // of dealing with those right now.
-        let doc = event.target.ownerDocument;
-
-        let menu = doc.getElementById("menuWebDeveloperPopup");
-
-        let itemsToDisplay = [...menu.children];
-        // Hardcode the addition of the "work offline" menuitem at the bottom:
-        itemsToDisplay.push({localName: "menuseparator", getAttribute: () => {}});
-        itemsToDisplay.push(doc.getElementById("goOfflineMenuitem"));
-
-        let developerItems = doc.getElementById("PanelUI-developerItems");
-        // Import private helpers from CustomizableWidgets
-        let { clearSubview, fillSubviewFromMenuItems } =
-          Cu.import("resource:///modules/CustomizableWidgets.jsm", {});
-        clearSubview(developerItems);
-        fillSubviewFromMenuItems(itemsToDisplay, developerItems);
-      },
-      onInit(anchor) {
-        // Since onBeforeCreated already bails out when initialized, we can call
-        // it right away.
-        this.onBeforeCreated(anchor.ownerDocument);
-      },
-      onBeforeCreated(doc) {
-        // Bug 1223127, CUI should make this easier to do.
-        if (doc.getElementById("PanelUI-developerItems")) {
-          return;
-        }
-        let view = doc.createElement("panelview");
-        view.id = "PanelUI-developerItems";
-        let panel = doc.createElement("vbox");
-        panel.setAttribute("class", "panel-subview-body");
-        view.appendChild(panel);
-        doc.getElementById("PanelUI-multiView").appendChild(view);
-      }
-    };
-    CustomizableUI.createWidget(item);
-    CustomizableWidgets.push(item);
-  },
-
-  /**
    * Install WebIDE widget
    */
   // Used by itself
   installWebIDEWidget() {
     if (this.isWebIDEWidgetInstalled()) {
       return;
     }
 
@@ -546,20 +486,16 @@ var gDevToolsBrowser = exports.gDevTools
   _registerBrowserWindow(win) {
     if (gDevToolsBrowser._trackedBrowserWindows.has(win)) {
       return;
     }
     gDevToolsBrowser._trackedBrowserWindows.add(win);
 
     BrowserMenus.addMenus(win.document);
 
-    // Register the Developer widget in the Hamburger menu or navbar
-    // only once menus are registered as it depends on it.
-    gDevToolsBrowser.installDeveloperWidget();
-
     this.updateCommandAvailability(win);
     this.updateDevtoolsThemeAttribute(win);
     this.ensurePrefObserver();
     win.addEventListener("unload", this);
 
     let tabContainer = win.gBrowser.tabContainer;
     tabContainer.addEventListener("TabSelect", this);
     tabContainer.addEventListener("TabOpen", this);