diff --git a/app/browser/menu.js b/app/browser/menu.js index 2141ff48f00..c532c7dd322 100644 --- a/app/browser/menu.js +++ b/app/browser/menu.js @@ -20,7 +20,7 @@ const settings = require('../../js/constants/settings') // State const {getByTabId} = require('../common/state/tabState') -const tabState = require('../../app/common/state/tabState') +const tabState = require('../common/state/tabState') const appStore = require('../../js/stores/appStore') // Actions @@ -485,7 +485,7 @@ const createHelpSubmenu = () => { return submenu } -const createDebugSubmenu = () => { +const createDebugSubmenu = (state) => { return [ { // Makes future renderer processes pause when they are created until a debugger appears. @@ -533,6 +533,13 @@ const createDebugSubmenu = () => { const win = BrowserWindow.getActiveWindow() appActions.noReportStateModeClicked(win.id) } + }, { + label: 'Allow manual tab discarding', + type: 'checkbox', + checked: !!getSetting(settings.DEBUG_ALLOW_MANUAL_TAB_DISCARD), + click: function (menuItem, browserWindow, e) { + appActions.changeSetting(settings.DEBUG_ALLOW_MANUAL_TAB_DISCARD, menuItem.checked) + } } ] } @@ -570,7 +577,7 @@ const createMenu = (state) => { ] if (process.env.NODE_ENV === 'development' || process.env.BRAVE_ENABLE_DEBUG_MENU !== undefined) { - template.push({ label: 'Debug', submenu: createDebugSubmenu() }) + template.push({ label: 'Debug', submenu: createDebugSubmenu(state) }) } if (isDarwin) { @@ -661,6 +668,9 @@ const doAction = (state, action) => { // Update the checkbox next to "Bookmarks Toolbar" (Bookmarks menu) setMenuItemChecked(state, locale.translation('bookmarksToolbar'), action.value) } + if (action.key === settings.DEBUG_ALLOW_MANUAL_TAB_DISCARD) { + setMenuItemChecked(state, 'Allow manual tab discarding', action.value) + } break case windowConstants.WINDOW_UNDO_CLOSED_FRAME: { diff --git a/app/browser/reducers/tabsReducer.js b/app/browser/reducers/tabsReducer.js index bd37fa3fd7a..b2935dbffba 100644 --- a/app/browser/reducers/tabsReducer.js +++ b/app/browser/reducers/tabsReducer.js @@ -119,6 +119,13 @@ const tabsReducer = (state, action, immutableAction) => { state = tabs.closeOtherTabs(state, tabId) break } + case appConstants.APP_DISCARD_TAB_REQUESTED: { + const tabId = action.get('tabId') + setImmediate(() => { + tabs.discard(tabId) + }) + break + } case appConstants.APP_CREATE_TAB_REQUESTED: if (action.getIn(['createProperties', 'windowId']) == null) { const senderWindowId = action.getIn(['senderWindowId']) diff --git a/app/browser/tabs.js b/app/browser/tabs.js index adbe6b25a8a..b5e0da8b6c4 100644 --- a/app/browser/tabs.js +++ b/app/browser/tabs.js @@ -770,6 +770,18 @@ const api = { } }, + discard: (tabId) => { + const tab = webContentsCache.getWebContents(tabId) + if (tab && !tab.isDestroyed()) { + tab.discard() + } else { + console.error( + `Asked for tab ${tabId} to be discarded but ` + + (tab ? 'tab was not in cache' : 'tab was discarded') + ) + } + }, + loadURL: (action) => { action = makeImmutable(action) const tabId = action.get('tabId') diff --git a/js/actions/appActions.js b/js/actions/appActions.js index 72d910fba75..1cde5b5e522 100644 --- a/js/actions/appActions.js +++ b/js/actions/appActions.js @@ -221,6 +221,13 @@ const appActions = { }) }, + discardTabRequested: function (tabId) { + dispatch({ + actionType: appConstants.APP_DISCARD_TAB_REQUESTED, + tabId + }) + }, + /** * A request for a new tab has been made with the specified createProperties * @param {Object} createProperties diff --git a/js/constants/appConfig.js b/js/constants/appConfig.js index 0c554de6885..dd8dadfa0a6 100644 --- a/js/constants/appConfig.js +++ b/js/constants/appConfig.js @@ -230,7 +230,8 @@ module.exports = { 'general.is-default-browser': null, 'notification-add-funds-timestamp': null, 'notification-reconcile-soon-timestamp': null, - + // debug + 'debug.manual-tab-discard.enabled': false, // DEPRECATED settings // DO NOT REMOVE OR CHANGE THESE VALUES // ######################## diff --git a/js/constants/appConstants.js b/js/constants/appConstants.js index 41e2ed91789..3d303216de0 100644 --- a/js/constants/appConstants.js +++ b/js/constants/appConstants.js @@ -57,6 +57,7 @@ const appConstants = { APP_CLOSE_TABS_TO_LEFT_MENU_ITEM_CLICKED: _, APP_CLOSE_TABS_TO_RIGHT_MENU_ITEM_CLICKED: _, APP_CLOSE_OTHER_TABS_MENU_ITEM_CLICKED: _, + APP_DISCARD_TAB_REQUESTED: _, APP_TAB_ATTACHED: _, APP_TAB_WILL_ATTACH: _, APP_TAB_ACTIVATE_REQUESTED: _, diff --git a/js/constants/settings.js b/js/constants/settings.js index e31aade2d5f..60947eb2089 100644 --- a/js/constants/settings.js +++ b/js/constants/settings.js @@ -97,6 +97,8 @@ const settings = { PINTEREST_ENABLED: 'extensions.pinterest.enabled', METAMASK_ENABLED: 'extensions.metamask.enabled', METAMASK_PROMPT_DISMISSED: 'extensions.metamask.promptDismissed', + // Debug settings + DEBUG_ALLOW_MANUAL_TAB_DISCARD: 'debug.manual-tab-discard.enabled', // DEPRECATED settings // DO NOT REMOVE OR CHANGE THESE VALUES diff --git a/js/contextMenus.js b/js/contextMenus.js index 84852bb437b..994e3cc94ea 100644 --- a/js/contextMenus.js +++ b/js/contextMenus.js @@ -549,6 +549,19 @@ function tabTemplateInit (frameProps) { } }, CommonMenu.separatorMenuItem) + // debug options, only in development + if (getSetting(settings.DEBUG_ALLOW_MANUAL_TAB_DISCARD) === true) { + template.push( + { + label: 'Discard', + click: (item) => { + appActions.discardTabRequested(tabId) + } + }, + CommonMenu.separatorMenuItem + ) + } + template.push(Object.assign({}, CommonMenu.reopenLastClosedTabItem(), { enabled: closedFrames ? closedFrames.size > 0 : false }