diff --git a/app/browser/reducers/tabsReducer.js b/app/browser/reducers/tabsReducer.js index f947f2b9c1b..43e2589a63f 100644 --- a/app/browser/reducers/tabsReducer.js +++ b/app/browser/reducers/tabsReducer.js @@ -75,6 +75,12 @@ const tabsReducer = (state, action) => { case appConstants.APP_ON_NAVIGATE_INDEX: state = tabs.goToIndex(state, action) break + case appConstants.APP_ON_NAVIGATE_BACK_LONG: + state = tabs.longPressBack(state, action) + break + case appConstants.APP_ON_NAVIGATE_FORWARD_LONG: + state = tabs.longPressForward(state, action) + break case appConstants.APP_FRAME_CHANGED: state = tabState.updateFrame(state, action) break diff --git a/app/browser/tabs.js b/app/browser/tabs.js index d437769e799..86346e94f28 100644 --- a/app/browser/tabs.js +++ b/app/browser/tabs.js @@ -18,6 +18,7 @@ const aboutHistoryState = require('../common/state/aboutHistoryState') const appStore = require('../../js/stores/appStore') const appConfig = require('../../js/constants/appConfig') const siteTags = require('../../js/constants/siteTags') +const historyState = require('../common/state/historyState.js') const {newTabMode} = require('../common/constants/settingsEnums') let currentWebContents = {} @@ -66,7 +67,7 @@ const getPartitionNumber = (partition) => { } /** - * Obtains the curent partition. + * Obtains the current partition. * Warning: This function has global side effects in that it increments the * global next partition number if isPartitioned is passed into the create options. */ @@ -638,6 +639,20 @@ const api = { const tab = api.getWebContents(action.get('tabId')) tab.goToIndex(action.get('index')) return state + }, + + longPressBack: (state, action) => { + const tabId = action.get('tabId') + const webContent = api.getWebContents(tabId) + historyState.onBackButtonHistory(state, tabId, webContent, action.get('rect')) + return state + }, + + longPressForward: (state, action) => { + const tabId = action.get('tabId') + const webContent = api.getWebContents(tabId) + historyState.onForwardButtonHistory(state, tabId, webContent, action.get('rect')) + return state } } diff --git a/app/common/state/historyState.js b/app/common/state/historyState.js new file mode 100644 index 00000000000..429bfd51091 --- /dev/null +++ b/app/common/state/historyState.js @@ -0,0 +1,166 @@ +const Immutable = require('immutable') +const tabState = require('./tabState.js') +const config = require('../../../js/constants/config.js') +const eventUtil = require('../../../js/lib/eventUtil.js') +const appActions = require('../../../js/actions/appActions.js') +const windowActions = require('../../../js/actions/windowActions.js') +const UrlUtil = require('../../../js/lib/urlutil.js') +const locale = require('../../locale.js') +const CommonMenu = require('../commonMenu.js') + +const onBackButtonHistoryMenu = (tabId, partitionNumber, history, rect) => { + const menuTemplate = [] + + if (tabId > -1 && history && history.entries.length > 0) { + const stopIndex = Math.max(((history.currentIndex - config.navigationBar.maxHistorySites) - 1), -1) + for (let index = (history.currentIndex - 1); index > stopIndex; index--) { + const url = history.entries[index].url + + menuTemplate.push({ + label: history.entries[index].display, + icon: history.entries[index].icon, + click: (e) => { + if (eventUtil.isForSecondaryAction(e)) { + appActions.createTabRequested({ + url, + partitionNumber: partitionNumber, + active: !!e.shiftKey + }) + } else { + appActions.onNavigateIndex(tabId, index) + } + } + }) + } + + // Always display "Show History" link + menuTemplate.push( + CommonMenu.separatorMenuItem, + { + label: locale.translation('showAllHistory'), + click: () => { + appActions.createTabRequested({ + url: 'about:history' + }) + windowActions.setContextMenuDetail() + } + }) + } + + windowActions.setContextMenuDetail(Immutable.fromJS({ + left: rect.left, + top: rect.bottom, + template: menuTemplate + })) +} + +const onForwardButtonHistoryMenu = (tabId, partitionNumber, history, rect) => { + const menuTemplate = [] + + if (tabId > -1 && history && history.entries.length > 0) { + const stopIndex = Math.max(((history.currentIndex - config.navigationBar.maxHistorySites) - 1), -1) + for (let index = (history.currentIndex - 1); index > stopIndex; index--) { + const url = history.entries[index].url + + menuTemplate.push({ + label: history.entries[index].display, + icon: history.entries[index].icon, + click: (e) => { + if (eventUtil.isForSecondaryAction(e)) { + appActions.createTabRequested({ + url, + partitionNumber: partitionNumber, + active: !!e.shiftKey + }) + } else { + appActions.onNavigateIndex(tabId, index) + } + } + }) + } + + // Always display "Show History" link + menuTemplate.push( + CommonMenu.separatorMenuItem, + { + label: locale.translation('showAllHistory'), + click: () => { + appActions.createTabRequested({ + url: 'about:history' + }) + windowActions.setContextMenuDetail() + } + }) + } + + windowActions.setContextMenuDetail(Immutable.fromJS({ + left: rect.left, + top: rect.bottom, + template: menuTemplate + })) +} + +const historyState = { + getHistoryItems: (state, webContent) => { + const historyCount = webContent.getEntryCount() + const currentIndex = webContent.getCurrentEntryIndex() + const sites = state ? state.get('sites') : null + + let history = { + count: historyCount, + currentIndex, + entries: [] + } + + for (let index = 0; index < historyCount; index++) { + const url = webContent.getURLAtIndex(index) + const title = webContent.getTitleAtIndex(index) + + let entry = { + index: index, + url: url, + display: title || url, + icon: null + } + + if (url.startsWith('chrome-extension://')) { + // TODO: return brave lion (or better: get icon from extension if possible as data URI) + } else { + if (sites) { + const site = sites.find(function (element) { return element.get('location') === url }) + if (site) { entry.icon = site.get('favicon') } + } + + if (!entry.icon) { entry.icon = UrlUtil.getDefaultFaviconUrl(url) } + } + + history.entries.push(entry) + } + + return history + }, + + onBackButtonHistory: (state, tabId, webContent, rect) => { + const tabValue = tabState.getByTabId(state, tabId) + + onBackButtonHistoryMenu( + tabValue.get('tabId'), + tabValue.get('partitionNumber'), + historyState.getHistoryItems(state, webContent), + rect + ) + }, + + onForwardButtonHistoryMenu: (state, tabId, webContent, rect) => { + const tabValue = tabState.getByTabId(state, tabId) + + onForwardButtonHistoryMenu( + tabValue.get('tabId'), + tabValue.get('partitionNumber'), + historyState.getHistoryItems(state, webContent), + rect + ) + } +} + +module.exports = historyState diff --git a/app/renderer/components/navigation/navigator.js b/app/renderer/components/navigation/navigator.js index 06b33136f0e..26175ab614c 100644 --- a/app/renderer/components/navigation/navigator.js +++ b/app/renderer/components/navigation/navigator.js @@ -8,7 +8,6 @@ const {StyleSheet, css} = require('aphrodite') // Actions const appActions = require('../../../../js/actions/appActions') const windowActions = require('../../../../js/actions/windowActions') -const contextMenus = require('../../../../js/contextMenus') const getSetting = require('../../../../js/settings').getSetting // Components @@ -128,12 +127,14 @@ class Navigator extends ImmutableComponent { onBackLongPress (target) { const activeTab = this.props.activeTab - contextMenus.onBackButtonHistoryMenu(activeTab.get('tabId'), activeTab.get('partitionNumber'), this.activeFrame.getHistory(this.props.appState), target) + const rect = target.parentNode.getBoundingClientRect() + appActions.onNavigateBackLong(activeTab.get('tabId'), rect) } onForwardLongPress (target) { const activeTab = this.props.activeTab - contextMenus.onForwardButtonHistoryMenu(activeTab.get('tabId'), activeTab.get('partitionNumber'), this.activeFrame.getHistory(this.props.appState), target) + const rect = target.parentNode.getBoundingClientRect() + appActions.onNavigateForwardLong(activeTab.get('tabId'), rect) } onDragOver (e) { diff --git a/docs/appActions.md b/docs/appActions.md index a092e44a76f..d022aadc7d3 100644 --- a/docs/appActions.md +++ b/docs/appActions.md @@ -987,6 +987,30 @@ Go to specific item in a history for a given tab +### onNavigateBackLong(tabId, rect) + +Go back in a history for a given tab + +**Parameters** + +**tabId**: `number`, Tab id used for an action + +**rect**: `ClientRect`, Parent element position for this action + + + +### onNavigateForwardLong(tabId, rect) + +Go forward in a history for a given tab + +**Parameters** + +**tabId**: `number`, Tab id used for an action + +**rect**: `ClientRect`, Parent element position for this action + + + * * * diff --git a/js/actions/appActions.js b/js/actions/appActions.js index f99829f778a..4fe05a28e6a 100644 --- a/js/actions/appActions.js +++ b/js/actions/appActions.js @@ -1233,6 +1233,32 @@ const appActions = { tabId, index }) + }, + + /** + * Go back in a history for a given tab + * @param {number} tabId - Tab id used for an action + * @param {ClientRect} rect - Parent element position for this action + */ + onNavigateBackLong: function (tabId, rect) { + AppDispatcher.dispatch({ + actionType: appConstants.APP_ON_NAVIGATE_BACK_LONG, + tabId, + rect + }) + }, + + /** + * Go forward in a history for a given tab + * @param {number} tabId - Tab id used for an action + * @param {ClientRect} rect - Parent element position for this action + */ + onNavigateForwardLong: function (tabId, rect) { + AppDispatcher.dispatch({ + actionType: appConstants.APP_ON_NAVIGATE_FORWARD_LONG, + tabId, + rect + }) } } diff --git a/js/actions/windowActions.js b/js/actions/windowActions.js index a40109e4ac9..3de28fe3d16 100644 --- a/js/actions/windowActions.js +++ b/js/actions/windowActions.js @@ -6,7 +6,7 @@ const AppDispatcher = require('../dispatcher/appDispatcher') const windowConstants = require('../constants/windowConstants') -const windowStore = require('../stores/windowStore') +// const windowStore = require('../stores/windowStore') TODO refactor function dispatch (action) { AppDispatcher.dispatch(action) @@ -638,7 +638,7 @@ const windowActions = { * @param {Object} frameToSkip - Properties of the frame to keep audio */ muteAllAudioExcept: function (frameToSkip) { - let framePropsList = windowStore.getState().get('frames') + /* let framePropsList = windowStore.getState().get('frames') framePropsList.forEach((frameProps) => { if (frameProps.get('key') !== frameToSkip.get('key') && frameProps.get('audioPlaybackActive') && !frameProps.get('audioMuted')) { @@ -646,7 +646,7 @@ const windowActions = { } else { this.setAudioMuted(frameProps, false) } - }) + }) */ }, /** diff --git a/js/components/frame.js b/js/components/frame.js index 573d29da41e..fafc6756e32 100644 --- a/js/components/frame.js +++ b/js/components/frame.js @@ -904,49 +904,6 @@ class Frame extends ImmutableComponent { this.webview.addEventListener('mousewheel', this.onMouseWheel.bind(this)) } - getHistoryEntry (sites, index) { - const url = this.webview.getURLAtIndex(index) - const title = this.webview.getTitleAtIndex(index) - - let entry = { - index: index, - url: url, - display: title || url, - icon: null - } - - if (url.startsWith('chrome-extension://')) { - // TODO: return brave lion (or better: get icon from extension if possible as data URI) - } else { - if (sites) { - const site = sites.find(function (element) { return element.get('location') === url }) - if (site) { entry.icon = site.get('favicon') } - } - - if (!entry.icon) { entry.icon = UrlUtil.getDefaultFaviconUrl(url) } - } - - return entry - } - - getHistory (appState) { - const historyCount = this.webview.getEntryCount() - const currentIndex = this.webview.getCurrentEntryIndex() - const sites = appState ? appState.get('sites') : null - - let history = { - count: historyCount, - currentIndex, - entries: [] - } - - for (let index = 0; index < historyCount; index++) { - history.entries.push(this.getHistoryEntry(sites, index)) - } - - return history - } - get origin () { return siteUtil.getOrigin(this.props.location) } diff --git a/js/components/main.js b/js/components/main.js index 996da1238dd..3014a398fc0 100644 --- a/js/components/main.js +++ b/js/components/main.js @@ -763,7 +763,6 @@ class Main extends ImmutableComponent { { this.frames[frame.get('key')] = node }} // TODO remove urlBarFocused={activeFrame && activeFrame.getIn(['navbar', 'urlbar', 'focused'])} tabIndex={frameStateUtil.getFrameIndex(this.props.windowState, frame.get('key'))} prefOpenInForeground={getSetting(settings.SWITCH_TO_NEW_TABS)} diff --git a/js/constants/appConstants.js b/js/constants/appConstants.js index 8c5e098bc01..46460e6e860 100644 --- a/js/constants/appConstants.js +++ b/js/constants/appConstants.js @@ -118,7 +118,9 @@ const appConstants = { APP_DRAGGED_OVER: _, APP_ON_NAVIGATE_BACK: _, APP_ON_NAVIGATE_FORWARD: _, - APP_ON_NAVIGATE_INDEX: _ + APP_ON_NAVIGATE_INDEX: _, + APP_ON_NAVIGATE_BACK_LONG: _, + APP_ON_NAVIGATE_FORWARD_LONG: _ } module.exports = mapValuesByKeys(appConstants) diff --git a/js/contextMenus.js b/js/contextMenus.js index 90849c6995d..3e5f9580a79 100644 --- a/js/contextMenus.js +++ b/js/contextMenus.js @@ -33,9 +33,7 @@ const {getPartitionFromNumber, frameOptsFromFrame, getActiveFrame} = require('./ const {isIntermediateAboutPage, isUrl, aboutUrls} = require('./lib/appUrlUtil') const {getBase64FromImageUrl} = require('./lib/imageUtil') const urlParse = require('../app/common/urlParse') -const eventUtil = require('./lib/eventUtil') const {getCurrentWindow} = require('../app/renderer/currentWindow') -const config = require('./constants/config') const {bookmarksToolbarMode} = require('../app/common/constants/settingsEnums') const extensionState = require('../app/common/state/extensionState') const extensionActions = require('../app/common/actions/extensionActions') @@ -1489,100 +1487,6 @@ function onMoreBookmarksMenu (activeFrame, allBookmarkItems, overflowItems, e) { })) } -function onBackButtonHistoryMenu (tabId, partitionNumber, history, target) { - const rect = target.parentNode.getBoundingClientRect() - const menuTemplate = [] - - if (tabId > -1 && history && history.entries.length > 0) { - const stopIndex = Math.max(((history.currentIndex - config.navigationBar.maxHistorySites) - 1), -1) - for (let index = (history.currentIndex - 1); index > stopIndex; index--) { - const url = history.entries[index].url - - menuTemplate.push({ - label: history.entries[index].display, - icon: history.entries[index].icon, - click: (e) => { - if (eventUtil.isForSecondaryAction(e)) { - appActions.createTabRequested({ - url, - partitionNumber: partitionNumber, - active: !!e.shiftKey - }) - } else { - appActions.onNavigateIndex(tabId, index) - } - } - }) - } - - // Always display "Show History" link - menuTemplate.push( - CommonMenu.separatorMenuItem, - { - label: locale.translation('showAllHistory'), - click: (e) => { - appActions.createTabRequested({ - url: 'about:history' - }) - windowActions.setContextMenuDetail() - } - }) - } - - windowActions.setContextMenuDetail(Immutable.fromJS({ - left: rect.left, - top: rect.bottom, - template: menuTemplate - })) -} - -function onForwardButtonHistoryMenu (tabId, partitionNumber, history, target) { - const rect = target.parentNode.getBoundingClientRect() - const menuTemplate = [] - - if (tabId > -1 && history && history.entries.length > 0) { - const stopIndex = Math.min(((history.currentIndex + config.navigationBar.maxHistorySites) + 1), history.entries.length) - for (let index = (history.currentIndex + 1); index < stopIndex; index++) { - const url = history.entries[index].url - - menuTemplate.push({ - label: history.entries[index].display, - icon: history.entries[index].icon, - click: (e) => { - if (eventUtil.isForSecondaryAction(e)) { - appActions.createTabRequested({ - url, - partitionNumber: partitionNumber, - active: !!e.shiftKey - }) - } else { - appActions.onNavigateIndex(tabId, index) - } - } - }) - } - - // Always display "Show History" link - menuTemplate.push( - CommonMenu.separatorMenuItem, - { - label: locale.translation('showAllHistory'), - click: (e) => { - appActions.createTabRequested({ - url: 'about:history' - }) - windowActions.setContextMenuDetail() - } - }) - } - - windowActions.setContextMenuDetail(Immutable.fromJS({ - left: rect.left, - top: rect.bottom, - template: menuTemplate - })) -} - function onReloadContextMenu (target) { const rect = target.getBoundingClientRect() const menuTemplate = [ @@ -1613,7 +1517,5 @@ module.exports = { onShowUsernameMenu, onShowAutofillMenu, onMoreBookmarksMenu, - onBackButtonHistoryMenu, - onForwardButtonHistoryMenu, onReloadContextMenu }