From 4140a299b3c9c6e1b43d9e896c033a90c74c6529 Mon Sep 17 00:00:00 2001 From: Lee Dohm <1038121+lee-dohm@users.noreply.github.com> Date: Wed, 11 Oct 2017 14:42:32 -0700 Subject: [PATCH 1/2] Add aborted bindings to the did-match-binding event --- spec/keymap-manager-spec.coffee | 13 ++++++++++++- src/keymap-manager.coffee | 10 +++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/spec/keymap-manager-spec.coffee b/spec/keymap-manager-spec.coffee index 04b48a8..33a9de8 100644 --- a/spec/keymap-manager-spec.coffee +++ b/spec/keymap-manager-spec.coffee @@ -1009,12 +1009,22 @@ describe "KeymapManager", -> assert.equal(keymapManager.findKeyBindings(command: 'Y').length, 0) describe "events", -> + [elementA] = [] + + beforeEach -> + elementA = appendContent $$ -> + @div class: 'a', -> + it "emits `matched` when a key binding matches an event", -> + elementA.addEventListener 'aborted-command', (e) -> e.abortKeyBinding() + handler = stub() keymapManager.onDidMatchBinding handler keymapManager.add "test", "body": "ctrl-x": "used-command" + ".a": + "ctrl-x": "aborted-command" "*": "ctrl-x": "unused-command" ".not-in-the-dom": @@ -1023,10 +1033,11 @@ describe "KeymapManager", -> keymapManager.handleKeyboardEvent(buildKeydownEvent(key: 'x', ctrlKey: true, target: document.body)) assert.equal(handler.callCount, 1) - {keystrokes, binding, keyboardEventTarget} = handler.firstCall.args[0] + {keystrokes, binding, keyboardEventTarget, abortedBindings} = handler.firstCall.args[0] assert.equal(keystrokes, 'ctrl-x') assert.equal(binding.command, 'used-command') assert.equal(keyboardEventTarget, document.body) + assert.equal(abortedBindings[0].command, 'aborted-command') it "emits `matched-partially` when a key binding partially matches an event", -> handler = stub() diff --git a/src/keymap-manager.coffee b/src/keymap-manager.coffee index 209ec61..7dadad6 100644 --- a/src/keymap-manager.coffee +++ b/src/keymap-manager.coffee @@ -144,6 +144,8 @@ class KeymapManager # * `binding` {KeyBinding} that the keystrokes matched. # * `keyboardEventTarget` DOM element that was the target of the most # recent keyboard event. + # * `abortedBindings` {KeyBinding} objects that were matched but the command aborted itself + # prior to `binding` being executed. # # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. onDidMatchBinding: (callback) -> @@ -547,6 +549,8 @@ class KeymapManager if isKeyup(keystroke) exactMatchCandidates = exactMatchCandidates.concat(@pendingKeyupMatcher.getMatches(keystroke)) + abortedBindings = [] + # Determine if the current keystrokes match any bindings *exactly*. If we # do find an exact match, the next step depends on whether we have any # partial matches. If we have no partial matches, we dispatch the command @@ -595,6 +599,9 @@ class KeymapManager for pendingKeyupMatch in pendingKeyupMatchCandidates @pendingKeyupMatcher.addPendingMatch(pendingKeyupMatch) break + else + abortedBindings.push(exactMatchCandidate) + currentTarget = currentTarget.parentElement # Emit events. These are done on their own for clarity. @@ -604,7 +611,8 @@ class KeymapManager keystrokes, eventType: event.type, binding: dispatchedExactMatch, - keyboardEventTarget: target + keyboardEventTarget: target, + abortedBindings } else if hasPartialMatches and shouldUsePartialMatches event.preventDefault() From 329ee501c4ee0fa750cb45003b60c440cca1ec67 Mon Sep 17 00:00:00 2001 From: Lee Dohm <1038121+lee-dohm@users.noreply.github.com> Date: Wed, 11 Oct 2017 15:54:04 -0700 Subject: [PATCH 2/2] Fix the spec for the matched event --- spec/keymap-manager-spec.coffee | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/keymap-manager-spec.coffee b/spec/keymap-manager-spec.coffee index 33a9de8..78abe9e 100644 --- a/spec/keymap-manager-spec.coffee +++ b/spec/keymap-manager-spec.coffee @@ -1013,7 +1013,7 @@ describe "KeymapManager", -> beforeEach -> elementA = appendContent $$ -> - @div class: 'a', -> + @div class: 'a' it "emits `matched` when a key binding matches an event", -> elementA.addEventListener 'aborted-command', (e) -> e.abortKeyBinding() @@ -1025,18 +1025,18 @@ describe "KeymapManager", -> "ctrl-x": "used-command" ".a": "ctrl-x": "aborted-command" - "*": + "html": "ctrl-x": "unused-command" ".not-in-the-dom": - "ctrl-x": "unmached-command" + "ctrl-x": "unmatched-command" - keymapManager.handleKeyboardEvent(buildKeydownEvent(key: 'x', ctrlKey: true, target: document.body)) + keymapManager.handleKeyboardEvent(buildKeydownEvent(key: 'x', ctrlKey: true, target: elementA)) assert.equal(handler.callCount, 1) {keystrokes, binding, keyboardEventTarget, abortedBindings} = handler.firstCall.args[0] assert.equal(keystrokes, 'ctrl-x') assert.equal(binding.command, 'used-command') - assert.equal(keyboardEventTarget, document.body) + assert.equal(keyboardEventTarget, elementA) assert.equal(abortedBindings[0].command, 'aborted-command') it "emits `matched-partially` when a key binding partially matches an event", ->