--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -77,16 +77,17 @@ SessionStore.prototype = {
// Get file references
this._sessionFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
this._sessionFileBackup = this._sessionFile.clone();
this._sessionFile.append("sessionstore.js");
this._sessionFileBackup.append("sessionstore.bak");
this._loadState = STATE_STOPPED;
+ this._startupRestoreFinished = false;
this._interval = Services.prefs.getIntPref("browser.sessionstore.interval");
this._maxTabsUndo = Services.prefs.getIntPref("browser.sessionstore.max_tabs_undo");
// Copy changes in Gecko settings to their Java counterparts,
// so the startup code can access them
Services.prefs.addObserver(PREFS_RESTORE_FROM_CRASH, function() {
SharedPreferences.forApp().setBoolPref(PREFS_RESTORE_FROM_CRASH,
@@ -209,31 +210,43 @@ SessionStore.prototype = {
observe: function (aSubject, aTopic, aData) {
Services.obs.removeObserver(restoreCleanup, "sessionstore-windows-restored");
if (window.BrowserApp.tabs.length == 0) {
window.BrowserApp.addTab("about:home", {
selected: true
});
}
+ // Normally, _restoreWindow() will have set this to true already,
+ // but we want to make sure it's set even in case of a restore failure.
+ this._startupRestoreFinished = true;
+ log("startupRestoreFinished = true (through notification)");
}.bind(this)
};
Services.obs.addObserver(restoreCleanup, "sessionstore-windows-restored", false);
// Do a restore, triggered by Java
let data = JSON.parse(aData);
this.restoreLastSession(data.sessionString);
} else {
// Not doing a restore; just send restore message
+ this._startupRestoreFinished = true;
+ log("startupRestoreFinished = true");
Services.obs.notifyObservers(null, "sessionstore-windows-restored", "");
}
break;
}
case "Session:NotifyLocationChange": {
let browser = aSubject;
+
+ if (browser.__SS_restoreReloadPending && this._startupRestoreFinished) {
+ delete browser.__SS_restoreReloadPending;
+ log("remove restoreReloadPending");
+ }
+
if (browser.__SS_restoreDataOnLocationChange) {
delete browser.__SS_restoreDataOnLocationChange;
this._restoreZoom(browser.__SS_data.scrolldata, browser);
}
break;
}
case "Tabs:OpenMultiple": {
let data = JSON.parse(aData);
@@ -537,18 +550,19 @@ SessionStore.prototype = {
log("onTabClose() ran for tab " + aWindow.BrowserApp.getTabForBrowser(aBrowser).id);
let evt = new Event("SSTabCloseProcessed", {"bubbles":true, "cancelable":false});
aBrowser.dispatchEvent(evt);
}
},
onTabLoad: function ss_onTabLoad(aWindow, aBrowser) {
- // If this browser is being restored, skip any session save activity
- if (aBrowser.__SS_restore) {
+ // If this browser belongs to a zombie tab or the initial restore hasn't yet finished,
+ // skip any session save activity.
+ if (aBrowser.__SS_restore || !this._startupRestoreFinished || aBrowser.__SS_restoreReloadPending) {
return;
}
// Ignore a transient "about:blank"
if (!aBrowser.canGoBack && aBrowser.currentURI.spec == "about:blank") {
return;
}
@@ -632,18 +646,19 @@ SessionStore.prototype = {
// notifications, we may have switched between different private browsing
// modes.
if (this._notifyClosedTabs) {
this._sendClosedTabsToJava(aWindow);
}
},
onTabInput: function ss_onTabInput(aWindow, aBrowser) {
- // If this browser is being restored, skip any session save activity
- if (aBrowser.__SS_restore) {
+ // If this browser belongs to a zombie tab or the initial restore hasn't yet finished,
+ // skip any session save activity.
+ if (aBrowser.__SS_restore || !this._startupRestoreFinished || aBrowser.__SS_restoreReloadPending) {
return;
}
// Don't bother trying to save text data if we don't have history yet
let data = aBrowser.__SS_data;
if (!data || data.entries.length == 0) {
return;
}
@@ -691,18 +706,19 @@ SessionStore.prototype = {
onTabScroll: function ss_onTabScroll(aWindow, aBrowser) {
// If we've been called directly, cancel any pending timeouts.
if (this._scrollSavePending) {
aWindow.clearTimeout(this._scrollSavePending);
this._scrollSavePending = null;
log("onTabScroll() clearing pending timeout");
}
- // If this browser is being restored, skip any session save activity.
- if (aBrowser.__SS_restore) {
+ // If this browser belongs to a zombie tab or the initial restore hasn't yet finished,
+ // skip any session save activity.
+ if (aBrowser.__SS_restore || !this._startupRestoreFinished || aBrowser.__SS_restoreReloadPending) {
return;
}
// Don't bother trying to save scroll positions if we don't have history yet.
let data = aBrowser.__SS_data;
if (!data || data.entries.length == 0) {
return;
}
@@ -1474,16 +1490,23 @@ SessionStore.prototype = {
}
tab.browser.__SS_data = tabData;
tab.browser.__SS_extdata = tabData.extData;
if (window.BrowserApp.selectedTab == tab) {
this._restoreTab(tabData, tab.browser);
+ // We can now lift the general ban on tab data capturing,
+ // but we still need to protect the foreground tab until we're
+ // sure it's actually reloading after history restoring has finished.
+ tab.browser.__SS_restoreReloadPending = true;
+ this._startupRestoreFinished = true;
+ log("startupRestoreFinished = true");
+
delete tab.browser.__SS_restore;
tab.browser.removeAttribute("pending");
} else {
// Mark the browser for delay loading
tab.browser.__SS_restore = true;
tab.browser.setAttribute("pending", "true");
}
}