зеркало из https://github.com/mozilla/gecko-dev.git
Bug 528776 - discard stale windows before messing with the browser state. r=zeniko
--HG-- extra : rebase_source : 29e4fdfe833a20a975c71efd7a112001636a3f1a
This commit is contained in:
Родитель
6fcef63d2e
Коммит
6d2c8ca062
|
@ -186,9 +186,6 @@ SessionStoreService.prototype = {
|
||||||
// whether we clearing history on shutdown
|
// whether we clearing history on shutdown
|
||||||
_clearingOnShutdown: false,
|
_clearingOnShutdown: false,
|
||||||
|
|
||||||
// List of windows that are being closed during setBrowserState.
|
|
||||||
_closingWindows: [],
|
|
||||||
|
|
||||||
#ifndef XP_MACOSX
|
#ifndef XP_MACOSX
|
||||||
// whether the last window was closed and should be restored
|
// whether the last window was closed and should be restored
|
||||||
_restoreLastWindow: false,
|
_restoreLastWindow: false,
|
||||||
|
@ -340,17 +337,9 @@ SessionStoreService.prototype = {
|
||||||
aSubject.addEventListener("load", function(aEvent) {
|
aSubject.addEventListener("load", function(aEvent) {
|
||||||
aEvent.currentTarget.removeEventListener("load", arguments.callee, false);
|
aEvent.currentTarget.removeEventListener("load", arguments.callee, false);
|
||||||
_this.onLoad(aEvent.currentTarget);
|
_this.onLoad(aEvent.currentTarget);
|
||||||
}, false);
|
}, false);
|
||||||
break;
|
break;
|
||||||
case "domwindowclosed": // catch closed windows
|
case "domwindowclosed": // catch closed windows
|
||||||
if (this._closingWindows.length > 0) {
|
|
||||||
let index = this._closingWindows.indexOf(aSubject);
|
|
||||||
if (index != -1) {
|
|
||||||
this._closingWindows.splice(index, 1);
|
|
||||||
if (this._closingWindows.length == 0)
|
|
||||||
this._sendRestoreCompletedNotifications(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.onClose(aSubject);
|
this.onClose(aSubject);
|
||||||
break;
|
break;
|
||||||
case "quit-application-requested":
|
case "quit-application-requested":
|
||||||
|
@ -901,6 +890,8 @@ SessionStoreService.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
setBrowserState: function sss_setBrowserState(aState) {
|
setBrowserState: function sss_setBrowserState(aState) {
|
||||||
|
this._handleClosedWindows();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var state = this._safeEval("(" + aState + ")");
|
var state = this._safeEval("(" + aState + ")");
|
||||||
}
|
}
|
||||||
|
@ -917,21 +908,20 @@ SessionStoreService.prototype = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// close all other browser windows
|
||||||
|
this._forEachBrowserWindow(function(aWindow) {
|
||||||
|
if (aWindow != window) {
|
||||||
|
aWindow.close();
|
||||||
|
this.onClose(aWindow);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// make sure closed window data isn't kept
|
// make sure closed window data isn't kept
|
||||||
this._closedWindows = [];
|
this._closedWindows = [];
|
||||||
|
|
||||||
// determine how many windows are meant to be restored
|
// determine how many windows are meant to be restored
|
||||||
this._restoreCount = state.windows ? state.windows.length : 0;
|
this._restoreCount = state.windows ? state.windows.length : 0;
|
||||||
|
|
||||||
var self = this;
|
|
||||||
// close all other browser windows
|
|
||||||
this._forEachBrowserWindow(function(aWindow) {
|
|
||||||
if (aWindow != window) {
|
|
||||||
self._closingWindows.push(aWindow);
|
|
||||||
aWindow.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// restore to the given state
|
// restore to the given state
|
||||||
this.restoreWindow(window, state, true);
|
this.restoreWindow(window, state, true);
|
||||||
},
|
},
|
||||||
|
@ -1722,6 +1712,8 @@ SessionStoreService.prototype = {
|
||||||
* @returns string
|
* @returns string
|
||||||
*/
|
*/
|
||||||
_getCurrentState: function sss_getCurrentState(aUpdateAll) {
|
_getCurrentState: function sss_getCurrentState(aUpdateAll) {
|
||||||
|
this._handleClosedWindows();
|
||||||
|
|
||||||
var activeWindow = this._getMostRecentBrowserWindow();
|
var activeWindow = this._getMostRecentBrowserWindow();
|
||||||
|
|
||||||
if (this._loadState == STATE_RUNNING) {
|
if (this._loadState == STATE_RUNNING) {
|
||||||
|
@ -1735,7 +1727,7 @@ SessionStoreService.prototype = {
|
||||||
else { // always update the window features (whose change alone never triggers a save operation)
|
else { // always update the window features (whose change alone never triggers a save operation)
|
||||||
this._updateWindowFeatures(aWindow);
|
this._updateWindowFeatures(aWindow);
|
||||||
}
|
}
|
||||||
}, this);
|
});
|
||||||
this._dirtyWindows = [];
|
this._dirtyWindows = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2670,6 +2662,24 @@ SessionStoreService.prototype = {
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls onClose for windows that are determined to be closed but aren't
|
||||||
|
* destroyed yet, which would otherwise cause getBrowserState and
|
||||||
|
* setBrowserState to treat them as open windows.
|
||||||
|
*/
|
||||||
|
_handleClosedWindows: function sss_handleClosedWindows() {
|
||||||
|
var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||||
|
getService(Ci.nsIWindowMediator);
|
||||||
|
var windowsEnum = windowMediator.getEnumerator("navigator:browser");
|
||||||
|
|
||||||
|
while (windowsEnum.hasMoreElements()) {
|
||||||
|
var window = windowsEnum.getNext();
|
||||||
|
if (window.closed) {
|
||||||
|
this.onClose(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open a new browser window for a given session state
|
* open a new browser window for a given session state
|
||||||
* called when restoring a multi-window session
|
* called when restoring a multi-window session
|
||||||
|
@ -2881,17 +2891,16 @@ SessionStoreService.prototype = {
|
||||||
return jsonString;
|
return jsonString;
|
||||||
},
|
},
|
||||||
|
|
||||||
_sendRestoreCompletedNotifications:
|
_sendRestoreCompletedNotifications: function sss_sendRestoreCompletedNotifications() {
|
||||||
function sss_sendRestoreCompletedNotifications(aOnWindowClose) {
|
if (this._restoreCount) {
|
||||||
if (this._restoreCount && !aOnWindowClose)
|
|
||||||
this._restoreCount--;
|
this._restoreCount--;
|
||||||
|
if (this._restoreCount == 0) {
|
||||||
if (this._restoreCount == 0 && this._closingWindows.length == 0) {
|
// This was the last window restored at startup, notify observers.
|
||||||
// This was the last window restored at startup, notify observers.
|
this._observerService.notifyObservers(null,
|
||||||
this._observerService.notifyObservers(null,
|
this._browserSetState ? NOTIFY_BROWSER_STATE_RESTORED : NOTIFY_WINDOWS_RESTORED,
|
||||||
this._browserSetState ? NOTIFY_BROWSER_STATE_RESTORED : NOTIFY_WINDOWS_RESTORED,
|
"");
|
||||||
"");
|
this._browserSetState = false;
|
||||||
this._browserSetState = false;
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,7 @@ _BROWSER_TEST_FILES = \
|
||||||
browser_514751.js \
|
browser_514751.js \
|
||||||
browser_522545.js \
|
browser_522545.js \
|
||||||
browser_526613.js \
|
browser_526613.js \
|
||||||
|
browser_528776.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
libs:: $(_BROWSER_TEST_FILES)
|
libs:: $(_BROWSER_TEST_FILES)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||||
|
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
|
||||||
|
|
||||||
|
function browserWindowsCount(expected) {
|
||||||
|
var count = 0;
|
||||||
|
var e = wm.getEnumerator("navigator:browser");
|
||||||
|
while (e.hasMoreElements()) {
|
||||||
|
if (!e.getNext().closed)
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
is(count, expected,
|
||||||
|
"number of open browser windows according to nsIWindowMediator");
|
||||||
|
is(JSON.parse(ss.getBrowserState()).windows.length, expected,
|
||||||
|
"number of open browser windows according to getBrowserState");
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
browserWindowsCount(1);
|
||||||
|
|
||||||
|
var win = openDialog(location, "", "chrome,all,dialog=no");
|
||||||
|
win.addEventListener("load", function () {
|
||||||
|
browserWindowsCount(2);
|
||||||
|
win.close();
|
||||||
|
browserWindowsCount(1);
|
||||||
|
finish();
|
||||||
|
}, false);
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче