Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Add aborted bindings to the did-match-binding event #227

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions spec/keymap-manager-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1009,24 +1009,35 @@ 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"
"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} = 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(keyboardEventTarget, elementA)
assert.equal(abortedBindings[0].command, 'aborted-command')

it "emits `matched-partially` when a key binding partially matches an event", ->
handler = stub()
Expand Down
10 changes: 9 additions & 1 deletion src/keymap-manager.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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) ->
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -604,7 +611,8 @@ class KeymapManager
keystrokes,
eventType: event.type,
binding: dispatchedExactMatch,
keyboardEventTarget: target
keyboardEventTarget: target,
abortedBindings
}
else if hasPartialMatches and shouldUsePartialMatches
event.preventDefault()
Expand Down