| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- import {
- transformOn as baseTransform,
- DirectiveTransform,
- createObjectProperty,
- createCallExpression,
- createSimpleExpression,
- NodeTypes,
- createCompoundExpression,
- ExpressionNode,
- SimpleExpressionNode,
- isStaticExp
- } from '@vue/compiler-core'
- import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../runtimeHelpers'
- import { makeMap, capitalize } from '@vue/shared'
- const isEventOptionModifier = /*#__PURE__*/ makeMap(`passive,once,capture`)
- const isNonKeyModifier = /*#__PURE__*/ makeMap(
- // event propagation management
- `stop,prevent,self,` +
- // system modifiers + exact
- `ctrl,shift,alt,meta,exact,` +
- // mouse
- `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 resolveModifiers = (key: ExpressionNode, modifiers: string[]) => {
- const keyModifiers = []
- const nonKeyModifiers = []
- const eventOptionModifiers = []
- for (let i = 0; i < modifiers.length; i++) {
- const modifier = modifiers[i]
- if (isEventOptionModifier(modifier)) {
- // eventOptionModifiers: modifiers for addEventListener() options,
- // e.g. .passive & .capture
- eventOptionModifiers.push(modifier)
- } else {
- // runtimeModifiers: modifiers that needs runtime guards
- if (maybeKeyModifier(modifier)) {
- if (isStaticExp(key)) {
- if (isKeyboardEvent((key as SimpleExpressionNode).content)) {
- keyModifiers.push(modifier)
- } else {
- nonKeyModifiers.push(modifier)
- }
- } else {
- keyModifiers.push(modifier)
- nonKeyModifiers.push(modifier)
- }
- } else {
- if (isNonKeyModifier(modifier)) {
- nonKeyModifiers.push(modifier)
- } else {
- keyModifiers.push(modifier)
- }
- }
- }
- }
- return {
- keyModifiers,
- nonKeyModifiers,
- eventOptionModifiers
- }
- }
- const transformClick = (key: ExpressionNode, event: string) => {
- const isStaticClick =
- isStaticExp(key) && key.content.toLowerCase() === 'onclick'
- return isStaticClick
- ? createSimpleExpression(event, true)
- : key.type !== NodeTypes.SIMPLE_EXPRESSION
- ? createCompoundExpression([
- `(`,
- key,
- `) === "onClick" ? "${event}" : (`,
- key,
- `)`
- ])
- : key
- }
- export const transformOn: DirectiveTransform = (dir, node, context) => {
- return baseTransform(dir, node, context, baseResult => {
- const { modifiers } = dir
- if (!modifiers.length) return baseResult
- let { key, value: handlerExp } = baseResult.props[0]
- const {
- keyModifiers,
- nonKeyModifiers,
- eventOptionModifiers
- } = resolveModifiers(key, modifiers)
- // normalize click.right and click.middle since they don't actually fire
- if (nonKeyModifiers.includes('right')) {
- key = transformClick(key, `onContextmenu`)
- }
- if (nonKeyModifiers.includes('middle')) {
- key = transformClick(key, `onMouseup`)
- }
- if (nonKeyModifiers.length) {
- handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [
- handlerExp,
- JSON.stringify(nonKeyModifiers)
- ])
- }
- if (
- keyModifiers.length &&
- // if event name is dynamic, always wrap with keys guard
- (!isStaticExp(key) || isKeyboardEvent(key.content))
- ) {
- handlerExp = createCallExpression(context.helper(V_ON_WITH_KEYS), [
- handlerExp,
- JSON.stringify(keyModifiers)
- ])
- }
- if (eventOptionModifiers.length) {
- const modifierPostfix = eventOptionModifiers.map(capitalize).join('')
- key = isStaticExp(key)
- ? createSimpleExpression(`${key.content}${modifierPostfix}`, true)
- : createCompoundExpression([`(`, key, `) + "${modifierPostfix}"`])
- }
- return {
- props: [createObjectProperty(key, handlerExp)]
- }
- })
- }
|