diff --git a/app/renderer/components/menubar.js b/app/renderer/components/menubar.js
index c4dcf663925..94120dbb726 100644
--- a/app/renderer/components/menubar.js
+++ b/app/renderer/components/menubar.js
@@ -53,22 +53,19 @@ class MenubarItem extends ImmutableComponent {
}
// If clicking on an already selected item, deselect it
const selected = this.props.menubar.props.selectedIndex
- ? this.props.menubar.props.selectedIndex[0]
- : null
if (selected && selected === this.props.index) {
windowActions.setContextMenuDetail()
- windowActions.setSubmenuSelectedIndex()
+ windowActions.setMenuBarSelectedIndex()
return
}
// Otherwise, mark item as selected and show its context menu
- windowActions.setSubmenuSelectedIndex([this.props.index])
+ windowActions.setMenuBarSelectedIndex(this.props.index)
+ windowActions.setContextMenuSelectedIndex([0])
const rect = e.target.getBoundingClientRect()
showContextMenu(rect, this.props.submenu, this.props.lastFocusedSelector)
}
onMouseOver (e) {
const selected = this.props.menubar.props.selectedIndex
- ? this.props.menubar.props.selectedIndex[0]
- : null
if (typeof selected === 'number' && selected !== this.props.index) {
this.onClick(e)
}
@@ -101,196 +98,75 @@ class Menubar extends ImmutableComponent {
document.removeEventListener('keydown', this.onKeyDown)
}
- /**
- * Used to get the submenu of a top level menu like File, Edit, etc.
- * Index will default to the selected menu if not provided / valid.
- */
- getTemplate (index) {
- if (typeof index !== 'number') index = this.props.selectedIndex[0]
- return this.props.template.get(index).get('submenu')
- }
- /**
- * Same as getTemplate but excluding line separators and items that are not visible.
- */
- getTemplateItemsOnly (index) {
- return this.getTemplate(index).filter((element) => {
- if (element.get('type') === separatorMenuItem.type) return false
- if (element.has('visible')) return element.get('visible')
- return true
- })
- }
/**
* Get client rect for the MenubarItem controls.
* Used to position the context menu object.
*/
getMenubarItemBounds (index) {
- if (typeof index !== 'number') index = this.props.selectedIndex[0]
+ if (typeof index !== 'number') index = this.props.selectedIndex
const selected = document.querySelectorAll('.menubar .menubarItem[data-index=\'' + index + '\']')
if (selected.length === 1) {
return selected.item(0).getBoundingClientRect()
}
return null
}
- /**
- * Get client rect for the actively selected ContextMenu.
- * Used to position the child menu if parent has children.
- */
- getContextMenuItemBounds () {
- const selected = document.querySelectorAll('.contextMenuItem.selectedByKeyboard')
- if (selected.length > 0) {
- return selected.item(selected.length - 1).getBoundingClientRect()
- }
- return null
- }
- /**
- * Returns index for the active / focused menu.
- */
- get currentIndex () {
- return this.props.selectedIndex[this.props.selectedIndex.length - 1]
- }
- /**
- * Upper bound for the active / focused menu.
- */
- get maxIndex () {
- return this.getMenuByIndex().size - 1
- }
- /**
- * Returns true is current state is inside a regular menu.
- */
- get hasMenuSelection () {
- return this.props.selectedIndex.length > 1
- }
- /**
- * Returns true if current state is inside a submenu.
- */
- get hasSubmenuSelection () {
- return this.props.selectedIndex.length > 2
- }
- /**
- * Fetch menu based on selected index.
- * Will navigate children to find nested menus.
- */
- getMenuByIndex (parentItem, currentDepth) {
- if (!parentItem) parentItem = this.getTemplateItemsOnly()
- if (!currentDepth) currentDepth = 0
-
- const selectedIndices = this.props.selectedIndex.slice(1)
- if (selectedIndices.length === 0) return parentItem
-
- const submenuIndex = selectedIndices[currentDepth]
- const childItem = parentItem.get(submenuIndex)
-
- if (childItem && childItem.get('submenu') && currentDepth < (selectedIndices.length - 1)) {
- return this.getMenuByIndex(childItem.get('submenu'), currentDepth + 1)
- }
-
- return parentItem
- }
onKeyDown (e) {
const selectedIndex = this.props.selectedIndex
+ const template = this.props.template
+ const contextMenuIndex = this.props.contextMenuSelectedIndex
- if (!selectedIndex || !this.props.template) return
+ if (!template) return
switch (e.which) {
- case keyCodes.ENTER:
- e.preventDefault()
- const selectedLabel = this.getMenuByIndex().getIn([this.currentIndex, 'label'])
- windowActions.clickMenubarSubmenu(selectedLabel)
- windowActions.resetMenuState()
- break
-
case keyCodes.LEFT:
case keyCodes.RIGHT:
- e.preventDefault()
-
- // Left arrow inside a submenu
- // <= go back one level
- if (e.which === keyCodes.LEFT && this.hasSubmenuSelection) {
- const newIndices = selectedIndex.slice()
- newIndices.pop()
- windowActions.setSubmenuSelectedIndex(newIndices)
-
- let openedSubmenuDetails = this.props.contextMenuDetail.get('openedSubmenuDetails')
- ? this.props.contextMenuDetail.get('openedSubmenuDetails')
- : new Immutable.List()
- openedSubmenuDetails = openedSubmenuDetails.pop()
-
- windowActions.setContextMenuDetail(this.props.contextMenuDetail.set('openedSubmenuDetails', openedSubmenuDetails))
- break
+ if (contextMenuIndex !== null) {
+ const currentTemplate = template.get(selectedIndex).get('submenu').filter((element) => {
+ if (element.get('type') === separatorMenuItem.type) return false
+ if (element.has('visible')) return element.get('visible')
+ return true
+ }).get(contextMenuIndex[0])
+
+ if (currentTemplate && currentTemplate.has('submenu')) {
+ break
+ }
}
- const selectedMenuItem = selectedIndex
- ? this.getMenuByIndex().get(this.currentIndex)
- : null
-
- // Right arrow on a menu item which has a submenu
- // => go up one level (default next menu to item 0)
- if (e.which === keyCodes.RIGHT && selectedMenuItem && selectedMenuItem.has('submenu')) {
- const newIndices = selectedIndex.slice()
- newIndices.push(0)
- windowActions.setSubmenuSelectedIndex(newIndices)
-
- let openedSubmenuDetails = this.props.contextMenuDetail.get('openedSubmenuDetails')
- ? this.props.contextMenuDetail.get('openedSubmenuDetails')
- : new Immutable.List()
-
- const rect = this.getContextMenuItemBounds()
- const itemHeight = (rect.bottom - rect.top)
-
- openedSubmenuDetails = openedSubmenuDetails.push(Immutable.fromJS({
- y: (rect.top - itemHeight),
- template: selectedMenuItem.get('submenu')
- }))
-
- windowActions.setContextMenuDetail(this.props.contextMenuDetail.set('openedSubmenuDetails', openedSubmenuDetails))
- break
- }
+ e.preventDefault()
+ e.stopPropagation()
// Regular old menu item
const nextIndex = selectedIndex === null
? 0
: wrappingClamp(
- selectedIndex[0] + (e.which === keyCodes.LEFT ? -1 : 1),
+ selectedIndex + (e.which === keyCodes.LEFT ? -1 : 1),
0,
this.props.template.size - 1)
- // Context menu already being displayed; auto-open the next one
+ windowActions.setMenuBarSelectedIndex(nextIndex)
+
if (this.props.contextMenuDetail) {
- windowActions.setSubmenuSelectedIndex([nextIndex, 0])
- showContextMenu(this.getMenubarItemBounds(nextIndex), this.getTemplate(nextIndex).toJS(), this.props.lastFocusedSelector)
+ windowActions.setContextMenuSelectedIndex([0])
+ showContextMenu(this.getMenubarItemBounds(nextIndex), template.get(nextIndex).get('submenu').toJS(), this.props.lastFocusedSelector)
} else {
- windowActions.setSubmenuSelectedIndex([nextIndex])
+ windowActions.setContextMenuSelectedIndex()
}
break
- case keyCodes.UP:
case keyCodes.DOWN:
+ case keyCodes.ENTER:
e.preventDefault()
- if (this.getTemplateItemsOnly()) {
- if (!this.props.contextMenuDetail) {
- // First time hitting up/down; popup the context menu
- const newIndices = selectedIndex.slice()
- newIndices.push(0)
- windowActions.setSubmenuSelectedIndex(newIndices)
- showContextMenu(this.getMenubarItemBounds(), this.getTemplate().toJS(), this.props.lastFocusedSelector)
- } else {
- // Context menu already visible; move selection up or down
- const nextIndex = wrappingClamp(
- this.currentIndex + (e.which === keyCodes.UP ? -1 : 1),
- 0,
- this.maxIndex)
-
- const newIndices = selectedIndex.slice()
- if (this.hasMenuSelection) {
- newIndices[selectedIndex.length - 1] = nextIndex
- } else {
- newIndices.push(0)
- }
- windowActions.setSubmenuSelectedIndex(newIndices)
- }
+ if (contextMenuIndex === null && template.get(selectedIndex).has('submenu')) {
+ e.stopPropagation()
+ windowActions.setContextMenuSelectedIndex([0])
+ showContextMenu(this.getMenubarItemBounds(selectedIndex), template.get(selectedIndex).get('submenu').toJS(), this.props.lastFocusedSelector)
}
break
+
+ case keyCodes.UP:
+ e.preventDefault()
+
}
}
shouldComponentUpdate (nextProps, nextState) {
@@ -309,7 +185,7 @@ class Menubar extends ImmutableComponent {
lastFocusedSelector: this.props.lastFocusedSelector,
menubar: this
}
- if (this.props.selectedIndex && props.index === this.props.selectedIndex[0]) {
+ if (props.index === this.props.selectedIndex) {
props.selected = true
}
return
diff --git a/docs/windowActions.md b/docs/windowActions.md
index d817b85702e..4aea42ff0d0 100644
--- a/docs/windowActions.md
+++ b/docs/windowActions.md
@@ -871,10 +871,10 @@ Used by `main.js` when click happens on content area (not on a link or react con
-### setSubmenuSelectedIndex(index)
+### setMenuBarSelectedIndex(index)
(Windows only)
-Used to track selected index of a context menu
+Used to track selected index of a menu bar
Needed because arrow keys can be used to navigate the custom menu
**Parameters**
@@ -884,6 +884,18 @@ Needed because arrow keys can be used to navigate the custom menu
+### setContextMenuSelectedIndex(index)
+
+Used to track selected index of a context menu
+Needed because arrow keys can be used to navigate the context menu
+
+**Parameters**
+
+**index**: `number`, zero based index of the item.
+ Index excludes menu separators and hidden items.
+
+
+
### setLastFocusedSelector(selector)
(Windows only at the moment)
diff --git a/js/actions/windowActions.js b/js/actions/windowActions.js
index 9fdea5b66eb..141768a6ec1 100644
--- a/js/actions/windowActions.js
+++ b/js/actions/windowActions.js
@@ -1108,14 +1108,27 @@ const windowActions = {
/**
* (Windows only)
- * Used to track selected index of a context menu
+ * Used to track selected index of a menu bar
* Needed because arrow keys can be used to navigate the custom menu
* @param {number} index - zero based index of the item.
* Index excludes menu separators and hidden items.
*/
- setSubmenuSelectedIndex: function (index) {
+ setMenuBarSelectedIndex: function (index) {
+ dispatch({
+ actionType: windowConstants.WINDOW_SET_MENUBAR_SELECTED_INDEX,
+ index
+ })
+ },
+
+ /**
+ * Used to track selected index of a context menu
+ * Needed because arrow keys can be used to navigate the context menu
+ * @param {number} index - zero based index of the item.
+ * Index excludes menu separators and hidden items.
+ */
+ setContextMenuSelectedIndex: function (index) {
dispatch({
- actionType: windowConstants.WINDOW_SET_SUBMENU_SELECTED_INDEX,
+ actionType: windowConstants.WINDOW_SET_CONTEXT_MENU_SELECTED_INDEX,
index
})
},
diff --git a/js/components/contextMenu.js b/js/components/contextMenu.js
index 6cfd4612217..620518746f9 100644
--- a/js/components/contextMenu.js
+++ b/js/components/contextMenu.js
@@ -8,21 +8,11 @@ const ImmutableComponent = require('./immutableComponent')
const windowActions = require('../actions/windowActions')
const cx = require('../lib/classSet')
const KeyCodes = require('../../app/common/constants/keyCodes')
-const {formatAccelerator} = require('../../app/common/lib/formatUtil')
+const {formatAccelerator, wrappingClamp} = require('../../app/common/lib/formatUtil')
const separatorMenuItem = require('../../app/common/commonMenu').separatorMenuItem
+const keyCodes = require('../../app/common/constants/keyCodes')
class ContextMenuItem extends ImmutableComponent {
- componentDidMount () {
- window.addEventListener('keydown', this.onKeyDown)
- }
- componentWillUnmount () {
- window.removeEventListener('keydown', this.onKeyDown)
- }
- onKeyDown (e) {
- if (e.keyCode === KeyCodes.ESC || e.keyCode === KeyCodes.TAB) {
- windowActions.setContextMenuDetail()
- }
- }
get submenu () {
return this.props.contextMenuItem.get('submenu')
}
@@ -100,10 +90,6 @@ class ContextMenuItem extends ImmutableComponent {
}
windowActions.setContextMenuDetail(this.props.contextMenuDetail.set('openedSubmenuDetails', openedSubmenuDetails))
}
- onMouseLeave (e) {
- if (this.hasSubmenu) {
- }
- }
getLabelForItem (item) {
const label = item.get('label')
if (label) {
@@ -170,7 +156,6 @@ class ContextMenuItem extends ImmutableComponent {
onContextMenu={this.onContextMenu.bind(this)}
disabled={this.props.contextMenuItem.get('enabled') === false}
onMouseEnter={this.onMouseEnter.bind(this)}
- onMouseLeave={this.onMouseLeave.bind(this)}
onClick={this.onClick.bind(this, this.props.contextMenuItem.get('click'), true)}>
{
this.props.contextMenuItem.get('checked')
@@ -252,13 +237,165 @@ class ContextMenuSingle extends ImmutableComponent {
* Represents a context menu including all submenus
*/
class ContextMenu extends ImmutableComponent {
+ constructor () {
+ super()
+ this.onKeyDown = this.onKeyDown.bind(this)
+ }
+
+ componentDidMount () {
+ window.addEventListener('keydown', this.onKeyDown)
+ window.addEventListener('keyup', this.onKeyUp)
+ }
+
+ componentWillUnmount () {
+ window.removeEventListener('keydown', this.onKeyDown)
+ window.removeEventListener('keyup', this.onKeyUp)
+ }
+
+ onKeyDown (e) {
+ const selectedIndex = (this.props.selectedIndex === null) ? [0] : this.props.selectedIndex
+ const currentIndex = selectedIndex[selectedIndex.length - 1]
+ const selectedTemplate = this.getMenuByIndex(selectedIndex, this.props.contextMenuDetail.get('template'))
+ const selectedMenuItem = selectedTemplate.get(currentIndex)
+
+ switch (e.keyCode) {
+ case keyCodes.ENTER:
+ e.preventDefault()
+ e.stopPropagation()
+ const action = selectedTemplate.getIn([currentIndex, 'click'])
+ if (action) {
+ action(e)
+ }
+ windowActions.resetMenuState()
+ break
+
+ case KeyCodes.ESC:
+ case KeyCodes.TAB:
+ windowActions.resetMenuState()
+ break
+
+ case keyCodes.LEFT:
+ // Left arrow inside a sub menu
+ // <= go back one level
+ if (this.hasSubmenuSelection) {
+ const newIndices = selectedIndex.slice()
+ newIndices.pop()
+ windowActions.setContextMenuSelectedIndex(newIndices)
+
+ let openedSubmenuDetails = this.props.contextMenuDetail.get('openedSubmenuDetails')
+ ? this.props.contextMenuDetail.get('openedSubmenuDetails')
+ : new Immutable.List()
+ openedSubmenuDetails = openedSubmenuDetails.pop()
+
+ windowActions.setContextMenuDetail(this.props.contextMenuDetail.set('openedSubmenuDetails', openedSubmenuDetails))
+ }
+ break
+
+ case keyCodes.RIGHT:
+ // Right arrow on a menu item which has a sub menu
+ // => go up one level (default next menu to item 0)
+ const isSubMenu = !!selectedMenuItem.get('submenu')
+
+ if (isSubMenu) {
+ e.stopPropagation()
+ const newIndices = selectedIndex.slice()
+ newIndices.push(0)
+ windowActions.setContextMenuSelectedIndex(newIndices)
+
+ let openedSubmenuDetails = this.props.contextMenuDetail.get('openedSubmenuDetails')
+ ? this.props.contextMenuDetail.get('openedSubmenuDetails')
+ : new Immutable.List()
+
+ const rect = this.getContextMenuItemBounds()
+ const itemHeight = (rect.bottom - rect.top)
+
+ openedSubmenuDetails = openedSubmenuDetails.push(Immutable.fromJS({
+ y: (rect.top - itemHeight),
+ template: selectedMenuItem.get('submenu')
+ }))
+
+ windowActions.setContextMenuDetail(this.props.contextMenuDetail.set('openedSubmenuDetails', openedSubmenuDetails))
+ }
+ break
+
+ case keyCodes.UP:
+ case keyCodes.DOWN:
+ if (this.props.contextMenuDetail) {
+ const nextIndex = wrappingClamp(
+ currentIndex + (e.which === keyCodes.UP ? -1 : 1),
+ 0,
+ this.maxIndex(selectedTemplate))
+
+ const newIndices = selectedIndex.slice()
+ newIndices[selectedIndex.length - 1] = nextIndex
+ windowActions.setContextMenuSelectedIndex(newIndices)
+ }
+ break
+ }
+ }
+
+ onKeyUp (e) {
+ e.preventDefault()
+ }
+
onClick () {
windowActions.resetMenuState()
}
+
+ getTemplateItemsOnly (template) {
+ return template.filter((element) => {
+ if (element.get('type') === separatorMenuItem.type) return false
+ if (element.has('visible')) return element.get('visible')
+ return true
+ })
+ }
+
+ getMenuByIndex (selectedIndex, parentItem, currentDepth) {
+ parentItem = this.getTemplateItemsOnly(parentItem)
+ if (!currentDepth) currentDepth = 0
+
+ const selectedIndices = selectedIndex.slice(1)
+ if (selectedIndices.length === 0) return parentItem
+
+ const submenuIndex = selectedIndex[0]
+ const childItem = parentItem.get(submenuIndex)
+
+ if (childItem && childItem.get('submenu')) {
+ return this.getMenuByIndex(selectedIndices, childItem.get('submenu'), currentDepth + 1)
+ }
+
+ return parentItem
+ }
+
+ getContextMenuItemBounds () {
+ const selected = document.querySelectorAll('.contextMenuItem.selectedByKeyboard')
+ if (selected.length > 0) {
+ return selected.item(selected.length - 1).getBoundingClientRect()
+ }
+ return null
+ }
+
+ /**
+ * Upper bound for the active / focused menu.
+ */
+ maxIndex (template) {
+ return template.filter((element) => {
+ if (element.get('type') === separatorMenuItem.type) return false
+ if (element.has('visible')) return element.get('visible')
+ return true
+ }).size - 1
+ }
+
get openedSubmenuDetails () {
return this.props.contextMenuDetail.get('openedSubmenuDetails') || new Immutable.List()
}
+
+ get hasSubmenuSelection () {
+ return this.props.selectedIndex.length > 1
+ }
+
render () {
+ const selectedIndex = (this.props.selectedIndex === null) ? [0] : this.props.selectedIndex
const styles = {}
if (this.props.contextMenuDetail.get('left') !== undefined) {
styles.left = this.props.contextMenuDetail.get('left')
@@ -290,7 +427,7 @@ class ContextMenu extends ImmutableComponent {
submenuIndex={0}
lastZoomPercentage={this.props.lastZoomPercentage}
template={this.props.contextMenuDetail.get('template')}
- selectedIndex={this.props.selectedIndex ? this.props.selectedIndex[0] : null} />
+ selectedIndex={selectedIndex[0]} />
{
this.openedSubmenuDetails.map((openedSubmenuDetail, i) =>
)
}
diff --git a/js/components/main.js b/js/components/main.js
index 22c9af543d8..2b21d4782ce 100644
--- a/js/components/main.js
+++ b/js/components/main.js
@@ -156,10 +156,10 @@ class Main extends ImmutableComponent {
windowActions.toggleMenubarVisible(null)
} else {
if (customTitlebar.menubarSelectedIndex) {
- windowActions.setSubmenuSelectedIndex()
+ windowActions.setMenuBarSelectedIndex()
windowActions.setContextMenuDetail()
} else {
- windowActions.setSubmenuSelectedIndex([0])
+ windowActions.setMenuBarSelectedIndex(0)
}
}
}
@@ -172,7 +172,7 @@ class Main extends ImmutableComponent {
}
if (customTitlebar.menubarSelectedIndex) {
e.preventDefault()
- windowActions.setSubmenuSelectedIndex()
+ windowActions.setMenuBarSelectedIndex()
windowActions.setContextMenuDetail()
}
break
@@ -825,15 +825,15 @@ class Main extends ImmutableComponent {
const customTitlebarEnabled = isWindows
const captionButtonsVisible = customTitlebarEnabled
const menubarVisible = customTitlebarEnabled && (!getSetting(settings.AUTO_HIDE_MENU) || this.props.windowState.getIn(['ui', 'menubar', 'isVisible']))
- const selectedIndex = this.props.windowState.getIn(['ui', 'menubar', 'selectedIndex'])
+ const selectedIndex = this.props.windowState.getIn(['ui', 'contextMenu', 'selectedIndex'])
return {
enabled: customTitlebarEnabled,
captionButtonsVisible: captionButtonsVisible,
menubarVisible: menubarVisible,
menubarTemplate: menubarVisible ? this.props.appState.getIn(['menu', 'template']) : null,
- menubarSelectedIndex: selectedIndex,
- contextMenuSelectedIndex: typeof selectedIndex === 'object' && Array.isArray(selectedIndex) && selectedIndex.length > 1
- ? selectedIndex.slice(1)
+ menubarSelectedIndex: this.props.windowState.getIn(['ui', 'menubar', 'selectedIndex']),
+ contextMenuSelectedIndex: typeof selectedIndex === 'object' && Array.isArray(selectedIndex) && selectedIndex.length > 0
+ ? selectedIndex
: null,
lastFocusedSelector: this.props.windowState.getIn(['ui', 'menubar', 'lastFocusedSelector']),
isMaximized: currentWindow.isMaximized() || currentWindow.isFullScreen()
@@ -938,6 +938,7 @@ class Main extends ImmutableComponent {
diff --git a/js/constants/windowConstants.js b/js/constants/windowConstants.js
index ffc52d4d922..c34cd3ff944 100644
--- a/js/constants/windowConstants.js
+++ b/js/constants/windowConstants.js
@@ -47,6 +47,7 @@ const windowConstants = {
WINDOW_SET_FIND_DETAIL: _,
WINDOW_SET_BOOKMARK_DETAIL: _, // If set, also indicates that add/edit is shown
WINDOW_SET_CONTEXT_MENU_DETAIL: _, // If set, also indicates that the context menu is shown
+ WINDOW_SET_CONTEXT_MENU_SELECTED_INDEX: _,
WINDOW_SET_POPUP_WINDOW_DETAIL: _, // If set, also indicates that the popup window is shown
WINDOW_HIDE_BOOKMARK_HANGER: _,
WINDOW_SET_AUDIO_MUTED: _,
@@ -79,7 +80,7 @@ const windowConstants = {
WINDOW_TOGGLE_MENUBAR_VISIBLE: _,
WINDOW_CLICK_MENUBAR_SUBMENU: _,
WINDOW_RESET_MENU_STATE: _,
- WINDOW_SET_SUBMENU_SELECTED_INDEX: _,
+ WINDOW_SET_MENUBAR_SELECTED_INDEX: _,
WINDOW_SET_LAST_FOCUSED_SELECTOR: _,
WINDOW_GOT_RESPONSE_DETAILS: _,
WINDOW_SET_BOOKMARKS_TOOLBAR_SELECTED_FOLDER_ID: _,
diff --git a/js/stores/windowStore.js b/js/stores/windowStore.js
index 861a1e5bc9b..604dd8434cd 100644
--- a/js/stores/windowStore.js
+++ b/js/stores/windowStore.js
@@ -697,7 +697,7 @@ const doAction = (action) => {
: !windowState.getIn(['ui', 'menubar', 'isVisible'])
// Clear selection when menu is shown
if (newVisibleStatus) {
- doAction({ actionType: windowConstants.WINDOW_SET_SUBMENU_SELECTED_INDEX, index: [0] })
+ doAction({ actionType: windowConstants.WINDOW_SET_MENUBAR_SELECTED_INDEX, index: 0 })
}
windowState = windowState.setIn(['ui', 'menubar', 'isVisible'], newVisibleStatus)
}
@@ -716,14 +716,18 @@ const doAction = (action) => {
} else {
doAction({actionType: windowConstants.WINDOW_SET_CONTEXT_MENU_DETAIL})
}
- doAction({actionType: windowConstants.WINDOW_SET_SUBMENU_SELECTED_INDEX})
+ doAction({actionType: windowConstants.WINDOW_SET_MENUBAR_SELECTED_INDEX})
+ doAction({actionType: windowConstants.WINDOW_SET_CONTEXT_MENU_SELECTED_INDEX})
doAction({actionType: windowConstants.WINDOW_SET_BOOKMARKS_TOOLBAR_SELECTED_FOLDER_ID})
break
- case windowConstants.WINDOW_SET_SUBMENU_SELECTED_INDEX:
- windowState = windowState.setIn(['ui', 'menubar', 'selectedIndex'],
- Array.isArray(action.index)
- ? action.index
- : null)
+ case windowConstants.WINDOW_SET_MENUBAR_SELECTED_INDEX:
+ windowState = windowState.setIn(['ui', 'menubar', 'selectedIndex'], action.index)
+ break
+ case windowConstants.WINDOW_SET_CONTEXT_MENU_SELECTED_INDEX:
+ windowState = windowState.setIn(['ui', 'contextMenu', 'selectedIndex'],
+ Array.isArray(action.index)
+ ? action.index
+ : null)
break
case windowConstants.WINDOW_SET_LAST_FOCUSED_SELECTOR:
windowState = windowState.setIn(['ui', 'menubar', 'lastFocusedSelector'], action.selector)
diff --git a/test/components/contextMenuTest.js b/test/components/contextMenuTest.js
new file mode 100644
index 00000000000..d644b6e49a3
--- /dev/null
+++ b/test/components/contextMenuTest.js
@@ -0,0 +1,128 @@
+/* global describe, it, before */
+
+const Brave = require('../lib/brave')
+const {urlInput} = require('../lib/selectors')
+
+describe('ContextMenu', function () {
+ function * setup (client) {
+ yield client
+ .waitForUrl(Brave.newTabUrl)
+ .waitForBrowserWindow()
+ .waitForEnabled(urlInput)
+ }
+
+ describe('navigation', function () {
+ Brave.beforeAll(this)
+
+ before(function *() {
+ yield setup(this.app.client)
+ this.formfill = Brave.server.url('formfill.html')
+ this.input = '[name="01___title"]'
+ this.values = ['Value 1', 'Value 2', 'Value 3', 'Value 4']
+
+ yield this.app.client
+ .tabByIndex(0)
+ .loadUrl(this.formfill)
+ .waitForVisible('