From 8a8147f5f4cbc62c577d3355a578e72ba161b972 Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Tue, 9 Jun 2015 22:10:50 +0200 Subject: [PATCH] Bug 1167508 - Use async flushing for LoadInOtherProcess() r=billm --- browser/base/content/browser.js | 20 +------ .../components/sessionstore/SessionStore.jsm | 58 +++++++++++++++---- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 0d5a88a86e0a..7e4ea85a1759 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -222,9 +222,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "SitePermissions", XPCOMUtils.defineLazyModuleGetter(this, "SessionStore", "resource:///modules/sessionstore/SessionStore.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "TabState", - "resource:///modules/sessionstore/TabState.jsm"); - XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", "resource://gre/modules/FxAccounts.jsm"); @@ -923,22 +920,7 @@ function _loadURIWithFlags(browser, uri, params) { // process function LoadInOtherProcess(browser, loadOptions, historyIndex = -1) { let tab = gBrowser.getTabForBrowser(browser); - // Flush the tab state before getting it - TabState.flush(browser); - let tabState = JSON.parse(SessionStore.getTabState(tab)); - - if (historyIndex < 0) { - tabState.userTypedValue = null; - // Tell session history the new page to load - SessionStore._restoreTabAndLoad(tab, JSON.stringify(tabState), loadOptions); - } - else { - // Update the history state to point to the requested index - tabState.index = historyIndex + 1; - // SessionStore takes care of setting the browser remoteness before restoring - // history into it. - SessionStore.setTabState(tab, JSON.stringify(tabState)); - } + SessionStore.navigateAndRestore(tab, loadOptions, historyIndex); } // Called when a docshell has attempted to load a page in an incorrect process. diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm index 3874614f31ec..fb2acedd3386 100644 --- a/browser/components/sessionstore/SessionStore.jsm +++ b/browser/components/sessionstore/SessionStore.jsm @@ -214,16 +214,6 @@ this.SessionStore = { SessionStoreInternal.setTabState(aTab, aState); }, - // This should not be used by external code, the intention is to remove it - // once a better fix is in place for process switching in e10s. - // See bug 1075658 for context. - _restoreTabAndLoad: function ss_restoreTabAndLoad(aTab, aState, aLoadArguments) { - SessionStoreInternal.setTabState(aTab, aState, { - restoreImmediately: true, - loadArguments: aLoadArguments - }); - }, - duplicateTab: function ss_duplicateTab(aWindow, aTab, aDelta = 0) { return SessionStoreInternal.duplicateTab(aWindow, aTab, aDelta); }, @@ -310,6 +300,10 @@ this.SessionStore = { reviveCrashedTab(aTab) { return SessionStoreInternal.reviveCrashedTab(aTab); + }, + + navigateAndRestore(tab, loadArguments, historyIndex) { + return SessionStoreInternal.navigateAndRestore(tab, loadArguments, historyIndex); } }; @@ -2163,6 +2157,50 @@ let SessionStoreInternal = { this.restoreTab(aTab, data); }, + /** + * Navigate the given |tab| by first collecting its current state and then + * either changing only the index of the currently shown shistory entry, + * or restoring the exact same state again and passing the new URL to load + * in |loadArguments|. Use this method to seamlessly switch between pages + * loaded in the parent and pages loaded in the child process. + */ + navigateAndRestore(tab, loadArguments, historyIndex) { + let window = tab.ownerDocument.defaultView; + let browser = tab.linkedBrowser; + + // Set tab title to "Connecting..." and start the throbber to pretend we're + // doing something while actually waiting for data from the frame script. + window.gBrowser.setTabTitleLoading(tab); + tab.setAttribute("busy", "true"); + + // Flush to get the latest tab state. + TabStateFlusher.flush(browser).then(() => { + // The tab might have been closed/gone in the meantime. + if (tab.closing || !tab.linkedBrowser || !tab.ownerDocument.defaultView) { + return; + } + + let tabState = TabState.clone(tab); + let options = {restoreImmediately: true}; + + if (historyIndex >= 0) { + tabState.index = historyIndex + 1; + tabState.index = Math.max(1, Math.min(tabState.index, tabState.entries.length)); + } else { + tabState.userTypedValue = null; + options.loadArguments = loadArguments; + } + + // Need to reset restoring tabs. + if (tab.linkedBrowser.__SS_restoreState) { + this._resetLocalTabRestoringState(tab); + } + + // Restore the state into the tab. + this.restoreTab(tab, tabState, options); + }); + }, + /** * See if aWindow is usable for use when restoring a previous session via * restoreLastSession. If usable, prepare it for use.