diff --git a/spec/atom/key-event-handler-spec.coffee b/spec/atom/key-event-handler-spec.coffee
index dea13b7cb..a56923dcf 100644
--- a/spec/atom/key-event-handler-spec.coffee
+++ b/spec/atom/key-event-handler-spec.coffee
@@ -7,23 +7,28 @@ describe "KeyEventHandler", ->
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
+ describe "handleKeypress", ->
+ fragment = null
+ deleteCharHandler = null
+ insertCharHandler = null
- beforeEach ->
- handler.bindKeys '.command-mode', 'x': 'deleteChar'
- handler.bindKeys '.insert-mode', 'x': 'insertChar'
+ 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
+ fragment = $ """
+
+ """
- it "only triggers an event based on the key-binding in that selector", ->
+ deleteCharHandler = jasmine.createSpy 'deleteCharHandler'
+ insertCharHandler = jasmine.createSpy 'insertCharHandler'
+ fragment.on 'deleteChar', deleteCharHandler
+ fragment.on 'insertChar', insertCharHandler
+
+ 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", ->
handler.handleKeypress(keypressEvent('x', target: fragment[0]))
expect(deleteCharHandler).toHaveBeenCalled()
expect(insertCharHandler).not.toHaveBeenCalled()
@@ -35,3 +40,17 @@ describe "KeyEventHandler", ->
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", ->
+ target = fragment.find('.descendant-node')[0]
+ handler.handleKeypress(keypressEvent('x', target: target))
+ expect(deleteCharHandler).toHaveBeenCalled()
+ expect(insertCharHandler).not.toHaveBeenCalled()
+
+ deleteCharHandler.reset()
+ fragment.removeClass('command-mode').addClass('insert-mode')
+
+ handler.handleKeypress(keypressEvent('x', target: target))
+ expect(deleteCharHandler).not.toHaveBeenCalled()
+ expect(insertCharHandler).toHaveBeenCalled()
+
diff --git a/src/atom/binding-set.coffee b/src/atom/binding-set.coffee
index 13e68399e..796fc68fd 100644
--- a/src/atom/binding-set.coffee
+++ b/src/atom/binding-set.coffee
@@ -15,7 +15,7 @@ class BindingSet
constructor: (@selector, @bindings) ->
commandForEvent: (event) ->
- if $(event.target).is(@selector)
+ if @selectorMatchesEvent(event)
for pattern, command of @bindings
return command if @eventMatchesPattern(event, pattern)
null
@@ -44,3 +44,10 @@ class BindingSet
which: charCode
key: key
+ selectorMatchesEvent: (event) ->
+ currentNode = event.target
+ while currentNode
+ return true if $(currentNode).is(@selector)
+ currentNode = currentNode.parentNode
+ false
+