From 6b63ba2f453b3f9bbf9e9e2167030de42f76b5ac Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 13 Jul 2020 14:00:08 -0400 Subject: [PATCH] fix(compiler-dom): fix v-on .left .right modifier handling --- .../__tests__/transforms/vOn.spec.ts | 36 +++++++++++++++++++ packages/compiler-dom/src/transforms/vOn.ts | 31 ++++++++++++---- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts index adc063da2f5..57e9300cd1f 100644 --- a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts @@ -137,6 +137,42 @@ describe('compiler-dom: transform v-on', () => { }) }) + it('should wrap keys guard for static key event w/ left/right modifiers', () => { + const { + props: [prop] + } = parseWithVOn(`
`, { + prefixIdentifiers: true + }) + expect(prop).toMatchObject({ + type: NodeTypes.JS_PROPERTY, + value: { + callee: V_ON_WITH_KEYS, + arguments: [{ content: '_ctx.test' }, '["left"]'] + } + }) + }) + + it('should wrap both for dynamic key event w/ left/right modifiers', () => { + const { + props: [prop] + } = parseWithVOn(`
`, { + prefixIdentifiers: true + }) + expect(prop).toMatchObject({ + type: NodeTypes.JS_PROPERTY, + value: { + callee: V_ON_WITH_KEYS, + arguments: [ + { + callee: V_ON_WITH_MODIFIERS, + arguments: [{ content: `_ctx.test` }, `["left"]`] + }, + '["left"]' + ] + } + }) + }) + it('should not wrap normal guard if there is only keys guard', () => { const { props: [prop] diff --git a/packages/compiler-dom/src/transforms/vOn.ts b/packages/compiler-dom/src/transforms/vOn.ts index b4c013d43ff..f527d282ca9 100644 --- a/packages/compiler-dom/src/transforms/vOn.ts +++ b/packages/compiler-dom/src/transforms/vOn.ts @@ -7,7 +7,8 @@ import { createSimpleExpression, NodeTypes, createCompoundExpression, - ExpressionNode + ExpressionNode, + SimpleExpressionNode } from '@vue/compiler-core' import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../runtimeHelpers' import { makeMap } from '@vue/shared' @@ -19,14 +20,17 @@ const isNonKeyModifier = /*#__PURE__*/ makeMap( // system modifiers + exact `ctrl,shift,alt,meta,exact,` + // mouse - `left,middle,right` + `middle` ) +// left & right could be mouse or key modifiers based on event type +const maybeKeyModifier = /*#__PURE__*/ makeMap('left,right') const isKeyboardEvent = /*#__PURE__*/ makeMap( `onkeyup,onkeydown,onkeypress`, true ) -const generateModifiers = (modifiers: string[]) => { +const resolveModifiers = (key: ExpressionNode, modifiers: string[]) => { + const isStaticKey = key.type === NodeTypes.SIMPLE_EXPRESSION && key.isStatic const keyModifiers = [] const nonKeyModifiers = [] const eventOptionModifiers = [] @@ -39,10 +43,23 @@ const generateModifiers = (modifiers: string[]) => { eventOptionModifiers.push(modifier) } else { // runtimeModifiers: modifiers that needs runtime guards - if (isNonKeyModifier(modifier)) { - nonKeyModifiers.push(modifier) + if (maybeKeyModifier(modifier)) { + if (isStaticKey) { + if (isKeyboardEvent((key as SimpleExpressionNode).content)) { + keyModifiers.push(modifier) + } else { + nonKeyModifiers.push(modifier) + } + } else { + keyModifiers.push(modifier) + nonKeyModifiers.push(modifier) + } } else { - keyModifiers.push(modifier) + if (isNonKeyModifier(modifier)) { + nonKeyModifiers.push(modifier) + } else { + keyModifiers.push(modifier) + } } } } @@ -82,7 +99,7 @@ export const transformOn: DirectiveTransform = (dir, node, context) => { keyModifiers, nonKeyModifiers, eventOptionModifiers - } = generateModifiers(modifiers) + } = resolveModifiers(key, modifiers) // normalize click.right and click.middle since they don't actually fire if (nonKeyModifiers.includes('right')) {