From 5e49f50910e72544225eb6e22985b32549c612e2 Mon Sep 17 00:00:00 2001 From: Paul Zuehlcke Date: Wed, 8 Nov 2023 12:07:17 +0000 Subject: [PATCH] Bug 1861215 - Skip recording closed tabs in SessionStore for PBM reset action. r=sfoster,sessionstore-reviewers,tabbrowser-reviewers,dao Differential Revision: https://phabricator.services.mozilla.com/D192686 --- browser/base/content/tabbrowser.js | 22 ++++++++++++++-- .../privatebrowsing/ResetPBMPanel.sys.mjs | 3 +++ .../sessionstore/SessionStore.sys.mjs | 25 ++++++------------- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js index f1d264d84fec..b5eaa371a324 100644 --- a/browser/base/content/tabbrowser.js +++ b/browser/base/content/tabbrowser.js @@ -3635,11 +3635,19 @@ * using it in tandem with `runBeforeUnloadForTabs`. * @param {boolean} options.skipRemoves * Skips actually removing the tabs. The beforeunload handlers still run. + * @param {boolean} options.skipSessionStore + * If true, don't record the closed tabs in SessionStore. * @returns {_startRemoveTabsReturnValue} */ _startRemoveTabs( tabs, - { animate, suppressWarnAboutClosingWindow, skipPermitUnload, skipRemoves } + { + animate, + suppressWarnAboutClosingWindow, + skipPermitUnload, + skipRemoves, + skipSessionStore, + } ) { // Note: if you change any of the unload algorithm, consider also // changing `runBeforeUnloadForTabs` above. @@ -3685,6 +3693,7 @@ animate, prewarmed: true, skipPermitUnload: true, + skipSessionStore, }); } } else { @@ -3717,6 +3726,7 @@ animate, prewarmed: true, skipPermitUnload, + skipSessionStore, }); } } @@ -3786,6 +3796,8 @@ * @param {boolean} [options.skipPermitUnload] * Skips the before unload checks for the tabs. Only set this to true when * using it in tandem with `runBeforeUnloadForTabs`. + * @param {boolean} [options.skipSessionStore] + * If true, don't record the closed tabs in SessionStore. */ removeTabs( tabs, @@ -3793,6 +3805,7 @@ animate = true, suppressWarnAboutClosingWindow = false, skipPermitUnload = false, + skipSessionStore = false, } = {} ) { // When 'closeWindowWithLastTab' pref is enabled, closing all tabs @@ -3820,6 +3833,7 @@ suppressWarnAboutClosingWindow, skipPermitUnload, skipRemoves: false, + skipSessionStore, }); // Wait for all the beforeunload events to have been processed by content processes. @@ -3842,6 +3856,7 @@ animate, prewarmed: true, skipPermitUnload, + skipSessionStore, }; // Now run again sequentially the beforeunload listeners that will result in a prompt. @@ -3886,6 +3901,7 @@ skipPermitUnload, closeWindowWithLastTab, prewarmed, + skipSessionStore, } = {} ) { if (UserInteraction.running("browser.tabs.opening", window)) { @@ -3924,6 +3940,7 @@ skipPermitUnload, closeWindowWithLastTab, prewarmed, + skipSessionStore, }) ) { TelemetryStopwatch.cancel("FX_TAB_CLOSE_TIME_ANIM_MS", aTab); @@ -4004,6 +4021,7 @@ closeWindowFastpath, skipPermitUnload, prewarmed, + skipSessionStore = false, } = {} ) { if (aTab.closing || this._windowIsClosing) { @@ -4149,7 +4167,7 @@ // inspect the tab that's about to close. let evt = new CustomEvent("TabClose", { bubbles: true, - detail: { adoptedBy: adoptedByTab }, + detail: { adoptedBy: adoptedByTab, skipSessionStore }, }); aTab.dispatchEvent(evt); diff --git a/browser/components/privatebrowsing/ResetPBMPanel.sys.mjs b/browser/components/privatebrowsing/ResetPBMPanel.sys.mjs index f1dcf3510653..a25ebc9b7989 100644 --- a/browser/components/privatebrowsing/ResetPBMPanel.sys.mjs +++ b/browser/components/privatebrowsing/ResetPBMPanel.sys.mjs @@ -183,6 +183,9 @@ export const ResetPBMPanel = { newTab, { skipPermitUnload: true, + // Instruct the SessionStore to not save closed tab data for these tabs. + // We don't want to leak them into the next private browsing session. + skipSessionStore: true, animate: false, }, true diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs index 17b592ea19ba..cb23a8c1f7e3 100644 --- a/browser/components/sessionstore/SessionStore.sys.mjs +++ b/browser/components/sessionstore/SessionStore.sys.mjs @@ -1847,7 +1847,9 @@ var SessionStoreInternal = { target.linkedBrowser, aEvent.detail.adoptedBy.linkedBrowser ); - } else { + } else if (!aEvent.detail.skipSessionStore) { + // `skipSessionStore` is set by tab close callers to indicate that we + // shouldn't record the closed tab. this.onTabClose(win, target); } this.onTabRemove(win, target); @@ -2728,23 +2730,12 @@ var SessionStoreInternal = { // Clear closed tab data. if (windowData._closedTabs.length) { - // Remove all of the closed tabs from the _lastClosedActions list - for (let closedTab of windowData._closedTabs) { - // If the closed tab's state still has a .permanentKey property then we - // haven't seen its final update message yet. Remove it from the map of - // closed tabs so that we will simply discard its last messages and will - // not add it back to the list of closed tabs again. - if (closedTab.permanentKey) { - this._closingTabMap.delete(closedTab.permanentKey); - this._tabClosingByWindowMap.delete(closedTab.permanentKey); - delete closedTab.permanentKey; - } - this._removeClosedAction( - this._LAST_ACTION_CLOSED_TAB, - closedTab.closedId - ); + // Remove all of the closed tabs data. + // This also clears out the permenentKey-mapped data for pending state updates + // and removes the tabs from from the _lastClosedActions list + while (windowData._closedTabs.length) { + this.removeClosedTabData(windowData, windowData._closedTabs, 0); } - // Reset the closed tab list. windowData._closedTabs = []; windowData._lastClosedTabGroupCount = -1;