Bug 859154 - add a pageshow promise to addTab. r=sfoster
authorJim Mathies <jmathies@mozilla.com>
Fri, 19 Apr 2013 05:25:36 -0500
changeset 129316 2ecc1c0eef3d57eee759862da81d95784df3a783
parent 129315 dc2ced1dd1754377584eb227ad038c5675304991
child 129317 aafed56a6c2e7195b0f7fb22505e98d6d84c30cf
push idunknown
push userunknown
push dateunknown
reviewerssfoster
bugs859154
milestone23.0a1
Bug 859154 - add a pageshow promise to addTab. r=sfoster
browser/metro/base/content/browser.js
--- a/browser/metro/base/content/browser.js
+++ b/browser/metro/base/content/browser.js
@@ -437,22 +437,17 @@ var Browser = {
     let params = aParams || {};
     let newTab = new Tab(aURI, params);
     newTab.owner = aOwner || null;
     this._tabs.push(newTab);
 
     if (aBringFront)
       this.selectedTab = newTab;
 
-    let getAttention = ("getAttention" in params ? params.getAttention : !aBringFront);
-    let event = document.createEvent("UIEvents");
-    event.initUIEvent("TabOpen", true, false, window, getAttention);
-    newTab.chromeTab.dispatchEvent(event);
-    newTab.browser.messageManager.sendAsyncMessage("Browser:TabOpen");
-
+    this._announceNewTab(newTab, params, aBringFront);
     return newTab;
   },
 
   closeTab: function closeTab(aTab, aOptions) {
     let tab = aTab instanceof XULElement ? this.getTabFromChrome(aTab) : aTab;
     if (!tab) {
       return;
     }
@@ -464,16 +459,28 @@ var Browser = {
 
     tab.browser.messageManager.sendAsyncMessage("Browser:CanUnload", {});
   },
 
   savePage: function() {
     ContentAreaUtils.saveDocument(this.selectedBrowser.contentWindow.document);
   },
 
+  /*
+   * helper for addTab related methods. Fires events related to
+   * new tab creation.
+   */
+  _announceNewTab: function _announceNewTab(aTab, aParams, aBringFront) {
+    let getAttention = ("getAttention" in aParams ? aParams.getAttention : !aBringFront);
+    let event = document.createEvent("UIEvents");
+    event.initUIEvent("TabOpen", true, false, window, getAttention);
+    aTab.chromeTab.dispatchEvent(event);
+    aTab.browser.messageManager.sendAsyncMessage("Browser:TabOpen");
+  },
+
   _doCloseTab: function _doCloseTab(aTab) {
     if (this._tabs.length === 1) {
       Browser.addTab(this.getHomePage());
     }
 
     let nextTab = this.getNextTab(aTab);
 
     // Tabs owned by the closed tab are now orphaned.
@@ -1394,16 +1401,17 @@ function showDownloadManager(aWindowCont
 
 function Tab(aURI, aParams) {
   this._id = null;
   this._browser = null;
   this._notification = null;
   this._loading = false;
   this._chromeTab = null;
   this._metadata = null;
+  this._eventDeferred = null;
 
   this.owner = null;
 
   this.hostChanged = false;
   this.state = null;
 
   // Set to 0 since new tabs that have not been viewed yet are good tabs to
   // toss if app needs more memory.
@@ -1429,16 +1437,20 @@ Tab.prototype = {
   get chromeTab() {
     return this._chromeTab;
   },
 
   get metadata() {
     return this._metadata || kDefaultMetadata;
   },
 
+  get pageShowPromise() {
+    return this._eventDeferred ? this._eventDeferred.promise : null;
+  },
+
   /** Update browser styles when the viewport metadata changes. */
   updateViewportMetadata: function updateViewportMetadata(aMetadata) {
     if (aMetadata && aMetadata.autoScale) {
       let scaleRatio = aMetadata.scaleRatio = Browser.getScaleRatio();
 
       if ("defaultZoom" in aMetadata && aMetadata.defaultZoom > 0)
         aMetadata.defaultZoom *= scaleRatio;
       if ("minZoom" in aMetadata && aMetadata.minZoom > 0)
@@ -1527,33 +1539,33 @@ Tab.prototype = {
     this.updateFavicon();
   },
 
   isLoading: function isLoading() {
     return this._loading;
   },
 
   create: function create(aURI, aParams) {
+    this._eventDeferred = Promise.defer();
+
     this._chromeTab = Elements.tabList.addTab();
     this._id = Browser.createTabId();
     let browser = this._createBrowser(aURI, null);
 
-    // Should we fully load the new browser, or wait until later
-    if ("delayLoad" in aParams && aParams.delayLoad)
-      return;
+    let self = this;
+    function onPageShowEvent(aEvent) {
+      browser.removeEventListener("pageshow", onPageShowEvent);
+      if (self._eventDeferred) {
+        self._eventDeferred.resolve(self);
+      }
+      self._eventDeferred = null;
+    }
+    browser.addEventListener("pageshow", onPageShowEvent, true);
 
-    try {
-      let flags = aParams.flags || Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
-      let postData = ("postData" in aParams && aParams.postData) ? aParams.postData.value : null;
-      let referrerURI = "referrerURI" in aParams ? aParams.referrerURI : null;
-      let charset = "charset" in aParams ? aParams.charset : null;
-      browser.loadURIWithFlags(aURI, flags, referrerURI, charset, postData);
-    } catch(e) {
-      dump("Error: " + e + "\n");
-    }
+    this._loadUsingParams(browser, aURI, aParams);
   },
 
   destroy: function destroy() {
     Elements.tabList.removeTab(this._chromeTab);
     this._chromeTab = null;
     this._destroyBrowser();
   },
 
@@ -1576,16 +1588,24 @@ Tab.prototype = {
       this.active = true;
 
     // Reattach session store data and flag this browser so it is restored on select
     browser.__SS_data = session.data;
     browser.__SS_extdata = session.extra;
     browser.__SS_restore = true;
   },
 
+  _loadUsingParams: function _loadUsingParams(aBrowser, aURI, aParams) {
+    let flags = aParams.flags || Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
+    let postData = ("postData" in aParams && aParams.postData) ? aParams.postData.value : null;
+    let referrerURI = "referrerURI" in aParams ? aParams.referrerURI : null;
+    let charset = "charset" in aParams ? aParams.charset : null;
+    aBrowser.loadURIWithFlags(aURI, flags, referrerURI, charset, postData);
+  },
+
   _createBrowser: function _createBrowser(aURI, aInsertBefore) {
     if (this._browser)
       throw "Browser already exists";
 
     // Create a notification box around the browser. Note this includes
     // the input overlay we use to shade content from input events when
     // we're intercepting touch input.
     let notification = this._notification = document.createElement("notificationbox");