Skip to content

Commit 3294eba

Browse files
committed
fix v-on .left .right compat with keyboard events (fix #5046)
1 parent 0b902e0 commit 3294eba

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

src/compiler/codegen/events.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ const modifierCode: { [key: string]: string } = {
2929
shift: genGuard(`!$event.shiftKey`),
3030
alt: genGuard(`!$event.altKey`),
3131
meta: genGuard(`!$event.metaKey`),
32-
left: genGuard(`$event.button !== 0`),
33-
middle: genGuard(`$event.button !== 1`),
34-
right: genGuard(`$event.button !== 2`)
32+
left: genGuard(`'button' in $event && $event.button !== 0`),
33+
middle: genGuard(`'button' in $event && $event.button !== 1`),
34+
right: genGuard(`'button' in $event && $event.button !== 2`)
3535
}
3636

3737
export function genHandlers (events: ASTElementHandlers, native?: boolean): string {
@@ -60,12 +60,16 @@ function genHandler (
6060
for (const key in handler.modifiers) {
6161
if (modifierCode[key]) {
6262
code += modifierCode[key]
63+
// left/right
64+
if (keyCodes[key]) {
65+
keys.push(key)
66+
}
6367
} else {
6468
keys.push(key)
6569
}
6670
}
6771
if (keys.length) {
68-
code = genKeyFilter(keys) + code
72+
code += genKeyFilter(keys)
6973
}
7074
const handlerCode = simplePathRE.test(handler.value)
7175
? handler.value + '($event)'
@@ -75,7 +79,7 @@ function genHandler (
7579
}
7680
7781
function genKeyFilter (keys: Array<string>): string {
78-
return `if(${keys.map(genFilterCode).join('&&')})return null;`
82+
return `if(!('button' in $event)&&${keys.map(genFilterCode).join('&&')})return null;`
7983
}
8084
8185
function genFilterCode (key: string): string {

test/unit/features/directives/on.spec.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ describe('Directive v-on', () => {
266266
e.keyCode = 1
267267
})
268268
expect(spy).toHaveBeenCalled()
269+
Vue.config.keyCodes = Object.create(null)
269270
})
270271

271272
it('should override build-in keyCode', () => {
@@ -288,6 +289,7 @@ describe('Directive v-on', () => {
288289
e.keyCode = 40
289290
})
290291
expect(spy).toHaveBeenCalledTimes(3)
292+
Vue.config.keyCodes = Object.create(null)
291293
})
292294

293295
it('should bind to a child component', () => {
@@ -483,4 +485,45 @@ describe('Directive v-on', () => {
483485
triggerEvent(vm.$el, 'click')
484486
}).not.toThrow()
485487
})
488+
489+
// Github Issue #5046
490+
it('should support keyboard modifier', () => {
491+
const spyLeft = jasmine.createSpy()
492+
const spyRight = jasmine.createSpy()
493+
const spyUp = jasmine.createSpy()
494+
const spyDown = jasmine.createSpy()
495+
vm = new Vue({
496+
el,
497+
template: `
498+
<div>
499+
<input ref="left" @keydown.left="foo"></input>
500+
<input ref="right" @keydown.right="foo1"></input>
501+
<input ref="up" @keydown.up="foo2"></input>
502+
<input ref="down" @keydown.down="foo3"></input>
503+
</div>
504+
`,
505+
methods: {
506+
foo: spyLeft,
507+
foo1: spyRight,
508+
foo2: spyUp,
509+
foo3: spyDown
510+
}
511+
})
512+
triggerEvent(vm.$refs.left, 'keydown', e => { e.keyCode = 37 })
513+
triggerEvent(vm.$refs.left, 'keydown', e => { e.keyCode = 39 })
514+
515+
triggerEvent(vm.$refs.right, 'keydown', e => { e.keyCode = 39 })
516+
triggerEvent(vm.$refs.right, 'keydown', e => { e.keyCode = 38 })
517+
518+
triggerEvent(vm.$refs.up, 'keydown', e => { e.keyCode = 38 })
519+
triggerEvent(vm.$refs.up, 'keydown', e => { e.keyCode = 37 })
520+
521+
triggerEvent(vm.$refs.down, 'keydown', e => { e.keyCode = 40 })
522+
triggerEvent(vm.$refs.down, 'keydown', e => { e.keyCode = 39 })
523+
524+
expect(spyLeft.calls.count()).toBe(1)
525+
expect(spyRight.calls.count()).toBe(1)
526+
expect(spyUp.calls.count()).toBe(1)
527+
expect(spyDown.calls.count()).toBe(1)
528+
})
486529
})

test/unit/modules/compiler/codegen.spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,27 +229,27 @@ describe('codegen', () => {
229229
it('generate events with keycode', () => {
230230
assertCodegen(
231231
'<input @input.enter="onInput">',
232-
`with(this){return _c('input',{on:{"input":function($event){if(_k($event.keyCode,"enter",13))return null;onInput($event)}}})}`
232+
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;onInput($event)}}})}`
233233
)
234234
// multiple keycodes (delete)
235235
assertCodegen(
236236
'<input @input.delete="onInput">',
237-
`with(this){return _c('input',{on:{"input":function($event){if(_k($event.keyCode,"delete",[8,46]))return null;onInput($event)}}})}`
237+
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"delete",[8,46]))return null;onInput($event)}}})}`
238238
)
239239
// multiple keycodes (chained)
240240
assertCodegen(
241241
'<input @keydown.enter.delete="onInput">',
242-
`with(this){return _c('input',{on:{"keydown":function($event){if(_k($event.keyCode,"enter",13)&&_k($event.keyCode,"delete",[8,46]))return null;onInput($event)}}})}`
242+
`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)}}})}`
243243
)
244244
// number keycode
245245
assertCodegen(
246246
'<input @input.13="onInput">',
247-
`with(this){return _c('input',{on:{"input":function($event){if($event.keyCode!==13)return null;onInput($event)}}})}`
247+
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&$event.keyCode!==13)return null;onInput($event)}}})}`
248248
)
249249
// custom keycode
250250
assertCodegen(
251251
'<input @input.custom="onInput">',
252-
`with(this){return _c('input',{on:{"input":function($event){if(_k($event.keyCode,"custom"))return null;onInput($event)}}})}`
252+
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"custom"))return null;onInput($event)}}})}`
253253
)
254254
})
255255

0 commit comments

Comments
 (0)