Skip to content

Commit

Permalink
feat: v-on automatic key inference
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Oct 4, 2017
1 parent 9761072 commit 4987eeb
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 16 deletions.
2 changes: 1 addition & 1 deletion flow/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ declare interface Component {
// apply v-on object
_g: (data: any, value: any) => VNodeData;
// check custom keyCode
_k: (eventKeyCode: number, key: string, builtInAlias: number | Array<number> | void) => boolean;
_k: (eventKeyCode: number, key: string, builtInAlias?: number | Array<number>, eventKeyName?: string) => ?boolean;
// resolve scoped slots
_u: (scopedSlots: ScopedSlotsData, res?: Object) => { [key: string]: Function };

Expand Down
9 changes: 7 additions & 2 deletions src/compiler/codegen/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ function genFilterCode (key: string): string {
if (keyVal) {
return `$event.keyCode!==${keyVal}`
}
const alias = keyCodes[key]
return `_k($event.keyCode,${JSON.stringify(key)}${alias ? ',' + JSON.stringify(alias) : ''})`
const code = keyCodes[key]
return (
`_k($event.keyCode,` +
`${JSON.stringify(key)},` +
`${JSON.stringify(code)},` +
`$event.key)`
)
}
20 changes: 14 additions & 6 deletions src/core/instance/render-helpers/check-keycodes.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
/* @flow */

import config from 'core/config'
import { hyphenate } from 'shared/util'

/**
* Runtime helper for checking keyCodes from config.
* exposed as Vue.prototype._k
* passing in eventKeyName as last argument separately for backwards compat
*/
export function checkKeyCodes (
eventKeyCode: number,
key: string,
builtInAlias: number | Array<number> | void
): boolean {
builtInAlias?: number | Array<number>,
eventKeyName?: string
): ?boolean {
const keyCodes = config.keyCodes[key] || builtInAlias
if (Array.isArray(keyCodes)) {
return keyCodes.indexOf(eventKeyCode) === -1
} else {
return keyCodes !== eventKeyCode
if (keyCodes) {
if (Array.isArray(keyCodes)) {
return keyCodes.indexOf(eventKeyCode) === -1
} else {
return keyCodes !== eventKeyCode
}
} else if (eventKeyName) {
return hyphenate(eventKeyName) !== key
}
}
12 changes: 12 additions & 0 deletions test/unit/features/directives/on.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,18 @@ describe('Directive v-on', () => {
expect(spy).toHaveBeenCalled()
})

it('should support automatic key name inference', () => {
vm = new Vue({
el,
template: `<input @keyup.arrow-right="foo">`,
methods: { foo: spy }
})
triggerEvent(vm.$el, 'keyup', e => {
e.key = 'ArrowRight'
})
expect(spy).toHaveBeenCalled()
})

// ctrl, shift, alt, meta
it('should support system modifers', () => {
vm = new Vue({
Expand Down
14 changes: 7 additions & 7 deletions test/unit/modules/compiler/codegen.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,17 @@ describe('codegen', () => {
it('generate events with keycode', () => {
assertCodegen(
'<input @input.enter="onInput">',
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;onInput($event)}}})}`
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key))return null;onInput($event)}}})}`
)
// multiple keycodes (delete)
assertCodegen(
'<input @input.delete="onInput">',
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"delete",[8,46]))return null;onInput($event)}}})}`
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"delete",[8,46],$event.key))return null;onInput($event)}}})}`
)
// multiple keycodes (chained)
assertCodegen(
'<input @keydown.enter.delete="onInput">',
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13)&&_k($event.keyCode,"delete",[8,46]))return null;onInput($event)}}})}`
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key)&&_k($event.keyCode,"delete",[8,46],$event.key))return null;onInput($event)}}})}`
)
// number keycode
assertCodegen(
Expand All @@ -263,7 +263,7 @@ describe('codegen', () => {
// custom keycode
assertCodegen(
'<input @input.custom="onInput">',
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"custom"))return null;onInput($event)}}})}`
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"custom",undefined,$event.key))return null;onInput($event)}}})}`
)
})

Expand All @@ -286,12 +286,12 @@ describe('codegen', () => {
it('generate events with generic modifiers and keycode correct order', () => {
assertCodegen(
'<input @keydown.enter.prevent="onInput">',
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;$event.preventDefault();onInput($event)}}})}`
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key))return null;$event.preventDefault();onInput($event)}}})}`
)

assertCodegen(
'<input @keydown.enter.stop="onInput">',
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;$event.stopPropagation();onInput($event)}}})}`
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key))return null;$event.stopPropagation();onInput($event)}}})}`
)
})

Expand Down Expand Up @@ -398,7 +398,7 @@ describe('codegen', () => {
// with modifiers
assertCodegen(
`<input @keyup.enter="e=>current++">`,
`with(this){return _c('input',{on:{"keyup":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;(e=>current++)($event)}}})}`
`with(this){return _c('input',{on:{"keyup":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key))return null;(e=>current++)($event)}}})}`
)
})

Expand Down

0 comments on commit 4987eeb

Please sign in to comment.