parent
e91dde5d22
commit
669fec8dad
|
@ -45,7 +45,7 @@ export * from './runtimeHelpers'
|
||||||
|
|
||||||
export { getBaseTransformPreset, type TransformPreset } from './compile'
|
export { getBaseTransformPreset, type TransformPreset } from './compile'
|
||||||
export { transformModel } from './transforms/vModel'
|
export { transformModel } from './transforms/vModel'
|
||||||
export { transformOn } from './transforms/vOn'
|
export { transformOn, fnExpRE } from './transforms/vOn'
|
||||||
export { transformBind } from './transforms/vBind'
|
export { transformBind } from './transforms/vBind'
|
||||||
export { noopDirectiveTransform } from './transforms/noopDirectiveTransform'
|
export { noopDirectiveTransform } from './transforms/noopDirectiveTransform'
|
||||||
export { processIf } from './transforms/vIf'
|
export { processIf } from './transforms/vIf'
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { validateBrowserExpression } from '../validateExpression'
|
||||||
import { hasScopeRef, isMemberExpression } from '../utils'
|
import { hasScopeRef, isMemberExpression } from '../utils'
|
||||||
import { TO_HANDLER_KEY } from '../runtimeHelpers'
|
import { TO_HANDLER_KEY } from '../runtimeHelpers'
|
||||||
|
|
||||||
const fnExpRE =
|
export const fnExpRE =
|
||||||
/^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/
|
/^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/
|
||||||
|
|
||||||
export interface VOnDirectiveNode extends DirectiveNode {
|
export interface VOnDirectiveNode extends DirectiveNode {
|
||||||
|
|
|
@ -146,12 +146,13 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compile > dynamic root nodes and interpolation 1`] = `
|
exports[`compile > dynamic root nodes and interpolation 1`] = `
|
||||||
"import { on as _on, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<button></button>")
|
const t0 = _template("<button></button>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => _ctx.handleClick)
|
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.handleClick))
|
||||||
_renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count))
|
_renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count))
|
||||||
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.count))
|
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.count))
|
||||||
return n0
|
return n0
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`compiler: v-for > basic v-for 1`] = `
|
exports[`compiler: v-for > basic v-for 1`] = `
|
||||||
"import { on as _on, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = _createFor(() => (_ctx.items), (_block) => {
|
const n0 = _createFor(() => (_ctx.items), (_block) => {
|
||||||
const n2 = t0()
|
const n2 = t0()
|
||||||
_on(n2, "click", () => $event => (_ctx.remove(_block.s[0])))
|
_recordMetadata(n2, "events", "click", _eventHandler(() => $event => (_ctx.remove(_block.s[0]))))
|
||||||
const _updateEffect = () => {
|
const _updateEffect = () => {
|
||||||
const [item] = _block.s
|
const [item] = _block.s
|
||||||
_setText(n2, item)
|
_setText(n2, item)
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`v-on > complex member expression w/ prefixIdentifiers: true 1`] = `
|
exports[`v-on > complex member expression w/ prefixIdentifiers: true 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => _ctx.a['b' + _ctx.c])
|
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.a['b' + _ctx.c]))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -45,11 +46,12 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > event modifier 1`] = `
|
exports[`v-on > event modifier 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<a></a>")
|
const t0 = _template("<a></a>")
|
||||||
const t1 = _template("<form></form>")
|
const t1 = _template("<form></form>")
|
||||||
const t2 = _template("<div></div>")
|
const t2 = _template("<div></div>")
|
||||||
const t3 = _template("<input>")
|
const t3 = _template("<input>")
|
||||||
|
_delegateEvents("click", "contextmenu", "mouseup", "keyup")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
|
@ -74,224 +76,249 @@ export function render(_ctx) {
|
||||||
const n19 = t3()
|
const n19 = t3()
|
||||||
const n20 = t3()
|
const n20 = t3()
|
||||||
const n21 = t3()
|
const n21 = t3()
|
||||||
_on(n0, "click", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.handleEvent, {
|
||||||
modifiers: ["stop"]
|
modifiers: ["stop"]
|
||||||
})
|
}))
|
||||||
_on(n1, "submit", () => _ctx.handleEvent, undefined, {
|
_on(n1, "submit", () => _ctx.handleEvent, undefined, {
|
||||||
modifiers: ["prevent"]
|
modifiers: ["prevent"]
|
||||||
})
|
})
|
||||||
_on(n2, "click", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n2, "events", "click", _eventHandler(() => _ctx.handleEvent, {
|
||||||
modifiers: ["stop", "prevent"]
|
modifiers: ["stop", "prevent"]
|
||||||
})
|
}))
|
||||||
_on(n3, "click", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n3, "events", "click", _eventHandler(() => _ctx.handleEvent, {
|
||||||
modifiers: ["self"]
|
modifiers: ["self"]
|
||||||
})
|
}))
|
||||||
_on(n4, "click", () => _ctx.handleEvent, { capture: true })
|
_on(n4, "click", () => _ctx.handleEvent, { capture: true })
|
||||||
_on(n5, "click", () => _ctx.handleEvent, { once: true })
|
_on(n5, "click", () => _ctx.handleEvent, { once: true })
|
||||||
_on(n6, "scroll", () => _ctx.handleEvent, { passive: true })
|
_on(n6, "scroll", () => _ctx.handleEvent, { passive: true })
|
||||||
_on(n7, "contextmenu", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n7, "events", "contextmenu", _eventHandler(() => _ctx.handleEvent, {
|
||||||
modifiers: ["right"]
|
modifiers: ["right"]
|
||||||
})
|
}))
|
||||||
_on(n8, "click", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n8, "events", "click", _eventHandler(() => _ctx.handleEvent, {
|
||||||
modifiers: ["left"]
|
modifiers: ["left"]
|
||||||
})
|
}))
|
||||||
_on(n9, "mouseup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n9, "events", "mouseup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
modifiers: ["middle"]
|
modifiers: ["middle"]
|
||||||
})
|
}))
|
||||||
_on(n10, "contextmenu", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n10, "events", "contextmenu", _eventHandler(() => _ctx.handleEvent, {
|
||||||
modifiers: ["right"]
|
modifiers: ["right"]
|
||||||
})
|
}))
|
||||||
_on(n11, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n11, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
keys: ["enter"]
|
keys: ["enter"]
|
||||||
})
|
}))
|
||||||
_on(n12, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n12, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
keys: ["tab"]
|
keys: ["tab"]
|
||||||
})
|
}))
|
||||||
_on(n13, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n13, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
keys: ["delete"]
|
keys: ["delete"]
|
||||||
})
|
}))
|
||||||
_on(n14, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n14, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
keys: ["esc"]
|
keys: ["esc"]
|
||||||
})
|
}))
|
||||||
_on(n15, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n15, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
keys: ["space"]
|
keys: ["space"]
|
||||||
})
|
}))
|
||||||
_on(n16, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n16, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
keys: ["up"]
|
keys: ["up"]
|
||||||
})
|
}))
|
||||||
_on(n17, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n17, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
keys: ["down"]
|
keys: ["down"]
|
||||||
})
|
}))
|
||||||
_on(n18, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n18, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
keys: ["left"]
|
keys: ["left"]
|
||||||
})
|
}))
|
||||||
_on(n19, "keyup", () => _ctx.submit, undefined, {
|
_recordMetadata(n19, "events", "keyup", _eventHandler(() => _ctx.submit, {
|
||||||
modifiers: ["middle"]
|
modifiers: ["middle"]
|
||||||
})
|
}))
|
||||||
_on(n20, "keyup", () => _ctx.submit, undefined, {
|
_recordMetadata(n20, "events", "keyup", _eventHandler(() => _ctx.submit, {
|
||||||
modifiers: ["middle", "self"]
|
modifiers: ["middle", "self"]
|
||||||
})
|
}))
|
||||||
_on(n21, "keyup", () => _ctx.handleEvent, undefined, {
|
_recordMetadata(n21, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||||
modifiers: ["self"],
|
modifiers: ["self"],
|
||||||
keys: ["enter"]
|
keys: ["enter"]
|
||||||
})
|
}))
|
||||||
return [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20, n21]
|
return [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20, n21]
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > function expression w/ prefixIdentifiers: true 1`] = `
|
exports[`v-on > function expression w/ prefixIdentifiers: true 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => e => _ctx.foo(e))
|
_recordMetadata(n0, "events", "click", _eventHandler(() => e => _ctx.foo(e)))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > inline statement w/ prefixIdentifiers: true 1`] = `
|
exports[`v-on > inline statement w/ prefixIdentifiers: true 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => $event => (_ctx.foo($event)))
|
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.foo($event))))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > multiple inline statements w/ prefixIdentifiers: true 1`] = `
|
exports[`v-on > multiple inline statements w/ prefixIdentifiers: true 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => $event => {_ctx.foo($event);_ctx.bar()})
|
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo($event);_ctx.bar()}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should NOT add a prefix to $event if the expression is a function expression 1`] = `
|
exports[`v-on > should NOT add a prefix to $event if the expression is a function expression 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => $event => {_ctx.i++;_ctx.foo($event)})
|
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.i++;_ctx.foo($event)}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should NOT wrap as function if expression is already function expression (with Typescript) 1`] = `
|
exports[`v-on > should NOT wrap as function if expression is already function expression (with Typescript) 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => (e: any): any => _ctx.foo(e))
|
_recordMetadata(n0, "events", "click", _eventHandler(() => (e: any): any => _ctx.foo(e)))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should NOT wrap as function if expression is already function expression (with newlines) 1`] = `
|
exports[`v-on > should NOT wrap as function if expression is already function expression (with newlines) 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () =>
|
_recordMetadata(n0, "events", "click", _eventHandler(() =>
|
||||||
$event => {
|
$event => {
|
||||||
_ctx.foo($event)
|
_ctx.foo($event)
|
||||||
}
|
}
|
||||||
)
|
))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should NOT wrap as function if expression is already function expression 1`] = `
|
exports[`v-on > should NOT wrap as function if expression is already function expression 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => $event => _ctx.foo($event))
|
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => _ctx.foo($event)))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should NOT wrap as function if expression is complex member expression 1`] = `
|
exports[`v-on > should NOT wrap as function if expression is complex member expression 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => _ctx.a['b' + _ctx.c])
|
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.a['b' + _ctx.c]))
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`v-on > should delegate event 1`] = `
|
||||||
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const n0 = t0()
|
||||||
|
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.test))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should handle multi-line statement 1`] = `
|
exports[`v-on > should handle multi-line statement 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => $event => {
|
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {
|
||||||
_ctx.foo();
|
_ctx.foo();
|
||||||
_ctx.bar()
|
_ctx.bar()
|
||||||
})
|
}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should handle multiple inline statement 1`] = `
|
exports[`v-on > should handle multiple inline statement 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => $event => {_ctx.foo();_ctx.bar()})
|
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo();_ctx.bar()}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should not prefix member expression 1`] = `
|
exports[`v-on > should not prefix member expression 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => _ctx.foo.bar)
|
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.foo.bar))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should not wrap keys guard if no key modifier is present 1`] = `
|
exports[`v-on > should not wrap keys guard if no key modifier is present 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("keyup")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "keyup", () => _ctx.test, undefined, {
|
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {
|
||||||
modifiers: ["exact"]
|
modifiers: ["exact"]
|
||||||
})
|
}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should support multiple events and modifiers options w/ prefixIdentifiers: true 1`] = `
|
exports[`v-on > should support multiple events and modifiers options w/ prefixIdentifiers: true 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click", "keyup")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => _ctx.test, undefined, {
|
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.test, {
|
||||||
modifiers: ["stop"]
|
modifiers: ["stop"]
|
||||||
})
|
}))
|
||||||
_on(n0, "keyup", () => _ctx.test, undefined, {
|
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {
|
||||||
keys: ["enter"]
|
keys: ["enter"]
|
||||||
})
|
}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -310,14 +337,15 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should transform click.middle 1`] = `
|
exports[`v-on > should transform click.middle 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("mouseup")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "mouseup", () => _ctx.test, undefined, {
|
_recordMetadata(n0, "events", "mouseup", _eventHandler(() => _ctx.test, {
|
||||||
modifiers: ["middle"]
|
modifiers: ["middle"]
|
||||||
})
|
}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -338,14 +366,15 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should transform click.right 1`] = `
|
exports[`v-on > should transform click.right 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("contextmenu")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "contextmenu", () => _ctx.test, undefined, {
|
_recordMetadata(n0, "events", "contextmenu", _eventHandler(() => _ctx.test, {
|
||||||
modifiers: ["right"]
|
modifiers: ["right"]
|
||||||
})
|
}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -367,12 +396,13 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should wrap as function if expression is inline statement 1`] = `
|
exports[`v-on > should wrap as function if expression is inline statement 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => $event => (_ctx.i++))
|
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.i++)))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -398,9 +428,9 @@ exports[`v-on > should wrap in unref if identifier is setup-maybe-ref w/ inline:
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
const n1 = t0()
|
const n1 = t0()
|
||||||
const n2 = t0()
|
const n2 = t0()
|
||||||
_on(n0, "click", () => $event => (x.value=_unref(y)))
|
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (x.value=_unref(y))))
|
||||||
_on(n1, "click", () => $event => (x.value++))
|
_recordMetadata(n1, "events", "click", _eventHandler(() => $event => (x.value++)))
|
||||||
_on(n2, "click", () => $event => ({ x: x.value } = _unref(y)))
|
_recordMetadata(n2, "events", "click", _eventHandler(() => $event => ({ x: x.value } = _unref(y))))
|
||||||
return [n0, n1, n2]
|
return [n0, n1, n2]
|
||||||
})()"
|
})()"
|
||||||
`;
|
`;
|
||||||
|
@ -420,25 +450,27 @@ export function render(_ctx) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > should wrap keys guard for static key event w/ left/right modifiers 1`] = `
|
exports[`v-on > should wrap keys guard for static key event w/ left/right modifiers 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("keyup")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "keyup", () => _ctx.test, undefined, {
|
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {
|
||||||
keys: ["left"]
|
keys: ["left"]
|
||||||
})
|
}))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`v-on > simple expression 1`] = `
|
exports[`v-on > simple expression 1`] = `
|
||||||
"import { on as _on, template as _template } from 'vue/vapor';
|
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
|
||||||
const t0 = _template("<div></div>")
|
const t0 = _template("<div></div>")
|
||||||
|
_delegateEvents("click")
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = t0()
|
const n0 = t0()
|
||||||
_on(n0, "click", () => _ctx.handleClick)
|
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.handleClick))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -25,10 +25,10 @@ describe('v-on', () => {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(vaporHelpers).contains('on')
|
expect(code).matchSnapshot()
|
||||||
|
expect(vaporHelpers).not.contains('on')
|
||||||
expect(helpers.size).toBe(0)
|
expect(helpers.size).toBe(0)
|
||||||
expect(ir.block.effect).toEqual([])
|
expect(ir.block.effect).toEqual([])
|
||||||
|
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
|
@ -45,10 +45,9 @@ describe('v-on', () => {
|
||||||
},
|
},
|
||||||
modifiers: { keys: [], nonKeys: [], options: [] },
|
modifiers: { keys: [], nonKeys: [], options: [] },
|
||||||
keyOverride: undefined,
|
keyOverride: undefined,
|
||||||
|
delegate: true,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('event modifier', () => {
|
test('event modifier', () => {
|
||||||
|
@ -155,10 +154,10 @@ describe('v-on', () => {
|
||||||
const { code, ir, helpers, vaporHelpers } =
|
const { code, ir, helpers, vaporHelpers } =
|
||||||
compileWithVOn(`<div @click="i++"/>`)
|
compileWithVOn(`<div @click="i++"/>`)
|
||||||
|
|
||||||
expect(vaporHelpers).contains('on')
|
expect(code).matchSnapshot()
|
||||||
|
expect(vaporHelpers).not.contains('on')
|
||||||
expect(helpers.size).toBe(0)
|
expect(helpers.size).toBe(0)
|
||||||
expect(ir.block.effect).toEqual([])
|
expect(ir.block.effect).toEqual([])
|
||||||
|
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
|
@ -168,11 +167,12 @@ describe('v-on', () => {
|
||||||
content: 'i++',
|
content: 'i++',
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
},
|
},
|
||||||
|
delegate: true,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
expect(code).contains(
|
||||||
expect(code).matchSnapshot()
|
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.i++)))',
|
||||||
expect(code).contains('_on(n0, "click", () => $event => (_ctx.i++))')
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should wrap in unref if identifier is setup-maybe-ref w/ inline: true', () => {
|
test('should wrap in unref if identifier is setup-maybe-ref w/ inline: true', () => {
|
||||||
|
@ -192,49 +192,49 @@ describe('v-on', () => {
|
||||||
expect(vaporHelpers).contains('unref')
|
expect(vaporHelpers).contains('unref')
|
||||||
expect(helpers.size).toBe(0)
|
expect(helpers.size).toBe(0)
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_on(n0, "click", () => $event => (x.value=_unref(y)))',
|
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (x.value=_unref(y))))',
|
||||||
)
|
)
|
||||||
expect(code).contains('_on(n1, "click", () => $event => (x.value++))')
|
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_on(n2, "click", () => $event => ({ x: x.value } = _unref(y)))',
|
'_recordMetadata(n1, "events", "click", _eventHandler(() => $event => (x.value++)))',
|
||||||
|
)
|
||||||
|
expect(code).contains(
|
||||||
|
'_recordMetadata(n2, "events", "click", _eventHandler(() => $event => ({ x: x.value } = _unref(y))))',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should handle multiple inline statement', () => {
|
test('should handle multiple inline statement', () => {
|
||||||
const { ir, code } = compileWithVOn(`<div @click="foo();bar()"/>`)
|
const { ir, code } = compileWithVOn(`<div @click="foo();bar()"/>`)
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: 'foo();bar()' },
|
value: { content: 'foo();bar()' },
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
// should wrap with `{` for multiple statements
|
// should wrap with `{` for multiple statements
|
||||||
// in this case the return value is discarded and the behavior is
|
// in this case the return value is discarded and the behavior is
|
||||||
// consistent with 2.x
|
// consistent with 2.x
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_on(n0, "click", () => $event => {_ctx.foo();_ctx.bar()})',
|
`_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo();_ctx.bar()}))`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should handle multi-line statement', () => {
|
test('should handle multi-line statement', () => {
|
||||||
const { code, ir } = compileWithVOn(`<div @click="\nfoo();\nbar()\n"/>`)
|
const { code, ir } = compileWithVOn(`<div @click="\nfoo();\nbar()\n"/>`)
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: '\nfoo();\nbar()\n' },
|
value: { content: '\nfoo();\nbar()\n' },
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
// should wrap with `{` for multiple statements
|
// should wrap with `{` for multiple statements
|
||||||
// in this case the return value is discarded and the behavior is
|
// in this case the return value is discarded and the behavior is
|
||||||
// consistent with 2.x
|
// consistent with 2.x
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_on(n0, "click", () => $event => {\n_ctx.foo();\n_ctx.bar()\n})',
|
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {\n_ctx.foo();\n_ctx.bar()\n})',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -243,17 +243,16 @@ describe('v-on', () => {
|
||||||
prefixIdentifiers: true,
|
prefixIdentifiers: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: 'foo($event)' },
|
value: { content: 'foo($event)' },
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
// should NOT prefix $event
|
// should NOT prefix $event
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_on(n0, "click", () => $event => (_ctx.foo($event)))',
|
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.foo($event))))',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -262,32 +261,32 @@ describe('v-on', () => {
|
||||||
prefixIdentifiers: true,
|
prefixIdentifiers: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: 'foo($event);bar()' },
|
value: { content: 'foo($event);bar()' },
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
// should NOT prefix $event
|
// should NOT prefix $event
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_on(n0, "click", () => $event => {_ctx.foo($event);_ctx.bar()})',
|
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo($event);_ctx.bar()}))',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should NOT wrap as function if expression is already function expression', () => {
|
test('should NOT wrap as function if expression is already function expression', () => {
|
||||||
const { code, ir } = compileWithVOn(`<div @click="$event => foo($event)"/>`)
|
const { code, ir } = compileWithVOn(`<div @click="$event => foo($event)"/>`)
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: '$event => foo($event)' },
|
value: { content: '$event => foo($event)' },
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
expect(code).contains(
|
||||||
expect(code).matchSnapshot()
|
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => _ctx.foo($event)))',
|
||||||
expect(code).contains('_on(n0, "click", () => $event => _ctx.foo($event))')
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should NOT wrap as function if expression is already function expression (with Typescript)', () => {
|
test('should NOT wrap as function if expression is already function expression (with Typescript)', () => {
|
||||||
|
@ -296,16 +295,15 @@ describe('v-on', () => {
|
||||||
{ expressionPlugins: ['typescript'] },
|
{ expressionPlugins: ['typescript'] },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: '(e: any): any => foo(e)' },
|
value: { content: '(e: any): any => foo(e)' },
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
expect(code).contains(
|
expect(code).contains(
|
||||||
'_on(n0, "click", () => (e: any): any => _ctx.foo(e))',
|
'_recordMetadata(n0, "events", "click", _eventHandler(() => (e: any): any => _ctx.foo(e)))',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -318,6 +316,7 @@ describe('v-on', () => {
|
||||||
"/>`,
|
"/>`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
|
@ -330,8 +329,6 @@ describe('v-on', () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should NOT add a prefix to $event if the expression is a function expression', () => {
|
test('should NOT add a prefix to $event if the expression is a function expression', () => {
|
||||||
|
@ -372,7 +369,9 @@ describe('v-on', () => {
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains(`_on(n0, "click", () => _ctx.a['b' + _ctx.c])`)
|
expect(code).contains(
|
||||||
|
`_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.a['b' + _ctx.c]))`,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('function expression w/ prefixIdentifiers: true', () => {
|
test('function expression w/ prefixIdentifiers: true', () => {
|
||||||
|
@ -380,15 +379,16 @@ describe('v-on', () => {
|
||||||
prefixIdentifiers: true,
|
prefixIdentifiers: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_EVENT,
|
type: IRNodeTypes.SET_EVENT,
|
||||||
value: { content: `e => foo(e)` },
|
value: { content: `e => foo(e)` },
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
expect(code).contains(
|
||||||
expect(code).matchSnapshot()
|
'_recordMetadata(n0, "events", "click", _eventHandler(() => e => _ctx.foo(e)))',
|
||||||
expect(code).contains('_on(n0, "click", () => e => _ctx.foo(e))')
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should error if no expression AND no modifier', () => {
|
test('should error if no expression AND no modifier', () => {
|
||||||
|
@ -423,6 +423,7 @@ describe('v-on', () => {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
expect(vaporHelpers).contains('on')
|
expect(vaporHelpers).contains('on')
|
||||||
expect(ir.block.operation).toMatchObject([
|
expect(ir.block.operation).toMatchObject([
|
||||||
{
|
{
|
||||||
|
@ -438,12 +439,13 @@ describe('v-on', () => {
|
||||||
options: ['capture', 'once'],
|
options: ['capture', 'once'],
|
||||||
},
|
},
|
||||||
keyOverride: undefined,
|
keyOverride: undefined,
|
||||||
|
delegate: false,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
expect(code).contains(
|
||||||
expect(code).matchSnapshot()
|
'_on(n0, "click", () => _ctx.test, { capture: true, once: true }, {',
|
||||||
|
)
|
||||||
expect(code).contains('modifiers: ["stop", "prevent"]')
|
expect(code).contains('modifiers: ["stop", "prevent"]')
|
||||||
expect(code).contains('{ capture: true, once: true }')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should support multiple events and modifiers options w/ prefixIdentifiers: true', () => {
|
test('should support multiple events and modifiers options w/ prefixIdentifiers: true', () => {
|
||||||
|
@ -494,10 +496,14 @@ describe('v-on', () => {
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains(`_on(n0, "click", () => _ctx.test, undefined`)
|
expect(code).contains(
|
||||||
|
`_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.test, {`,
|
||||||
|
)
|
||||||
expect(code).contains(`modifiers: ["stop"]`)
|
expect(code).contains(`modifiers: ["stop"]`)
|
||||||
|
|
||||||
expect(code).contains(`_on(n0, "keyup", () => _ctx.test, undefined`)
|
expect(code).contains(
|
||||||
|
`_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {`,
|
||||||
|
)
|
||||||
expect(code).contains(`keys: ["enter"]`)
|
expect(code).contains(`keys: ["enter"]`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -680,6 +686,22 @@ describe('v-on', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains(`_on(n0, "click", () => _ctx.foo.bar)`)
|
expect(code).contains(
|
||||||
|
`_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.foo.bar))`,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should delegate event', () => {
|
||||||
|
const { code, ir, vaporHelpers } = compileWithVOn(`<div @click="test"/>`)
|
||||||
|
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(code).contains('_delegateEvents("click")')
|
||||||
|
expect(vaporHelpers).contains('delegateEvents')
|
||||||
|
expect(ir.block.operation).toMatchObject([
|
||||||
|
{
|
||||||
|
type: IRNodeTypes.SET_EVENT,
|
||||||
|
delegate: true,
|
||||||
|
},
|
||||||
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
LF,
|
LF,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
buildCodeFragment,
|
buildCodeFragment,
|
||||||
|
genCall,
|
||||||
genCodeFragment,
|
genCodeFragment,
|
||||||
} from './generators/utils'
|
} from './generators/utils'
|
||||||
|
|
||||||
|
@ -39,6 +40,8 @@ export class CodegenContext {
|
||||||
return `_${name}`
|
return `_${name}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delegates = new Set<string>()
|
||||||
|
|
||||||
identifiers: Record<string, string[]> = Object.create(null)
|
identifiers: Record<string, string[]> = Object.create(null)
|
||||||
withId = <T>(fn: () => T, map: Record<string, string | null>): T => {
|
withId = <T>(fn: () => T, map: Record<string, string | null>): T => {
|
||||||
const { identifiers } = this
|
const { identifiers } = this
|
||||||
|
@ -127,10 +130,11 @@ export function generate(
|
||||||
push('}')
|
push('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deligates = genDeligates(context)
|
||||||
// TODO source map?
|
// TODO source map?
|
||||||
const templates = genTemplates(ir.template, context)
|
const templates = genTemplates(ir.template, context)
|
||||||
const imports = genHelperImports(context)
|
const imports = genHelperImports(context)
|
||||||
const preamble = imports + templates
|
const preamble = imports + templates + deligates
|
||||||
|
|
||||||
const newlineCount = [...preamble].filter(c => c === '\n').length
|
const newlineCount = [...preamble].filter(c => c === '\n').length
|
||||||
if (newlineCount && !isSetupInlined) {
|
if (newlineCount && !isSetupInlined) {
|
||||||
|
@ -152,6 +156,15 @@ export function generate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function genDeligates({ delegates, vaporHelper }: CodegenContext) {
|
||||||
|
return delegates.size
|
||||||
|
? genCall(
|
||||||
|
vaporHelper('delegateEvents'),
|
||||||
|
...Array.from(delegates).map(v => `"${v}"`),
|
||||||
|
).join('') + '\n'
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
|
||||||
function genHelperImports({ helpers, vaporHelpers, options }: CodegenContext) {
|
function genHelperImports({ helpers, vaporHelpers, options }: CodegenContext) {
|
||||||
let imports = ''
|
let imports = ''
|
||||||
if (helpers.size) {
|
if (helpers.size) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { isMemberExpression } from '@vue/compiler-dom'
|
import { fnExpRE, isMemberExpression } from '@vue/compiler-dom'
|
||||||
import type { CodegenContext } from '../generate'
|
import type { CodegenContext } from '../generate'
|
||||||
import type { SetEventIRNode } from '../ir'
|
import type { SetEventIRNode } from '../ir'
|
||||||
import { genExpression } from './expression'
|
import { genExpression } from './expression'
|
||||||
|
@ -11,10 +11,6 @@ import {
|
||||||
genCall,
|
genCall,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
|
||||||
// TODO: share this with compiler-core
|
|
||||||
const fnExpRE =
|
|
||||||
/^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/
|
|
||||||
|
|
||||||
export function genSetEvent(
|
export function genSetEvent(
|
||||||
oper: SetEventIRNode,
|
oper: SetEventIRNode,
|
||||||
context: CodegenContext,
|
context: CodegenContext,
|
||||||
|
@ -25,6 +21,22 @@ export function genSetEvent(
|
||||||
const name = genName()
|
const name = genName()
|
||||||
const handler = genEventHandler()
|
const handler = genEventHandler()
|
||||||
const modifierOptions = genModifierOptions()
|
const modifierOptions = genModifierOptions()
|
||||||
|
|
||||||
|
if (oper.delegate) {
|
||||||
|
// oper.key is static
|
||||||
|
context.delegates.add(oper.key.content)
|
||||||
|
return [
|
||||||
|
NEWLINE,
|
||||||
|
...genCall(
|
||||||
|
vaporHelper('recordMetadata'),
|
||||||
|
`n${oper.element}`,
|
||||||
|
'"events"',
|
||||||
|
name,
|
||||||
|
genCall(vaporHelper('eventHandler'), handler, modifierOptions),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
const handlerOptions = options.length
|
const handlerOptions = options.length
|
||||||
? `{ ${options.map(v => `${v}: true`).join(', ')} }`
|
? `{ ${options.map(v => `${v}: true`).join(', ')} }`
|
||||||
: modifierOptions
|
: modifierOptions
|
||||||
|
@ -45,8 +57,8 @@ export function genSetEvent(
|
||||||
|
|
||||||
function genName(): CodeFragment[] {
|
function genName(): CodeFragment[] {
|
||||||
const expr = genExpression(oper.key, context)
|
const expr = genExpression(oper.key, context)
|
||||||
// TODO unit test
|
|
||||||
if (oper.keyOverride) {
|
if (oper.keyOverride) {
|
||||||
|
// TODO unit test
|
||||||
const find = JSON.stringify(oper.keyOverride[0])
|
const find = JSON.stringify(oper.keyOverride[0])
|
||||||
const replacement = JSON.stringify(oper.keyOverride[1])
|
const replacement = JSON.stringify(oper.keyOverride[1])
|
||||||
const wrapped: CodeFragment[] = ['(', ...expr, ')']
|
const wrapped: CodeFragment[] = ['(', ...expr, ')']
|
||||||
|
|
|
@ -116,6 +116,7 @@ export interface SetEventIRNode extends BaseIRNode {
|
||||||
nonKeys: string[]
|
nonKeys: string[]
|
||||||
}
|
}
|
||||||
keyOverride?: KeyOverride
|
keyOverride?: KeyOverride
|
||||||
|
delegate: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetHtmlIRNode extends BaseIRNode {
|
export interface SetHtmlIRNode extends BaseIRNode {
|
||||||
|
|
|
@ -2,9 +2,16 @@ import { ErrorCodes, createCompilerError } from '@vue/compiler-dom'
|
||||||
import type { DirectiveTransform } from '../transform'
|
import type { DirectiveTransform } from '../transform'
|
||||||
import { IRNodeTypes, type KeyOverride, type SetEventIRNode } from '../ir'
|
import { IRNodeTypes, type KeyOverride, type SetEventIRNode } from '../ir'
|
||||||
import { resolveModifiers } from '@vue/compiler-dom'
|
import { resolveModifiers } from '@vue/compiler-dom'
|
||||||
import { extend } from '@vue/shared'
|
import { extend, makeMap } from '@vue/shared'
|
||||||
import { resolveExpression } from '../utils'
|
import { resolveExpression } from '../utils'
|
||||||
|
|
||||||
|
const delegatedEvents = /*#__PURE__*/ makeMap(
|
||||||
|
'beforeinput,click,dblclick,contextmenu,focusin,focusout,input,keydown,' +
|
||||||
|
'keyup,mousedown,mousemove,mouseout,mouseover,mouseup,pointerdown,' +
|
||||||
|
'pointermove,pointerout,pointerover,pointerup,touchend,touchmove,' +
|
||||||
|
'touchstart',
|
||||||
|
)
|
||||||
|
|
||||||
export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
||||||
let { arg, exp, loc, modifiers } = dir
|
let { arg, exp, loc, modifiers } = dir
|
||||||
if (!exp && !modifiers.length) {
|
if (!exp && !modifiers.length) {
|
||||||
|
@ -29,6 +36,8 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
||||||
|
|
||||||
let keyOverride: KeyOverride | undefined
|
let keyOverride: KeyOverride | undefined
|
||||||
const isStaticClick = arg.isStatic && arg.content.toLowerCase() === 'click'
|
const isStaticClick = arg.isStatic && arg.content.toLowerCase() === 'click'
|
||||||
|
const delegate =
|
||||||
|
arg.isStatic && !eventOptionModifiers.length && delegatedEvents(arg.content)
|
||||||
|
|
||||||
// normalize click.right and click.middle since they don't actually fire
|
// normalize click.right and click.middle since they don't actually fire
|
||||||
if (nonKeyModifiers.includes('middle')) {
|
if (nonKeyModifiers.includes('middle')) {
|
||||||
|
@ -60,6 +69,7 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
||||||
options: eventOptionModifiers,
|
options: eventOptionModifiers,
|
||||||
},
|
},
|
||||||
keyOverride,
|
keyOverride,
|
||||||
|
delegate,
|
||||||
}
|
}
|
||||||
|
|
||||||
context.registerEffect([arg], [operation])
|
context.registerEffect([arg], [operation])
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
onEffectCleanup,
|
onEffectCleanup,
|
||||||
onScopeDispose,
|
onScopeDispose,
|
||||||
} from '@vue/reactivity'
|
} from '@vue/reactivity'
|
||||||
import { recordMetadata } from '../metadata'
|
import { getMetadata, recordMetadata } from '../metadata'
|
||||||
import { withKeys, withModifiers } from '@vue/runtime-dom'
|
import { withKeys, withModifiers } from '@vue/runtime-dom'
|
||||||
|
|
||||||
export function addEventListener(
|
export function addEventListener(
|
||||||
|
@ -17,25 +17,19 @@ export function addEventListener(
|
||||||
return () => el.removeEventListener(event, handler, options)
|
return () => el.removeEventListener(event, handler, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ModifierOptions {
|
||||||
|
modifiers?: string[]
|
||||||
|
keys?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
export function on(
|
export function on(
|
||||||
el: HTMLElement,
|
el: HTMLElement,
|
||||||
event: string,
|
event: string,
|
||||||
handlerGetter: () => undefined | ((...args: any[]) => any),
|
handlerGetter: () => undefined | ((...args: any[]) => any),
|
||||||
options?: AddEventListenerOptions,
|
options?: AddEventListenerOptions,
|
||||||
{ modifiers, keys }: { modifiers?: string[]; keys?: string[] } = {},
|
modifierOptions?: ModifierOptions,
|
||||||
) {
|
) {
|
||||||
const handler = (...args: any[]) => {
|
const handler = eventHandler(handlerGetter, modifierOptions)
|
||||||
let handler = handlerGetter()
|
|
||||||
if (!handler) return
|
|
||||||
|
|
||||||
if (modifiers) {
|
|
||||||
handler = withModifiers(handler, modifiers)
|
|
||||||
}
|
|
||||||
if (keys) {
|
|
||||||
handler = withKeys(handler, keys)
|
|
||||||
}
|
|
||||||
handler && handler(...args)
|
|
||||||
}
|
|
||||||
recordMetadata(el, 'events', event, handler)
|
recordMetadata(el, 'events', event, handler)
|
||||||
const cleanup = addEventListener(el, event, handler, options)
|
const cleanup = addEventListener(el, event, handler, options)
|
||||||
|
|
||||||
|
@ -48,3 +42,64 @@ export function on(
|
||||||
onScopeDispose(cleanup)
|
onScopeDispose(cleanup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function eventHandler(
|
||||||
|
getter: () => undefined | ((...args: any[]) => any),
|
||||||
|
{ modifiers, keys }: ModifierOptions = {},
|
||||||
|
) {
|
||||||
|
return (...args: any[]) => {
|
||||||
|
let handler = getter()
|
||||||
|
if (!handler) return
|
||||||
|
|
||||||
|
if (modifiers) {
|
||||||
|
handler = withModifiers(handler, modifiers)
|
||||||
|
}
|
||||||
|
if (keys) {
|
||||||
|
handler = withKeys(handler, keys)
|
||||||
|
}
|
||||||
|
handler && handler(...args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event delegation borrowed from solid
|
||||||
|
*/
|
||||||
|
const delegatedEvents = Object.create(null)
|
||||||
|
|
||||||
|
export const delegateEvents = (...names: string[]) => {
|
||||||
|
for (const name of names) {
|
||||||
|
if (!delegatedEvents[name]) {
|
||||||
|
delegatedEvents[name] = true
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
document.addEventListener(name, delegatedEventHandler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const delegatedEventHandler = (e: Event) => {
|
||||||
|
let node = ((e.composedPath && e.composedPath()[0]) || e.target) as any
|
||||||
|
if (e.target !== node) {
|
||||||
|
Object.defineProperty(e, 'target', {
|
||||||
|
configurable: true,
|
||||||
|
value: node,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Object.defineProperty(e, 'currentTarget', {
|
||||||
|
configurable: true,
|
||||||
|
get() {
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
return node || document
|
||||||
|
},
|
||||||
|
})
|
||||||
|
while (node !== null) {
|
||||||
|
const handler = getMetadata(node).events[e.type] as (...args: any[]) => any
|
||||||
|
if (handler && !node.disabled) {
|
||||||
|
handler(e)
|
||||||
|
if (e.cancelBubble) return
|
||||||
|
}
|
||||||
|
node =
|
||||||
|
node.host && node.host !== node && node.host instanceof Node
|
||||||
|
? node.host
|
||||||
|
: node.parentNode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ export * from './apiLifecycle'
|
||||||
export * from './if'
|
export * from './if'
|
||||||
export * from './for'
|
export * from './for'
|
||||||
export { defineComponent } from './apiDefineComponent'
|
export { defineComponent } from './apiDefineComponent'
|
||||||
|
export { recordMetadata } from './metadata'
|
||||||
|
|
||||||
export * from './directives/vShow'
|
export * from './directives/vShow'
|
||||||
export * from './directives/vModel'
|
export * from './directives/vModel'
|
||||||
|
|
Loading…
Reference in New Issue