From f2f44b9ab668d7e1af0b9d9eb5aab9a69a51f883 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 9 May 2012 10:56:31 -0600 Subject: [PATCH] Can match key patterns with the '-' character Add a parser to parse keystroke patterns instead of splitting on '-' with a regex --- benchmark/benchmark-helper.coffee | 2 +- spec/app/binding-set-spec.coffee | 20 -------------------- spec/app/keymap-spec.coffee | 6 ++++++ spec/spec-helper.coffee | 29 ++++++++--------------------- src/app/binding-set.coffee | 13 +++++++------ src/app/keystroke-pattern.pegjs | 3 +++ 6 files changed, 25 insertions(+), 48 deletions(-) delete mode 100644 spec/app/binding-set-spec.coffee create mode 100644 src/app/keystroke-pattern.pegjs diff --git a/benchmark/benchmark-helper.coffee b/benchmark/benchmark-helper.coffee index b02dda583..d01fa3dbb 100644 --- a/benchmark/benchmark-helper.coffee +++ b/benchmark/benchmark-helper.coffee @@ -75,7 +75,7 @@ window.eventPropertiesForPattern = (pattern) -> window.keydownEvent = (pattern, properties={}) -> event = $.Event "keydown", _.extend(eventPropertiesForPattern(pattern), properties) - event.keystroke = (new Keymap).keystrokeStringForEvent(event) + # event.keystroke = (new Keymap).keystrokeStringForEvent(event) event window.clickEvent = (properties={}) -> diff --git a/spec/app/binding-set-spec.coffee b/spec/app/binding-set-spec.coffee deleted file mode 100644 index 7df8fdc39..000000000 --- a/spec/app/binding-set-spec.coffee +++ /dev/null @@ -1,20 +0,0 @@ -$ = require 'jquery' -_ = require 'underscore' -BindingSet = require 'binding-set' - -describe "BindingSet", -> - bindingSet = null - beforeEach -> - bindingSet = new BindingSet('*', 'x': 'foo') - - describe ".eventMatchesPattern(event, pattern)", -> - it "handles patterns with and without modifiers", -> - expect(bindingSet.eventMatchesPattern(keydownEvent('q'), 'q')).toBeTruthy() - expect(bindingSet.eventMatchesPattern(keydownEvent('left'), 'left')).toBeTruthy() - expect(bindingSet.eventMatchesPattern(keydownEvent('0', altKey: true), '')).toBeTruthy() - expect(bindingSet.eventMatchesPattern(keydownEvent('A', shiftKey: true), 'A')).toBeTruthy() - expect(bindingSet.eventMatchesPattern(keydownEvent('0', altKey: true, ctrlKey: true, metaKey: true, shiftKey: true), '')).toBeTruthy() - - # negative examples - expect(bindingSet.eventMatchesPattern(keydownEvent('a'), '')).toBeFalsy() - expect(bindingSet.eventMatchesPattern(keydownEvent('d'), 'k')).toBeFalsy() diff --git a/spec/app/keymap-spec.coffee b/spec/app/keymap-spec.coffee index d0c26265b..5cdb9978c 100644 --- a/spec/app/keymap-spec.coffee +++ b/spec/app/keymap-spec.coffee @@ -134,6 +134,12 @@ describe "Keymap", -> expect(result).toBe(false) expect(fooHandler).toHaveBeenCalled() + fooHandler.reset() + keymap.bindKeys '*', 'ctrl-alt--': 'foo' + result = keymap.handleKeyEvent(keydownEvent('-', ctrlKey: true, altKey: true, target: fragment[0])) + expect(result).toBe(false) + expect(fooHandler).toHaveBeenCalled() + describe "when called with a selector and a function", -> it "calls the given function when selector matches", -> handler = jasmine.createSpy 'handler' diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index bc51e1330..4c7dbd84d 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -46,29 +46,16 @@ jasmine.StringPrettyPrinter.prototype.emitObject = (obj) -> else emitObject.call(this, obj) -window.eventPropertiesForPattern = (pattern) -> - [modifiers..., key] = pattern.split '-' - - modifiers.push 'shift' if key == key.toUpperCase() and key.toUpperCase() != key.toLowerCase() - charCode = key.toUpperCase().charCodeAt 0 - - isNamedKey = key.length > 1 - if isNamedKey - keyIdentifier = key +window.keyIdentifierForKey = (key) -> + if key.length > 1 # named key + key else - keyIdentifier = "U+00" + charCode.toString(16) + charCode = key.toUpperCase().charCodeAt(0) + "U+00" + charCode.toString(16) - ctrlKey: 'ctrl' in modifiers - altKey: 'alt' in modifiers - shiftKey: 'shift' in modifiers - metaKey: 'meta' in modifiers - which: charCode - originalEvent: - keyIdentifier: keyIdentifier - -window.keydownEvent = (pattern, properties={}) -> - event = $.Event "keydown", _.extend(eventPropertiesForPattern(pattern), properties) - event.keystroke = (new Keymap).keystrokeStringForEvent(event) +window.keydownEvent = (key, properties={}) -> + event = $.Event "keydown", _.extend({originalEvent: { keyIdentifier: keyIdentifierForKey(key) }}, properties) + # event.keystroke = (new Keymap).keystrokeStringForEvent(event) event window.mouseEvent = (type, properties) -> diff --git a/src/app/binding-set.coffee b/src/app/binding-set.coffee index 5aa6f54d3..1f2dc4ca8 100644 --- a/src/app/binding-set.coffee +++ b/src/app/binding-set.coffee @@ -1,13 +1,18 @@ $ = require 'jquery' _ = require 'underscore' Specificity = require 'specificity' +fs = require 'fs' + +PEG = require 'pegjs' module.exports = class BindingSet selector: null commandForEvent: null + keystrokePatternParser: null constructor: (@selector, mapOrFunction) -> + @parser = PEG.buildParser(fs.read(require.resolve 'keystroke-pattern.pegjs')) @specificity = Specificity(@selector) @commandForEvent = @buildEventHandler(mapOrFunction) @@ -18,13 +23,9 @@ class BindingSet mapOrFunction = @normalizeKeystrokePatterns(mapOrFunction) (event) => for pattern, command of mapOrFunction - return command if @eventMatchesPattern(event, pattern) + return command if event.keystroke == pattern null - eventMatchesPattern: (event, pattern) -> - pattern = pattern.replace(/^<|>$/g, '') - event.keystroke == pattern - normalizeKeystrokePatterns: (map) -> normalizedMap = {} for pattern, event of map @@ -32,7 +33,7 @@ class BindingSet normalizedMap normalizeKeystrokePattern: (pattern) -> - keys = pattern.split('-') + keys = @parser.parse(pattern) modifiers = keys[0...-1] modifiers.sort() [modifiers..., _.last(keys)].join('-') diff --git a/src/app/keystroke-pattern.pegjs b/src/app/keystroke-pattern.pegjs new file mode 100644 index 000000000..5c0283916 --- /dev/null +++ b/src/app/keystroke-pattern.pegjs @@ -0,0 +1,3 @@ +keystrokePattern = key:key additionalKeys:additionalKey* { return [key].concat(additionalKeys); } +additionalKey = '-' key:key { return key; } +key = '-' / chars:[^-]+ { return chars.join('') }