Bug 1284886 - Add discardBrowser method to tabbrowser.xml, which returns tab to its lazy state. r=dao, r=mikedeboer

--HG--
extra : rebase_source : b63734bccd6a08535e2037fcd05081ade819e40b
This commit is contained in:
Kevin Jones 2017-09-03 15:31:00 -04:00
Родитель faea0f5c55
Коммит 0a5839402a
5 изменённых файлов: 174 добавлений и 14 удалений

Просмотреть файл

@ -2271,7 +2271,8 @@
"audioPlaybackStopped", "pauseMedia", "stopMedia", "audioPlaybackStopped", "pauseMedia", "stopMedia",
"resumeMedia", "mute", "unmute", "blockedPopups", "lastURI", "resumeMedia", "mute", "unmute", "blockedPopups", "lastURI",
"purgeSessionHistory", "stopScroll", "startScroll", "purgeSessionHistory", "stopScroll", "startScroll",
"userTypedValue", "userTypedClear", "mediaBlocked" "userTypedValue", "userTypedClear", "mediaBlocked",
"didStartLoadSinceLastUserTyping"
]</field> ]</field>
<method name="_createLazyBrowser"> <method name="_createLazyBrowser">
@ -2299,6 +2300,9 @@
return Services.io.newURI(url); return Services.io.newURI(url);
}; };
break; break;
case "didStartLoadSinceLastUserTyping":
getter = () => () => false;
break;
case "fullZoom": case "fullZoom":
case "textZoom": case "textZoom":
getter = () => 1; getter = () => 1;
@ -2441,6 +2445,56 @@
</body> </body>
</method> </method>
<method name="discardBrowser">
<parameter name="aBrowser"/>
<body>
<![CDATA[
"use strict";
let tab = this.getTabForBrowser(aBrowser);
if (!tab ||
tab.selected ||
tab.closing ||
this._windowIsClosing ||
!aBrowser.isConnected ||
!aBrowser.isRemoteBrowser ||
aBrowser.frameLoader.tabParent.hasBeforeUnload) {
return;
}
// Set browser parameters for when browser is restored. Also remove
// listeners and set up lazy restore data in SessionStore. This must
// be done before aBrowser is destroyed and removed from the document.
tab._browserParams = { uriIsAboutBlank: aBrowser.currentURI.spec == "about:blank",
remoteType: aBrowser.remoteType,
usingPreloadedContent: false };
SessionStore.resetBrowserToLazyState(tab);
this._outerWindowIDBrowserMap.delete(aBrowser.outerWindowID);
// Remove the tab's filter and progress listener.
let filter = this._tabFilters.get(tab);
let listener = this._tabListeners.get(tab);
aBrowser.webProgress.removeProgressListener(filter);
filter.removeProgressListener(listener);
listener.destroy();
this._tabListeners.delete(tab);
this._tabFilters.delete(tab);
aBrowser.destroy();
let notificationbox = this.getNotificationBox(aBrowser);
this.mPanelContainer.removeChild(notificationbox);
tab.removeAttribute("linkedpanel");
this._createLazyBrowser(tab);
]]>
</body>
</method>
<method name="addTab"> <method name="addTab">
<parameter name="aURI"/> <parameter name="aURI"/>
<parameter name="aReferrerURI"/> <parameter name="aReferrerURI"/>

Просмотреть файл

@ -370,6 +370,10 @@ this.SessionStore = {
return SessionStoreInternal.undoCloseById(aClosedId); return SessionStoreInternal.undoCloseById(aClosedId);
}, },
resetBrowserToLazyState(tab) {
return SessionStoreInternal.resetBrowserToLazyState(tab);
},
/** /**
* Determines whether the passed version number is compatible with * Determines whether the passed version number is compatible with
* the current version number of the SessionStore. * the current version number of the SessionStore.
@ -1898,19 +1902,7 @@ var SessionStoreInternal = {
* bool Do not save state if we're updating an existing tab * bool Do not save state if we're updating an existing tab
*/ */
onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) { onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) {
let browser = aTab.linkedBrowser; this.cleanUpRemovedBrowser(aTab);
browser.removeEventListener("SwapDocShells", this);
browser.removeEventListener("oop-browser-crashed", this);
// 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
// restore the next tab.
let previousState = browser.__SS_restoreState;
if (previousState) {
this._resetTabRestoringState(aTab);
if (previousState == TAB_STATE_RESTORING)
this.restoreNextTab();
}
if (!aNoNotification) { if (!aNoNotification) {
this.saveStateDelayed(aWindow); this.saveStateDelayed(aWindow);
@ -1979,6 +1971,57 @@ var SessionStoreInternal = {
this._closedTabs.set(permanentKey, {closedTabs, tabData}); this._closedTabs.set(permanentKey, {closedTabs, tabData});
}, },
/**
* Remove listeners which were added when browser was inserted and reset restoring state.
* Also re-instate lazy data and basically revert tab to its lazy browser state.
* @param aTab
* Tab reference
*/
resetBrowserToLazyState(aTab) {
let browser = aTab.linkedBrowser;
// Browser is already lazy so don't do anything.
if (!browser.isConnected) {
return;
}
this.cleanUpRemovedBrowser(aTab);
aTab.setAttribute("pending", "true");
this._lastKnownFrameLoader.delete(browser.permanentKey);
this._crashedBrowsers.delete(browser.permanentKey);
aTab.removeAttribute("crashed");
aTab.__SS_lazyData = {
url: browser.currentURI.spec,
title: aTab.label,
userTypedValue: browser.userTypedValue || "",
userTypedClear: browser.userTypedClear || 0
}
},
/**
* When a tab is removed or suspended, remove listeners and reset restoring state.
* @param aBrowser
* Browser reference
*/
cleanUpRemovedBrowser(aTab) {
let browser = aTab.linkedBrowser;
browser.removeEventListener("SwapDocShells", this);
browser.removeEventListener("oop-browser-crashed", this);
// 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
// restore the next tab.
let previousState = browser.__SS_restoreState;
if (previousState) {
this._resetTabRestoringState(aTab);
if (previousState == TAB_STATE_RESTORING)
this.restoreNextTab();
}
},
/** /**
* Insert a given |tabData| object into the list of |closedTabs|. We will * Insert a given |tabData| object into the list of |closedTabs|. We will
* determine the right insertion point based on the .closedAt properties of * determine the right insertion point based on the .closedAt properties of

Просмотреть файл

@ -55,6 +55,7 @@ support-files =
restore_redirect_js.html restore_redirect_js.html
restore_redirect_target.html restore_redirect_target.html
browser_1234021_page.html browser_1234021_page.html
browser_1284886_suspend_tab.html
#NB: the following are disabled #NB: the following are disabled
# browser_464620_a.html # browser_464620_a.html
@ -228,6 +229,7 @@ skip-if = os == "mac" || (os == "linux" && debug) # linux, Bug 1348583
[browser_906076_lazy_tabs.js] [browser_906076_lazy_tabs.js]
[browser_911547.js] [browser_911547.js]
[browser_1284886_suspend_tab.js]
[browser_send_async_message_oom.js] [browser_send_async_message_oom.js]
[browser_multiple_navigateAndRestore.js] [browser_multiple_navigateAndRestore.js]
run-if = e10s run-if = e10s

Просмотреть файл

@ -0,0 +1,12 @@
<html>
<head>
<script>
window.onbeforeunload = function() {
return true;
}
</script>
</head>
<body>
TEST PAGE
</body>
</html>

Просмотреть файл

@ -0,0 +1,49 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function test() {
let url = "about:robots";
let tab0 = gBrowser.tabs[0];
let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
gBrowser.discardBrowser(tab0.linkedBrowser);
ok(!tab0.linkedPanel, "tab0 is suspended");
await BrowserTestUtils.switchTab(gBrowser, tab0);
// Test that active tab is not able to be suspended.
gBrowser.discardBrowser(tab0.linkedBrowser);
ok(tab0.linkedPanel, "active tab is not able to be suspended");
// Test that tab that is closing is not able to be suspended.
gBrowser._beginRemoveTab(tab1);
gBrowser.discardBrowser(tab1.linkedBrowser);
ok(tab1.linkedPanel, "cannot suspend a tab that is closing");
gBrowser._endRemoveTab(tab1);
// Test that tab with beforeunload handler is not able to be suspended.
url = "http://example.com/browser/browser/components/sessionstore/test/browser_1284886_suspend_tab.html";
tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
await BrowserTestUtils.switchTab(gBrowser, tab0);
gBrowser.discardBrowser(tab1.linkedBrowser);
ok(tab1.linkedPanel, "cannot suspend a tab with beforeunload handler");
await promiseRemoveTab(tab1);
// Test that remote tab is not able to be suspended.
url = "about:robots";
tab1 = BrowserTestUtils.addTab(gBrowser, url, { forceNotRemote: true });
await promiseBrowserLoaded(tab1.linkedBrowser, true, url);
await BrowserTestUtils.switchTab(gBrowser, tab1);
await BrowserTestUtils.switchTab(gBrowser, tab0);
gBrowser.discardBrowser(tab1.linkedBrowser);
ok(tab1.linkedPanel, "cannot suspend a remote tab");
promiseRemoveTab(tab1);
});