parent
e91dde5d22
commit
669fec8dad
|
@ -45,7 +45,7 @@ export * from './runtimeHelpers'
|
|||
|
||||
export { getBaseTransformPreset, type TransformPreset } from './compile'
|
||||
export { transformModel } from './transforms/vModel'
|
||||
export { transformOn } from './transforms/vOn'
|
||||
export { transformOn, fnExpRE } from './transforms/vOn'
|
||||
export { transformBind } from './transforms/vBind'
|
||||
export { noopDirectiveTransform } from './transforms/noopDirectiveTransform'
|
||||
export { processIf } from './transforms/vIf'
|
||||
|
|
|
@ -16,7 +16,7 @@ import { validateBrowserExpression } from '../validateExpression'
|
|||
import { hasScopeRef, isMemberExpression } from '../utils'
|
||||
import { TO_HANDLER_KEY } from '../runtimeHelpers'
|
||||
|
||||
const fnExpRE =
|
||||
export const fnExpRE =
|
||||
/^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/
|
||||
|
||||
export interface VOnDirectiveNode extends DirectiveNode {
|
||||
|
|
|
@ -146,12 +146,13 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
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(() => _setDynamicProp(n0, "id", _ctx.count))
|
||||
return n0
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = _createFor(() => (_ctx.items), (_block) => {
|
||||
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 [item] = _block.s
|
||||
_setText(n2, item)
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => _ctx.a['b' + _ctx.c])
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.a['b' + _ctx.c]))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -45,11 +46,12 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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 t1 = _template("<form></form>")
|
||||
const t2 = _template("<div></div>")
|
||||
const t3 = _template("<input>")
|
||||
_delegateEvents("click", "contextmenu", "mouseup", "keyup")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
|
@ -74,224 +76,249 @@ export function render(_ctx) {
|
|||
const n19 = t3()
|
||||
const n20 = t3()
|
||||
const n21 = t3()
|
||||
_on(n0, "click", () => _ctx.handleEvent, undefined, {
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.handleEvent, {
|
||||
modifiers: ["stop"]
|
||||
})
|
||||
}))
|
||||
_on(n1, "submit", () => _ctx.handleEvent, undefined, {
|
||||
modifiers: ["prevent"]
|
||||
})
|
||||
_on(n2, "click", () => _ctx.handleEvent, undefined, {
|
||||
_recordMetadata(n2, "events", "click", _eventHandler(() => _ctx.handleEvent, {
|
||||
modifiers: ["stop", "prevent"]
|
||||
})
|
||||
_on(n3, "click", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n3, "events", "click", _eventHandler(() => _ctx.handleEvent, {
|
||||
modifiers: ["self"]
|
||||
})
|
||||
}))
|
||||
_on(n4, "click", () => _ctx.handleEvent, { capture: true })
|
||||
_on(n5, "click", () => _ctx.handleEvent, { once: true })
|
||||
_on(n6, "scroll", () => _ctx.handleEvent, { passive: true })
|
||||
_on(n7, "contextmenu", () => _ctx.handleEvent, undefined, {
|
||||
_recordMetadata(n7, "events", "contextmenu", _eventHandler(() => _ctx.handleEvent, {
|
||||
modifiers: ["right"]
|
||||
})
|
||||
_on(n8, "click", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n8, "events", "click", _eventHandler(() => _ctx.handleEvent, {
|
||||
modifiers: ["left"]
|
||||
})
|
||||
_on(n9, "mouseup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n9, "events", "mouseup", _eventHandler(() => _ctx.handleEvent, {
|
||||
modifiers: ["middle"]
|
||||
})
|
||||
_on(n10, "contextmenu", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n10, "events", "contextmenu", _eventHandler(() => _ctx.handleEvent, {
|
||||
modifiers: ["right"]
|
||||
})
|
||||
_on(n11, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n11, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
keys: ["enter"]
|
||||
})
|
||||
_on(n12, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n12, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
keys: ["tab"]
|
||||
})
|
||||
_on(n13, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n13, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
keys: ["delete"]
|
||||
})
|
||||
_on(n14, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n14, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
keys: ["esc"]
|
||||
})
|
||||
_on(n15, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n15, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
keys: ["space"]
|
||||
})
|
||||
_on(n16, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n16, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
keys: ["up"]
|
||||
})
|
||||
_on(n17, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n17, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
keys: ["down"]
|
||||
})
|
||||
_on(n18, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n18, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
keys: ["left"]
|
||||
})
|
||||
_on(n19, "keyup", () => _ctx.submit, undefined, {
|
||||
}))
|
||||
_recordMetadata(n19, "events", "keyup", _eventHandler(() => _ctx.submit, {
|
||||
modifiers: ["middle"]
|
||||
})
|
||||
_on(n20, "keyup", () => _ctx.submit, undefined, {
|
||||
}))
|
||||
_recordMetadata(n20, "events", "keyup", _eventHandler(() => _ctx.submit, {
|
||||
modifiers: ["middle", "self"]
|
||||
})
|
||||
_on(n21, "keyup", () => _ctx.handleEvent, undefined, {
|
||||
}))
|
||||
_recordMetadata(n21, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
|
||||
modifiers: ["self"],
|
||||
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]
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => e => _ctx.foo(e))
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => e => _ctx.foo(e)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => $event => (_ctx.foo($event)))
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.foo($event))))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
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
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
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
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
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
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () =>
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() =>
|
||||
$event => {
|
||||
_ctx.foo($event)
|
||||
}
|
||||
)
|
||||
))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => $event => _ctx.foo($event))
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => _ctx.foo($event)))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
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
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => $event => {
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {
|
||||
_ctx.foo();
|
||||
_ctx.bar()
|
||||
})
|
||||
}))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => $event => {_ctx.foo();_ctx.bar()})
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo();_ctx.bar()}))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => _ctx.foo.bar)
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.foo.bar))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("keyup")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "keyup", () => _ctx.test, undefined, {
|
||||
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {
|
||||
modifiers: ["exact"]
|
||||
})
|
||||
}))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click", "keyup")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => _ctx.test, undefined, {
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.test, {
|
||||
modifiers: ["stop"]
|
||||
})
|
||||
_on(n0, "keyup", () => _ctx.test, undefined, {
|
||||
}))
|
||||
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {
|
||||
keys: ["enter"]
|
||||
})
|
||||
}))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -310,14 +337,15 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("mouseup")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "mouseup", () => _ctx.test, undefined, {
|
||||
_recordMetadata(n0, "events", "mouseup", _eventHandler(() => _ctx.test, {
|
||||
modifiers: ["middle"]
|
||||
})
|
||||
}))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -338,14 +366,15 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("contextmenu")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "contextmenu", () => _ctx.test, undefined, {
|
||||
_recordMetadata(n0, "events", "contextmenu", _eventHandler(() => _ctx.test, {
|
||||
modifiers: ["right"]
|
||||
})
|
||||
}))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -367,12 +396,13 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => $event => (_ctx.i++))
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.i++)))
|
||||
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 n1 = t0()
|
||||
const n2 = t0()
|
||||
_on(n0, "click", () => $event => (x.value=_unref(y)))
|
||||
_on(n1, "click", () => $event => (x.value++))
|
||||
_on(n2, "click", () => $event => ({ x: x.value } = _unref(y)))
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (x.value=_unref(y))))
|
||||
_recordMetadata(n1, "events", "click", _eventHandler(() => $event => (x.value++)))
|
||||
_recordMetadata(n2, "events", "click", _eventHandler(() => $event => ({ x: x.value } = _unref(y))))
|
||||
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`] = `
|
||||
"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>")
|
||||
_delegateEvents("keyup")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "keyup", () => _ctx.test, undefined, {
|
||||
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {
|
||||
keys: ["left"]
|
||||
})
|
||||
}))
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
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>")
|
||||
_delegateEvents("click")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_on(n0, "click", () => _ctx.handleClick)
|
||||
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.handleClick))
|
||||
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(ir.block.effect).toEqual([])
|
||||
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
|
@ -45,10 +45,9 @@ describe('v-on', () => {
|
|||
},
|
||||
modifiers: { keys: [], nonKeys: [], options: [] },
|
||||
keyOverride: undefined,
|
||||
delegate: true,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
})
|
||||
|
||||
test('event modifier', () => {
|
||||
|
@ -155,10 +154,10 @@ describe('v-on', () => {
|
|||
const { code, ir, helpers, vaporHelpers } =
|
||||
compileWithVOn(`<div @click="i++"/>`)
|
||||
|
||||
expect(vaporHelpers).contains('on')
|
||||
expect(code).matchSnapshot()
|
||||
expect(vaporHelpers).not.contains('on')
|
||||
expect(helpers.size).toBe(0)
|
||||
expect(ir.block.effect).toEqual([])
|
||||
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
|
@ -168,11 +167,12 @@ describe('v-on', () => {
|
|||
content: 'i++',
|
||||
isStatic: false,
|
||||
},
|
||||
delegate: true,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_on(n0, "click", () => $event => (_ctx.i++))')
|
||||
expect(code).contains(
|
||||
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.i++)))',
|
||||
)
|
||||
})
|
||||
|
||||
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(helpers.size).toBe(0)
|
||||
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(
|
||||
'_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', () => {
|
||||
const { ir, code } = compileWithVOn(`<div @click="foo();bar()"/>`)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: 'foo();bar()' },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
// should wrap with `{` for multiple statements
|
||||
// in this case the return value is discarded and the behavior is
|
||||
// consistent with 2.x
|
||||
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', () => {
|
||||
const { code, ir } = compileWithVOn(`<div @click="\nfoo();\nbar()\n"/>`)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: '\nfoo();\nbar()\n' },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
// should wrap with `{` for multiple statements
|
||||
// in this case the return value is discarded and the behavior is
|
||||
// consistent with 2.x
|
||||
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,
|
||||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: 'foo($event)' },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
// should NOT prefix $event
|
||||
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,
|
||||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: 'foo($event);bar()' },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
// should NOT prefix $event
|
||||
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', () => {
|
||||
const { code, ir } = compileWithVOn(`<div @click="$event => foo($event)"/>`)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: '$event => foo($event)' },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_on(n0, "click", () => $event => _ctx.foo($event))')
|
||||
expect(code).contains(
|
||||
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => _ctx.foo($event)))',
|
||||
)
|
||||
})
|
||||
|
||||
test('should NOT wrap as function if expression is already function expression (with Typescript)', () => {
|
||||
|
@ -296,16 +295,15 @@ describe('v-on', () => {
|
|||
{ expressionPlugins: ['typescript'] },
|
||||
)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: '(e: any): any => foo(e)' },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
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([
|
||||
{
|
||||
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', () => {
|
||||
|
@ -372,7 +369,9 @@ describe('v-on', () => {
|
|||
])
|
||||
|
||||
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', () => {
|
||||
|
@ -380,15 +379,16 @@ describe('v-on', () => {
|
|||
prefixIdentifiers: true,
|
||||
})
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
value: { content: `e => foo(e)` },
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains('_on(n0, "click", () => e => _ctx.foo(e))')
|
||||
expect(code).contains(
|
||||
'_recordMetadata(n0, "events", "click", _eventHandler(() => e => _ctx.foo(e)))',
|
||||
)
|
||||
})
|
||||
|
||||
test('should error if no expression AND no modifier', () => {
|
||||
|
@ -423,6 +423,7 @@ describe('v-on', () => {
|
|||
},
|
||||
)
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(vaporHelpers).contains('on')
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
|
@ -438,12 +439,13 @@ describe('v-on', () => {
|
|||
options: ['capture', 'once'],
|
||||
},
|
||||
keyOverride: undefined,
|
||||
delegate: false,
|
||||
},
|
||||
])
|
||||
|
||||
expect(code).matchSnapshot()
|
||||
expect(code).contains(
|
||||
'_on(n0, "click", () => _ctx.test, { capture: true, once: true }, {',
|
||||
)
|
||||
expect(code).contains('modifiers: ["stop", "prevent"]')
|
||||
expect(code).contains('{ capture: true, once: true }')
|
||||
})
|
||||
|
||||
test('should support multiple events and modifiers options w/ prefixIdentifiers: true', () => {
|
||||
|
@ -494,10 +496,14 @@ describe('v-on', () => {
|
|||
])
|
||||
|
||||
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(`_on(n0, "keyup", () => _ctx.test, undefined`)
|
||||
expect(code).contains(
|
||||
`_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {`,
|
||||
)
|
||||
expect(code).contains(`keys: ["enter"]`)
|
||||
})
|
||||
|
||||
|
@ -680,6 +686,22 @@ describe('v-on', () => {
|
|||
})
|
||||
|
||||
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,
|
||||
NEWLINE,
|
||||
buildCodeFragment,
|
||||
genCall,
|
||||
genCodeFragment,
|
||||
} from './generators/utils'
|
||||
|
||||
|
@ -39,6 +40,8 @@ export class CodegenContext {
|
|||
return `_${name}`
|
||||
}
|
||||
|
||||
delegates = new Set<string>()
|
||||
|
||||
identifiers: Record<string, string[]> = Object.create(null)
|
||||
withId = <T>(fn: () => T, map: Record<string, string | null>): T => {
|
||||
const { identifiers } = this
|
||||
|
@ -127,10 +130,11 @@ export function generate(
|
|||
push('}')
|
||||
}
|
||||
|
||||
const deligates = genDeligates(context)
|
||||
// TODO source map?
|
||||
const templates = genTemplates(ir.template, context)
|
||||
const imports = genHelperImports(context)
|
||||
const preamble = imports + templates
|
||||
const preamble = imports + templates + deligates
|
||||
|
||||
const newlineCount = [...preamble].filter(c => c === '\n').length
|
||||
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) {
|
||||
let imports = ''
|
||||
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 { SetEventIRNode } from '../ir'
|
||||
import { genExpression } from './expression'
|
||||
|
@ -11,10 +11,6 @@ import {
|
|||
genCall,
|
||||
} 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(
|
||||
oper: SetEventIRNode,
|
||||
context: CodegenContext,
|
||||
|
@ -25,6 +21,22 @@ export function genSetEvent(
|
|||
const name = genName()
|
||||
const handler = genEventHandler()
|
||||
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
|
||||
? `{ ${options.map(v => `${v}: true`).join(', ')} }`
|
||||
: modifierOptions
|
||||
|
@ -45,8 +57,8 @@ export function genSetEvent(
|
|||
|
||||
function genName(): CodeFragment[] {
|
||||
const expr = genExpression(oper.key, context)
|
||||
// TODO unit test
|
||||
if (oper.keyOverride) {
|
||||
// TODO unit test
|
||||
const find = JSON.stringify(oper.keyOverride[0])
|
||||
const replacement = JSON.stringify(oper.keyOverride[1])
|
||||
const wrapped: CodeFragment[] = ['(', ...expr, ')']
|
||||
|
|
|
@ -116,6 +116,7 @@ export interface SetEventIRNode extends BaseIRNode {
|
|||
nonKeys: string[]
|
||||
}
|
||||
keyOverride?: KeyOverride
|
||||
delegate: boolean
|
||||
}
|
||||
|
||||
export interface SetHtmlIRNode extends BaseIRNode {
|
||||
|
|
|
@ -2,9 +2,16 @@ import { ErrorCodes, createCompilerError } from '@vue/compiler-dom'
|
|||
import type { DirectiveTransform } from '../transform'
|
||||
import { IRNodeTypes, type KeyOverride, type SetEventIRNode } from '../ir'
|
||||
import { resolveModifiers } from '@vue/compiler-dom'
|
||||
import { extend } from '@vue/shared'
|
||||
import { extend, makeMap } from '@vue/shared'
|
||||
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) => {
|
||||
let { arg, exp, loc, modifiers } = dir
|
||||
if (!exp && !modifiers.length) {
|
||||
|
@ -29,6 +36,8 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
|||
|
||||
let keyOverride: KeyOverride | undefined
|
||||
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
|
||||
if (nonKeyModifiers.includes('middle')) {
|
||||
|
@ -60,6 +69,7 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
|
|||
options: eventOptionModifiers,
|
||||
},
|
||||
keyOverride,
|
||||
delegate,
|
||||
}
|
||||
|
||||
context.registerEffect([arg], [operation])
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
onEffectCleanup,
|
||||
onScopeDispose,
|
||||
} from '@vue/reactivity'
|
||||
import { recordMetadata } from '../metadata'
|
||||
import { getMetadata, recordMetadata } from '../metadata'
|
||||
import { withKeys, withModifiers } from '@vue/runtime-dom'
|
||||
|
||||
export function addEventListener(
|
||||
|
@ -17,25 +17,19 @@ export function addEventListener(
|
|||
return () => el.removeEventListener(event, handler, options)
|
||||
}
|
||||
|
||||
interface ModifierOptions {
|
||||
modifiers?: string[]
|
||||
keys?: string[]
|
||||
}
|
||||
|
||||
export function on(
|
||||
el: HTMLElement,
|
||||
event: string,
|
||||
handlerGetter: () => undefined | ((...args: any[]) => any),
|
||||
options?: AddEventListenerOptions,
|
||||
{ modifiers, keys }: { modifiers?: string[]; keys?: string[] } = {},
|
||||
modifierOptions?: ModifierOptions,
|
||||
) {
|
||||
const handler = (...args: any[]) => {
|
||||
let handler = handlerGetter()
|
||||
if (!handler) return
|
||||
|
||||
if (modifiers) {
|
||||
handler = withModifiers(handler, modifiers)
|
||||
}
|
||||
if (keys) {
|
||||
handler = withKeys(handler, keys)
|
||||
}
|
||||
handler && handler(...args)
|
||||
}
|
||||
const handler = eventHandler(handlerGetter, modifierOptions)
|
||||
recordMetadata(el, 'events', event, handler)
|
||||
const cleanup = addEventListener(el, event, handler, options)
|
||||
|
||||
|
@ -48,3 +42,64 @@ export function on(
|
|||
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 './for'
|
||||
export { defineComponent } from './apiDefineComponent'
|
||||
export { recordMetadata } from './metadata'
|
||||
|
||||
export * from './directives/vShow'
|
||||
export * from './directives/vModel'
|
||||
|
|
Loading…
Reference in New Issue