Remove ability to associate a binding set with a function

This was cool, but it's really hard to optimize the keymap with this feature because we never know if a keystroke will match against a binding set with a function, which will force us to always consider this binding set against every key event.
This commit is contained in:
Nathan Sobo 2012-11-02 13:39:21 -06:00
parent 0c3498d29f
commit 2c211ba504
2 changed files with 19 additions and 74 deletions

View File

@ -216,71 +216,20 @@ describe "Keymap", ->
describe "when there is a complete binding with a more specific selector", -> describe "when there is a complete binding with a more specific selector", ->
it "favors the more specific complete match", -> it "favors the more specific complete match", ->
describe ".bindKeys(selector, fnOrMap)", -> describe ".bindKeys(selector, hash)", ->
describe "when called with a selector and a hash", -> it "normalizes the key patterns in the hash to put the modifiers in alphabetical order", ->
it "normalizes the key patterns in the hash to put the modifiers in alphabetical order", -> fooHandler = jasmine.createSpy('fooHandler')
fooHandler = jasmine.createSpy('fooHandler') fragment.on 'foo', fooHandler
fragment.on 'foo', fooHandler keymap.bindKeys '*', 'ctrl-alt-delete': 'foo'
keymap.bindKeys '*', 'ctrl-alt-delete': 'foo' result = keymap.handleKeyEvent(keydownEvent('delete', ctrlKey: true, altKey: true, target: fragment[0]))
result = keymap.handleKeyEvent(keydownEvent('delete', ctrlKey: true, altKey: true, target: fragment[0])) expect(result).toBe(false)
expect(result).toBe(false) expect(fooHandler).toHaveBeenCalled()
expect(fooHandler).toHaveBeenCalled()
fooHandler.reset() fooHandler.reset()
keymap.bindKeys '*', 'ctrl-alt--': 'foo' keymap.bindKeys '*', 'ctrl-alt--': 'foo'
result = keymap.handleKeyEvent(keydownEvent('-', ctrlKey: true, altKey: true, target: fragment[0])) result = keymap.handleKeyEvent(keydownEvent('-', ctrlKey: true, altKey: true, target: fragment[0]))
expect(result).toBe(false) expect(result).toBe(false)
expect(fooHandler).toHaveBeenCalled() expect(fooHandler).toHaveBeenCalled()
describe "when called with a selector and a function", ->
it "calls the given function when selector matches", ->
handler = jasmine.createSpy 'handler'
keymap.bindKeys '.child-node', handler
target = fragment.find('.grandchild-node')[0]
event = keydownEvent('y', target: target)
keymap.handleKeyEvent event
expect(handler).toHaveBeenCalledWith(event)
describe "when the function returns a command string", ->
it "triggers the command event on the target and stops propagating the event", ->
keymap.bindKeys '*', 'x': 'foo'
keymap.bindKeys '*', -> 'bar'
fooHandler = jasmine.createSpy('fooHandler')
barHandler = jasmine.createSpy('barHandler')
fragment.on 'foo', fooHandler
fragment.on 'bar', barHandler
target = fragment.find('.child-node')[0]
keymap.handleKeyEvent(keydownEvent('x', target: target))
expect(fooHandler).not.toHaveBeenCalled()
expect(barHandler).toHaveBeenCalled()
describe "when the function returns false", ->
it "stops propagating the event", ->
keymap.bindKeys '*', 'x': 'foo'
keymap.bindKeys '*', -> false
fooHandler = jasmine.createSpy('fooHandler')
fragment.on 'foo', fooHandler
target = fragment.find('.child-node')[0]
keymap.handleKeyEvent(keydownEvent('x', target: target))
expect(fooHandler).not.toHaveBeenCalled()
describe "when the function returns anything other than a string or false", ->
it "continues to propagate the event", ->
keymap.bindKeys '*', 'x': 'foo'
keymap.bindKeys '*', -> undefined
fooHandler = jasmine.createSpy('fooHandler')
fragment.on 'foo', fooHandler
target = fragment.find('.child-node')[0]
keymap.handleKeyEvent(keydownEvent('x', target: target))
expect(fooHandler).toHaveBeenCalled()
describe ".keystrokeStringForEvent(event)", -> describe ".keystrokeStringForEvent(event)", ->
describe "when no modifiers are pressed", -> describe "when no modifiers are pressed", ->

View File

@ -12,19 +12,15 @@ class BindingSet
commandForEvent: null commandForEvent: null
parser: null parser: null
constructor: (@selector, mapOrFunction, @index) -> constructor: (@selector, commandsByKeystrokes, @index) ->
@parser = PEG.buildParser(fs.read(require.resolve 'keystroke-pattern.pegjs')) @parser = PEG.buildParser(fs.read(require.resolve 'keystroke-pattern.pegjs'))
@specificity = Specificity(@selector) @specificity = Specificity(@selector)
@commandsByKeystrokes = {} @commandsByKeystrokes = @normalizeCommandsByKeystrokes(commandsByKeystrokes)
if _.isFunction(mapOrFunction) commandForEvent: (event) ->
@commandForEvent = mapOrFunction for keystrokes, command of @commandsByKeystrokes
else return command if event.keystrokes == keystrokes
@commandsByKeystrokes = @normalizeCommandsByKeystrokes(mapOrFunction) null
@commandForEvent = (event) =>
for keystrokes, command of @commandsByKeystrokes
return command if event.keystrokes == keystrokes
null
matchesKeystrokePrefix: (event) -> matchesKeystrokePrefix: (event) ->
eventKeystrokes = event.keystrokes.split(' ') eventKeystrokes = event.keystrokes.split(' ')