Skip to content

Commit

Permalink
Bug 675539 - Make tab discard functionality work on tab objects direc…
Browse files Browse the repository at this point in the history
…tly r=mconley

This removes the need to go through the browser-to-tab mapping when discarding
a tab and simplifies the relevant code. Besides being renamed discardBrowser()
was also split so that one can check if a tab can be discarded prior to trying
it.

Differential Revision: https://phabricator.services.mozilla.com/D20475

--HG--
extra : moz-landing-system : lando
  • Loading branch information
gabrielesvelto committed Feb 26, 2019
1 parent f9ecc88 commit 0443979
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 46 deletions.
80 changes: 45 additions & 35 deletions browser/base/content/tabbrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2196,67 +2196,77 @@ window._gBrowser = {
aTab.dispatchEvent(evt);
},

discardBrowser(aBrowser, aForceDiscard) {
"use strict";
_mayDiscardBrowser(aTab, aForceDiscard) {
let browser = aTab.linkedBrowser;
let permitUnloadFlags = aForceDiscard ? browser.dontPromptAndUnload
: browser.dontPromptAndDontUnload;

let tab = this.getTabForBrowser(aBrowser);
if (!aTab ||
aTab.selected ||
aTab.closing ||
this._windowIsClosing ||
!browser.isConnected ||
!browser.isRemoteBrowser ||
!browser.permitUnload(permitUnloadFlags).permitUnload) {
return false;
}

let permitUnloadFlags = aForceDiscard ? aBrowser.dontPromptAndUnload : aBrowser.dontPromptAndDontUnload;
return true;
},

if (!tab ||
tab.selected ||
tab.closing ||
this._windowIsClosing ||
!aBrowser.isConnected ||
!aBrowser.isRemoteBrowser ||
!aBrowser.permitUnload(permitUnloadFlags).permitUnload) {
return;
discardBrowser(aTab, aForceDiscard) {
"use strict";
let browser = aTab.linkedBrowser;

if (!this._mayDiscardBrowser(aTab, aForceDiscard)) {
return false;
}

// Reset webrtc sharing state.
if (tab._sharingState) {
this.setBrowserSharing(aBrowser, {});
if (aTab._sharingState) {
this.setBrowserSharing(browser, {});
}
webrtcUI.forgetStreamsFromBrowser(aBrowser);
webrtcUI.forgetStreamsFromBrowser(browser);

// 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,
// be done before browser is destroyed and removed from the document.
aTab._browserParams = {
uriIsAboutBlank: browser.currentURI.spec == "about:blank",
remoteType: browser.remoteType,
usingPreloadedContent: false,
};

SessionStore.resetBrowserToLazyState(tab);
SessionStore.resetBrowserToLazyState(aTab);

this._outerWindowIDBrowserMap.delete(aBrowser.outerWindowID);
this._outerWindowIDBrowserMap.delete(browser.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);
let filter = this._tabFilters.get(aTab);
let listener = this._tabListeners.get(aTab);
browser.webProgress.removeProgressListener(filter);
filter.removeProgressListener(listener);
listener.destroy();

this._tabListeners.delete(tab);
this._tabFilters.delete(tab);
this._tabListeners.delete(aTab);
this._tabFilters.delete(aTab);

// Reset the findbar and remove it if it is attached to the tab.
if (tab._findBar) {
tab._findBar.close(true);
tab._findBar.remove();
delete tab._findBar;
if (aTab._findBar) {
aTab._findBar.close(true);
aTab._findBar.remove();
delete aTab._findBar;
}

aBrowser.destroy();
this.getPanel(aBrowser).remove();
tab.removeAttribute("linkedpanel");
browser.destroy();
this.getPanel(browser).remove();
aTab.removeAttribute("linkedpanel");

this._createLazyBrowser(tab);
this._createLazyBrowser(aTab);

let evt = new CustomEvent("TabBrowserDiscarded", { bubbles: true });
tab.dispatchEvent(evt);
aTab.dispatchEvent(evt);
return true;
},

/**
Expand Down
2 changes: 1 addition & 1 deletion browser/components/extensions/parent/ext-tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ this.tabs = class extends ExtensionAPI {

async discard(tabIds) {
for (let nativeTab of getNativeTabsFromIDArray(tabIds)) {
nativeTab.ownerGlobal.gBrowser.discardBrowser(nativeTab.linkedBrowser);
nativeTab.ownerGlobal.gBrowser.discardBrowser(nativeTab);
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ add_task(async function test() {
let tab0 = gBrowser.tabs[0];
let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);

gBrowser.discardBrowser(tab0.linkedBrowser);
gBrowser.discardBrowser(tab0);
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);
gBrowser.discardBrowser(tab0);
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);
gBrowser.discardBrowser(tab1);

ok(tab1.linkedPanel, "cannot suspend a tab that is closing");

Expand All @@ -32,27 +32,25 @@ add_task(async function test() {
// Open tab containing a page which has a beforeunload handler which shows a prompt.
url = "http://example.com/browser/browser/components/sessionstore/test/browser_1284886_suspend_tab.html";
tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
let browser1 = tab1.linkedBrowser;
await BrowserTestUtils.switchTab(gBrowser, tab0);

// Test that tab with beforeunload handler which would show a prompt cannot be suspended.
gBrowser.discardBrowser(browser1);
gBrowser.discardBrowser(tab1);
ok(tab1.linkedPanel, "cannot suspend a tab with beforeunload handler which would show a prompt");

// Test that tab with beforeunload handler which would show a prompt will be suspended if forced.
gBrowser.discardBrowser(browser1, true);
gBrowser.discardBrowser(tab1, true);
ok(!tab1.linkedPanel, "force suspending a tab with beforeunload handler which would show a prompt");

BrowserTestUtils.removeTab(tab1);

// Open tab containing a page which has a beforeunload handler which does not show a prompt.
url = "http://example.com/browser/browser/components/sessionstore/test/browser_1284886_suspend_tab_2.html";
tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
browser1 = tab1.linkedBrowser;
await BrowserTestUtils.switchTab(gBrowser, tab0);

// Test that tab with beforeunload handler which would not show a prompt can be suspended.
gBrowser.discardBrowser(browser1);
gBrowser.discardBrowser(tab1);
ok(!tab1.linkedPanel, "can suspend a tab with beforeunload handler which would not show a prompt");

BrowserTestUtils.removeTab(tab1);
Expand All @@ -64,7 +62,7 @@ add_task(async function test() {
await BrowserTestUtils.switchTab(gBrowser, tab1);
await BrowserTestUtils.switchTab(gBrowser, tab0);

gBrowser.discardBrowser(tab1.linkedBrowser);
gBrowser.discardBrowser(tab1);
ok(tab1.linkedPanel, "cannot suspend a remote tab");

BrowserTestUtils.removeTab(tab1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def test_close_browserless_tab(self):
win.addEventListener("TabBrowserDiscarded", ev => {
arguments[0](true);
}, { once: true});
win.gBrowser.discardBrowser(win.gBrowser.tabs[1].linkedBrowser);
win.gBrowser.discardBrowser(win.gBrowser.tabs[1]);
""")

window_handles = self.marionette.window_handles
Expand Down

0 comments on commit 0443979

Please sign in to comment.