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 347687 1300b2a51f1d65579b4875f33f0075538e1391b6
parent 347686 7e34593bd9edad80833782f1c94e0f40fdb3ff4b
child 347688 4b00370192a495bf15b4110a2dd6c8fd8084e0c9
push id14647
push userbmo:ahunt@mozilla.com
push dateTue, 05 Apr 2016 18:15:38 +0000
reviewersjryans, jwalker
bugs1261092
milestone48.0a1
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);
   },