From 6a87879c09e0c21fbac1a0799efb969901e4f4e8 Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Mon, 22 Aug 2016 13:54:46 -0400 Subject: [PATCH] Clear recently closed when clearing browsing history Auditors: @aekeus Fix #3287 --- app/sessionStore.js | 9 +++++-- js/actions/windowActions.js | 9 +++++++ js/constants/messages.js | 1 + js/constants/windowConstants.js | 1 + js/entry.js | 8 +++++- js/stores/appStore.js | 2 ++ js/stores/windowStore.js | 3 +++ test/components/clearBrowsingDataPanelTest.js | 27 +++++++++++++++++++ test/lib/brave.js | 17 ++++++++++++ 9 files changed, 74 insertions(+), 3 deletions(-) diff --git a/app/sessionStore.js b/app/sessionStore.js index c306b97e0b8..44885cb0b95 100644 --- a/app/sessionStore.js +++ b/app/sessionStore.js @@ -89,7 +89,7 @@ module.exports.saveAppState = (payload, isShutdown) => { /** * Cleans session data from unwanted values. */ -module.exports.cleanPerWindowData = (perWindowData) => { +module.exports.cleanPerWindowData = (perWindowData, isShutdown) => { if (!perWindowData) { perWindowData = {} } @@ -195,6 +195,10 @@ module.exports.cleanPerWindowData = (perWindowData) => { } } } + const clearHistory = isShutdown && getSetting(settings.SHUTDOWN_CLEAR_HISTORY) === true + if (clearHistory) { + perWindowData.closedFrames = [] + } // Clean closed frame data before frames because the keys are re-ordered // and the new next key is calculated in windowStore.js based on @@ -233,7 +237,8 @@ module.exports.cleanAppData = (data, isShutdown) => { // Get rid of them here. delete data.windows if (data.perWindowState) { - data.perWindowState.forEach(module.exports.cleanPerWindowData) + data.perWindowState.forEach((perWindowState) => + module.exports.cleanPerWindowData(perWindowState, isShutdown)) } // Delete expired Flash approvals let now = Date.now() diff --git a/js/actions/windowActions.js b/js/actions/windowActions.js index 0656d734a39..cb0ae8b455c 100644 --- a/js/actions/windowActions.js +++ b/js/actions/windowActions.js @@ -375,6 +375,15 @@ const windowActions = { }) }, + /** + * Dispatches a message to the store to clear closed frames + */ + clearClosedFrames: function () { + dispatch({ + actionType: WindowConstants.WINDOW_CLEAR_CLOSED_FRAMES + }) + }, + /** * Dispatches a message to the store to set a new frame as the active frame. * diff --git a/js/constants/messages.js b/js/constants/messages.js index 792231447c7..fdcc070f01c 100644 --- a/js/constants/messages.js +++ b/js/constants/messages.js @@ -109,6 +109,7 @@ const messages = { RESPONSE_WINDOW_STATE: _, LAST_WINDOW_STATE: _, UNDO_CLOSED_WINDOW: _, + CLEAR_CLOSED_FRAMES: _, // Menu rebuilding REQUEST_MENU_DATA_FOR_WINDOW: _, RESPONSE_MENU_DATA_FOR_WINDOW: _, diff --git a/js/constants/windowConstants.js b/js/constants/windowConstants.js index 9085a0e3718..fa4db57ab3f 100644 --- a/js/constants/windowConstants.js +++ b/js/constants/windowConstants.js @@ -36,6 +36,7 @@ const windowConstants = { WINDOW_SET_NAVIGATED: _, WINDOW_SET_URL_BAR_ACTIVE: _, // whether the URL bar is being typed in WINDOW_UNDO_CLOSED_FRAME: _, + WINDOW_CLEAR_CLOSED_FRAMES: _, WINDOW_SET_ACTIVE_FRAME_SHORTCUT: _, WINDOW_SET_URL_BAR_SELECTED: _, WINDOW_SET_SEARCH_DETAIL: _, diff --git a/js/entry.js b/js/entry.js index 020cc73fcd8..4f319b93d29 100644 --- a/js/entry.js +++ b/js/entry.js @@ -30,6 +30,7 @@ const ipc = electron.ipcRenderer const webFrame = electron.webFrame const windowStore = require('./stores/windowStore') const appStoreRenderer = require('./stores/appStoreRenderer') +const windowActions = require('./actions/windowActions') const messages = require('./constants/messages') const Immutable = require('immutable') const patch = require('immutablepatch') @@ -66,7 +67,8 @@ ipc.on(messages.REQUEST_MENU_DATA_FOR_WINDOW, () => { if (process.env.NODE_ENV === 'test') { window.appStoreRenderer = appStoreRenderer - window.windowActions = require('./actions/windowActions') + window.windowActions = windowActions + window.windowStore = windowStore } ipc.on(messages.APP_STATE_CHANGE, (e, action) => { @@ -75,6 +77,10 @@ ipc.on(messages.APP_STATE_CHANGE, (e, action) => { : appStoreRenderer.state = Immutable.fromJS(action.state) }) +ipc.on(messages.CLEAR_CLOSED_FRAMES, () => { + windowActions.clearClosedFrames() +}) + window.addEventListener('beforeunload', function () { ipc.send(messages.LAST_WINDOW_STATE, windowStore.getState().toJS()) }) diff --git a/js/stores/appStore.js b/js/stores/appStore.js index dff54de3e1b..732dfc18a21 100644 --- a/js/stores/appStore.js +++ b/js/stores/appStore.js @@ -523,6 +523,8 @@ const handleAppAction = (action) => { case AppConstants.APP_CLEAR_DATA: if (action.clearDataDetail.get('browserHistory')) { handleAppAction({actionType: AppConstants.APP_CLEAR_SITES_WITHOUT_TAGS}) + BrowserWindow.getAllWindows().forEach((wnd) => wnd.webContents.send(messages.CLEAR_CLOSED_FRAMES)) + BrowserWindow.getAllWindows().forEach((wnd) => wnd.webContents.send(messages.REQUEST_MENU_DATA_FOR_WINDOW)) } if (action.clearDataDetail.get('downloadHistory')) { handleAppAction({actionType: AppConstants.APP_CLEAR_COMPLETED_DOWNLOADS}) diff --git a/js/stores/windowStore.js b/js/stores/windowStore.js index 9ed2094ae02..7db1c3c1af0 100644 --- a/js/stores/windowStore.js +++ b/js/stores/windowStore.js @@ -458,6 +458,9 @@ const doAction = (action) => { windowState = windowState.merge(FrameStateUtil.undoCloseFrame(windowState, windowState.get('closedFrames'))) focusWebview(activeFrameStatePath()) break + case WindowConstants.WINDOW_CLEAR_CLOSED_FRAMES: + windowState = windowState.set('closedFrames', new Immutable.List()) + break case WindowConstants.WINDOW_SET_ACTIVE_FRAME: if (!action.frameProps) { break diff --git a/test/components/clearBrowsingDataPanelTest.js b/test/components/clearBrowsingDataPanelTest.js index 5a87d7b8326..77217e06cc9 100644 --- a/test/components/clearBrowsingDataPanelTest.js +++ b/test/components/clearBrowsingDataPanelTest.js @@ -3,6 +3,7 @@ const Brave = require('../lib/brave') const {urlInput, clearBrowsingDataPanel} = require('../lib/selectors') const {getTargetAboutUrl} = require('../../js/lib/appUrlUtil') +const messages = require('../../js/constants/messages') describe('Clear Browsing Panel', function () { function * setup (client) { @@ -56,5 +57,31 @@ describe('Clear Browsing Panel', function () { }) }) }) + it('Clearing browsing history clears closedFrames', function * () { + const page1Url = Brave.server.url('page1.html') + yield this.app.client + .windowByUrl(Brave.browserWindowUrl) + .tabByIndex(0) + .url(page1Url) + .windowByUrl(Brave.browserWindowUrl) + .ipcSend(messages.SHORTCUT_NEW_FRAME, page1Url) + .waitUntil(function () { + return this.getWindowState().then((val) => { + return val.value.frames.length === 2 + }) + }) + .ipcSend(messages.SHORTCUT_CLOSE_FRAME) + .waitUntil(function () { + return this.getWindowState().then((val) => { + return val.value.closedFrames.length === 1 + }) + }) + .clearAppData({browserHistory: true}) + .waitUntil(function () { + return this.getWindowState().then((val) => { + return val.value.closedFrames.length === 0 + }) + }) + }) }) }) diff --git a/test/lib/brave.js b/test/lib/brave.js index a79eb504873..48f0e13a12a 100644 --- a/test/lib/brave.js +++ b/test/lib/brave.js @@ -190,6 +190,12 @@ var exports = { }) }) + this.app.client.addCommand('getWindowState', function () { + return this.execute(function () { + return window.windowStore.state.toJS() + }) + }) + this.app.client.addCommand('showFindbar', function (show) { return this.execute(function (show) { window.windowActions.setFindbarShown(Object.assign({ @@ -269,6 +275,17 @@ var exports = { }, key, value).then((response) => response.value) }) + /** + * Clears application data + * + * @param {object} clearDataDetail - the options to use for clearing + */ + this.app.client.addCommand('clearAppData', function (clearDataDetail) { + return this.execute(function (clearDataDetail) { + return require('../../../js/actions/appActions').clearAppData(clearDataDetail) + }, clearDataDetail).then((response) => response.value) + }) + this.app.client.addCommand('getDefaultWindowHeight', function () { return this.execute(function () { let screen = require('electron').screen