Bug 1261092 - Simplify gcli initialization/destruction codepaths. r=jryans,jwalker
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 05 Apr 2016 07:16:48 -0700
changeset 291787 1300b2a51f1d65579b4875f33f0075538e1391b6
parent 291786 7e34593bd9edad80833782f1c94e0f40fdb3ff4b
child 291788 4b00370192a495bf15b4110a2dd6c8fd8084e0c9
push id74679
push userkwierso@gmail.com
push dateTue, 05 Apr 2016 23:39:26 +0000
treeherdermozilla-inbound@b70ae970d45d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjryans, jwalker
bugs1261092
milestone48.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 1261092 - Simplify gcli initialization/destruction codepaths. r=jryans,jwalker
browser/base/content/browser.js
devtools/bootstrap.js
devtools/client/framework/devtools-browser.js
devtools/client/shared/developer-toolbar.js
devtools/shared/Loader.jsm
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -152,22 +152,16 @@ XPCOMUtils.defineLazyGetter(this, "Popup
                                       document.getElementById("notification-popup"),
                                       document.getElementById("notification-popup-box"));
   } catch (ex) {
     Cu.reportError(ex);
     return null;
   }
 });
 
-XPCOMUtils.defineLazyGetter(this, "DeveloperToolbar", function() {
-  let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
-  let { DeveloperToolbar } = require("devtools/client/shared/developer-toolbar");
-  return new DeveloperToolbar(window);
-});
-
 XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function() {
   let tmp = {};
   Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", tmp);
   return tmp.BrowserToolboxProcess;
 });
 
 XPCOMUtils.defineLazyModuleGetter(this, "Social",
   "resource:///modules/Social.jsm");
@@ -1395,21 +1389,16 @@ var gBrowserInit = {
 
   onUnload: function() {
     // In certain scenarios it's possible for unload to be fired before onload,
     // (e.g. if the window is being closed after browser.js loads but before the
     // load completes). In that case, there's nothing to do here.
     if (!this._loadHandled)
       return;
 
-    let desc = Object.getOwnPropertyDescriptor(window, "DeveloperToolbar");
-    if (desc && !desc.get) {
-      DeveloperToolbar.destroy();
-    }
-
     // First clean up services initialized in gBrowserInit.onLoad (or those whose
     // uninit methods don't depend on the services having been initialized).
 
     CombinedStopReload.uninit();
 
     gGestureSupport.init(false);
 
     gHistorySwipeAnimation.uninit();
--- a/devtools/bootstrap.js
+++ b/devtools/bootstrap.js
@@ -107,34 +107,16 @@ function reload(event) {
         // We have to use a frame script to query "baseURI"
         mm.loadFrameScript("data:text/javascript,new " + function () {
           let isJSONView = content.document.baseURI.startsWith("resource://devtools/");
           if (isJSONView) {
             content.location.reload();
           }
         }, false);
       }
-
-      // Manually reload gcli if it has been used
-      // Bug 1248348: Inject the developer toolbar dynamically within browser/
-      // so that we can easily remove/reinject it
-      const desc = Object.getOwnPropertyDescriptor(window, "DeveloperToolbar");
-      if (desc && !desc.get) {
-        let wasVisible = window.DeveloperToolbar.visible;
-        window.DeveloperToolbar.hide()
-          .then(() => {
-            window.DeveloperToolbar.destroy();
-
-            let { DeveloperToolbar } = devtools.require("devtools/client/shared/developer-toolbar");
-            window.DeveloperToolbar = new DeveloperToolbar(window, window.document.getElementById("developer-toolbar"));
-            if (wasVisible) {
-              window.DeveloperToolbar.show();
-            }
-          });
-      }
     } else if (windowtype === "devtools:webide") {
       window.location.reload();
     } else if (windowtype === "devtools:webconsole") {
       // Browser console document can't just be reloaded.
       // HUDService is going to close it on unload.
       // Instead we have to manually toggle it.
       let HUDService = devtools.require("devtools/client/webconsole/hudservice");
       HUDService.toggleBrowserConsole()
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -347,16 +347,23 @@ var gDevToolsBrowser = exports.gDevTools
    */
   _registerBrowserWindow: function(win) {
     if (gDevToolsBrowser._trackedBrowserWindows.has(win)) {
       return;
     }
     gDevToolsBrowser._trackedBrowserWindows.add(win);
 
     BrowserMenus.addMenus(win.document);
+
+    // Inject lazily DeveloperToolbar on the chrome window
+    loader.lazyGetter(win, "DeveloperToolbar", function() {
+      let { DeveloperToolbar } = require("devtools/client/shared/developer-toolbar");
+      return new DeveloperToolbar(win);
+    });
+
     this.updateCommandAvailability(win);
     this.ensurePrefObserver();
     win.addEventListener("unload", this);
 
     let tabContainer = win.gBrowser.tabContainer;
     tabContainer.addEventListener("TabSelect", this, false);
     tabContainer.addEventListener("TabOpen", this, false);
     tabContainer.addEventListener("TabClose", this, false);
@@ -546,28 +553,37 @@ var gDevToolsBrowser = exports.gDevTools
   /**
    * Called on browser unload to remove menu entries, toolboxes and event
    * listeners from the closed browser window.
    *
    * @param  {XULWindow} win
    *         The window containing the menu entry
    */
   _forgetBrowserWindow: function(win) {
+    if (!gDevToolsBrowser._trackedBrowserWindows.has(win)) {
+      return;
+    }
     gDevToolsBrowser._trackedBrowserWindows.delete(win);
     win.removeEventListener("unload", this);
 
     BrowserMenus.removeMenus(win.document);
 
     // Destroy toolboxes for closed window
     for (let [target, toolbox] of gDevTools._toolboxes) {
       if (toolbox.frame && toolbox.frame.ownerDocument.defaultView == win) {
         toolbox.destroy();
       }
     }
 
+    // Destroy the Developer toolbar if it has been accessed
+    let desc = Object.getOwnPropertyDescriptor(win, "DeveloperToolbar");
+    if (desc && !desc.get) {
+      win.DeveloperToolbar.destroy();
+    }
+
     let tabContainer = win.gBrowser.tabContainer;
     tabContainer.removeEventListener("TabSelect", this, false);
     tabContainer.removeEventListener("TabOpen", this, false);
     tabContainer.removeEventListener("TabClose", this, false);
     tabContainer.removeEventListener("TabPinned", this, false);
     tabContainer.removeEventListener("TabUnpinned", this, false);
   },
 
--- a/devtools/client/shared/developer-toolbar.js
+++ b/devtools/client/shared/developer-toolbar.js
@@ -493,20 +493,16 @@ DeveloperToolbar.prototype.show = functi
 
           let tabbrowser = this._chromeWindow.gBrowser;
           tabbrowser.tabContainer.addEventListener("TabSelect", this, false);
           tabbrowser.tabContainer.addEventListener("TabClose", this, false);
           tabbrowser.addEventListener("load", this, true);
           tabbrowser.addEventListener("beforeunload", this, true);
 
           this._initErrorsCount(tabbrowser.selectedTab);
-          this._devtoolsUnloaded = this._devtoolsUnloaded.bind(this);
-          this._devtoolsLoaded = this._devtoolsLoaded.bind(this);
-          Services.obs.addObserver(this._devtoolsUnloaded, "devtools-unloaded", false);
-          Services.obs.addObserver(this._devtoolsLoaded, "devtools-loaded", false);
 
           this._element.hidden = false;
 
           if (focus) {
             // If the toolbar was just inserted, the <textbox> may still have
             // its binding in process of being applied and not be focusable yet
             let waitForBinding = () => {
               // Bail out if the toolbar has been destroyed in the meantime
@@ -567,34 +563,16 @@ DeveloperToolbar.prototype.hide = functi
 
     this._hidePromise = null;
   });
 
   return this._hidePromise;
 };
 
 /**
- * The devtools-unloaded event handler.
- * @private
- */
-DeveloperToolbar.prototype._devtoolsUnloaded = function() {
-  let tabbrowser = this._chromeWindow.gBrowser;
-  Array.prototype.forEach.call(tabbrowser.tabs, this._stopErrorsCount, this);
-};
-
-/**
- * The devtools-loaded event handler.
- * @private
- */
-DeveloperToolbar.prototype._devtoolsLoaded = function() {
-  let tabbrowser = this._chromeWindow.gBrowser;
-  this._initErrorsCount(tabbrowser.selectedTab);
-};
-
-/**
  * Initialize the listeners needed for tracking the number of errors for a given
  * tab.
  *
  * @private
  * @param nsIDOMNode tab the xul:tab for which you want to track the number of
  * errors.
  */
 DeveloperToolbar.prototype._initErrorsCount = function(tab) {
@@ -652,18 +630,16 @@ DeveloperToolbar.prototype.destroy = fun
   }
 
   let tabbrowser = this._chromeWindow.gBrowser;
   tabbrowser.tabContainer.removeEventListener("TabSelect", this, false);
   tabbrowser.tabContainer.removeEventListener("TabClose", this, false);
   tabbrowser.removeEventListener("load", this, true);
   tabbrowser.removeEventListener("beforeunload", this, true);
 
-  Services.obs.removeObserver(this._devtoolsUnloaded, "devtools-unloaded");
-  Services.obs.removeObserver(this._devtoolsLoaded, "devtools-loaded");
   Array.prototype.forEach.call(tabbrowser.tabs, this._stopErrorsCount, this);
 
   this.focusManager.removeMonitoredElement(this.outputPanel._frame);
   this.focusManager.removeMonitoredElement(this._element);
 
   this.focusManager.onVisibilityChange.remove(this.outputPanel._visibilityChanged,
                                               this.outputPanel);
   this.focusManager.onVisibilityChange.remove(this.tooltipPanel._visibilityChanged,
--- a/devtools/shared/Loader.jsm
+++ b/devtools/shared/Loader.jsm
@@ -262,18 +262,16 @@ DevToolsLoader.prototype = {
    * Override the provider used to load the tools.
    */
   setProvider: function(provider) {
     if (provider === this._provider) {
       return;
     }
 
     if (this._provider) {
-      var events = this.require("sdk/system/events");
-      events.emit("devtools-unloaded", {});
       delete this.require;
       this._provider.unload("newprovider");
     }
     this._provider = provider;
 
     // Pass through internal loader settings specific to this loader instance
     this._provider.invisibleToDebugger = this.invisibleToDebugger;
     // Changes here should be mirrored to devtools/.eslintrc.
@@ -325,17 +323,16 @@ DevToolsLoader.prototype = {
   },
 
   /**
    * Reload the current provider.
    */
   reload: function() {
     var events = this.require("sdk/system/events");
     events.emit("startupcache-invalidate", {});
-    events.emit("devtools-unloaded", {});
 
     this._provider.unload("reload");
     delete this._provider;
     let mainid = this._mainid;
     delete this._mainid;
     this._loadProvider();
     this.main(mainid);
   },