From f5be55e0008aba3018441b70c52b0ea403557b33 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 9 Jan 2012 17:49:00 -0800 Subject: [PATCH] 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. --- spec/atom/key-event-handler-spec.coffee | 20 +++++++++++++++++--- src/atom/binding-set.coffee | 12 ++---------- src/atom/key-event-handler.coffee | 12 ++++++++---- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/spec/atom/key-event-handler-spec.coffee b/spec/atom/key-event-handler-spec.coffee index a56923dcf..b09223dae 100644 --- a/spec/atom/key-event-handler-spec.coffee +++ b/spec/atom/key-event-handler-spec.coffee @@ -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 = $ """
-
+
+
+
""" @@ -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() + diff --git a/src/atom/binding-set.coffee b/src/atom/binding-set.coffee index 796fc68fd..08584506a 100644 --- a/src/atom/binding-set.coffee +++ b/src/atom/binding-set.coffee @@ -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 - diff --git a/src/atom/key-event-handler.coffee b/src/atom/key-event-handler.coffee index 4ae8fb5ec..786cf26b0 100644 --- a/src/atom/key-event-handler.coffee +++ b/src/atom/key-event-handler.coffee @@ -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