Bug 1175267: When a load redirected to a new process is cancelled restore the existing content.

--HG--
extra : commitid : GTJPPc0CiVF
extra : rebase_source : 8f12d85271b2fa9fbca346659b58dfe7f369b22b
This commit is contained in:
Dave Townsend 2015-08-10 13:38:39 -07:00
parent 2a35d1e14f
commit 1060021790
2 changed files with 74 additions and 8 deletions

View File

@ -8,6 +8,7 @@ this.EXPORTED_SYMBOLS = ["ContentRestore"];
const Cu = Components.utils;
const Ci = Components.interfaces;
const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
@ -182,8 +183,19 @@ ContentRestoreInternal.prototype = {
let webNavigation = this.docShell.QueryInterface(Ci.nsIWebNavigation);
let history = webNavigation.sessionHistory;
// Listen for the tab to finish loading.
this.restoreTabContentStarted(finishCallback);
// Wait for the tab load to complete or fail
this.restoreTabContentStarted((status) => {
// If loadArgument is not null then we're attempting to load a new url
// that required us to switch process. If that load is cancelled (for
// example by a content handler) we want to restore the current history
// entry.
if (loadArguments && (status == Cr.NS_BINDING_ABORTED)) {
this._tabData = tabData;
this.restoreTabContent(null, finishCallback);
} else {
finishCallback();
}
});
// Reset the current URI to about:blank. We changed it above for
// switch-to-tab, but now it must go back to the correct value before the
@ -248,22 +260,26 @@ ContentRestoreInternal.prototype = {
*/
restoreTabContentStarted(finishCallback) {
// The reload listener is no longer needed.
this._historyListener.uninstall();
this._historyListener = null;
if (this._historyListener) {
this._historyListener.uninstall();
this._historyListener = null;
}
// Remove the old progress listener.
this._progressListener.uninstall();
if (this._progressListener) {
this._progressListener.uninstall();
}
// We're about to start a load. This listener will be called when the load
// has finished getting everything from the network.
this._progressListener = new ProgressListener(this.docShell, {
onStopRequest: () => {
onStopRequest: (status) => {
// Call resetRestore() to reset the state back to normal. The data
// needed for restoreDocument() (which hasn't happened yet) will
// remain in _restoringDocument.
this.resetRestore();
finishCallback();
finishCallback(status);
}
});
},
@ -415,7 +431,7 @@ ProgressListener.prototype = {
}
if (stateFlags & STATE_STOP && this.callbacks.onStopRequest) {
this.callbacks.onStopRequest();
this.callbacks.onStopRequest(status);
}
},

View File

@ -45,3 +45,53 @@ add_task(function* () {
// Cleanup.
gBrowser.removeTab(tab);
});
add_task(function* () {
// Add a new non-remote tab.
let tab = gBrowser.addTab("about:robots");
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
ok(!browser.isRemoteBrowser, "browser is not remote");
// Wait for the tab to change to remote before adding the progress listener
tab.addEventListener("TabRemotenessChange", function listener() {
tab.removeEventListener("TabRemotenessChange", listener);
ContentTask.spawn(browser, URL, function*(url) {
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let wp = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress);
wp.addProgressListener({
onStateChange: function(progress, request, stateFlags, status) {
if (!(request instanceof Ci.nsIChannel))
return;
if (request.URI.spec == url) {
request.cancel(Cr.NS_BINDING_ABORTED);
wp.removeProgressListener(this);
}
},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference
])
}, Ci.nsIWebProgress.NOTIFY_ALL);
});
});
// Load a new remote URI and when we see the load start cancel it
browser.loadURI(URL);
yield promiseTabRestored(tab);
let count = yield countHistoryEntries(browser);
is(count, 1, "Should only be the one history entry.");
is(browser.currentURI.spec, "about:robots", "Should be back to the original URI");
ok(!browser.isRemoteBrowser, "Should have gone back to a remote browser");
// Cleanup.
gBrowser.removeTab(tab);
});