diff --git a/src/menu-helpers.coffee b/src/menu-helpers.coffee new file mode 100644 index 000000000..156c83752 --- /dev/null +++ b/src/menu-helpers.coffee @@ -0,0 +1,32 @@ +merge = (menu, item) -> + matchingItem = findMatchingItem(menu, item) + + if matchingItem? + if item.submenu? + merge(matchingItem.submenu, submenuItem) for submenuItem in item.submenu + else + menu.push(item) + +unmerge = (menu, item) -> + if matchingItem = findMatchingItem(menu, item) + if item.submenu? + unmerge(matchingItem.submenu, submenuItem) for submenuItem in item.submenu + + unless matchingItem.submenu?.length > 0 + menu.splice(menu.indexOf(matchingItem), 1) + +findMatchingItem = (menu, {label, submenu}) -> + for item in menu + if normalizeLabel(item.label) is normalizeLabel(label) and item.submenu? is submenu? + return item + null + +normalizeLabel = (label) -> + return undefined unless label? + + if process.platform is 'darwin' + label + else + label.replace(/\&/g, '') + +module.exports = {merge, unmerge, findMatchingItem, normalizeLabel} diff --git a/src/menu-manager.coffee b/src/menu-manager.coffee index 94d6fe5d3..d7190e80c 100644 --- a/src/menu-manager.coffee +++ b/src/menu-manager.coffee @@ -6,6 +6,8 @@ CSON = require 'season' fs = require 'fs-plus' {Disposable} = require 'event-kit' +MenuHelpers = require './menu-helpers' + # Extended: Provides a registry for menu items that you'd like to appear in the # application menu. # @@ -39,6 +41,7 @@ class MenuManager # Returns a {Disposable} on which `.dispose()` can be called to remove the # added menu items. add: (items) -> + items = _.deepClone(items) @merge(@template, item) for item in items @update() new Disposable => @remove(items) @@ -103,30 +106,10 @@ class MenuManager # Merges an item in a submenu aware way such that new items are always # appended to the bottom of existing menus where possible. merge: (menu, item) -> - item = _.deepClone(item) - matchingItem = @findMatchingItem(menu, item) - - if matchingItem? - if item.submenu? - @merge(matchingItem.submenu, submenuItem) for submenuItem in item.submenu - else - menu.push(item) + MenuHelpers.merge(menu, item) unmerge: (menu, item) -> - if matchingItem = @findMatchingItem(menu, item) - if item.submenu? - @unmerge(matchingItem.submenu, submenuItem) for submenuItem in item.submenu - - unless matchingItem.submenu?.length > 0 - menu.splice(menu.indexOf(matchingItem), 1) - - # find an existing menu item matching the given item - findMatchingItem: (menu, {label, submenu}) -> - debugger unless menu? - for item in menu - if @normalizeLabel(item.label) is @normalizeLabel(label) and item.submenu? is submenu? - return item - null + MenuHelpers.unmerge(menu, item) # OSX can't handle displaying accelerators for multiple keystrokes. # If they are sent across, it will stop processing accelerators for the rest @@ -145,25 +128,17 @@ class MenuManager keystrokesByCommand = @filterMultipleKeystroke(keystrokesByCommand) ipc.send 'update-application-menu', template, keystrokesByCommand - normalizeLabel: (label) -> - return undefined unless label? - - if process.platform is 'darwin' - label - else - label.replace(/\&/g, '') - # Get an {Array} of {String} classes for the given element. classesForElement: (element) -> element?.classList.toString().split(' ') ? [] sortPackagesMenu: -> - packagesMenu = @template.find ({label}) => @normalizeLabel(label) is 'Packages' + packagesMenu = @template.find ({label}) => MenuHelpers.normalizeLabel(label) is 'Packages' return unless packagesMenu?.submenu? packagesMenu.submenu.sort (item1, item2) => if item1.label and item2.label - @normalizeLabel(item1.label).localeCompare(@normalizeLabel(item2.label)) + MenuHelpers.normalizeLabel(item1.label).localeCompare(MenuHelpers.normalizeLabel(item2.label)) else 0 @update()