diff --git a/spec/atom/key-event-handler-spec.coffee b/spec/atom/key-event-handler-spec.coffee new file mode 100644 index 000000000..dea13b7cb --- /dev/null +++ b/spec/atom/key-event-handler-spec.coffee @@ -0,0 +1,37 @@ +KeyEventHandler = require 'key-event-handler' +$ = require 'jquery' + +describe "KeyEventHandler", -> + handler = null + + beforeEach -> + handler = new KeyEventHandler + + fdescribe "handleKeypress", -> + describe "when there is a mapping in a selector that matches the event's element", -> + fragment = null + deleteCharHandler = null + insertCharHandler = null + + beforeEach -> + handler.bindKeys '.command-mode', 'x': 'deleteChar' + handler.bindKeys '.insert-mode', 'x': 'insertChar' + + fragment = $('
') + deleteCharHandler = jasmine.createSpy 'deleteCharHandler' + insertCharHandler = jasmine.createSpy 'insertCharHandler' + fragment.on 'deleteChar', deleteCharHandler + fragment.on 'insertChar', insertCharHandler + + it "only triggers an event based on the key-binding in that selector", -> + handler.handleKeypress(keypressEvent('x', target: fragment[0])) + expect(deleteCharHandler).toHaveBeenCalled() + expect(insertCharHandler).not.toHaveBeenCalled() + + deleteCharHandler.reset() + fragment.removeClass('command-mode').addClass('insert-mode') + + handler.handleKeypress(keypressEvent('x', target: fragment[0])) + expect(deleteCharHandler).not.toHaveBeenCalled() + expect(insertCharHandler).toHaveBeenCalled() + diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 4d2fb0d41..8c792775f 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -15,6 +15,9 @@ window.keydown = (pattern) -> window.createKeyEvent = (pattern) -> $.Event "keydown", atom.keyBinder.parseKeyPattern(pattern) +window.keypressEvent = (pattern, properties={}) -> + $.Event "keypress", _.extend(atom.keyBinder.parseKeyPattern(pattern), properties) + window.waitsForPromise = (fn) -> window.waitsFor (moveOn) -> fn().done(moveOn) diff --git a/src/atom/binding-set.coffee b/src/atom/binding-set.coffee new file mode 100644 index 000000000..13e68399e --- /dev/null +++ b/src/atom/binding-set.coffee @@ -0,0 +1,46 @@ +$ = require 'jquery' + +module.exports = +class BindingSet + namedKeys: + backspace: 8, tab: 9, clear: 12, enter: 13, 'return': 13, + esc: 27, escape: 27, space: 32, left: 37, up: 38, right: 39, + down: 40, del: 46, 'delete': 46, home: 36, end: 35, pageup: 33, + pagedown: 34, ',': 188, '.': 190, '/': 191, '`': 192, '-': 189, + '=': 187, ';': 186, '\'': 222, '[': 219, ']': 221, '\\': 220 + + selector: null + bindings: null + + constructor: (@selector, @bindings) -> + + commandForEvent: (event) -> + if $(event.target).is(@selector) + for pattern, command of @bindings + return command if @eventMatchesPattern(event, pattern) + null + + eventMatchesPattern: (event, pattern) -> + pattern = @parseKeyPattern pattern + pattern.ctrlKey == event.ctrlKey and + pattern.altKey == event.altKey and + pattern.shiftKey == event.shiftKey and + pattern.metaKey == event.metaKey and + pattern.which == event.which + + parseKeyPattern: (pattern) -> + [modifiers..., key] = pattern.split '+' + + if @namedKeys[key] + charCode = @namedKeys[key] + key = null + else + charCode = key.toUpperCase().charCodeAt 0 + + ctrlKey: 'ctrl' in modifiers + altKey: 'alt' in modifiers + shiftKey: 'shift' in modifiers + metaKey: 'meta' in modifiers + which: charCode + key: key + diff --git a/src/atom/key-event-handler.coffee b/src/atom/key-event-handler.coffee new file mode 100644 index 000000000..4ae8fb5ec --- /dev/null +++ b/src/atom/key-event-handler.coffee @@ -0,0 +1,19 @@ +$ = require 'jquery' +BindingSet = require 'binding-set' + +module.exports = +class KeyEventHandler + bindingSetsBySelector: null + + constructor: -> + @bindingSets = [] + + bindKeys: (selector, bindings) -> + @bindingSets.push(new BindingSet(selector, bindings)) + + handleKeypress: (event) -> + for bindingSet in @bindingSets + if command = bindingSet.commandForEvent(event) + $(event.target).trigger(command) + return +