зеркало из https://github.com/mozilla/gecko-dev.git
Bug 597757 - Reloading throttled tab doesn't work correctly [r=dietrich, a=blocking-b7]
This commit is contained in:
Родитель
b0f0a207f0
Коммит
9f6e5a25a8
|
@ -853,7 +853,7 @@ SessionStoreService.prototype = {
|
|||
|
||||
// If this tab was in the middle of restoring, we want to restore the next
|
||||
// tab. If the tab hasn't been restored, we want to remove it from the array.
|
||||
this._resetTabRestoringState(aTab, true);
|
||||
this._resetTabRestoringState(aTab, true, false);
|
||||
|
||||
if (!aNoNotification) {
|
||||
this.saveStateDelayed(aWindow);
|
||||
|
@ -2197,7 +2197,7 @@ SessionStoreService.prototype = {
|
|||
// If overwriting tabs, we want to remove __SS_restoring from the browser.
|
||||
if (aOverwriteTabs) {
|
||||
for (let i = 0; i < tabbrowser.tabs.length; i++)
|
||||
this._resetTabRestoringState(tabbrowser.tabs[i], false);
|
||||
this._resetTabRestoringState(tabbrowser.tabs[i], false, false);
|
||||
}
|
||||
|
||||
// We want to set up a counter on the window that indicates how many tabs
|
||||
|
@ -2435,7 +2435,10 @@ SessionStoreService.prototype = {
|
|||
history.PurgeHistory(history.count);
|
||||
}
|
||||
history.QueryInterface(Ci.nsISHistoryInternal);
|
||||
|
||||
|
||||
browser.__SS_shistoryListener = new SessionStoreSHistoryListener(this, tab);
|
||||
history.addSHistoryListener(browser.__SS_shistoryListener);
|
||||
|
||||
if (!tabData.entries) {
|
||||
tabData.entries = [];
|
||||
}
|
||||
|
@ -3518,9 +3521,27 @@ SessionStoreService.prototype = {
|
|||
this._tabsRestoringCount = 0;
|
||||
},
|
||||
|
||||
_resetTabRestoringState: function sss__resetTabRestoringState(aTab, aRestoreNextTab) {
|
||||
/**
|
||||
* Reset the restoring state for a particular tab. This will be called when
|
||||
* removing a tab, when a tab needs to be reset (it's being overwritten), or
|
||||
* when reload occurs. This is multipurpose and is meant to provide a single
|
||||
* path for very similar functionality.
|
||||
*
|
||||
* @param aTab
|
||||
* The tab that will be "reset"
|
||||
* @param aRestoreNextTab
|
||||
* If the tab is currently restoring, should we allow a new restore to
|
||||
* begin
|
||||
* @param aRestoreThisTab
|
||||
* In the process of "resetting" this tab, should we also restore it.
|
||||
*/
|
||||
_resetTabRestoringState:
|
||||
function sss__resetTabRestoringState(aTab, aRestoreNextTab, aRestoreThisTab) {
|
||||
let browser = aTab.linkedBrowser;
|
||||
|
||||
// Always delete the session history listener off the browser
|
||||
delete browser.__SS_shistoryListener;
|
||||
|
||||
if (browser.__SS_restoring) {
|
||||
delete browser.__SS_restoring;
|
||||
if (aRestoreNextTab) {
|
||||
|
@ -3534,13 +3555,32 @@ SessionStoreService.prototype = {
|
|||
}
|
||||
}
|
||||
else if (browser.__SS_needsRestore) {
|
||||
let window = aTab.ownerDocument.defaultView;
|
||||
window.__SS_tabsToRestore--;
|
||||
delete browser.__SS_needsRestore;
|
||||
if (aTab.hidden)
|
||||
this._tabsToRestore.hidden.splice(this._tabsToRestore.hidden.indexOf(aTab));
|
||||
else
|
||||
this._tabsToRestore.visible.splice(this._tabsToRestore.visible.indexOf(aTab));
|
||||
// First we'll remove the tab from the hidden/visible array of tabs left
|
||||
// to restore.
|
||||
let splicedTabs;
|
||||
if (aTab.hidden) {
|
||||
splicedTabs =
|
||||
this._tabsToRestore.hidden.splice(this._tabsToRestore.hidden.indexOf(aTab), 1);
|
||||
}
|
||||
else {
|
||||
splicedTabs =
|
||||
this._tabsToRestore.visible.splice(this._tabsToRestore.visible.indexOf(aTab), 1);
|
||||
}
|
||||
if (aRestoreThisTab && splicedTabs.length) {
|
||||
// If we want to restore the tab, then we'll do that. This tab still
|
||||
// needs restore, so we're going to restore this one, not the next one
|
||||
// as was done above.
|
||||
this.restoreTab(aTab);
|
||||
}
|
||||
else {
|
||||
// If we don't want to restore the tab, we want to explicitly remove
|
||||
// __SS_needsRestore and decrement __SS_tabsToRestore. Normally this is
|
||||
// done in restoreTab.
|
||||
let window = aTab.ownerDocument.defaultView;
|
||||
window.__SS_tabsToRestore--;
|
||||
delete browser.__SS_needsRestore;
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -3675,11 +3715,10 @@ let XPathHelper = {
|
|||
let gRestoreTabsProgressListener = {
|
||||
ss: null,
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
// Ignore state changes on browsers that we've already restored
|
||||
if (!aBrowser.__SS_restoring)
|
||||
return;
|
||||
|
||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||
// Ignore state changes on browsers that we've already restored and state
|
||||
// changes that aren't applicable.
|
||||
if (aBrowser.__SS_restoring &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
||||
delete aBrowser.__SS_restoring;
|
||||
|
@ -3688,6 +3727,35 @@ let gRestoreTabsProgressListener = {
|
|||
}
|
||||
}
|
||||
|
||||
// A SessionStoreSHistoryListener will be attached to each browser before it is
|
||||
// restored. We need to catch reloads that occur before the tab is restored
|
||||
// because otherwise, docShell will reload an old URI (usually about:blank).
|
||||
function SessionStoreSHistoryListener(ss, aTab) {
|
||||
this.tab = aTab;
|
||||
this.ss = ss;
|
||||
}
|
||||
SessionStoreSHistoryListener.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
browser: null,
|
||||
ss: null,
|
||||
OnHistoryNewEntry: function(aNewURI) { },
|
||||
OnHistoryGoBack: function(aBackURI) { return true; },
|
||||
OnHistoryGoForward: function(aForwardURI) { return true; },
|
||||
OnHistoryGotoIndex: function(aIndex, aGotoURI) { return true; },
|
||||
OnHistoryPurge: function(aNumEntries) { return true; },
|
||||
OnHistoryReload: function(aReloadURI, aReloadFlags) {
|
||||
// On reload, we want to make sure that session history loads the right
|
||||
// URI. In order to do that, we will call _resetTabRestoringState.
|
||||
// __SS_needsRestore will still be on this tab's browser, so we will end up
|
||||
// calling restoreTab and this tab will be loaded.
|
||||
this.ss._resetTabRestoringState(this.tab, false, true);
|
||||
// Returning false will stop the load that docshell is attempting.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// see nsPrivateBrowsingService.js
|
||||
String.prototype.hasRootDomain = function hasRootDomain(aDomain)
|
||||
{
|
||||
|
|
|
@ -50,7 +50,7 @@ function test() {
|
|||
|
||||
let tests = [test_cascade, test_select, test_multiWindowState,
|
||||
test_setWindowStateNoOverwrite, test_setWindowStateOverwrite,
|
||||
test_setBrowserStateInterrupted];
|
||||
test_setBrowserStateInterrupted, test_reload];
|
||||
function runNextTest() {
|
||||
// Reset the pref
|
||||
try {
|
||||
|
@ -60,6 +60,7 @@ function runNextTest() {
|
|||
// set an empty state & run the next test, or finish
|
||||
if (tests.length) {
|
||||
ss.setBrowserState(JSON.stringify({ windows: [{ tabs: [{ url: 'about:blank' }], }] }));
|
||||
info("running next test");
|
||||
executeSoon(tests.shift());
|
||||
}
|
||||
else {
|
||||
|
@ -531,6 +532,66 @@ function test_setBrowserStateInterrupted() {
|
|||
}
|
||||
|
||||
|
||||
function test_reload() {
|
||||
// Set the pref to 0 so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 0);
|
||||
|
||||
// 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_restoring &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)
|
||||
test_reload_progressCallback(aBrowser);
|
||||
}
|
||||
}
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org/#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#2" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#3" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#4" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#5" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#6" }], extData: { "uniq": r() } }
|
||||
], selected: 1 }] };
|
||||
|
||||
let loadCount = 0;
|
||||
function test_reload_progressCallback(aBrowser) {
|
||||
loadCount++;
|
||||
|
||||
is(aBrowser.currentURI.spec, state.windows[0].tabs[loadCount - 1].entries[0].url,
|
||||
"test_reload: load " + loadCount + " - browser loaded correct url");
|
||||
|
||||
if (loadCount <= state.windows[0].tabs.length) {
|
||||
// double check that this tab was the right one
|
||||
let expectedData = state.windows[0].tabs[loadCount - 1].extData.uniq;
|
||||
let tab;
|
||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||
if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
|
||||
tab = window.gBrowser.tabs[i];
|
||||
}
|
||||
is(ss.getTabValue(tab, "uniq"), expectedData,
|
||||
"test_reload: load " + loadCount + " - correct tab was restored");
|
||||
|
||||
if (loadCount == state.windows[0].tabs.length) {
|
||||
window.gBrowser.removeTabsProgressListener(progressListener);
|
||||
runNextTest();
|
||||
}
|
||||
else {
|
||||
// reload the next tab
|
||||
window.gBrowser.reloadTab(window.gBrowser.tabs[loadCount]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window.gBrowser.addTabsProgressListener(progressListener);
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
|
||||
function countTabs() {
|
||||
let needsRestore = 0,
|
||||
isRestoring = 0,
|
||||
|
|
Загрузка…
Ссылка в новой задаче