Merge pull request #16620 from captbaritone/decaf-menu-helpers

Decaffeinate menu-helpers.coffee
This commit is contained in:
Max Brunsfeld
2018-01-25 11:01:14 -08:00
committed by GitHub
2 changed files with 128 additions and 74 deletions

View File

@@ -1,74 +0,0 @@
_ = require 'underscore-plus'
ItemSpecificities = new WeakMap
merge = (menu, item, itemSpecificity=Infinity) ->
item = cloneMenuItem(item)
ItemSpecificities.set(item, itemSpecificity) if itemSpecificity
matchingItemIndex = findMatchingItemIndex(menu, item)
matchingItem = menu[matchingItemIndex] unless matchingItemIndex is - 1
if matchingItem?
if item.submenu?
merge(matchingItem.submenu, submenuItem, itemSpecificity) for submenuItem in item.submenu
else if itemSpecificity
unless itemSpecificity < ItemSpecificities.get(matchingItem)
menu[matchingItemIndex] = item
else unless item.type is 'separator' and _.last(menu)?.type is 'separator'
menu.push(item)
return
unmerge = (menu, item) ->
matchingItemIndex = findMatchingItemIndex(menu, item)
matchingItem = menu[matchingItemIndex] unless matchingItemIndex is - 1
if matchingItem?
if item.submenu?
unmerge(matchingItem.submenu, submenuItem) for submenuItem in item.submenu
unless matchingItem.submenu?.length > 0
menu.splice(matchingItemIndex, 1)
findMatchingItemIndex = (menu, {type, label, submenu}) ->
return -1 if type is 'separator'
for item, index in menu
if normalizeLabel(item.label) is normalizeLabel(label) and item.submenu? is submenu?
return index
-1
normalizeLabel = (label) ->
return undefined unless label?
if process.platform is 'darwin'
label
else
label.replace(/\&/g, '')
cloneMenuItem = (item) ->
item = _.pick(item, 'type', 'label', 'enabled', 'visible', 'command', 'submenu', 'commandDetail', 'role', 'accelerator')
if item.submenu?
item.submenu = item.submenu.map (submenuItem) -> cloneMenuItem(submenuItem)
item
# Determine the Electron accelerator for a given Atom keystroke.
#
# keystroke - The keystroke.
#
# Returns a String containing the keystroke in a format that can be interpreted
# by Electron to provide nice icons where available.
acceleratorForKeystroke = (keystroke) ->
return null unless keystroke
modifiers = keystroke.split(/-(?=.)/)
key = modifiers.pop().toUpperCase().replace('+', 'Plus')
modifiers = modifiers.map (modifier) ->
modifier.replace(/shift/ig, "Shift")
.replace(/cmd/ig, "Command")
.replace(/ctrl/ig, "Ctrl")
.replace(/alt/ig, "Alt")
keys = modifiers.concat([key])
keys.join("+")
module.exports = {merge, unmerge, normalizeLabel, cloneMenuItem, acceleratorForKeystroke}

128
src/menu-helpers.js Normal file
View File

@@ -0,0 +1,128 @@
const _ = require('underscore-plus')
const ItemSpecificities = new WeakMap()
// Add an item to a menu, ensuring separators are not duplicated.
function addItemToMenu (item, menu) {
const lastMenuItem = _.last(menu)
const lastMenuItemIsSpearator = lastMenuItem && lastMenuItem.type === 'separator'
if (!(item.type === 'separator' && lastMenuItemIsSpearator)) {
menu.push(item)
}
}
function merge (menu, item, itemSpecificity = Infinity) {
item = cloneMenuItem(item)
ItemSpecificities.set(item, itemSpecificity)
const matchingItemIndex = findMatchingItemIndex(menu, item)
if (matchingItemIndex === -1) {
addItemToMenu(item, menu)
return
}
const matchingItem = menu[matchingItemIndex]
if (item.submenu != null) {
for (let submenuItem of item.submenu) {
merge(matchingItem.submenu, submenuItem, itemSpecificity)
}
} else if (itemSpecificity && itemSpecificity >= ItemSpecificities.get(matchingItem)) {
menu[matchingItemIndex] = item
}
}
function unmerge (menu, item) {
const matchingItemIndex = findMatchingItemIndex(menu, item)
if (matchingItemIndex === -1) {
return
}
const matchingItem = menu[matchingItemIndex]
if (item.submenu != null) {
for (let submenuItem of item.submenu) {
unmerge(matchingItem.submenu, submenuItem)
}
}
if (matchingItem.submenu == null || matchingItem.submenu.length === 0) {
menu.splice(matchingItemIndex, 1)
}
}
function findMatchingItemIndex (menu, { type, label, submenu }) {
if (type === 'separator') {
return -1
}
for (let index = 0; index < menu.length; index++) {
const item = menu[index]
if (
normalizeLabel(item.label) === normalizeLabel(label) &&
(item.submenu != null) === (submenu != null)
) {
return index
}
}
return -1
}
function normalizeLabel (label) {
if (label == null) {
return
}
return process.platform === 'darwin' ? label : label.replace(/&/g, '')
}
function cloneMenuItem (item) {
item = _.pick(
item,
'type',
'label',
'enabled',
'visible',
'command',
'submenu',
'commandDetail',
'role',
'accelerator'
)
if (item.submenu != null) {
item.submenu = item.submenu.map(submenuItem => cloneMenuItem(submenuItem))
}
return item
}
// Determine the Electron accelerator for a given Atom keystroke.
//
// keystroke - The keystroke.
//
// Returns a String containing the keystroke in a format that can be interpreted
// by Electron to provide nice icons where available.
function acceleratorForKeystroke (keystroke) {
if (!keystroke) {
return null
}
let modifiers = keystroke.split(/-(?=.)/)
const key = modifiers
.pop()
.toUpperCase()
.replace('+', 'Plus')
modifiers = modifiers.map(modifier =>
modifier
.replace(/shift/gi, 'Shift')
.replace(/cmd/gi, 'Command')
.replace(/ctrl/gi, 'Ctrl')
.replace(/alt/gi, 'Alt')
)
const keys = [...modifiers, key]
return keys.join('+')
}
module.exports = {
merge,
unmerge,
normalizeLabel,
cloneMenuItem,
acceleratorForKeystroke
}