mirror of https://github.com/vuejs/core.git
refactor(compiler-vapor): v-on
This commit is contained in:
parent
45e86e36d7
commit
da8e196ca5
|
@ -152,11 +152,17 @@ export const isMemberExpressionBrowser = (path: string): boolean => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isMemberExpressionNode = __BROWSER__
|
export const isMemberExpressionNode = __BROWSER__
|
||||||
? (NOOP as any as (path: string, context: TransformContext) => boolean)
|
? (NOOP as any as (
|
||||||
: (path: string, context: TransformContext): boolean => {
|
path: string,
|
||||||
|
options: Pick<TransformContext, 'expressionPlugins'>
|
||||||
|
) => boolean)
|
||||||
|
: (
|
||||||
|
path: string,
|
||||||
|
options: Pick<TransformContext, 'expressionPlugins'>
|
||||||
|
): boolean => {
|
||||||
try {
|
try {
|
||||||
let ret: Expression = parseExpression(path, {
|
let ret: Expression = parseExpression(path, {
|
||||||
plugins: context.expressionPlugins
|
plugins: options.expressionPlugins
|
||||||
})
|
})
|
||||||
if (ret.type === 'TSAsExpression' || ret.type === 'TSTypeAssertion') {
|
if (ret.type === 'TSAsExpression' || ret.type === 'TSTypeAssertion') {
|
||||||
ret = ret.expression
|
ret = ret.expression
|
||||||
|
|
|
@ -438,19 +438,31 @@ function genSetEvent(oper: SetEventIRNode, context: CodegenContext) {
|
||||||
const { vaporHelper, push, pushWithNewline } = context
|
const { vaporHelper, push, pushWithNewline } = context
|
||||||
|
|
||||||
pushWithNewline(`${vaporHelper('on')}(n${oper.element}, `)
|
pushWithNewline(`${vaporHelper('on')}(n${oper.element}, `)
|
||||||
// second arg: event name
|
|
||||||
|
// 2nd arg: event name
|
||||||
|
if (oper.keyOverride) {
|
||||||
|
const find = JSON.stringify(oper.keyOverride[0])
|
||||||
|
const replacement = JSON.stringify(oper.keyOverride[1])
|
||||||
|
push('(')
|
||||||
genExpression(oper.key, context)
|
genExpression(oper.key, context)
|
||||||
|
push(`) === ${find} ? ${replacement} : (`)
|
||||||
|
genExpression(oper.key, context)
|
||||||
|
push(')')
|
||||||
|
} else {
|
||||||
|
genExpression(oper.key, context)
|
||||||
|
}
|
||||||
push(', ')
|
push(', ')
|
||||||
|
|
||||||
const { keys, nonKeys, options } = oper.modifiers
|
const { keys, nonKeys, options } = oper.modifiers
|
||||||
|
|
||||||
|
// 3rd arg: event handler
|
||||||
|
if (oper.value && oper.value.content.trim()) {
|
||||||
if (keys.length) {
|
if (keys.length) {
|
||||||
push(`${vaporHelper('withKeys')}(`)
|
push(`${vaporHelper('withKeys')}(`)
|
||||||
}
|
}
|
||||||
if (nonKeys.length) {
|
if (nonKeys.length) {
|
||||||
push(`${vaporHelper('withModifiers')}(`)
|
push(`${vaporHelper('withModifiers')}(`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// gen event handler
|
|
||||||
push('(...args) => (')
|
push('(...args) => (')
|
||||||
genExpression(oper.value, context)
|
genExpression(oper.value, context)
|
||||||
push(' && ')
|
push(' && ')
|
||||||
|
@ -463,6 +475,11 @@ function genSetEvent(oper: SetEventIRNode, context: CodegenContext) {
|
||||||
if (keys.length) {
|
if (keys.length) {
|
||||||
push(`, ${genArrayExpression(keys)})`)
|
push(`, ${genArrayExpression(keys)})`)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
push('() => {}')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4th arg, gen options
|
||||||
if (options.length) {
|
if (options.length) {
|
||||||
push(`, { ${options.map((v) => `${v}: true`).join(', ')} }`)
|
push(`, { ${options.map((v) => `${v}: true`).join(', ')} }`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,11 +69,12 @@ export interface SetTextIRNode extends BaseIRNode {
|
||||||
value: IRExpression
|
value: IRExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type KeyOverride = [find: string, replacement: string]
|
||||||
export interface SetEventIRNode extends BaseIRNode {
|
export interface SetEventIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.SET_EVENT
|
type: IRNodeTypes.SET_EVENT
|
||||||
element: number
|
element: number
|
||||||
key: IRExpression
|
key: IRExpression
|
||||||
value: IRExpression
|
value?: SimpleExpressionNode
|
||||||
modifiers: {
|
modifiers: {
|
||||||
// modifiers for addEventListener() options, e.g. .passive & .capture
|
// modifiers for addEventListener() options, e.g. .passive & .capture
|
||||||
options: string[]
|
options: string[]
|
||||||
|
@ -82,6 +83,7 @@ export interface SetEventIRNode extends BaseIRNode {
|
||||||
// modifiers that needs runtime guards, withModifiers
|
// modifiers that needs runtime guards, withModifiers
|
||||||
nonKeys: string[]
|
nonKeys: string[]
|
||||||
}
|
}
|
||||||
|
keyOverride?: KeyOverride
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetHtmlIRNode extends BaseIRNode {
|
export interface SetHtmlIRNode extends BaseIRNode {
|
||||||
|
|
|
@ -1,70 +1,64 @@
|
||||||
import {
|
import { createCompilerError, ErrorCodes } from '@vue/compiler-core'
|
||||||
createCompilerError,
|
|
||||||
createSimpleExpression,
|
|
||||||
ErrorCodes,
|
|
||||||
ExpressionNode,
|
|
||||||
isStaticExp,
|
|
||||||
NodeTypes,
|
|
||||||
} from '@vue/compiler-core'
|
|
||||||
import type { DirectiveTransform } from '../transform'
|
import type { DirectiveTransform } from '../transform'
|
||||||
import { IRNodeTypes } from '../ir'
|
import { IRNodeTypes, KeyOverride } from '../ir'
|
||||||
import { resolveModifiers } from '@vue/compiler-dom'
|
import { resolveModifiers } from '@vue/compiler-dom'
|
||||||
|
|
||||||
export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
||||||
const { arg, exp, loc, modifiers } = dir
|
let { arg, exp, loc, modifiers } = dir
|
||||||
if (!exp && !modifiers.length) {
|
if (!exp && !modifiers.length) {
|
||||||
context.options.onError(
|
context.options.onError(
|
||||||
createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc),
|
createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc),
|
||||||
)
|
)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
// TODO support v-on="{}"
|
// TODO support v-on="{}"
|
||||||
return
|
return
|
||||||
} else if (exp === undefined) {
|
|
||||||
// TODO X_V_ON_NO_EXPRESSION error
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlerKey = `on${arg.content}`
|
|
||||||
const { keyModifiers, nonKeyModifiers, eventOptionModifiers } =
|
const { keyModifiers, nonKeyModifiers, eventOptionModifiers } =
|
||||||
resolveModifiers(handlerKey, modifiers, null, loc)
|
resolveModifiers(
|
||||||
|
arg.isStatic ? `on${arg.content}` : arg,
|
||||||
|
modifiers,
|
||||||
|
null,
|
||||||
|
loc,
|
||||||
|
)
|
||||||
|
|
||||||
|
let keyOverride: KeyOverride | undefined
|
||||||
|
|
||||||
// normalize click.right and click.middle since they don't actually fire
|
// normalize click.right and click.middle since they don't actually fire
|
||||||
let name = arg.content
|
|
||||||
|
const isStaticClick = arg.isStatic && arg.content.toLowerCase() === 'click'
|
||||||
|
|
||||||
if (nonKeyModifiers.includes('right')) {
|
if (nonKeyModifiers.includes('right')) {
|
||||||
name = transformClick(arg, 'contextmenu')
|
if (isStaticClick) {
|
||||||
|
arg = { ...arg, content: 'contextmenu' }
|
||||||
|
} else if (!arg.isStatic) {
|
||||||
|
keyOverride = ['click', 'contextmenu']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nonKeyModifiers.includes('middle')) {
|
if (nonKeyModifiers.includes('middle')) {
|
||||||
name = transformClick(arg, 'mouseup')
|
if (keyOverride) {
|
||||||
|
// TODO error here
|
||||||
|
}
|
||||||
|
if (isStaticClick) {
|
||||||
|
arg = { ...arg, content: 'mouseup' }
|
||||||
|
} else if (!arg.isStatic) {
|
||||||
|
keyOverride = ['click', 'mouseup']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO reactive
|
|
||||||
context.registerOperation({
|
context.registerOperation({
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
loc,
|
loc,
|
||||||
element: context.reference(),
|
element: context.reference(),
|
||||||
key: createSimpleExpression(name, true, arg.loc),
|
key: arg,
|
||||||
value: exp,
|
value: exp,
|
||||||
modifiers: {
|
modifiers: {
|
||||||
keys: keyModifiers,
|
keys: keyModifiers,
|
||||||
nonKeys: nonKeyModifiers,
|
nonKeys: nonKeyModifiers,
|
||||||
options: eventOptionModifiers,
|
options: eventOptionModifiers,
|
||||||
},
|
},
|
||||||
|
keyOverride,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformClick(key: ExpressionNode, event: string) {
|
|
||||||
const isStaticClick =
|
|
||||||
isStaticExp(key) && key.content.toLowerCase() === 'click'
|
|
||||||
|
|
||||||
if (isStaticClick) {
|
|
||||||
return event
|
|
||||||
} else if (key.type !== NodeTypes.SIMPLE_EXPRESSION) {
|
|
||||||
// TODO: handle CompoundExpression
|
|
||||||
return 'TODO'
|
|
||||||
} else {
|
|
||||||
return key.content.toLowerCase()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue