WIP: Begin introducing multi-keystroke bindings to Keymap

This commit is contained in:
Nathan Sobo
2012-06-18 16:46:39 -06:00
parent d9500e6bcd
commit ac4aae2cec
3 changed files with 144 additions and 81 deletions

View File

@@ -8,30 +8,39 @@ PEG = require 'pegjs'
module.exports =
class BindingSet
selector: null
keystrokeMap: null
commandsByKeystrokes: null
commandForEvent: null
parser: null
constructor: (@selector, mapOrFunction) ->
@parser = PEG.buildParser(fs.read(require.resolve 'keystroke-pattern.pegjs'))
@specificity = Specificity(@selector)
@keystrokeMap = {}
@commandsByKeystrokes = {}
if _.isFunction(mapOrFunction)
@commandForEvent = mapOrFunction
else
@keystrokeMap = @normalizeKeystrokeMap(mapOrFunction)
@commandsByKeystrokes = @normalizeCommandsByKeystrokes(mapOrFunction)
@commandForEvent = (event) =>
for keystroke, command of @keystrokeMap
return command if event.keystroke == keystroke
for keystrokes, command of @commandsByKeystrokes
return command if event.keystrokes == keystrokes
null
normalizeKeystrokeMap: (keystrokeMap) ->
normalizeKeystrokeMap = {}
for keystroke, command of keystrokeMap
normalizeKeystrokeMap[@normalizeKeystroke(keystroke)] = command
matchesKeystrokePrefix: (event) ->
for keystrokes, command of @commandsByKeystrokes
return true if keystrokes.indexOf(event.keystrokes) == 0
false
normalizeKeystrokeMap
normalizeCommandsByKeystrokes: (commandsByKeystrokes) ->
normalizedCommandsByKeystrokes = {}
for keystrokes, command of commandsByKeystrokes
normalizedCommandsByKeystrokes[@normalizeKeystrokes(keystrokes)] = command
normalizedCommandsByKeystrokes
normalizeKeystrokes: (keystrokes) ->
normalizedKeystrokes = keystrokes.split(/\s+/).map (keystroke) =>
@normalizeKeystroke(keystroke)
normalizedKeystrokes.join(' ')
normalizeKeystroke: (keystroke) ->
keys = @parser.parse(keystroke)

View File

@@ -8,6 +8,7 @@ Specificity = require 'specificity'
module.exports =
class Keymap
bindingSets: null
queuedKeystrokes: null
constructor: ->
@bindingSets = []
@@ -40,7 +41,8 @@ class Keymap
keystrokeMap
handleKeyEvent: (event) ->
event.keystroke = @keystrokeStringForEvent(event)
event.keystrokes = @multiKeystrokeStringForEvent(event)
@queuedKeystrokes = null
currentNode = $(event.target)
while currentNode.length
candidateBindingSets = @bindingSets.filter (set) -> currentNode.is(set.selector)
@@ -52,6 +54,10 @@ class Keymap
return false
else if command == false
return false
if bindingSet.matchesKeystrokePrefix(event)
@queuedKeystrokes = event.keystrokes
return false
currentNode = currentNode.parent()
true
@@ -60,6 +66,13 @@ class Keymap
commandEvent.keyEvent = keyEvent
$(keyEvent.target).trigger(commandEvent)
multiKeystrokeStringForEvent: (event) ->
currentKeystroke = @keystrokeStringForEvent(event)
if @queuedKeystrokes
@queuedKeystrokes + ' ' + currentKeystroke
else
currentKeystroke
keystrokeStringForEvent: (event) ->
if /^U\+/i.test event.originalEvent.keyIdentifier
hexCharCode = event.originalEvent.keyIdentifier.replace(/^U\+/i, '')