Skip to content

Commit 6b63ba2

Browse files
committed
fix(compiler-dom): fix v-on .left .right modifier handling
1 parent d1586f4 commit 6b63ba2

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

packages/compiler-dom/__tests__/transforms/vOn.spec.ts

+36
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,42 @@ describe('compiler-dom: transform v-on', () => {
137137
})
138138
})
139139

140+
it('should wrap keys guard for static key event w/ left/right modifiers', () => {
141+
const {
142+
props: [prop]
143+
} = parseWithVOn(`<div @keyup.left="test"/>`, {
144+
prefixIdentifiers: true
145+
})
146+
expect(prop).toMatchObject({
147+
type: NodeTypes.JS_PROPERTY,
148+
value: {
149+
callee: V_ON_WITH_KEYS,
150+
arguments: [{ content: '_ctx.test' }, '["left"]']
151+
}
152+
})
153+
})
154+
155+
it('should wrap both for dynamic key event w/ left/right modifiers', () => {
156+
const {
157+
props: [prop]
158+
} = parseWithVOn(`<div @[e].left="test"/>`, {
159+
prefixIdentifiers: true
160+
})
161+
expect(prop).toMatchObject({
162+
type: NodeTypes.JS_PROPERTY,
163+
value: {
164+
callee: V_ON_WITH_KEYS,
165+
arguments: [
166+
{
167+
callee: V_ON_WITH_MODIFIERS,
168+
arguments: [{ content: `_ctx.test` }, `["left"]`]
169+
},
170+
'["left"]'
171+
]
172+
}
173+
})
174+
})
175+
140176
it('should not wrap normal guard if there is only keys guard', () => {
141177
const {
142178
props: [prop]

packages/compiler-dom/src/transforms/vOn.ts

+24-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
createSimpleExpression,
88
NodeTypes,
99
createCompoundExpression,
10-
ExpressionNode
10+
ExpressionNode,
11+
SimpleExpressionNode
1112
} from '@vue/compiler-core'
1213
import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../runtimeHelpers'
1314
import { makeMap } from '@vue/shared'
@@ -19,14 +20,17 @@ const isNonKeyModifier = /*#__PURE__*/ makeMap(
1920
// system modifiers + exact
2021
`ctrl,shift,alt,meta,exact,` +
2122
// mouse
22-
`left,middle,right`
23+
`middle`
2324
)
25+
// left & right could be mouse or key modifiers based on event type
26+
const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right')
2427
const isKeyboardEvent = /*#__PURE__*/ makeMap(
2528
`onkeyup,onkeydown,onkeypress`,
2629
true
2730
)
2831

29-
const generateModifiers = (modifiers: string[]) => {
32+
const resolveModifiers = (key: ExpressionNode, modifiers: string[]) => {
33+
const isStaticKey = key.type === NodeTypes.SIMPLE_EXPRESSION && key.isStatic
3034
const keyModifiers = []
3135
const nonKeyModifiers = []
3236
const eventOptionModifiers = []
@@ -39,10 +43,23 @@ const generateModifiers = (modifiers: string[]) => {
3943
eventOptionModifiers.push(modifier)
4044
} else {
4145
// runtimeModifiers: modifiers that needs runtime guards
42-
if (isNonKeyModifier(modifier)) {
43-
nonKeyModifiers.push(modifier)
46+
if (maybeKeyModifier(modifier)) {
47+
if (isStaticKey) {
48+
if (isKeyboardEvent((key as SimpleExpressionNode).content)) {
49+
keyModifiers.push(modifier)
50+
} else {
51+
nonKeyModifiers.push(modifier)
52+
}
53+
} else {
54+
keyModifiers.push(modifier)
55+
nonKeyModifiers.push(modifier)
56+
}
4457
} else {
45-
keyModifiers.push(modifier)
58+
if (isNonKeyModifier(modifier)) {
59+
nonKeyModifiers.push(modifier)
60+
} else {
61+
keyModifiers.push(modifier)
62+
}
4663
}
4764
}
4865
}
@@ -82,7 +99,7 @@ export const transformOn: DirectiveTransform = (dir, node, context) => {
8299
keyModifiers,
83100
nonKeyModifiers,
84101
eventOptionModifiers
85-
} = generateModifiers(modifiers)
102+
} = resolveModifiers(key, modifiers)
86103

87104
// normalize click.right and click.middle since they don't actually fire
88105
if (nonKeyModifiers.includes('right')) {

0 commit comments

Comments
 (0)