2013-11-07 02:52:28 +04:00
|
|
|
path = require 'path'
|
|
|
|
|
2013-09-18 05:58:41 +04:00
|
|
|
Keymap = require '../src/keymap'
|
2013-09-20 00:51:53 +04:00
|
|
|
{$, $$, RootView} = require 'atom'
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
describe "Keymap", ->
|
|
|
|
fragment = null
|
|
|
|
keymap = null
|
2013-10-15 05:32:24 +04:00
|
|
|
resourcePath = atom.getLoadSettings().resourcePath
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
beforeEach ->
|
2013-10-15 05:32:24 +04:00
|
|
|
keymap = new Keymap({configDirPath: atom.getConfigDirPath(), resourcePath})
|
2012-08-28 02:36:36 +04:00
|
|
|
fragment = $ """
|
|
|
|
<div class="command-mode">
|
|
|
|
<div class="child-node">
|
|
|
|
<div class="grandchild-node"/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
"""
|
|
|
|
|
|
|
|
describe ".handleKeyEvent(event)", ->
|
|
|
|
deleteCharHandler = null
|
|
|
|
insertCharHandler = null
|
2013-11-12 03:46:17 +04:00
|
|
|
metaZHandler = null
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
beforeEach ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', '.command-mode', 'x': 'deleteChar'
|
|
|
|
keymap.bindKeys 'name', '.insert-mode', 'x': 'insertChar'
|
|
|
|
keymap.bindKeys 'name', '.command-mode', 'meta-z': 'metaZPressed'
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2013-02-09 02:56:55 +04:00
|
|
|
deleteCharHandler = jasmine.createSpy('deleteCharHandler')
|
|
|
|
insertCharHandler = jasmine.createSpy('insertCharHandler')
|
2013-11-12 03:46:17 +04:00
|
|
|
metaZHandler = jasmine.createSpy('metaZHandler')
|
2012-08-28 02:36:36 +04:00
|
|
|
fragment.on 'deleteChar', deleteCharHandler
|
|
|
|
fragment.on 'insertChar', insertCharHandler
|
2013-11-12 03:46:17 +04:00
|
|
|
fragment.on 'metaZPressed', metaZHandler
|
2013-06-29 03:36:55 +04:00
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
describe "when no binding matches the event's keystroke", ->
|
2013-02-13 05:27:40 +04:00
|
|
|
it "does not return false so the event continues to propagate", ->
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('0', target: fragment[0]))).not.toBe false
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2013-06-29 03:36:55 +04:00
|
|
|
describe "when a non-English keyboard language is used", ->
|
|
|
|
it "uses the physical character pressed instead of the character it maps to in the current language", ->
|
2013-11-12 03:46:17 +04:00
|
|
|
event = keydownEvent('U+03B6', metaKey: true, which: 122, target: fragment[0]) # This is the 'z' key using the Greek keyboard layout
|
|
|
|
result = keymap.handleKeyEvent(event)
|
|
|
|
|
|
|
|
expect(result).toBe(false)
|
|
|
|
expect(metaZHandler).toHaveBeenCalled()
|
2013-06-29 03:36:55 +04:00
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
describe "when at least one binding fully matches the event's keystroke", ->
|
|
|
|
describe "when the event's target node matches a selector with a matching binding", ->
|
|
|
|
it "triggers the command event associated with that binding on the target node and returns false", ->
|
|
|
|
result = keymap.handleKeyEvent(keydownEvent('x', target: fragment[0]))
|
|
|
|
expect(result).toBe(false)
|
|
|
|
expect(deleteCharHandler).toHaveBeenCalled()
|
|
|
|
expect(insertCharHandler).not.toHaveBeenCalled()
|
|
|
|
|
|
|
|
deleteCharHandler.reset()
|
|
|
|
fragment.removeClass('command-mode').addClass('insert-mode')
|
|
|
|
|
|
|
|
event = keydownEvent('x', target: fragment[0])
|
|
|
|
keymap.handleKeyEvent(event)
|
|
|
|
expect(deleteCharHandler).not.toHaveBeenCalled()
|
|
|
|
expect(insertCharHandler).toHaveBeenCalled()
|
|
|
|
|
|
|
|
describe "when the event's target node *descends* from a selector with a matching binding", ->
|
|
|
|
it "triggers the command event associated with that binding on the target node and returns false", ->
|
|
|
|
target = fragment.find('.child-node')[0]
|
|
|
|
result = keymap.handleKeyEvent(keydownEvent('x', target: target))
|
|
|
|
expect(result).toBe(false)
|
|
|
|
expect(deleteCharHandler).toHaveBeenCalled()
|
|
|
|
expect(insertCharHandler).not.toHaveBeenCalled()
|
|
|
|
|
|
|
|
deleteCharHandler.reset()
|
|
|
|
fragment.removeClass('command-mode').addClass('insert-mode')
|
|
|
|
|
|
|
|
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
|
|
|
expect(deleteCharHandler).not.toHaveBeenCalled()
|
|
|
|
expect(insertCharHandler).toHaveBeenCalled()
|
|
|
|
|
|
|
|
describe "when the event's target node descends from multiple nodes that match selectors with a binding", ->
|
|
|
|
beforeEach ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', '.child-node', 'x': 'foo'
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
it "only triggers bindings on selectors associated with the closest ancestor node", ->
|
|
|
|
fooHandler = jasmine.createSpy 'fooHandler'
|
|
|
|
fragment.on 'foo', fooHandler
|
|
|
|
|
|
|
|
target = fragment.find('.grandchild-node')[0]
|
|
|
|
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
|
|
|
expect(fooHandler).toHaveBeenCalled()
|
|
|
|
expect(deleteCharHandler).not.toHaveBeenCalled()
|
|
|
|
expect(insertCharHandler).not.toHaveBeenCalled()
|
|
|
|
|
|
|
|
describe "when 'abortKeyBinding' is called on the triggered event", ->
|
2012-10-19 22:42:27 +04:00
|
|
|
[fooHandler1, fooHandler2] = []
|
|
|
|
|
|
|
|
beforeEach ->
|
2012-08-28 02:36:36 +04:00
|
|
|
fooHandler1 = jasmine.createSpy('fooHandler1').andCallFake (e) ->
|
|
|
|
expect(deleteCharHandler).not.toHaveBeenCalled()
|
|
|
|
e.abortKeyBinding()
|
|
|
|
fooHandler2 = jasmine.createSpy('fooHandler2')
|
|
|
|
|
|
|
|
fragment.find('.child-node').on 'foo', fooHandler1
|
|
|
|
fragment.on 'foo', fooHandler2
|
|
|
|
|
2012-10-19 22:42:27 +04:00
|
|
|
it "aborts the current event and tries again with the next-most-specific key binding", ->
|
2012-08-28 02:36:36 +04:00
|
|
|
target = fragment.find('.grandchild-node')[0]
|
|
|
|
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
|
|
|
expect(fooHandler1).toHaveBeenCalled()
|
|
|
|
expect(fooHandler2).not.toHaveBeenCalled()
|
|
|
|
expect(deleteCharHandler).toHaveBeenCalled()
|
|
|
|
|
2012-10-19 22:58:42 +04:00
|
|
|
it "does not throw an exception if the event was not triggered by the keymap", ->
|
2012-10-19 22:42:27 +04:00
|
|
|
fragment.find('.grandchild-node').trigger 'foo'
|
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
describe "when the event bubbles to a node that matches multiple selectors", ->
|
|
|
|
describe "when the matching selectors differ in specificity", ->
|
|
|
|
it "triggers the binding for the most specific selector", ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', 'div .child-node', 'x': 'foo'
|
|
|
|
keymap.bindKeys 'name', '.command-mode .child-node !important', 'x': 'baz'
|
|
|
|
keymap.bindKeys 'name', '.command-mode .child-node', 'x': 'quux'
|
|
|
|
keymap.bindKeys 'name', '.child-node', 'x': 'bar'
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
fooHandler = jasmine.createSpy 'fooHandler'
|
|
|
|
barHandler = jasmine.createSpy 'barHandler'
|
|
|
|
bazHandler = jasmine.createSpy 'bazHandler'
|
|
|
|
fragment.on 'foo', fooHandler
|
|
|
|
fragment.on 'bar', barHandler
|
|
|
|
fragment.on 'baz', bazHandler
|
|
|
|
|
|
|
|
target = fragment.find('.grandchild-node')[0]
|
|
|
|
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
|
|
|
|
|
|
|
expect(fooHandler).not.toHaveBeenCalled()
|
|
|
|
expect(barHandler).not.toHaveBeenCalled()
|
|
|
|
expect(bazHandler).toHaveBeenCalled()
|
|
|
|
|
|
|
|
describe "when the matching selectors have the same specificity", ->
|
|
|
|
it "triggers the bindings for the most recently declared selector", ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', '.child-node', 'x': 'foo', 'y': 'baz'
|
|
|
|
keymap.bindKeys 'name', '.child-node', 'x': 'bar'
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
fooHandler = jasmine.createSpy 'fooHandler'
|
|
|
|
barHandler = jasmine.createSpy 'barHandler'
|
|
|
|
bazHandler = jasmine.createSpy 'bazHandler'
|
|
|
|
fragment.on 'foo', fooHandler
|
|
|
|
fragment.on 'bar', barHandler
|
|
|
|
fragment.on 'baz', bazHandler
|
|
|
|
|
|
|
|
target = fragment.find('.grandchild-node')[0]
|
|
|
|
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
|
|
|
|
|
|
|
expect(barHandler).toHaveBeenCalled()
|
|
|
|
expect(fooHandler).not.toHaveBeenCalled()
|
|
|
|
|
|
|
|
keymap.handleKeyEvent(keydownEvent('y', target: target))
|
|
|
|
expect(bazHandler).toHaveBeenCalled()
|
|
|
|
|
2013-02-09 02:56:55 +04:00
|
|
|
describe "when the event's target is the document body", ->
|
|
|
|
it "triggers the mapped event on the rootView", ->
|
2013-02-20 04:18:25 +04:00
|
|
|
window.rootView = new RootView
|
2013-11-12 03:46:17 +04:00
|
|
|
rootView.attachToDom()
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', 'body', 'x': 'foo'
|
2013-02-09 02:56:55 +04:00
|
|
|
fooHandler = jasmine.createSpy("fooHandler")
|
|
|
|
rootView.on 'foo', fooHandler
|
|
|
|
|
|
|
|
result = keymap.handleKeyEvent(keydownEvent('x', target: document.body))
|
|
|
|
expect(result).toBe(false)
|
|
|
|
expect(fooHandler).toHaveBeenCalled()
|
|
|
|
expect(deleteCharHandler).not.toHaveBeenCalled()
|
|
|
|
expect(insertCharHandler).not.toHaveBeenCalled()
|
|
|
|
|
2013-04-11 02:57:37 +04:00
|
|
|
describe "when the event matches a 'native!' binding", ->
|
|
|
|
it "returns true, allowing the browser's native key handling to process the event", ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', '.grandchild-node', 'x': 'native!'
|
2013-04-11 02:57:37 +04:00
|
|
|
nativeHandler = jasmine.createSpy("nativeHandler")
|
|
|
|
fragment.on 'native!', nativeHandler
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment.find('.grandchild-node')[0]))).toBe true
|
|
|
|
expect(nativeHandler).not.toHaveBeenCalled()
|
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
describe "when at least one binding partially matches the event's keystroke", ->
|
|
|
|
[quitHandler, closeOtherWindowsHandler] = []
|
|
|
|
|
|
|
|
beforeEach ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', "*",
|
2012-08-28 02:36:36 +04:00
|
|
|
'ctrl-x ctrl-c': 'quit'
|
|
|
|
'ctrl-x 1': 'close-other-windows'
|
|
|
|
|
|
|
|
quitHandler = jasmine.createSpy('quitHandler')
|
|
|
|
closeOtherWindowsHandler = jasmine.createSpy('closeOtherWindowsHandler')
|
|
|
|
fragment.on 'quit', quitHandler
|
|
|
|
fragment.on 'close-other-windows', closeOtherWindowsHandler
|
|
|
|
|
2013-02-13 05:27:40 +04:00
|
|
|
it "only matches entire keystroke patterns", ->
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0]))).not.toBe false
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
describe "when the event's target node matches a selector with a partially matching multi-stroke binding", ->
|
|
|
|
describe "when a second keystroke added to the first to match a multi-stroke binding completely", ->
|
|
|
|
it "triggers the event associated with the matched multi-stroke binding", ->
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment[0], ctrlKey: true))).toBeFalsy()
|
2013-11-01 22:15:01 +04:00
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('ctrl', target: fragment[0]))).toBeFalsy() # This simulates actual key event behavior
|
2012-08-28 02:36:36 +04:00
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0], ctrlKey: true))).toBeFalsy()
|
|
|
|
|
|
|
|
expect(quitHandler).toHaveBeenCalled()
|
|
|
|
expect(closeOtherWindowsHandler).not.toHaveBeenCalled()
|
|
|
|
quitHandler.reset()
|
|
|
|
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment[0], ctrlKey: true))).toBeFalsy()
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('1', target: fragment[0]))).toBeFalsy()
|
|
|
|
|
|
|
|
expect(quitHandler).not.toHaveBeenCalled()
|
|
|
|
expect(closeOtherWindowsHandler).toHaveBeenCalled()
|
|
|
|
|
|
|
|
describe "when a second keystroke added to the first doesn't match any bindings", ->
|
2013-11-12 02:05:48 +04:00
|
|
|
it "clears the queued keystroke without triggering any events", ->
|
2013-02-13 05:27:40 +04:00
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment[0], ctrlKey: true))).toBe false
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0]))).toBe false
|
2012-08-28 02:36:36 +04:00
|
|
|
expect(quitHandler).not.toHaveBeenCalled()
|
|
|
|
expect(closeOtherWindowsHandler).not.toHaveBeenCalled()
|
|
|
|
|
2013-02-13 05:27:40 +04:00
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0]))).not.toBe false
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
describe "when the event's target node descends from multiple nodes that match selectors with a partial binding match", ->
|
|
|
|
it "allows any of the bindings to be triggered upon a second keystroke, favoring the most specific selector", ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', ".grandchild-node", 'ctrl-x ctrl-c': 'more-specific-quit'
|
2013-05-29 22:55:06 +04:00
|
|
|
grandchildNode = fragment.find('.grandchild-node')[0]
|
|
|
|
moreSpecificQuitHandler = jasmine.createSpy('moreSpecificQuitHandler')
|
|
|
|
fragment.on 'more-specific-quit', moreSpecificQuitHandler
|
|
|
|
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('x', target: grandchildNode, ctrlKey: true))).toBeFalsy()
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('1', target: grandchildNode))).toBeFalsy()
|
|
|
|
expect(quitHandler).not.toHaveBeenCalled()
|
|
|
|
expect(moreSpecificQuitHandler).not.toHaveBeenCalled()
|
|
|
|
expect(closeOtherWindowsHandler).toHaveBeenCalled()
|
|
|
|
closeOtherWindowsHandler.reset()
|
|
|
|
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('x', target: grandchildNode, ctrlKey: true))).toBeFalsy()
|
|
|
|
expect(keymap.handleKeyEvent(keydownEvent('c', target: grandchildNode, ctrlKey: true))).toBeFalsy()
|
|
|
|
expect(quitHandler).not.toHaveBeenCalled()
|
|
|
|
expect(closeOtherWindowsHandler).not.toHaveBeenCalled()
|
|
|
|
expect(moreSpecificQuitHandler).toHaveBeenCalled()
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
describe "when there is a complete binding with a less specific selector", ->
|
|
|
|
it "favors the more specific partial match", ->
|
|
|
|
|
|
|
|
describe "when there is a complete binding with a more specific selector", ->
|
|
|
|
it "favors the more specific complete match", ->
|
|
|
|
|
2013-11-15 22:21:38 +04:00
|
|
|
describe ".bindKeys(name, selector, bindings)", ->
|
2012-11-02 23:39:21 +04:00
|
|
|
it "normalizes the key patterns in the hash to put the modifiers in alphabetical order", ->
|
|
|
|
fooHandler = jasmine.createSpy('fooHandler')
|
|
|
|
fragment.on 'foo', fooHandler
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', '*', 'ctrl-alt-delete': 'foo'
|
2012-11-02 23:39:21 +04:00
|
|
|
result = keymap.handleKeyEvent(keydownEvent('delete', ctrlKey: true, altKey: true, target: fragment[0]))
|
|
|
|
expect(result).toBe(false)
|
|
|
|
expect(fooHandler).toHaveBeenCalled()
|
|
|
|
|
|
|
|
fooHandler.reset()
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', '*', 'ctrl-alt--': 'foo'
|
2012-11-02 23:39:21 +04:00
|
|
|
result = keymap.handleKeyEvent(keydownEvent('-', ctrlKey: true, altKey: true, target: fragment[0]))
|
|
|
|
expect(result).toBe(false)
|
|
|
|
expect(fooHandler).toHaveBeenCalled()
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2013-03-26 21:56:45 +04:00
|
|
|
describe ".remove(name)", ->
|
|
|
|
it "removes the binding set with the given selector and bindings", ->
|
|
|
|
keymap.add 'nature',
|
|
|
|
'.green':
|
|
|
|
'ctrl-c': 'cultivate'
|
|
|
|
'.brown':
|
|
|
|
'ctrl-h': 'harvest'
|
|
|
|
|
2013-11-16 01:49:17 +04:00
|
|
|
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'green')).toHaveLength 1
|
|
|
|
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'brown')).toHaveLength 1
|
2013-03-26 21:56:45 +04:00
|
|
|
|
|
|
|
keymap.remove('nature')
|
|
|
|
|
2013-11-16 01:49:17 +04:00
|
|
|
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'green')).toEqual []
|
|
|
|
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'brown')).toEqual []
|
2013-03-26 21:56:45 +04:00
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
describe ".keystrokeStringForEvent(event)", ->
|
|
|
|
describe "when no modifiers are pressed", ->
|
|
|
|
it "returns a string that identifies the key pressed", ->
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('a'))).toBe 'a'
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('['))).toBe '['
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('*'))).toBe '*'
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('left'))).toBe 'left'
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('\b'))).toBe 'backspace'
|
|
|
|
|
|
|
|
describe "when ctrl, alt or meta is pressed with a non-modifier key", ->
|
|
|
|
it "returns a string that identifies the key pressed", ->
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('a', altKey: true))).toBe 'alt-a'
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('[', metaKey: true))).toBe 'meta-['
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('*', ctrlKey: true))).toBe 'ctrl-*'
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('left', ctrlKey: true, metaKey: true, altKey: true))).toBe 'alt-ctrl-meta-left'
|
|
|
|
|
|
|
|
describe "when shift is pressed when a non-modifer key", ->
|
|
|
|
it "returns a string that identifies the key pressed", ->
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('A', shiftKey: true))).toBe 'A'
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('{', shiftKey: true))).toBe '{'
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('left', shiftKey: true))).toBe 'shift-left'
|
|
|
|
expect(keymap.keystrokeStringForEvent(keydownEvent('Left', shiftKey: true))).toBe 'shift-left'
|
|
|
|
|
2013-11-16 01:49:17 +04:00
|
|
|
describe ".keyBindingsMatchingElement(element)", ->
|
2012-08-28 02:36:36 +04:00
|
|
|
it "returns the matching bindings for the element", ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', '.command-mode', 'c': 'c'
|
|
|
|
keymap.bindKeys 'name', '.grandchild-node', 'g': 'g'
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2013-11-16 01:49:17 +04:00
|
|
|
bindings = keymap.keyBindingsMatchingElement(fragment.find('.grandchild-node'))
|
2013-11-15 04:20:12 +04:00
|
|
|
expect(bindings).toHaveLength 2
|
|
|
|
expect(bindings[0].command).toEqual "g"
|
|
|
|
expect(bindings[1].command).toEqual "c"
|
2012-08-28 02:36:36 +04:00
|
|
|
|
|
|
|
describe "when multiple bindings match a keystroke", ->
|
|
|
|
it "only returns bindings that match the most specific selector", ->
|
2013-11-15 22:21:38 +04:00
|
|
|
keymap.bindKeys 'name', '.command-mode', 'g': 'command-mode'
|
|
|
|
keymap.bindKeys 'name', '.command-mode .grandchild-node', 'g': 'command-and-grandchild-node'
|
|
|
|
keymap.bindKeys 'name', '.grandchild-node', 'g': 'grandchild-node'
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2013-11-16 01:49:17 +04:00
|
|
|
bindings = keymap.keyBindingsMatchingElement(fragment.find('.grandchild-node'))
|
2013-11-15 04:20:12 +04:00
|
|
|
expect(bindings).toHaveLength 3
|
|
|
|
expect(bindings[0].command).toEqual "command-and-grandchild-node"
|