mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge pull request #16620 from captbaritone/decaf-menu-helpers
Decaffeinate menu-helpers.coffee
This commit is contained in:
@@ -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
128
src/menu-helpers.js
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user