mirror of
https://github.com/atom/atom.git
synced 2026-01-24 22:38:20 -05:00
Start experiment: associate key bindings with CSS selectors
KeyEventHandler holds references to BindingSets. The name "binding set" is based on the concept of a CSS ruleset. The idea is to choose a key binding for an event based on what selectors (match / most closely contain) the event's target DOM node.
This commit is contained in:
committed by
Corey Johnson & Nathan Sobo
parent
3a1d167a0f
commit
18e614e88d
37
spec/atom/key-event-handler-spec.coffee
Normal file
37
spec/atom/key-event-handler-spec.coffee
Normal file
@@ -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 = $('<div class="command-mode">')
|
||||
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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
46
src/atom/binding-set.coffee
Normal file
46
src/atom/binding-set.coffee
Normal file
@@ -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
|
||||
|
||||
19
src/atom/key-event-handler.coffee
Normal file
19
src/atom/key-event-handler.coffee
Normal file
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user