Bug 1428191 - create developer toggle widget before first paint in DevEdition;r=ochameau draft
authorJulian Descottes <jdescottes@mozilla.com>
Fri, 05 Jan 2018 13:44:19 +0100
changeset 717551 d046029277b34da86457eac4c41ebd1d361dd2e5
parent 716014 3acb14b949150529ec761f845f9a3d61ee341dac
child 745300 715ebae608eee7e149b1218d97d71aa7b4ed247f
push id94726
push userjdescottes@mozilla.com
push dateTue, 09 Jan 2018 08:31:11 +0000
reviewersochameau
bugs1428191
milestone59.0a1
Bug 1428191 - create developer toggle widget before first paint in DevEdition;r=ochameau MozReview-Commit-ID: KEJNzXrDrEE
devtools/shim/devtools-startup.js
--- a/devtools/shim/devtools-startup.js
+++ b/devtools/shim/devtools-startup.js
@@ -205,16 +205,22 @@ DevToolsStartup.prototype = {
       let hasDevToolsFlag = consoleFlag || devtoolsFlag || debuggerFlag;
       this.setupEnabledPref(hasDevToolsFlag);
 
       // Store devtoolsFlag to check it later in onWindowReady.
       this.devtoolsFlag = devtoolsFlag;
       // Only top level Firefox Windows fire a browser-delayed-startup-finished event
       Services.obs.addObserver(this.onWindowReady, "browser-delayed-startup-finished");
 
+      if (AppConstants.MOZ_DEV_EDITION) {
+        // On DevEdition, the developer toggle is displayed by default in the navbar area
+        // and should be created before the first paint.
+        this.hookDeveloperToggle();
+      }
+
       // Update menu items when devtools.enabled changes.
       Services.prefs.addObserver(DEVTOOLS_ENABLED_PREF, this.onEnabledPrefChanged);
     }
 
     if (consoleFlag) {
       this.handleConsoleFlag(cmdLine);
     }
     if (debuggerFlag) {
@@ -292,20 +298,17 @@ DevToolsStartup.prototype = {
    */
   hookWindow(window) {
     // Key Shortcuts need to be added on all the created windows.
     this.hookKeyShortcuts(window);
 
     // In some situations (e.g. starting Firefox with --jsconsole) DevTools will be
     // initialized before the first browser-delayed-startup-finished event is received.
     // We use a dedicated flag because we still need to hook the developer toggle.
-    if (!this.developerToggleCreated) {
-      this.hookDeveloperToggle();
-      this.developerToggleCreated = true;
-    }
+    this.hookDeveloperToggle();
 
     // The developer menu hook only needs to be added if devtools have not been
     // initialized yet.
     if (!this.initialized) {
       this.hookWebDeveloperMenu(window);
     }
 
     this.createDevToolsEnableMenuItem(window);
@@ -324,16 +327,20 @@ DevToolsStartup.prototype = {
    *
    * 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() {
+    if (this.developerToggleCreated) {
+      return;
+    }
+
     let id = "developer-button";
     let widget = CustomizableUI.getWidget(id);
     if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
       return;
     }
     let item = {
       id: id,
       type: "view",
@@ -366,34 +373,38 @@ DevToolsStartup.prototype = {
         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) {
+      onBeforeCreated: (doc) => {
+        // The developer toggle needs the "key_toggleToolbox" <key> element.
+        // In DEV EDITION, the toggle is added before 1st paint and hookKeyShortcuts() is
+        // not called yet when CustomizableUI creates the widget.
+        this.hookKeyShortcuts(doc.defaultView);
+
         // 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);
       }
     };
-    if (AppConstants.MOZ_DEV_EDITION) {
-      item.defaultArea = CustomizableUI.AREA_NAVBAR;
-    }
     CustomizableUI.createWidget(item);
     CustomizableWidgets.push(item);
+
+    this.developerToggleCreated = true;
   },
 
   /*
    * 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) {
@@ -503,16 +514,23 @@ DevToolsStartup.prototype = {
     let hasToolbarPref = Services.prefs.getBoolPref(TOOLBAR_VISIBLE_PREF, false);
     if (hasDevToolsFlag || hasToolbarPref || isDevToolsUser) {
       Services.prefs.setBoolPref(DEVTOOLS_ENABLED_PREF, true);
     }
   },
 
   hookKeyShortcuts(window) {
     let doc = window.document;
+
+    // hookKeyShortcuts can be called both from hookWindow and from the developer toggle
+    // onBeforeCreated. Make sure shortcuts are only added once per window.
+    if (doc.getElementById("devtoolsKeyset")) {
+      return;
+    }
+
     let keyset = doc.createElement("keyset");
     keyset.setAttribute("id", "devtoolsKeyset");
 
     for (let key of KeyShortcuts) {
       let xulKey = this.createKey(doc, key, () => this.onKey(window, key));
       keyset.appendChild(xulKey);
     }