Skip to content

Commit

Permalink
fix: support KeyboardEvent.key in built-in keyboard event modifiers (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jkzing authored and yyx990803 committed Mar 7, 2018
1 parent 50b711a commit 1c8e2e8
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
31 changes: 25 additions & 6 deletions src/core/instance/render-helpers/check-keycodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@
import config from 'core/config'
import { hyphenate } from 'shared/util'

const keyNames: { [key: string]: string | Array<string> } = {
esc: 'Escape',
tab: 'Tab',
enter: 'Enter',
space: ' ',
up: 'ArrowUp',
left: 'ArrowLeft',
right: 'ArrowRight',
down: 'ArrowDown',
'delete': ['Backspace', 'Delete']
}

function isKeyNotMatch<T> (expect: T | Array<T>, actual: T): boolean {
if (Array.isArray(expect)) {
return expect.indexOf(actual) === -1
} else {
return expect !== actual
}
}

/**
* Runtime helper for checking keyCodes from config.
* exposed as Vue.prototype._k
Expand All @@ -15,12 +35,11 @@ export function checkKeyCodes (
eventKeyName?: string
): ?boolean {
const keyCodes = config.keyCodes[key] || builtInAlias
if (keyCodes) {
if (Array.isArray(keyCodes)) {
return keyCodes.indexOf(eventKeyCode) === -1
} else {
return keyCodes !== eventKeyCode
}
const builtInName: string | Array<string> = keyNames[key]
if (builtInName && keyCodes === builtInAlias && eventKeyName) {
return isKeyNotMatch(builtInName, eventKeyName)
} else if (keyCodes) {
return isKeyNotMatch(keyCodes, eventKeyCode)
} else if (eventKeyName) {
return hyphenate(eventKeyName) !== key
}
Expand Down
29 changes: 29 additions & 0 deletions test/unit/features/directives/on.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,35 @@ describe('Directive v-on', () => {
expect(spyMiddle).toHaveBeenCalled()
})

it('should support KeyboardEvent.key for built in aliases', () => {
vm = new Vue({
el,
template: `
<div>
<input ref="enter" @keyup.enter="foo">
<input ref="space" @keyup.space="foo">
<input ref="esc" @keyup.esc="foo">
<input ref="left" @keyup.left="foo">
<input ref="delete" @keyup.delete="foo">
</div>
`,
methods: { foo: spy }
})

triggerEvent(vm.$refs.enter, 'keyup', e => { e.key = 'Enter' })
expect(spy.calls.count()).toBe(1)
triggerEvent(vm.$refs.space, 'keyup', e => { e.key = ' ' })
expect(spy.calls.count()).toBe(2)
triggerEvent(vm.$refs.esc, 'keyup', e => { e.key = 'Escape' })
expect(spy.calls.count()).toBe(3)
triggerEvent(vm.$refs.left, 'keyup', e => { e.key = 'ArrowLeft' })
expect(spy.calls.count()).toBe(4)
triggerEvent(vm.$refs.delete, 'keyup', e => { e.key = 'Backspace' })
expect(spy.calls.count()).toBe(5)
triggerEvent(vm.$refs.delete, 'keyup', e => { e.key = 'Delete' })
expect(spy.calls.count()).toBe(6)
})

it('should support custom keyCode', () => {
Vue.config.keyCodes.test = 1
vm = new Vue({
Expand Down

0 comments on commit 1c8e2e8

Please sign in to comment.