Bug 633575 - Preference/tools panels are broken if opened during initial page load [r=mfinkle]
authorMatt Brubeck <mbrubeck@mozilla.com>
Thu, 17 Feb 2011 13:25:59 -0800
changeset 67402 09e4d10b735c588f6a465f8077ee970dab71e2b8
parent 67401 80287a75ad45af4a4a36f03c33387c7d114e1e72
child 67403 e59dbbdb208b6c8f4f6f02b9713ea2a26e9dc8e8
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs633575
Bug 633575 - Preference/tools panels are broken if opened during initial page load [r=mfinkle]
mobile/chrome/content/browser-ui.js
mobile/chrome/content/console.js
mobile/chrome/content/downloads.js
mobile/chrome/content/extensions.js
mobile/chrome/content/preferences.js
mobile/chrome/tests/browser_addons.js
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -495,20 +495,19 @@ var BrowserUI = {
       Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
       Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
 
       // Listen tabs event
       Elements.tabs.addEventListener("TabSelect", BrowserUI, true);
       Elements.tabs.addEventListener("TabOpen", BrowserUI, true);
       Elements.tabs.addEventListener("TabRemove", BrowserUI, true);
 
-      // Init the views
+      // Init the tool panel views
       ExtensionsView.init();
       DownloadsView.init();
-      PreferencesView.init();
       ConsoleView.init();
 
 #ifdef MOZ_IPC
       // Pre-start the content process
       Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
           .ensureContentProcess();
 #endif
 
@@ -530,16 +529,33 @@ var BrowserUI = {
 
 #ifdef MOZ_UPDATER
       // Check for updates in progress
       let updatePrompt = Cc["@mozilla.org/updates/update-prompt;1"].createInstance(Ci.nsIUpdatePrompt);
       updatePrompt.checkForUpdates();
 #endif
     }, false);
 
+    let panels = document.getElementById("panel-items");
+    let panelViews = { // Use strings to avoid lazy-loading objects too soon.
+      "prefs-container": "PreferencesView",
+      "downloads-container": "DownloadsView",
+      "addons-container": "ExtensionsView",
+      "console-container": "ConsoleView"
+    };
+
+    // Some initialization can be delayed until a panel is selected.
+    panels.addEventListener("select", function(aEvent) {
+      if (aEvent.target != panels)
+        return;
+      let viewName = panelViews[panels.selectedPanel.id];
+      if (viewName)
+        window[viewName].delayedInit();
+    }, true);
+
 #ifndef MOZ_OFFICIAL_BRANDING
       setTimeout(function() {
         let startup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup_MOZILLA_2_0).getStartupInfo();
         for (let name in startup) {
           if (name != "process")
             Services.console.logStringMessage("[timing] " + name + ": " + (startup[name] - startup.process) + "ms");
         }
       }, 3000);
--- a/mobile/chrome/content/console.js
+++ b/mobile/chrome/content/console.js
@@ -51,56 +51,47 @@ let ConsoleView = {
 
     this._list = document.getElementById("console-box");
     this._evalTextbox = document.getElementById("console-eval-textbox");
     this._bundle = Strings.browser;
 
     this._count = 0;
     this.limit = 250;
 
-    let self = this;
-    let panels = document.getElementById("panel-items");
-
-    panels.addEventListener("select",
-                            function(aEvent) {
-                              if (panels.selectedPanel.id == "console-container")
-                                self._delayedInit();
-                            },
-                            false);
-
     try {
       // update users using the legacy pref
       if (Services.prefs.getBoolPref("browser.console.showInPanel")) {
         Services.prefs.setBoolPref(this._enabledPref, true);
         Services.prefs.clearUserPref("browser.console.showInPanel");
       }
     } catch(ex) {
       // likely don't have an old pref
     }
     this.updateVisibility();
     Services.prefs.addObserver(this._enabledPref, this, false);
   },
 
-  _delayedInit: function cv__delayedInit() {
+  delayedInit: function cv__delayedInit() {
     if (this._inited)
       return;
     this._inited = true;
 
+    this.init(); // In case the panel is selected before init has been called.
+
     Services.console.registerListener(this);
 
     this.appendInitialItems();
 
     // Delay creation of the iframe for startup performance
     this._evalFrame = document.createElement("iframe");
     this._evalFrame.id = "console-evaluator";
     this._evalFrame.collapsed = true;
     document.getElementById("console-container").appendChild(this._evalFrame);
 
-    let self = this;
-    this._evalFrame.addEventListener("load", function() { self.loadOrDisplayResult(); }, true);
+    this._evalFrame.addEventListener("load", this.loadOrDisplayResult.bind(this), true);
   },
 
   uninit: function cv_uninit() {
     if (this._inited)
       Services.console.unregisterListener(this);
 
     Services.prefs.removeObserver(this._enabledPref, this, false);
   },
--- a/mobile/chrome/content/downloads.js
+++ b/mobile/chrome/content/downloads.js
@@ -141,31 +141,24 @@ var DownloadsView = {
     os.addObserver(this, "dl-failed", true);
     os.addObserver(this, "dl-done", true);
     os.addObserver(this, "dl-blocked", true);
     os.addObserver(this, "dl-dirty", true);
     os.addObserver(this, "dl-cancel", true);
 
     // Monitor downloads being removed by the download manager (non-UI)
     os.addObserver(this, "download-manager-remove-download", true);
-
-    let self = this;
-    let panels = document.getElementById("panel-items");
-    panels.addEventListener("select",
-                            function(aEvent) {
-                              if (panels.selectedPanel.id == "downloads-container")
-                                self._delayedInit();
-                            },
-                            false);
   },
 
-  _delayedInit: function dv__delayedInit() {
+  delayedInit: function dv__delayedInit() {
     if (this._list)
       return;
 
+    this.init(); // In case the panel is selected before init has been called.
+
     this._list = document.getElementById("downloads-list");
 
     if (this._dlmgr == null)
       this._dlmgr = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
 
     this._progress = new DownloadProgressListener();
     this._dlmgr.addListener(this._progress);
 
--- a/mobile/chrome/content/extensions.js
+++ b/mobile/chrome/content/extensions.js
@@ -220,38 +220,31 @@ var ExtensionsView = {
     // Watch for add-on update notifications
     let os = Services.obs;
     os.addObserver(this, "addon-update-started", false);
     os.addObserver(this, "addon-update-ended", false);
 
     if (!Services.prefs.getBoolPref("extensions.hideUpdateButton"))
       document.getElementById("addons-update-all").hidden = false;
 
-    let self = this;
-    let panels = document.getElementById("panel-items");
-    panels.addEventListener("select",
-                            function(aEvent) {
-                              if (panels.selectedPanel.id == "addons-container")
-                                self._delayedInit();
-                            },
-                            false);
-
 #ifdef ANDROID
     // Hide the notification
     let alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
     let progressListener = alertsService.QueryInterface(Ci.nsIAlertsProgressListener);
     if (progressListener)
       progressListener.onCancel(ADDONS_NOTIFICATION_NAME);
 #endif
   },
 
-  _delayedInit: function ev__delayedInit() {
+  delayedInit: function ev__delayedInit() {
     if (this._list)
       return;
 
+    this.init(); // In case the panel is selected before init has been called.
+
     this._list = document.getElementById("addons-list");
     this._localItem = document.getElementById("addons-local");
     this._repoItem = document.getElementById("addons-repo");
     this._msg = document.getElementById("addons-messages");
 
     // Show the restart notification in case a restart is needed, but the view
     // was not visible at the time
     let notification = this._msg.getNotificationWithValue("restart-app");
--- a/mobile/chrome/content/preferences.js
+++ b/mobile/chrome/content/preferences.js
@@ -92,38 +92,21 @@ var PreferencesView = {
     this._restartCount--;
     if (this._restartCount == 0 && this._msg) {
       let notification = this._msg.getNotificationWithValue("restart-app");
       if (notification)
         notification.close();
     }
   },
 
-  init: function ev_init() {
-    if (this._msg)
+  delayedInit: function pv__delayedInit() {
+    if (this._languages)
       return;
 
     this._msg = document.getElementById("prefs-messages");
-
-    let self = this;
-    let panels = document.getElementById("panel-items");
-    panels.addEventListener("select",
-                            function(aEvent) {
-                              if (aEvent.target != panels)
-                                return;
-                              if (panels.selectedPanel.id == "prefs-container")
-                                self._delayedInit();
-                            },
-                            false);
-  },
-
-  _delayedInit: function pv__delayedInit() {
-    if (this._languages)
-      return;
-
     this._languages = document.getElementById("prefs-languages");
     this._loadLocales();
 
     this._loadHomePage();
   },
 
   _loadLocales: function _loadLocales() {
     // Query available and selected locales
--- a/mobile/chrome/tests/browser_addons.js
+++ b/mobile/chrome/tests/browser_addons.js
@@ -264,17 +264,17 @@ function checkUpdate(aSettings) {
 function get_addon_element(aId) {
   return document.getElementById("urn:mozilla:item:" + aId);
 }
 
 function open_manager(aView, aCallback) {
   BrowserUI.showPanel("addons-container");
 
   ExtensionsView.init();
-  ExtensionsView._delayedInit();
+  ExtensionsView.delayedInit();
 
   window.addEventListener("ViewChanged", function() {
     window.removeEventListener("ViewChanged", arguments.callee, true);
      aCallback();
   }, true);
 }
 
 function close_manager(aCallback) {