mirror of https://github.com/vuejs/core.git
test: add all tests for `v-on` (#52)
This commit is contained in:
parent
2e25c22ddf
commit
42b913283b
|
@ -1,5 +1,31 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`v-on > case conversion for kebab-case events 1`] = `
|
||||
"import { template as _template, children as _children, on as _on } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "fooBar", (...args) => (_ctx.onMount && _ctx.onMount(...args)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > dynamic arg 1`] = `
|
||||
"import { template as _template, children as _children, effect as _effect, on as _on } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_effect(() => {
|
||||
_on(n1, _ctx.event, (...args) => (_ctx.handler && _ctx.handler(...args)))
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > event modifier 1`] = `
|
||||
"import { template as _template, children as _children, on as _on, withModifiers as _withModifiers, withKeys as _withKeys } from 'vue/vapor';
|
||||
|
||||
|
@ -33,6 +59,131 @@ export function render(_ctx) {
|
|||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should not wrap keys guard if no key modifier is present 1`] = `
|
||||
"import { template as _template, children as _children, on as _on, withModifiers as _withModifiers } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "keyup", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["exact"]))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should support multiple events and modifiers options w/ prefixIdentifiers: true 1`] = `
|
||||
"import { template as _template, children as _children, on as _on, withModifiers as _withModifiers, withKeys as _withKeys } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "click", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["stop"]))
|
||||
_on(n1, "keyup", _withKeys((...args) => (_ctx.test && _ctx.test(...args)), ["enter"]))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should support multiple modifiers and event options w/ prefixIdentifiers: true 1`] = `
|
||||
"import { template as _template, children as _children, on as _on, withModifiers as _withModifiers } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "click", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["stop", "prevent"]), { capture: true, once: true })
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should transform click.middle 1`] = `
|
||||
"import { template as _template, children as _children, on as _on, withModifiers as _withModifiers } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "mouseup", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["middle"]))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should transform click.middle 2`] = `
|
||||
"import { template as _template, children as _children, effect as _effect, on as _on, withModifiers as _withModifiers } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_effect(() => {
|
||||
_on(n1, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["middle"]))
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should transform click.right 1`] = `
|
||||
"import { template as _template, children as _children, on as _on, withModifiers as _withModifiers } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "contextmenu", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["right"]))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should transform click.right 2`] = `
|
||||
"import { template as _template, children as _children, effect as _effect, on as _on, withKeys as _withKeys, withModifiers as _withModifiers } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_effect(() => {
|
||||
_on(n1, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), _withKeys(_withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["right"]), ["right"]))
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should wrap as function if expression is inline statement 1`] = `
|
||||
"import { template as _template, children as _children, on as _on } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "click", (...args) => (_ctx.i++ && _ctx.i++(...args)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should wrap keys guard for keyboard events or dynamic events 1`] = `
|
||||
"import { template as _template, children as _children, on as _on, withKeys as _withKeys, withModifiers as _withModifiers } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "keydown", _withKeys(_withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["stop", "ctrl"]), ["a"]), { capture: true })
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > should wrap keys guard for static key event w/ left/right modifiers 1`] = `
|
||||
"import { template as _template, children as _children, on as _on, withKeys as _withKeys } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_on(n1, "keyup", _withKeys((...args) => (_ctx.test && _ctx.test(...args)), ["left"]))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`v-on > simple expression 1`] = `
|
||||
"import { template as _template, children as _children, on as _on } from 'vue/vapor';
|
||||
|
||||
|
|
|
@ -80,6 +80,9 @@ describe('v-html', () => {
|
|||
expect(ir.vaporHelpers).contains('setHtml')
|
||||
expect(ir.helpers.size).toBe(0)
|
||||
|
||||
// children should have been removed
|
||||
expect(ir.template).toMatchObject([{ template: '<div></div>' }])
|
||||
|
||||
expect(ir.operation).toEqual([])
|
||||
expect(ir.effect).toMatchObject([
|
||||
{
|
||||
|
@ -109,6 +112,8 @@ describe('v-html', () => {
|
|||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
// children should have been removed
|
||||
expect(code).contains('template("<div></div>")')
|
||||
})
|
||||
|
||||
test('should raise error if has no expression', () => {
|
||||
|
|
|
@ -1,45 +1,72 @@
|
|||
import { type RootNode, BindingTypes, ErrorCodes } from '@vue/compiler-dom'
|
||||
import { type CompilerOptions, compile as _compile } from '../../src'
|
||||
import { BindingTypes, ErrorCodes, parse, NodeTypes } from '@vue/compiler-dom'
|
||||
import {
|
||||
type CompilerOptions,
|
||||
compile as _compile,
|
||||
RootIRNode,
|
||||
transform,
|
||||
generate,
|
||||
IRNodeTypes,
|
||||
} from '../../src'
|
||||
|
||||
function compile(template: string | RootNode, options: CompilerOptions = {}) {
|
||||
let { code } = _compile(template, {
|
||||
...options,
|
||||
mode: 'module',
|
||||
import { transformVOn } from '../../src/transforms/vOn'
|
||||
import { transformElement } from '../../src/transforms/transformElement'
|
||||
|
||||
function compileWithVOn(
|
||||
template: string,
|
||||
options: CompilerOptions = {},
|
||||
): {
|
||||
ir: RootIRNode
|
||||
code: string
|
||||
} {
|
||||
const ast = parse(template, { prefixIdentifiers: true, ...options })
|
||||
const ir = transform(ast, {
|
||||
nodeTransforms: [transformElement],
|
||||
directiveTransforms: {
|
||||
on: transformVOn,
|
||||
},
|
||||
prefixIdentifiers: true,
|
||||
...options,
|
||||
})
|
||||
return code
|
||||
const { code } = generate(ir, { prefixIdentifiers: true, ...options })
|
||||
return { ir, code }
|
||||
}
|
||||
|
||||
describe('v-on', () => {
|
||||
test('simple expression', () => {
|
||||
const code = compile(`<div @click="handleClick"></div>`, {
|
||||
const { code, ir } = compileWithVOn(`<div @click="handleClick"></div>`, {
|
||||
bindingMetadata: {
|
||||
handleClick: BindingTypes.SETUP_CONST,
|
||||
},
|
||||
})
|
||||
|
||||
expect(ir.vaporHelpers).contains('on')
|
||||
expect(ir.helpers.size).toBe(0)
|
||||
expect(ir.effect).toEqual([])
|
||||
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
element: 1,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'click',
|
||||
isStatic: true,
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'handleClick',
|
||||
isStatic: false,
|
||||
},
|
||||
modifiers: { keys: [], nonKeys: [], options: [] },
|
||||
keyOverride: undefined,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
})
|
||||
|
||||
test('should error if no expression AND no modifier', () => {
|
||||
const onError = vi.fn()
|
||||
compile(`<div v-on:click />`, { onError })
|
||||
expect(onError.mock.calls[0][0]).toMatchObject({
|
||||
code: ErrorCodes.X_V_ON_NO_EXPRESSION,
|
||||
loc: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 6,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 16,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test('event modifier', () => {
|
||||
const code = compile(
|
||||
const { code } = compileWithVOn(
|
||||
`<a @click.stop="handleEvent"></a>
|
||||
<form @submit.prevent="handleEvent"></form>
|
||||
<a @click.stop.prevent="handleEvent"></a>
|
||||
|
@ -70,4 +97,364 @@ describe('v-on', () => {
|
|||
)
|
||||
expect(code).matchSnapshot()
|
||||
})
|
||||
|
||||
test('dynamic arg', () => {
|
||||
const { code, ir } = compileWithVOn(`<div v-on:[event]="handler"/>`)
|
||||
|
||||
expect(ir.vaporHelpers).contains('on')
|
||||
expect(ir.vaporHelpers).contains('effect')
|
||||
expect(ir.helpers.size).toBe(0)
|
||||
expect(ir.operation).toEqual([])
|
||||
|
||||
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
element: 1,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'event',
|
||||
isStatic: false,
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'handler',
|
||||
isStatic: false,
|
||||
},
|
||||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
})
|
||||
|
||||
test.todo('dynamic arg with prefixing')
|
||||
test.todo('dynamic arg with complex exp prefixing')
|
||||
test.todo('should wrap as function if expression is inline statement')
|
||||
test.todo('should handle multiple inline statement')
|
||||
test.todo('should handle multi-line statement')
|
||||
test.todo('inline statement w/ prefixIdentifiers: true')
|
||||
test.todo('multiple inline statements w/ prefixIdentifiers: true')
|
||||
test.todo(
|
||||
'should NOT wrap as function if expression is already function expression',
|
||||
)
|
||||
test.todo(
|
||||
'should NOT wrap as function if expression is already function expression (with Typescript)',
|
||||
)
|
||||
test.todo(
|
||||
'should NOT wrap as function if expression is already function expression (with newlines)',
|
||||
)
|
||||
test.todo(
|
||||
'should NOT wrap as function if expression is already function expression (with newlines + function keyword)',
|
||||
)
|
||||
test.todo(
|
||||
'should NOT wrap as function if expression is complex member expression',
|
||||
)
|
||||
test.todo('complex member expression w/ prefixIdentifiers: true')
|
||||
test.todo('function expression w/ prefixIdentifiers: true')
|
||||
|
||||
test('should error if no expression AND no modifier', () => {
|
||||
const onError = vi.fn()
|
||||
compileWithVOn(`<div v-on:click />`, { onError })
|
||||
expect(onError.mock.calls[0][0]).toMatchObject({
|
||||
code: ErrorCodes.X_V_ON_NO_EXPRESSION,
|
||||
loc: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 6,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 16,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test('should NOT error if no expression but has modifier', () => {
|
||||
const onError = vi.fn()
|
||||
compileWithVOn(`<div v-on:click.prevent />`, { onError })
|
||||
expect(onError).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('case conversion for kebab-case events', () => {
|
||||
const { ir, code } = compileWithVOn(`<div v-on:foo-bar="onMount"/>`)
|
||||
|
||||
expect(ir.vaporHelpers).contains('on')
|
||||
expect(ir.helpers.size).toBe(0)
|
||||
expect(ir.effect).toEqual([])
|
||||
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
element: 1,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'fooBar',
|
||||
isStatic: true,
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'onMount',
|
||||
isStatic: false,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('fooBar')
|
||||
})
|
||||
|
||||
test('error for vnode hooks', () => {
|
||||
const onError = vi.fn()
|
||||
compileWithVOn(`<div v-on:vnode-mounted="onMount"/>`, { onError })
|
||||
expect(onError.mock.calls[0][0]).toMatchObject({
|
||||
code: ErrorCodes.X_VNODE_HOOKS,
|
||||
loc: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 11,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 24,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test.todo('vue: prefixed events')
|
||||
|
||||
test('should support multiple modifiers and event options w/ prefixIdentifiers: true', () => {
|
||||
const { code, ir } = compileWithVOn(
|
||||
`<div @click.stop.prevent.capture.once="test"/>`,
|
||||
{
|
||||
prefixIdentifiers: true,
|
||||
},
|
||||
)
|
||||
|
||||
expect(ir.vaporHelpers).contains('on')
|
||||
expect(ir.vaporHelpers).contains('withModifiers')
|
||||
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'test',
|
||||
isStatic: false,
|
||||
},
|
||||
modifiers: {
|
||||
keys: [],
|
||||
nonKeys: ['stop', 'prevent'],
|
||||
options: ['capture', 'once'],
|
||||
},
|
||||
keyOverride: undefined,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_withModifiers')
|
||||
expect(code).contains('["stop", "prevent"]')
|
||||
expect(code).contains('{ capture: true, once: true }')
|
||||
})
|
||||
|
||||
test('should support multiple events and modifiers options w/ prefixIdentifiers: true', () => {
|
||||
const { code, ir } = compileWithVOn(
|
||||
`<div @click.stop="test" @keyup.enter="test" />`,
|
||||
{
|
||||
prefixIdentifiers: true,
|
||||
},
|
||||
)
|
||||
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'click',
|
||||
isStatic: true,
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'test',
|
||||
isStatic: false,
|
||||
},
|
||||
modifiers: {
|
||||
keys: [],
|
||||
nonKeys: ['stop'],
|
||||
options: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'keyup',
|
||||
isStatic: true,
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'test',
|
||||
isStatic: false,
|
||||
},
|
||||
modifiers: {
|
||||
keys: ['enter'],
|
||||
nonKeys: [],
|
||||
options: [],
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains(
|
||||
'_on(n1, "click", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["stop"]))',
|
||||
)
|
||||
expect(code).contains(
|
||||
'_on(n1, "keyup", _withKeys((...args) => (_ctx.test && _ctx.test(...args)), ["enter"]))',
|
||||
)
|
||||
})
|
||||
|
||||
test('should wrap keys guard for keyboard events or dynamic events', () => {
|
||||
const { code, ir } = compileWithVOn(
|
||||
`<div @keydown.stop.capture.ctrl.a="test"/>`,
|
||||
{
|
||||
prefixIdentifiers: true,
|
||||
},
|
||||
)
|
||||
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
element: 1,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'keydown',
|
||||
isStatic: true,
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'test',
|
||||
isStatic: false,
|
||||
},
|
||||
modifiers: {
|
||||
keys: ['a'],
|
||||
nonKeys: ['stop', 'ctrl'],
|
||||
options: ['capture'],
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
})
|
||||
|
||||
test('should not wrap keys guard if no key modifier is present', () => {
|
||||
const { code, ir } = compileWithVOn(`<div @keyup.exact="test"/>`, {
|
||||
prefixIdentifiers: true,
|
||||
})
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
modifiers: { nonKeys: ['exact'] },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
})
|
||||
|
||||
test('should wrap keys guard for static key event w/ left/right modifiers', () => {
|
||||
const { code, ir } = compileWithVOn(`<div @keyup.left="test"/>`, {
|
||||
prefixIdentifiers: true,
|
||||
})
|
||||
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
modifiers: { keys: ['left'] },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
})
|
||||
|
||||
test.todo('should wrap both for dynamic key event w/ left/right modifiers')
|
||||
|
||||
test('should transform click.right', () => {
|
||||
const { code, ir } = compileWithVOn(`<div @click.right="test"/>`)
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'contextmenu',
|
||||
isStatic: true,
|
||||
},
|
||||
modifiers: { nonKeys: ['right'] },
|
||||
keyOverride: undefined,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('"contextmenu"')
|
||||
|
||||
// dynamic
|
||||
const { code: code2, ir: ir2 } = compileWithVOn(
|
||||
`<div @[event].right="test"/>`,
|
||||
)
|
||||
expect(ir2.effect[0].operations).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'event',
|
||||
isStatic: false,
|
||||
},
|
||||
modifiers: { nonKeys: ['right'] },
|
||||
keyOverride: ['click', 'contextmenu'],
|
||||
},
|
||||
])
|
||||
|
||||
expect(code2).matchSnapshot()
|
||||
expect(code2).contains(
|
||||
'(_ctx.event) === "click" ? "contextmenu" : (_ctx.event)',
|
||||
)
|
||||
})
|
||||
|
||||
test('should transform click.middle', () => {
|
||||
const { code, ir } = compileWithVOn(`<div @click.middle="test"/>`)
|
||||
expect(ir.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'mouseup',
|
||||
isStatic: true,
|
||||
},
|
||||
modifiers: { nonKeys: ['middle'] },
|
||||
keyOverride: undefined,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('"mouseup"')
|
||||
|
||||
// dynamic
|
||||
const { code: code2, ir: ir2 } = compileWithVOn(
|
||||
`<div @[event].middle="test"/>`,
|
||||
)
|
||||
|
||||
expect(ir2.effect[0].operations).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'event',
|
||||
isStatic: false,
|
||||
},
|
||||
modifiers: { nonKeys: ['middle'] },
|
||||
keyOverride: ['click', 'mouseup'],
|
||||
},
|
||||
])
|
||||
|
||||
expect(code2).matchSnapshot()
|
||||
expect(code2).contains(
|
||||
'(_ctx.event) === "click" ? "mouseup" : (_ctx.event)',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import { createCompilerError, ErrorCodes } from '@vue/compiler-core'
|
||||
import {
|
||||
createCompilerError,
|
||||
ElementTypes,
|
||||
ErrorCodes,
|
||||
} from '@vue/compiler-core'
|
||||
import type { DirectiveTransform } from '../transform'
|
||||
import { IRNodeTypes, KeyOverride } from '../ir'
|
||||
import { IRNodeTypes, KeyOverride, SetEventIRNode } from '../ir'
|
||||
import { resolveModifiers } from '@vue/compiler-dom'
|
||||
import { camelize } from '@vue/shared'
|
||||
|
||||
export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
||||
let { arg, exp, loc, modifiers } = dir
|
||||
|
@ -16,6 +21,23 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
|||
return
|
||||
}
|
||||
|
||||
if (arg.isStatic) {
|
||||
let rawName = arg.content
|
||||
if (__DEV__ && rawName.startsWith('vnode')) {
|
||||
context.options.onError(
|
||||
createCompilerError(ErrorCodes.X_VNODE_HOOKS, arg.loc),
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
node.tagType !== ElementTypes.ELEMENT ||
|
||||
rawName.startsWith('vnode') ||
|
||||
!/[A-Z]/.test(rawName)
|
||||
) {
|
||||
arg.content = camelize(arg.content)
|
||||
}
|
||||
}
|
||||
|
||||
const { keyModifiers, nonKeyModifiers, eventOptionModifiers } =
|
||||
resolveModifiers(
|
||||
arg.isStatic ? `on${arg.content}` : arg,
|
||||
|
@ -48,7 +70,7 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
|||
}
|
||||
}
|
||||
|
||||
context.registerOperation({
|
||||
const operation: SetEventIRNode = {
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
loc,
|
||||
element: context.reference(),
|
||||
|
@ -60,5 +82,11 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
|||
options: eventOptionModifiers,
|
||||
},
|
||||
keyOverride,
|
||||
})
|
||||
}
|
||||
|
||||
if (arg.isStatic) {
|
||||
context.registerOperation(operation)
|
||||
} else {
|
||||
context.registerEffect([arg], [operation])
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue