diff --git a/app/browser/reducers/tabsReducer.js b/app/browser/reducers/tabsReducer.js index d4116bb9a07..7232f3ee64c 100644 --- a/app/browser/reducers/tabsReducer.js +++ b/app/browser/reducers/tabsReducer.js @@ -8,9 +8,11 @@ const appConstants = require('../../../js/constants/appConstants') const tabs = require('../tabs') const tabState = require('../../common/state/tabState') const windowConstants = require('../../../js/constants/windowConstants') +const windowAction = require('../../../js/actions/windowActions.js') const {makeImmutable} = require('../../common/state/immutableUtil') const {getFlashResourceId} = require('../../../js/flash') const {l10nErrorText} = require('../../common/lib/httpUtil') +const windows = require('../windows') const tabsReducer = (state, action) => { action = makeImmutable(action) @@ -71,6 +73,51 @@ const tabsReducer = (state, action) => { case appConstants.APP_LOAD_URL_IN_ACTIVE_TAB_REQUESTED: state = tabs.loadURLInActiveTab(state, action) break + case appConstants.APP_ON_GO_BACK: + state = tabs.goBack(state, action) + break + case appConstants.APP_ON_GO_FORWARD: + state = tabs.goForward(state, action) + break + case appConstants.APP_ON_GO_TO_INDEX: + state = tabs.goToIndex(state, action) + break + case appConstants.APP_ON_GO_BACK_LONG: + { + const history = tabs.getHistoryEntries(state, action) + const tabValue = tabState.getByTabId(state, action.get('tabId')) + const windowId = windows.getActiveWindowId() + + if (history !== null) { + windowAction.onLongBackHistory( + history, + action.getIn(['rect', 'left']), + action.getIn(['rect', 'bottom']), + tabValue.get('partitionNumber'), + action.get('tabId'), + windowId + ) + } + break + } + case appConstants.APP_ON_GO_FORWARD_LONG: + { + const history = tabs.getHistoryEntries(state, action) + const tabValue = tabState.getByTabId(state, action.get('tabId')) + const windowId = windows.getActiveWindowId() + + if (history !== null) { + windowAction.onLongForwardHistory( + history, + action.getIn(['rect', 'left']), + action.getIn(['rect', 'bottom']), + tabValue.get('partitionNumber'), + action.get('tabId'), + windowId + ) + } + 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 7241e9b43a1..a0392d2ddff 100644 --- a/app/browser/tabs.js +++ b/app/browser/tabs.js @@ -1,11 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + const appActions = require('../../js/actions/appActions') const config = require('../../js/constants/config') const Immutable = require('immutable') const tabState = require('../common/state/tabState') const {app, BrowserWindow, extensions, session, ipcMain} = require('electron') const {makeImmutable} = require('../common/state/immutableUtil') -const {getTargetAboutUrl, getSourceAboutUrl, isSourceAboutUrl, newFrameUrl} = require('../../js/lib/appUrlUtil') -const {isURL, getUrlFromInput, toPDFJSLocation} = require('../../js/lib/urlutil') +const {getTargetAboutUrl, getSourceAboutUrl, isSourceAboutUrl, newFrameUrl, isTargetAboutUrl} = require('../../js/lib/appUrlUtil') +const {isURL, getUrlFromInput, toPDFJSLocation, getDefaultFaviconUrl} = require('../../js/lib/urlutil') const {isSessionPartition} = require('../../js/state/frameStateUtil') const {getOrigin} = require('../../js/state/siteUtil') const {getSetting} = require('../../js/settings') @@ -69,7 +73,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. */ @@ -619,6 +623,79 @@ const api = { api.createTab(state, action) } return state + }, + + goBack: (state, action) => { + action = makeImmutable(action) + const tab = api.getWebContents(action.get('tabId')) + if (tab && !tab.isDestroyed()) { + tab.goBack() + } + return state + }, + + goForward: (state, action) => { + action = makeImmutable(action) + const tab = api.getWebContents(action.get('tabId')) + if (tab && !tab.isDestroyed()) { + tab.goForward() + } + return state + }, + + goToIndex: (state, action) => { + action = makeImmutable(action) + const tab = api.getWebContents(action.get('tabId')) + if (tab && !tab.isDestroyed()) { + tab.goToIndex(action.get('index')) + } + return state + }, + + getHistoryEntries: (state, action) => { + const tab = api.getWebContents(action.get('tabId')) + const sites = state ? state.get('sites') : null + + if (tab && !tab.isDestroyed()) { + let history = { + count: tab.getEntryCount(), + currentIndex: tab.getCurrentEntryIndex(), + entries: [] + } + + for (let index = 0; index < history.count; index++) { + const url = tab.getURLAtIndex(index) + const title = tab.getTitleAtIndex(index) + + let entry = { + index: index, + url: url, + display: title || url, + icon: null + } + + if (isTargetAboutUrl(url)) { + // 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 = getDefaultFaviconUrl(url) + } + } + + history.entries.push(entry) + } + + return history + } + + return null } } diff --git a/app/browser/windows.js b/app/browser/windows.js index ee336614ba6..c609b6e9a53 100644 --- a/app/browser/windows.js +++ b/app/browser/windows.js @@ -328,6 +328,14 @@ const api = { getWindow: (windowId) => { return currentWindows[windowId] + }, + + getActiveWindowId: () => { + if (BrowserWindow.getFocusedWindow()) { + return BrowserWindow.getFocusedWindow().id + } + + return windowState.WINDOW_ID_NONE } } diff --git a/app/common/state/contextMenuState.js b/app/common/state/contextMenuState.js new file mode 100644 index 00000000000..0f88ce240c1 --- /dev/null +++ b/app/common/state/contextMenuState.js @@ -0,0 +1,37 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const assert = require('assert') +const { makeImmutable, isMap } = require('./immutableUtil') + +const validateState = function (state) { + state = makeImmutable(state) + assert.ok(isMap(state), 'state must be an Immutable.Map') + return state +} + +const contextMenuState = { + setContextMenu: (state, detail) => { + detail = makeImmutable(detail) + state = validateState(state) + + if (!detail) { + if (state.getIn(['contextMenuDetail', 'type']) === 'hamburgerMenu') { + state = state.set('hamburgerMenuWasOpen', true) + } else { + state = state.set('hamburgerMenuWasOpen', false) + } + state = state.delete('contextMenuDetail') + } else { + if (!(detail.get('type') === 'hamburgerMenu' && state.get('hamburgerMenuWasOpen'))) { + state = state.set('contextMenuDetail', detail) + } + state = state.set('hamburgerMenuWasOpen', false) + } + + return state + } +} + +module.exports = contextMenuState diff --git a/app/renderer/components/navigation/navigator.js b/app/renderer/components/navigation/navigator.js index 546069d97ed..4847fac4dc4 100644 --- a/app/renderer/components/navigation/navigator.js +++ b/app/renderer/components/navigation/navigator.js @@ -10,7 +10,6 @@ const ipc = electron.ipcRenderer // 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 @@ -69,7 +68,7 @@ class Navigator extends ImmutableComponent { }) } } else { - navAction.call(this.activeFrame) + navAction.call(this, this.props.activeTab.get('tabId')) } } @@ -122,19 +121,29 @@ class Navigator extends ImmutableComponent { } onBack (e) { - this.onNav(e, 'canGoBack', 'back', this.activeFrame.goBack) + this.onNav(e, 'canGoBack', 'back', appActions.onGoBack) } onForward (e) { - this.onNav(e, 'canGoForward', 'forward', this.activeFrame.goForward) + this.onNav(e, 'canGoForward', 'forward', appActions.onGoForward) } onBackLongPress (target) { - contextMenus.onBackButtonHistoryMenu(this.activeFrame, this.activeFrame.getHistory(this.props.appState), target) + const activeTab = this.props.activeTab + const rect = target.parentNode.getBoundingClientRect() + appActions.onGoBackLong(activeTab.get('tabId'), { + left: rect.left, + bottom: rect.bottom + }) } onForwardLongPress (target) { - contextMenus.onForwardButtonHistoryMenu(this.activeFrame, this.activeFrame.getHistory(this.props.appState), target) + const activeTab = this.props.activeTab + const rect = target.parentNode.getBoundingClientRect() + appActions.onGoForwardLong(activeTab.get('tabId'), { + left: rect.left, + bottom: rect.bottom + }) } onDragOver (e) { diff --git a/app/renderer/reducers/contextMenuReducer.js b/app/renderer/reducers/contextMenuReducer.js new file mode 100644 index 00000000000..5e878a032fe --- /dev/null +++ b/app/renderer/reducers/contextMenuReducer.js @@ -0,0 +1,155 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const assert = require('assert') + +// Constants +const config = require('../../../js/constants/config.js') +const windowConstants = require('../../../js/constants/windowConstants') + +// State +const contextMenuState = require('../../common/state/contextMenuState.js') + +// Actions +const appActions = require('../../../js/actions/appActions.js') +const windowAction = require('../../../js/actions/windowActions.js') + +// Utils +const eventUtil = require('../../../js/lib/eventUtil.js') +const CommonMenu = require('../../common/commonMenu.js') +const locale = require('../../../js/l10n.js') +const { makeImmutable, isMap } = require('../../common/state/immutableUtil') + +const validateAction = function (action) { + action = makeImmutable(action) + assert.ok(isMap(action), 'action must be an Immutable.Map') + return action +} + +const validateState = function (state) { + state = makeImmutable(state) + assert.ok(isMap(state), 'state must be an Immutable.Map') + return state +} + +const onLongBackHistory = (state, action) => { + action = validateAction(action) + state = validateState(state) + const history = action.get('history') + + const menuTemplate = [] + + if (action.get('tabId') > -1 && history && history.get('entries').size > 0) { + const stopIndex = Math.max(((history.get('currentIndex') - config.navigationBar.maxHistorySites) - 1), -1) + for (let index = (history.get('currentIndex') - 1); index > stopIndex; index--) { + const entry = history.getIn(['entries', index]) + const url = entry.get('url') + + menuTemplate.push({ + label: entry.get('display'), + icon: entry.get('icon'), + click: function (e) { + if (eventUtil.isForSecondaryAction(e)) { + appActions.createTabRequested({ + url, + partitionNumber: action.get('partitionNumber'), + active: !!e.shiftKey + }) + } else { + appActions.onGoToIndex(action.get('tabId'), index) + } + } + }) + } + + // Always display "Show History" link + menuTemplate.push( + CommonMenu.separatorMenuItem, + { + label: locale.translation('showAllHistory'), + click: function () { + appActions.createTabRequested({ + url: 'about:history' + }) + windowAction.setContextMenuDetail() + } + }) + + state = contextMenuState.setContextMenu(state, makeImmutable({ + left: action.get('left'), + top: action.get('top'), + template: menuTemplate + })) + } + + return state +} + +const onLongForwardHistory = (state, action) => { + action = validateAction(action) + state = validateState(state) + const history = action.get('history') + + const menuTemplate = [] + + if (action.get('tabId') > -1 && history && history.get('entries').size > 0) { + const stopIndex = Math.min(((history.get('currentIndex') + config.navigationBar.maxHistorySites) + 1), history.get('entries').size) + for (let index = (history.get('currentIndex') + 1); index < stopIndex; index++) { + const entry = history.getIn(['entries', index]) + const url = entry.get('url') + + menuTemplate.push({ + label: entry.get('display'), + icon: entry.get('icon'), + click: function (e) { + if (eventUtil.isForSecondaryAction(e)) { + appActions.createTabRequested({ + url, + partitionNumber: action.get('partitionNumber'), + active: !!e.shiftKey + }) + } else { + appActions.onGoToIndex(action.get('tabId'), index) + } + } + }) + } + + // Always display "Show History" link + menuTemplate.push( + CommonMenu.separatorMenuItem, + { + label: locale.translation('showAllHistory'), + click: function () { + appActions.createTabRequested({ + url: 'about:history' + }) + windowAction.setContextMenuDetail() + } + }) + + state = contextMenuState.setContextMenu(state, makeImmutable({ + left: action.get('left'), + top: action.get('top'), + template: menuTemplate + })) + } + + return state +} + +const contextMenuReducer = (windowState, action) => { + switch (action.actionType) { + case windowConstants.WINDOW_ON_GO_BACK_LONG: + windowState = onLongBackHistory(windowState, action) + break + case windowConstants.WINDOW_ON_GO_FORWARD_LONG: + windowState = onLongForwardHistory(windowState, action) + break + } + + return windowState +} + +module.exports = contextMenuReducer diff --git a/docs/appActions.md b/docs/appActions.md index 5bf3478d23a..d1099a82cbd 100644 --- a/docs/appActions.md +++ b/docs/appActions.md @@ -955,6 +955,62 @@ Notifies the app that a drop operation occurred +### onGoBack(tabId) + +Go back in a history for a given tab + +**Parameters** + +**tabId**: `number`, Tab id used for an action + + + +### onGoForward(tabId) + +Go forward in a history for a given tab + +**Parameters** + +**tabId**: `number`, Tab id used for an action + + + +### onGoToIndex(tabId, index) + +Go to specific item in a history for a given tab + +**Parameters** + +**tabId**: `number`, Tab id used for an action + +**index**: `number`, Index in the history + + + +### onGoBackLong(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 + + + +### onGoForwardLong(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 e64e53043a1..2cfbece5e28 100644 --- a/js/actions/appActions.js +++ b/js/actions/appActions.js @@ -1198,6 +1198,68 @@ const appActions = { actionType: appConstants.APP_DRAGGED_OVER, draggedOverData }) + }, + + /** + * Go back in a history for a given tab + * @param {number} tabId - Tab id used for an action + */ + onGoBack: function (tabId) { + AppDispatcher.dispatch({ + actionType: appConstants.APP_ON_GO_BACK, + tabId + }) + }, + + /** + * Go forward in a history for a given tab + * @param {number} tabId - Tab id used for an action + */ + onGoForward: function (tabId) { + AppDispatcher.dispatch({ + actionType: appConstants.APP_ON_GO_FORWARD, + tabId + }) + }, + + /** + * Go to specific item in a history for a given tab + * @param {number} tabId - Tab id used for an action + * @param {number} index - Index in the history + */ + onGoToIndex: function (tabId, index) { + AppDispatcher.dispatch({ + actionType: appConstants.APP_ON_GO_TO_INDEX, + 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 + */ + onGoBackLong: function (tabId, rect) { + AppDispatcher.dispatch({ + actionType: appConstants.APP_ON_GO_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 + */ + onGoForwardLong: function (tabId, rect) { + AppDispatcher.dispatch({ + actionType: appConstants.APP_ON_GO_FORWARD_LONG, + tabId, + rect + }) } } diff --git a/js/actions/windowActions.js b/js/actions/windowActions.js index 0f21d744d8b..ef4dfa1e8e1 100644 --- a/js/actions/windowActions.js +++ b/js/actions/windowActions.js @@ -1179,6 +1179,34 @@ const windowActions = { actionType: windowConstants.WINDOW_ON_EXIT_FULL_SCREEN, windowId }) + }, + + onLongBackHistory: function (history, left, top, partition, tabId, windowId) { + dispatch({ + actionType: windowConstants.WINDOW_ON_GO_BACK_LONG, + queryInfo: { + windowId + }, + history, + left, + top, + partition, + tabId + }) + }, + + onLongForwardHistory: function (history, left, top, partition, tabId, windowId) { + dispatch({ + actionType: windowConstants.WINDOW_ON_GO_FORWARD_LONG, + queryInfo: { + windowId + }, + history, + left, + top, + partition, + tabId + }) } } diff --git a/js/components/frame.js b/js/components/frame.js index 49672f46e67..ea2ea4cc1bf 100644 --- a/js/components/frame.js +++ b/js/components/frame.js @@ -629,10 +629,10 @@ class Frame extends ImmutableComponent { method = () => this.webview.stop() break case messages.GO_BACK: - method = () => this.webview.goBack() + method = () => appActions.onGoBack(this.props.tabId) break case messages.GO_FORWARD: - method = () => this.webview.goForward() + method = () => appActions.onGoForward(this.props.tabId) break case messages.RELOAD: method = () => { @@ -728,7 +728,7 @@ class Frame extends ImmutableComponent { } else if (isTargetAboutUrl(e.validatedURL)) { // open a new tab for other about urls // and send this tab back to wherever it came from - this.goBack() + appActions.onGoBack(this.props.tabId) appActions.createTabRequested({ url: e.validatedURL, active: true @@ -904,61 +904,6 @@ class Frame extends ImmutableComponent { this.webview.addEventListener('mousewheel', this.onMouseWheel.bind(this)) } - goBack () { - this.webview.goBack() - } - - 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 - } - - goToIndex (index) { - this.webview.goToIndex(index) - } - - goForward () { - this.webview.goForward() - } - get origin () { return siteUtil.getOrigin(this.props.location) } diff --git a/js/components/main.js b/js/components/main.js index 5bb6d619354..ec6997793f8 100644 --- a/js/components/main.js +++ b/js/components/main.js @@ -688,7 +688,6 @@ class Main extends ImmutableComponent { // can be passed everywhere other than the Frame elements. const sortedFrames = frameStateUtil.getSortedFrames(this.props.windowState) const activeFrame = frameStateUtil.getActiveFrame(this.props.windowState) - this.frames = {} const allSiteSettings = this.allSiteSettings const lastCommittedURL = frameStateUtil.getLastCommittedURL(activeFrame) const activeSiteSettings = this.frameSiteSettings(lastCommittedURL) @@ -760,7 +759,6 @@ class Main extends ImmutableComponent { { this.frames[frame.get('key')] = node }} 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 17ff7a89f7e..5ef90c36054 100644 --- a/js/constants/appConstants.js +++ b/js/constants/appConstants.js @@ -115,7 +115,12 @@ const appConstants = { APP_DRAG_STARTED: _, APP_DRAG_STOPPED: _, APP_DATA_DROPPED: _, - APP_DRAGGED_OVER: _ + APP_DRAGGED_OVER: _, + APP_ON_GO_BACK: _, + APP_ON_GO_FORWARD: _, + APP_ON_GO_TO_INDEX: _, + APP_ON_GO_BACK_LONG: _, + APP_ON_GO_FORWARD_LONG: _ } module.exports = mapValuesByKeys(appConstants) diff --git a/js/constants/windowConstants.js b/js/constants/windowConstants.js index 9094daa01fa..b67fdcf97a2 100644 --- a/js/constants/windowConstants.js +++ b/js/constants/windowConstants.js @@ -101,7 +101,9 @@ const windowConstants = { WINDOW_SHOULD_UNMAXIMIZE: _, WINDOW_SHOULD_EXIT_FULL_SCREEN: _, WINDOW_SHOULD_OPEN_DEV_TOOLS: _, - WINDOW_SET_ALL_AUDIO_MUTED: _ + WINDOW_SET_ALL_AUDIO_MUTED: _, + WINDOW_ON_GO_BACK_LONG: _, + WINDOW_ON_GO_FORWARD_LONG: _ } module.exports = mapValuesByKeys(windowConstants) diff --git a/js/contextMenus.js b/js/contextMenus.js index 6d24a52c064..5978cc77f2b 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') @@ -1513,100 +1511,6 @@ function onMoreBookmarksMenu (activeFrame, allBookmarkItems, overflowItems, e) { })) } -function onBackButtonHistoryMenu (activeFrame, history, target) { - const rect = target.parentNode.getBoundingClientRect() - const menuTemplate = [] - - if (activeFrame && 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: activeFrame.props.partitionNumber, - active: !!e.shiftKey - }) - } else { - activeFrame.goToIndex(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 (activeFrame, history, target) { - const rect = target.parentNode.getBoundingClientRect() - const menuTemplate = [] - - if (activeFrame && 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: activeFrame.props.partitionNumber, - active: !!e.shiftKey - }) - } else { - activeFrame.goToIndex(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 = [ @@ -1637,7 +1541,5 @@ module.exports = { onShowUsernameMenu, onShowAutofillMenu, onMoreBookmarksMenu, - onBackButtonHistoryMenu, - onForwardButtonHistoryMenu, onReloadContextMenu } diff --git a/js/lib/urlutil.js b/js/lib/urlutil.js index d4d231f3ceb..f0e230779e4 100644 --- a/js/lib/urlutil.js +++ b/js/lib/urlutil.js @@ -354,7 +354,7 @@ const UrlUtil = { */ getDefaultFaviconUrl: function (url) { if (UrlUtil.isURL(url)) { - const loc = new window.URL(url) + const loc = urlParse(url) return loc.protocol + '//' + loc.host + '/favicon.ico' } return '' diff --git a/js/stores/windowStore.js b/js/stores/windowStore.js index d70bb850e53..3f456e15193 100644 --- a/js/stores/windowStore.js +++ b/js/stores/windowStore.js @@ -25,6 +25,7 @@ const {aboutUrls, getTargetAboutUrl, newFrameUrl} = require('../lib/appUrlUtil') const Serializer = require('../dispatcher/serializer') const {updateTabPageIndex} = require('../../app/renderer/lib/tabUtil') const assert = require('assert') +const contextMenuState = require('../../app/common/state/contextMenuState.js') let windowState = Immutable.fromJS({ activeFrameKey: null, @@ -237,7 +238,8 @@ const emitChanges = debounce(windowStore.emitChanges.bind(windowStore), 5) const applyReducers = (state, action) => [ require('../../app/renderer/reducers/urlBarReducer'), require('../../app/renderer/reducers/urlBarSuggestionsReducer'), - require('../../app/renderer/reducers/frameReducer') + require('../../app/renderer/reducers/frameReducer'), + require('../../app/renderer/reducers/contextMenuReducer') ].reduce( (windowState, reducer) => { const newState = reducer(windowState, action) @@ -472,19 +474,7 @@ const doAction = (action) => { } break case windowConstants.WINDOW_SET_CONTEXT_MENU_DETAIL: - if (!action.detail) { - if (windowState.getIn(['contextMenuDetail', 'type']) === 'hamburgerMenu') { - windowState = windowState.set('hamburgerMenuWasOpen', true) - } else { - windowState = windowState.set('hamburgerMenuWasOpen', false) - } - windowState = windowState.delete('contextMenuDetail') - } else { - if (!(action.detail.get('type') === 'hamburgerMenu' && windowState.get('hamburgerMenuWasOpen'))) { - windowState = windowState.set('contextMenuDetail', action.detail) - } - windowState = windowState.set('hamburgerMenuWasOpen', false) - } + windowState = contextMenuState.setContextMenu(windowState, action.detail) break case windowConstants.WINDOW_SET_POPUP_WINDOW_DETAIL: if (!action.detail) {