mirror of
https://github.com/atom/atom.git
synced 2026-01-24 22:38:20 -05:00
Only trigger bindings on the closest ancestor node of an event target.
Say we have a structure like:
div.parent
div.child
div.grandchild
And we have two mappings:
.parent { x: foo }
.child { x:bar }
If there's an event originating on grandchild, it will *only* trigger
bar, because that selector selects a closer ancestor.
This commit is contained in:
committed by
Corey Johnson & Nathan Sobo
parent
9c98e971fc
commit
f5be55e000
@@ -7,7 +7,7 @@ describe "KeyEventHandler", ->
|
||||
beforeEach ->
|
||||
handler = new KeyEventHandler
|
||||
|
||||
describe "handleKeypress", ->
|
||||
fdescribe "handleKeypress", ->
|
||||
fragment = null
|
||||
deleteCharHandler = null
|
||||
insertCharHandler = null
|
||||
@@ -18,7 +18,9 @@ describe "KeyEventHandler", ->
|
||||
|
||||
fragment = $ """
|
||||
<div class="command-mode">
|
||||
<div class="descendant-node"/>
|
||||
<div class="child-node">
|
||||
<div class="grandchild-node"/>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
@@ -42,7 +44,7 @@ describe "KeyEventHandler", ->
|
||||
|
||||
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]
|
||||
target = fragment.find('.child-node')[0]
|
||||
handler.handleKeypress(keypressEvent('x', target: target))
|
||||
expect(deleteCharHandler).toHaveBeenCalled()
|
||||
expect(insertCharHandler).not.toHaveBeenCalled()
|
||||
@@ -54,3 +56,15 @@ describe "KeyEventHandler", ->
|
||||
expect(deleteCharHandler).not.toHaveBeenCalled()
|
||||
expect(insertCharHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when the event's target node descends from *multiple* selectors with a matching binding", ->
|
||||
it "only triggers bindings on selectors associated with the closest ancestor node", ->
|
||||
handler.bindKeys '.child-node', 'x': 'foo'
|
||||
fooHandler = jasmine.createSpy 'fooHandler'
|
||||
fragment.on 'foo', fooHandler
|
||||
|
||||
target = fragment.find('.grandchild-node')[0]
|
||||
handler.handleKeypress(keypressEvent('x', target: target))
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
expect(deleteCharHandler).not.toHaveBeenCalled()
|
||||
expect(insertCharHandler).not.toHaveBeenCalled()
|
||||
|
||||
|
||||
@@ -15,9 +15,8 @@ class BindingSet
|
||||
constructor: (@selector, @bindings) ->
|
||||
|
||||
commandForEvent: (event) ->
|
||||
if @selectorMatchesEvent(event)
|
||||
for pattern, command of @bindings
|
||||
return command if @eventMatchesPattern(event, pattern)
|
||||
for pattern, command of @bindings
|
||||
return command if @eventMatchesPattern(event, pattern)
|
||||
null
|
||||
|
||||
eventMatchesPattern: (event, pattern) ->
|
||||
@@ -44,10 +43,3 @@ class BindingSet
|
||||
which: charCode
|
||||
key: key
|
||||
|
||||
selectorMatchesEvent: (event) ->
|
||||
currentNode = event.target
|
||||
while currentNode
|
||||
return true if $(currentNode).is(@selector)
|
||||
currentNode = currentNode.parentNode
|
||||
false
|
||||
|
||||
|
||||
@@ -12,8 +12,12 @@ class KeyEventHandler
|
||||
@bindingSets.push(new BindingSet(selector, bindings))
|
||||
|
||||
handleKeypress: (event) ->
|
||||
for bindingSet in @bindingSets
|
||||
if command = bindingSet.commandForEvent(event)
|
||||
$(event.target).trigger(command)
|
||||
return
|
||||
currentNode = event.target
|
||||
while currentNode
|
||||
for bindingSet in @bindingSets
|
||||
if $(currentNode).is(bindingSet.selector)
|
||||
if command = bindingSet.commandForEvent(event)
|
||||
$(event.target).trigger(command)
|
||||
return
|
||||
currentNode = currentNode.parentNode
|
||||
|
||||
|
||||
Reference in New Issue
Block a user