diff --git a/app/common/state/contextMenuState.js b/app/common/state/contextMenuState.js index d278e679561..a046e220c2d 100644 --- a/app/common/state/contextMenuState.js +++ b/app/common/state/contextMenuState.js @@ -33,6 +33,12 @@ const api = { return windowState }, + getContextMenu: (windowState) => { + windowState = validateState(windowState) + + return windowState.get('contextMenuDetail') + }, + selectedIndex: (windowState) => { const selectedIndex = windowState.getIn(['ui', 'contextMenu', 'selectedIndex']) return (typeof selectedIndex === 'object' && diff --git a/app/renderer/components/common/contextMenu.js b/app/renderer/components/common/contextMenu.js index 736fc4ae12c..97c75db97ee 100644 --- a/app/renderer/components/common/contextMenu.js +++ b/app/renderer/components/common/contextMenu.js @@ -34,7 +34,7 @@ class ContextMenuItem extends ImmutableComponent { return this.props.contextMenuItem.get('items') } get hasSubmenu () { - return this.submenu && this.submenu.size > 0 + return (this.submenu && this.submenu.size > 0) || this.props.contextMenuItem.has('folderKey') } get isMulti () { return this.items && this.items.size > 0 @@ -49,6 +49,24 @@ class ContextMenuItem extends ImmutableComponent { get hasAccelerator () { return this.accelerator !== null } + + getNewCoordinates (e) { + let node = e.target + while (node && node.classList && !node.classList.contains('contextMenuItem')) { + node = node.parentNode + } + let parentNode = node.parentNode + while (parentNode && parentNode.classList && !parentNode.classList.contains('contextMenu')) { + parentNode = parentNode.parentNode + } + const parentBoundingRect = parentNode.getBoundingClientRect() + const boundingRect = node.getBoundingClientRect() + + return { + y: boundingRect.top - parentBoundingRect.top - 1 + parentNode.scrollTop + } + } + onClick (clickAction, shouldHide, e) { e.stopPropagation() if (clickAction) { @@ -93,28 +111,21 @@ class ContextMenuItem extends ImmutableComponent { } onMouseEnter (e) { - let openedSubmenuDetails = this.props.contextMenuDetail.get('openedSubmenuDetails') - openedSubmenuDetails = openedSubmenuDetails - ? openedSubmenuDetails.splice(this.props.submenuIndex, this.props.contextMenuDetail.get('openedSubmenuDetails').size) - : new Immutable.List() - - if (this.hasSubmenu) { - let node = e.target - while (node && node.classList && !node.classList.contains('contextMenuItem')) { - node = node.parentNode - } - let parentNode = node.parentNode - while (parentNode && parentNode.classList && !parentNode.classList.contains('contextMenu')) { - parentNode = parentNode.parentNode - } - const parentBoundingRect = parentNode.getBoundingClientRect() - const boundingRect = node.getBoundingClientRect() + if (this.props.contextMenuItem.has('folderKey')) { + const coordinates = this.getNewCoordinates(e) + windowActions.onShowBookmarkFolderMenu(this.props.contextMenuItem.get('folderKey'), coordinates.y, null, this.props.submenuIndex) + } else if (this.hasSubmenu) { + let openedSubmenuDetails = this.props.contextMenuDetail.get('openedSubmenuDetails') + openedSubmenuDetails = openedSubmenuDetails + ? openedSubmenuDetails.splice(this.props.submenuIndex, this.props.contextMenuDetail.get('openedSubmenuDetails').size) + : new Immutable.List() + const coordinates = this.getNewCoordinates(e) openedSubmenuDetails = openedSubmenuDetails.push(Immutable.fromJS({ - y: boundingRect.top - parentBoundingRect.top - 1 + parentNode.scrollTop, + y: coordinates.y, template: this.submenu })) + windowActions.setContextMenuDetail(this.props.contextMenuDetail.set('openedSubmenuDetails', openedSubmenuDetails)) } - windowActions.setContextMenuDetail(this.props.contextMenuDetail.set('openedSubmenuDetails', openedSubmenuDetails)) } getLabelForItem (item) { const label = item.get('label') diff --git a/app/renderer/reducers/contextMenuReducer.js b/app/renderer/reducers/contextMenuReducer.js index 87fe93f1f63..396adf50214 100644 --- a/app/renderer/reducers/contextMenuReducer.js +++ b/app/renderer/reducers/contextMenuReducer.js @@ -464,7 +464,7 @@ const bookmarkItemsInit = (state, items) => { } } if (isFolder) { - templateItem.submenu = showBookmarkFolderInit(state, siteKey) + templateItem.folderKey = siteKey } template.push(templateItem) } @@ -509,11 +509,24 @@ const onShowBookmarkFolderMenu = (state, action) => { state = validateState(state) const menuTemplate = showBookmarkFolderInit(state, action.get('bookmarkKey')) - state = contextMenuState.setContextMenu(state, makeImmutable({ - left: action.get('left'), - top: action.get('top'), - template: menuTemplate - })) + if (action.get('submenuIndex') != null) { + let contextMenu = contextMenuState.getContextMenu(state) + let openedSubmenuDetails = contextMenu.get('openedSubmenuDetails', Immutable.List()) + + openedSubmenuDetails = openedSubmenuDetails + .splice(action.get('submenuIndex'), openedSubmenuDetails.size) + .push(makeImmutable({ + left: action.get('left'), + template: menuTemplate + })) + state = contextMenuState.setContextMenu(state, contextMenu.set('openedSubmenuDetails', openedSubmenuDetails)) + } else { + state = contextMenuState.setContextMenu(state, makeImmutable({ + left: action.get('left'), + top: action.get('top'), + template: menuTemplate + })) + } return state } diff --git a/js/actions/windowActions.js b/js/actions/windowActions.js index db4c40e04e6..181bd3a4688 100644 --- a/js/actions/windowActions.js +++ b/js/actions/windowActions.js @@ -1230,12 +1230,13 @@ const windowActions = { }) }, - onShowBookmarkFolderMenu: function (bookmarkKey, left, top) { + onShowBookmarkFolderMenu: function (bookmarkKey, left, top, submenuIndex) { dispatch({ actionType: windowConstants.WINDOW_ON_SHOW_BOOKMARK_FOLDER_MENU, bookmarkKey, left, - top + top, + submenuIndex }) },