зеркало из https://github.com/mozilla/gecko-dev.git
Bug 867142 - Remove browser.__SS_restoreState and use a WeakMap instead; r=yoric
This commit is contained in:
Родитель
cffc4ca1cb
Коммит
39a6f12a13
|
@ -16,9 +16,6 @@ const STATE_QUITTING = -1;
|
||||||
const STATE_STOPPED_STR = "stopped";
|
const STATE_STOPPED_STR = "stopped";
|
||||||
const STATE_RUNNING_STR = "running";
|
const STATE_RUNNING_STR = "running";
|
||||||
|
|
||||||
const TAB_STATE_NEEDS_RESTORE = 1;
|
|
||||||
const TAB_STATE_RESTORING = 2;
|
|
||||||
|
|
||||||
const PRIVACY_NONE = 0;
|
const PRIVACY_NONE = 0;
|
||||||
const PRIVACY_ENCRYPTED = 1;
|
const PRIVACY_ENCRYPTED = 1;
|
||||||
const PRIVACY_FULL = 2;
|
const PRIVACY_FULL = 2;
|
||||||
|
@ -235,6 +232,29 @@ this.SessionStore = {
|
||||||
|
|
||||||
checkPrivacyLevel: function ss_checkPrivacyLevel(aIsHTTPS, aUseDefaultPref) {
|
checkPrivacyLevel: function ss_checkPrivacyLevel(aIsHTTPS, aUseDefaultPref) {
|
||||||
return SessionStoreInternal.checkPrivacyLevel(aIsHTTPS, aUseDefaultPref);
|
return SessionStoreInternal.checkPrivacyLevel(aIsHTTPS, aUseDefaultPref);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a given browser is waiting to be restored. That means its
|
||||||
|
* history and state is ready but we wait until it's higher up in the priority
|
||||||
|
* queue or until it's made visible (if restore_on_demand=true).
|
||||||
|
*
|
||||||
|
* @param aBrowser Browser reference
|
||||||
|
* @returns bool
|
||||||
|
*/
|
||||||
|
isTabStateNeedsRestore: function ss_isTabStateNeedsRestore(aBrowser) {
|
||||||
|
return TabRestoreStates.isNeedsRestore(aBrowser);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a given browser is currently restoring, i.e. we wait for
|
||||||
|
* the actual page to load and will restore form data when it's finished.
|
||||||
|
*
|
||||||
|
* @param aBrowser Browser reference
|
||||||
|
* @returns bool
|
||||||
|
*/
|
||||||
|
isTabStateRestoring: function ss_isTabStateRestoring(aBrowser) {
|
||||||
|
return TabRestoreStates.isRestoring(aBrowser);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1057,7 +1077,7 @@ let SessionStoreInternal = {
|
||||||
RestoringTabsData.remove(aTab.linkedBrowser);
|
RestoringTabsData.remove(aTab.linkedBrowser);
|
||||||
delete aTab.linkedBrowser.__SS_formDataSaved;
|
delete aTab.linkedBrowser.__SS_formDataSaved;
|
||||||
delete aTab.linkedBrowser.__SS_hostSchemeData;
|
delete aTab.linkedBrowser.__SS_hostSchemeData;
|
||||||
if (aTab.linkedBrowser.__SS_restoreState)
|
if (TabRestoreStates.has(aTab.linkedBrowser))
|
||||||
this._resetTabRestoringState(aTab);
|
this._resetTabRestoringState(aTab);
|
||||||
});
|
});
|
||||||
openWindows[aWindow.__SSi] = true;
|
openWindows[aWindow.__SSi] = true;
|
||||||
|
@ -1252,10 +1272,10 @@ let SessionStoreInternal = {
|
||||||
// If this tab was in the middle of restoring or still needs to be restored,
|
// If this tab was in the middle of restoring or still needs to be restored,
|
||||||
// we need to reset that state. If the tab was restoring, we will attempt to
|
// we need to reset that state. If the tab was restoring, we will attempt to
|
||||||
// restore the next tab.
|
// restore the next tab.
|
||||||
let previousState = browser.__SS_restoreState;
|
if (TabRestoreStates.has(browser)) {
|
||||||
if (previousState) {
|
let wasRestoring = TabRestoreStates.isRestoring(browser);
|
||||||
this._resetTabRestoringState(aTab);
|
this._resetTabRestoringState(aTab);
|
||||||
if (previousState == TAB_STATE_RESTORING)
|
if (wasRestoring)
|
||||||
this.restoreNextTab();
|
this.restoreNextTab();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1317,8 +1337,7 @@ let SessionStoreInternal = {
|
||||||
// following "load" is too late for deleting the data caches)
|
// following "load" is too late for deleting the data caches)
|
||||||
// It's possible to get a load event after calling stop on a browser (when
|
// It's possible to get a load event after calling stop on a browser (when
|
||||||
// overwriting tabs). We want to return early if the tab hasn't been restored yet.
|
// overwriting tabs). We want to return early if the tab hasn't been restored yet.
|
||||||
if (aBrowser.__SS_restoreState &&
|
if (TabRestoreStates.isNeedsRestore(aBrowser)) {
|
||||||
aBrowser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1354,11 +1373,8 @@ let SessionStoreInternal = {
|
||||||
this._windows[aWindow.__SSi].selected = aWindow.gBrowser.tabContainer.selectedIndex;
|
this._windows[aWindow.__SSi].selected = aWindow.gBrowser.tabContainer.selectedIndex;
|
||||||
|
|
||||||
let tab = aWindow.gBrowser.selectedTab;
|
let tab = aWindow.gBrowser.selectedTab;
|
||||||
// If __SS_restoreState is still on the browser and it is
|
// Explicitly call restoreTab() to to restore the tab if we need to.
|
||||||
// TAB_STATE_NEEDS_RESTORE, then then we haven't restored
|
if (TabRestoreStates.isNeedsRestore(tab.linkedBrowser))
|
||||||
// this tab yet. Explicitly call restoreTab to kick off the restore.
|
|
||||||
if (tab.linkedBrowser.__SS_restoreState &&
|
|
||||||
tab.linkedBrowser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
|
||||||
this.restoreTab(tab);
|
this.restoreTab(tab);
|
||||||
|
|
||||||
// attempt to update the current URL we send in a crash report
|
// attempt to update the current URL we send in a crash report
|
||||||
|
@ -1368,8 +1384,7 @@ let SessionStoreInternal = {
|
||||||
|
|
||||||
onTabShow: function ssi_onTabShow(aWindow, aTab) {
|
onTabShow: function ssi_onTabShow(aWindow, aTab) {
|
||||||
// If the tab hasn't been restored yet, move it into the right bucket
|
// If the tab hasn't been restored yet, move it into the right bucket
|
||||||
if (aTab.linkedBrowser.__SS_restoreState &&
|
if (TabRestoreStates.isNeedsRestore(aTab.linkedBrowser)) {
|
||||||
aTab.linkedBrowser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE) {
|
|
||||||
TabRestoreQueue.hiddenToVisible(aTab);
|
TabRestoreQueue.hiddenToVisible(aTab);
|
||||||
|
|
||||||
// let's kick off tab restoration again to ensure this tab gets restored
|
// let's kick off tab restoration again to ensure this tab gets restored
|
||||||
|
@ -1384,8 +1399,7 @@ let SessionStoreInternal = {
|
||||||
|
|
||||||
onTabHide: function ssi_onTabHide(aWindow, aTab) {
|
onTabHide: function ssi_onTabHide(aWindow, aTab) {
|
||||||
// If the tab hasn't been restored yet, move it into the right bucket
|
// If the tab hasn't been restored yet, move it into the right bucket
|
||||||
if (aTab.linkedBrowser.__SS_restoreState &&
|
if (TabRestoreStates.isNeedsRestore(aTab.linkedBrowser)) {
|
||||||
aTab.linkedBrowser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE) {
|
|
||||||
TabRestoreQueue.visibleToHidden(aTab);
|
TabRestoreQueue.visibleToHidden(aTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2756,7 +2770,7 @@ let SessionStoreInternal = {
|
||||||
// state (in restoreHistoryPrecursor).
|
// state (in restoreHistoryPrecursor).
|
||||||
if (aOverwriteTabs) {
|
if (aOverwriteTabs) {
|
||||||
for (let i = 0; i < tabbrowser.tabs.length; i++) {
|
for (let i = 0; i < tabbrowser.tabs.length; i++) {
|
||||||
if (tabbrowser.browsers[i].__SS_restoreState)
|
if (TabRestoreStates.has(tabbrowser.browsers[i]))
|
||||||
this._resetTabRestoringState(tabbrowser.tabs[i]);
|
this._resetTabRestoringState(tabbrowser.tabs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2986,7 +3000,7 @@ let SessionStoreInternal = {
|
||||||
// keep the data around to prevent dataloss in case
|
// keep the data around to prevent dataloss in case
|
||||||
// a tab gets closed before it's been properly restored
|
// a tab gets closed before it's been properly restored
|
||||||
RestoringTabsData.set(browser, tabData);
|
RestoringTabsData.set(browser, tabData);
|
||||||
browser.__SS_restoreState = TAB_STATE_NEEDS_RESTORE;
|
TabRestoreStates.setNeedsRestore(browser);
|
||||||
browser.setAttribute("pending", "true");
|
browser.setAttribute("pending", "true");
|
||||||
tab.setAttribute("pending", "true");
|
tab.setAttribute("pending", "true");
|
||||||
|
|
||||||
|
@ -3176,7 +3190,7 @@ let SessionStoreInternal = {
|
||||||
this._tabsRestoringCount++;
|
this._tabsRestoringCount++;
|
||||||
|
|
||||||
// Set this tab's state to restoring
|
// Set this tab's state to restoring
|
||||||
browser.__SS_restoreState = TAB_STATE_RESTORING;
|
TabRestoreStates.setIsRestoring(browser);
|
||||||
browser.removeAttribute("pending");
|
browser.removeAttribute("pending");
|
||||||
aTab.removeAttribute("pending");
|
aTab.removeAttribute("pending");
|
||||||
|
|
||||||
|
@ -4398,10 +4412,11 @@ let SessionStoreInternal = {
|
||||||
let browser = aTab.linkedBrowser;
|
let browser = aTab.linkedBrowser;
|
||||||
|
|
||||||
// Keep the tab's previous state for later in this method
|
// Keep the tab's previous state for later in this method
|
||||||
let previousState = browser.__SS_restoreState;
|
let wasRestoring = TabRestoreStates.isRestoring(browser);
|
||||||
|
let wasNeedsRestore = TabRestoreStates.isNeedsRestore(browser);
|
||||||
|
|
||||||
// The browser is no longer in any sort of restoring state.
|
// The browser is no longer in any sort of restoring state.
|
||||||
delete browser.__SS_restoreState;
|
TabRestoreStates.remove(browser);
|
||||||
|
|
||||||
aTab.removeAttribute("pending");
|
aTab.removeAttribute("pending");
|
||||||
browser.removeAttribute("pending");
|
browser.removeAttribute("pending");
|
||||||
|
@ -4413,11 +4428,11 @@ let SessionStoreInternal = {
|
||||||
// Remove the progress listener if we should.
|
// Remove the progress listener if we should.
|
||||||
this._removeTabsProgressListener(window);
|
this._removeTabsProgressListener(window);
|
||||||
|
|
||||||
if (previousState == TAB_STATE_RESTORING) {
|
if (wasRestoring) {
|
||||||
if (this._tabsRestoringCount)
|
if (this._tabsRestoringCount)
|
||||||
this._tabsRestoringCount--;
|
this._tabsRestoringCount--;
|
||||||
}
|
}
|
||||||
else if (previousState == TAB_STATE_NEEDS_RESTORE) {
|
else if (wasNeedsRestore) {
|
||||||
// Make sure the session history listener is removed. This is normally
|
// Make sure the session history listener is removed. This is normally
|
||||||
// done in restoreTab, but this tab is being removed before that gets called.
|
// done in restoreTab, but this tab is being removed before that gets called.
|
||||||
this._removeSHistoryListener(aTab);
|
this._removeSHistoryListener(aTab);
|
||||||
|
@ -4670,6 +4685,41 @@ let TabAttributes = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A map keeping track of all tab restore states. A tab might be 'needs-restore'
|
||||||
|
// if it waits until the restoration process is kicked off. This might start
|
||||||
|
// when the tab reaches a higher position in the priority queue or when it's
|
||||||
|
// made visible (when restore_on_demand=true). If a tab is 'restoring' we wait
|
||||||
|
// for its actual page to load and will then restore form data etc. If has()
|
||||||
|
// returns false the tab has not been restored from previous data or it has
|
||||||
|
// already finished restoring and is thus now seen as a valid and complete tab.
|
||||||
|
let TabRestoreStates = {
|
||||||
|
_states: new WeakMap(),
|
||||||
|
|
||||||
|
has: function (browser) {
|
||||||
|
return this._states.has(browser);
|
||||||
|
},
|
||||||
|
|
||||||
|
isNeedsRestore: function ss_isNeedsRestore(browser) {
|
||||||
|
return this._states.get(browser) === "needs-restore";
|
||||||
|
},
|
||||||
|
|
||||||
|
setNeedsRestore: function (browser) {
|
||||||
|
this._states.set(browser, "needs-restore");
|
||||||
|
},
|
||||||
|
|
||||||
|
isRestoring: function ss_isRestoring(browser) {
|
||||||
|
return this._states.get(browser) === "restoring";
|
||||||
|
},
|
||||||
|
|
||||||
|
setIsRestoring: function (browser) {
|
||||||
|
this._states.set(browser, "restoring");
|
||||||
|
},
|
||||||
|
|
||||||
|
remove: function (browser) {
|
||||||
|
this._states.delete(browser);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// This is used to help meter the number of restoring tabs. This is the control
|
// This is used to help meter the number of restoring tabs. This is the control
|
||||||
// point for telling the next tab to restore. It gets attached to each gBrowser
|
// point for telling the next tab to restore. It gets attached to each gBrowser
|
||||||
// via gBrowser.addTabsProgressListener
|
// via gBrowser.addTabsProgressListener
|
||||||
|
@ -4677,8 +4727,7 @@ let gRestoreTabsProgressListener = {
|
||||||
onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||||
// Ignore state changes on browsers that we've already restored and state
|
// Ignore state changes on browsers that we've already restored and state
|
||||||
// changes that aren't applicable.
|
// changes that aren't applicable.
|
||||||
if (aBrowser.__SS_restoreState &&
|
if (TabRestoreStates.isRestoring(aBrowser) &&
|
||||||
aBrowser.__SS_restoreState == TAB_STATE_RESTORING &&
|
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ let TabsProgressListener = {
|
||||||
},
|
},
|
||||||
|
|
||||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||||
if (this.callback && aBrowser.__SS_restoreState == TAB_STATE_RESTORING &&
|
if (this.callback && SessionStore.isTabStateRestoring(aBrowser) &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)
|
||||||
|
@ -85,9 +85,9 @@ let TabsProgressListener = {
|
||||||
|
|
||||||
for (let i = 0; i < this.window.gBrowser.tabs.length; i++) {
|
for (let i = 0; i < this.window.gBrowser.tabs.length; i++) {
|
||||||
let browser = this.window.gBrowser.tabs[i].linkedBrowser;
|
let browser = this.window.gBrowser.tabs[i].linkedBrowser;
|
||||||
if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
if (SessionStore.isTabStateRestoring(browser))
|
||||||
isRestoring++;
|
isRestoring++;
|
||||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
else if (SessionStore.isTabStateNeedsRestore(browser))
|
||||||
needsRestore++;
|
needsRestore++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,17 +22,6 @@ function test() {
|
||||||
// any given time. This guarantees that a finishing load won't start another.
|
// any given time. This guarantees that a finishing load won't start another.
|
||||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||||
|
|
||||||
// We have our own progress listener for this test, which we'll attach before our state is set
|
|
||||||
let progressListener = {
|
|
||||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
|
||||||
if (aBrowser.__SS_restoreState == TAB_STATE_RESTORING &&
|
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)
|
|
||||||
progressCallback(aBrowser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let state = { windows: [{ tabs: [
|
let state = { windows: [{ tabs: [
|
||||||
{ entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
|
{ entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
|
||||||
{ entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } }, // overwriting
|
{ entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } }, // overwriting
|
||||||
|
@ -42,10 +31,10 @@ function test() {
|
||||||
{ entries: [{ url: "http://example.org#6" }] } // creating
|
{ entries: [{ url: "http://example.org#6" }] } // creating
|
||||||
], selected: 1 }] };
|
], selected: 1 }] };
|
||||||
|
|
||||||
function progressCallback(aBrowser) {
|
gProgressListener.setCallback(function progressCallback(aBrowser) {
|
||||||
// We'll remove the progress listener after the first one because we aren't
|
// We'll remove the progress listener after the first one because we aren't
|
||||||
// loading any other tabs
|
// loading any other tabs
|
||||||
window.gBrowser.removeTabsProgressListener(progressListener);
|
gProgressListener.unsetCallback();
|
||||||
|
|
||||||
let curState = JSON.parse(ss.getBrowserState());
|
let curState = JSON.parse(ss.getBrowserState());
|
||||||
for (let i = 0; i < curState.windows[0].tabs.length; i++) {
|
for (let i = 0; i < curState.windows[0].tabs.length; i++) {
|
||||||
|
@ -109,9 +98,8 @@ function test() {
|
||||||
"(creating) new data is stored in extData where there was none");
|
"(creating) new data is stored in extData where there was none");
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
});
|
||||||
|
|
||||||
window.gBrowser.addTabsProgressListener(progressListener);
|
|
||||||
ss.setBrowserState(JSON.stringify(state));
|
ss.setBrowserState(JSON.stringify(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,19 +18,15 @@ function test() {
|
||||||
waitForExplicitFinish();
|
waitForExplicitFinish();
|
||||||
|
|
||||||
registerCleanupFunction(function () {
|
registerCleanupFunction(function () {
|
||||||
TabsProgressListener.uninit();
|
|
||||||
ss.setBrowserState(stateBackup);
|
ss.setBrowserState(stateBackup);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
TabsProgressListener.init();
|
|
||||||
|
|
||||||
window.addEventListener("SSWindowStateReady", function onReady() {
|
window.addEventListener("SSWindowStateReady", function onReady() {
|
||||||
window.removeEventListener("SSWindowStateReady", onReady, false);
|
window.removeEventListener("SSWindowStateReady", onReady, false);
|
||||||
|
|
||||||
let firstProgress = true;
|
let firstProgress = true;
|
||||||
|
|
||||||
TabsProgressListener.setCallback(function (needsRestore, isRestoring) {
|
gProgressListener.setCallback(function (browser, needsRestore, isRestoring) {
|
||||||
if (firstProgress) {
|
if (firstProgress) {
|
||||||
firstProgress = false;
|
firstProgress = false;
|
||||||
is(isRestoring, 3, "restoring 3 tabs concurrently");
|
is(isRestoring, 3, "restoring 3 tabs concurrently");
|
||||||
|
@ -39,7 +35,7 @@ function test() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == needsRestore) {
|
if (0 == needsRestore) {
|
||||||
TabsProgressListener.unsetCallback();
|
gProgressListener.unsetCallback();
|
||||||
waitForFocus(finish);
|
waitForFocus(finish);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -49,51 +45,3 @@ function test() {
|
||||||
|
|
||||||
ss.setBrowserState(JSON.stringify(statePinned));
|
ss.setBrowserState(JSON.stringify(statePinned));
|
||||||
}
|
}
|
||||||
|
|
||||||
function countTabs() {
|
|
||||||
let needsRestore = 0, isRestoring = 0;
|
|
||||||
let windowsEnum = Services.wm.getEnumerator("navigator:browser");
|
|
||||||
|
|
||||||
while (windowsEnum.hasMoreElements()) {
|
|
||||||
let window = windowsEnum.getNext();
|
|
||||||
if (window.closed)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
|
||||||
let browser = window.gBrowser.tabs[i].linkedBrowser;
|
|
||||||
if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
|
||||||
isRestoring++;
|
|
||||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
|
||||||
needsRestore++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [needsRestore, isRestoring];
|
|
||||||
}
|
|
||||||
|
|
||||||
let TabsProgressListener = {
|
|
||||||
init: function () {
|
|
||||||
gBrowser.addTabsProgressListener(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
uninit: function () {
|
|
||||||
this.unsetCallback();
|
|
||||||
gBrowser.removeTabsProgressListener(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
setCallback: function (callback) {
|
|
||||||
this.callback = callback;
|
|
||||||
},
|
|
||||||
|
|
||||||
unsetCallback: function () {
|
|
||||||
delete this.callback;
|
|
||||||
},
|
|
||||||
|
|
||||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
|
||||||
if (this.callback && aBrowser.__SS_restoreState == TAB_STATE_RESTORING &&
|
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)
|
|
||||||
this.callback.apply(null, countTabs());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ function test() {
|
||||||
isnot(gBrowser.selectedTab, tab, "newly created tab is not selected");
|
isnot(gBrowser.selectedTab, tab, "newly created tab is not selected");
|
||||||
|
|
||||||
ss.setTabState(tab, JSON.stringify(tabState));
|
ss.setTabState(tab, JSON.stringify(tabState));
|
||||||
is(browser.__SS_restoreState, TAB_STATE_NEEDS_RESTORE, "tab needs restoring");
|
ok(SessionStore.isTabStateNeedsRestore(browser), "tab needs restoring");
|
||||||
|
|
||||||
let state = JSON.parse(ss.getTabState(tab));
|
let state = JSON.parse(ss.getTabState(tab));
|
||||||
let formdata = state.entries[0].formdata;
|
let formdata = state.entries[0].formdata;
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
const TAB_STATE_NEEDS_RESTORE = 1;
|
|
||||||
const TAB_STATE_RESTORING = 2;
|
|
||||||
|
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
Cu.import("resource:///modules/sessionstore/SessionStore.jsm", tmp);
|
Cu.import("resource:///modules/sessionstore/SessionStore.jsm", tmp);
|
||||||
let SessionStore = tmp.SessionStore;
|
let SessionStore = tmp.SessionStore;
|
||||||
|
@ -241,7 +238,7 @@ let gProgressListener = {
|
||||||
function gProgressListener_onStateChange(aBrowser, aWebProgress, aRequest,
|
function gProgressListener_onStateChange(aBrowser, aWebProgress, aRequest,
|
||||||
aStateFlags, aStatus) {
|
aStateFlags, aStatus) {
|
||||||
if ((!this._checkRestoreState ||
|
if ((!this._checkRestoreState ||
|
||||||
aBrowser.__SS_restoreState == TAB_STATE_RESTORING) &&
|
SessionStore.isTabStateRestoring(aBrowser)) &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
||||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
||||||
|
@ -256,9 +253,9 @@ let gProgressListener = {
|
||||||
for (let win in BrowserWindowIterator()) {
|
for (let win in BrowserWindowIterator()) {
|
||||||
for (let i = 0; i < win.gBrowser.tabs.length; i++) {
|
for (let i = 0; i < win.gBrowser.tabs.length; i++) {
|
||||||
let browser = win.gBrowser.tabs[i].linkedBrowser;
|
let browser = win.gBrowser.tabs[i].linkedBrowser;
|
||||||
if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
if (SessionStore.isTabStateRestoring(browser))
|
||||||
isRestoring++;
|
isRestoring++;
|
||||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
else if (SessionStore.isTabStateNeedsRestore(browser))
|
||||||
needsRestore++;
|
needsRestore++;
|
||||||
else
|
else
|
||||||
wasRestored++;
|
wasRestored++;
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
|
|
||||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||||
|
|
||||||
const TAB_STATE_NEEDS_RESTORE = 1;
|
|
||||||
const TAB_STATE_RESTORING = 2;
|
|
||||||
|
|
||||||
let stateBackup = ss.getBrowserState();
|
let stateBackup = ss.getBrowserState();
|
||||||
|
|
||||||
let state = {windows:[{tabs:[
|
let state = {windows:[{tabs:[
|
||||||
|
@ -125,9 +122,9 @@ function countTabs() {
|
||||||
|
|
||||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||||
let browser = window.gBrowser.tabs[i].linkedBrowser;
|
let browser = window.gBrowser.tabs[i].linkedBrowser;
|
||||||
if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
if (SessionStore.isTabStateRestoring(browser))
|
||||||
isRestoring++;
|
isRestoring++;
|
||||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
else if (SessionStore.isTabStateNeedsRestore(browser))
|
||||||
needsRestore++;
|
needsRestore++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,8 +165,9 @@ let TabsProgressListener = {
|
||||||
self.callback.apply(null, countTabs());
|
self.callback.apply(null, countTabs());
|
||||||
};
|
};
|
||||||
|
|
||||||
let isRestoring = aBrowser.__SS_restoreState == TAB_STATE_RESTORING;
|
let isRestoring = SessionStore.isTabStateRestoring(aBrowser);
|
||||||
let wasRestoring = !aBrowser.__SS_restoreState && aBrowser.__wasRestoring;
|
let needsRestore = SessionStore.isTabStateNeedsRestore(aBrowser);
|
||||||
|
let wasRestoring = !isRestoring && !needsRestore && aBrowser.__wasRestoring;
|
||||||
let hasStopped = aStateFlags & Ci.nsIWebProgressListener.STATE_STOP;
|
let hasStopped = aStateFlags & Ci.nsIWebProgressListener.STATE_STOP;
|
||||||
|
|
||||||
if (isRestoring && !hasStopped)
|
if (isRestoring && !hasStopped)
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let tmp = {};
|
||||||
|
Cu.import("resource:///modules/sessionstore/SessionStore.jsm", tmp);
|
||||||
|
let SessionStore = tmp.SessionStore;
|
||||||
|
|
||||||
// Some tests here assume that all restored tabs are loaded without waiting for
|
// Some tests here assume that all restored tabs are loaded without waiting for
|
||||||
// the user to bring them to the foreground. We ensure this by resetting the
|
// the user to bring them to the foreground. We ensure this by resetting the
|
||||||
// related preference (see the "firefox.js" defaults file for details).
|
// related preference (see the "firefox.js" defaults file for details).
|
||||||
|
@ -117,8 +121,6 @@ function newWindowWithTabView(shownCallback, loadCallback, width, height) {
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
function afterAllTabsLoaded(callback, win) {
|
function afterAllTabsLoaded(callback, win) {
|
||||||
const TAB_STATE_NEEDS_RESTORE = 1;
|
|
||||||
|
|
||||||
win = win || window;
|
win = win || window;
|
||||||
|
|
||||||
let stillToLoad = 0;
|
let stillToLoad = 0;
|
||||||
|
@ -137,8 +139,7 @@ function afterAllTabsLoaded(callback, win) {
|
||||||
let browser = tab.linkedBrowser;
|
let browser = tab.linkedBrowser;
|
||||||
|
|
||||||
let isRestorable = !(tab.hidden && !restoreHiddenTabs &&
|
let isRestorable = !(tab.hidden && !restoreHiddenTabs &&
|
||||||
browser.__SS_restoreState &&
|
SessionStore.isTabStateNeedsRestore(browser));
|
||||||
browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE);
|
|
||||||
|
|
||||||
if (isRestorable && browser.contentDocument.readyState != "complete" ||
|
if (isRestorable && browser.contentDocument.readyState != "complete" ||
|
||||||
browser.webProgress.isLoadingDocument) {
|
browser.webProgress.isLoadingDocument) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче