|
|
|
|
@ -714,7 +714,7 @@ function serialize_inline_component(node, component_name, context, anchor = cont
|
|
|
|
|
lets.push(/** @type {ExpressionStatement} */ (context.visit(attribute)));
|
|
|
|
|
} else if (attribute.type === 'OnDirective') {
|
|
|
|
|
events[attribute.name] ||= [];
|
|
|
|
|
let handler = serialize_event_handler(attribute, context);
|
|
|
|
|
let handler = serialize_event_handler(attribute, null, context);
|
|
|
|
|
if (attribute.modifiers.includes('once')) {
|
|
|
|
|
handler = b.call('$.once', handler);
|
|
|
|
|
}
|
|
|
|
|
@ -1122,9 +1122,10 @@ function serialize_render_stmt(update) {
|
|
|
|
|
/**
|
|
|
|
|
* Serializes the event handler function of the `on:` directive
|
|
|
|
|
* @param {Pick<import('#compiler').OnDirective, 'name' | 'modifiers' | 'expression'>} node
|
|
|
|
|
* @param {null | { contains_call_expression: boolean; dynamic: boolean; } | null} metadata
|
|
|
|
|
* @param {import('../types.js').ComponentContext} context
|
|
|
|
|
*/
|
|
|
|
|
function serialize_event_handler(node, { state, visit }) {
|
|
|
|
|
function serialize_event_handler(node, metadata, { state, visit }) {
|
|
|
|
|
/** @type {Expression} */
|
|
|
|
|
let handler;
|
|
|
|
|
|
|
|
|
|
@ -1147,28 +1148,6 @@ function serialize_event_handler(node, { state, visit }) {
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const derived_dynamic_handler = () => {
|
|
|
|
|
const id = b.id(state.scope.generate('event_handler'));
|
|
|
|
|
|
|
|
|
|
state.init.push(
|
|
|
|
|
b.var(id, b.call('$.derived', b.thunk(/** @type {Expression} */ (visit(handler)))))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return b.function(
|
|
|
|
|
null,
|
|
|
|
|
[b.rest(b.id('$$args'))],
|
|
|
|
|
b.block([
|
|
|
|
|
b.return(
|
|
|
|
|
b.call(
|
|
|
|
|
b.member(b.call('$.get', id), b.id('apply'), false, true),
|
|
|
|
|
b.this,
|
|
|
|
|
b.id('$$args')
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (handler.type === 'Identifier' || handler.type === 'MemberExpression') {
|
|
|
|
|
const id = object(handler);
|
|
|
|
|
const binding = id === null ? null : state.scope.get(id.name);
|
|
|
|
|
@ -1187,8 +1166,33 @@ function serialize_event_handler(node, { state, visit }) {
|
|
|
|
|
} else {
|
|
|
|
|
handler = /** @type {Expression} */ (visit(handler));
|
|
|
|
|
}
|
|
|
|
|
} else if (handler.type === 'CallExpression') {
|
|
|
|
|
handler = derived_dynamic_handler();
|
|
|
|
|
} else if (
|
|
|
|
|
metadata?.contains_call_expression &&
|
|
|
|
|
!(
|
|
|
|
|
(handler.type === 'ArrowFunctionExpression' || handler.type === 'FunctionExpression') &&
|
|
|
|
|
handler.metadata.hoistable
|
|
|
|
|
)
|
|
|
|
|
) {
|
|
|
|
|
// Create a derived dynamic event handler
|
|
|
|
|
const id = b.id(state.scope.generate('event_handler'));
|
|
|
|
|
|
|
|
|
|
state.init.push(
|
|
|
|
|
b.var(id, b.call('$.derived', b.thunk(/** @type {Expression} */ (visit(handler)))))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
handler = b.function(
|
|
|
|
|
null,
|
|
|
|
|
[b.rest(b.id('$$args'))],
|
|
|
|
|
b.block([
|
|
|
|
|
b.return(
|
|
|
|
|
b.call(
|
|
|
|
|
b.member(b.call('$.get', id), b.id('apply'), false, true),
|
|
|
|
|
b.this,
|
|
|
|
|
b.id('$$args')
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
} else if (handler.type === 'ConditionalExpression' || handler.type === 'LogicalExpression') {
|
|
|
|
|
handler = dynamic_handler();
|
|
|
|
|
} else {
|
|
|
|
|
@ -1226,17 +1230,18 @@ function serialize_event_handler(node, { state, visit }) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Serializes an event handler function of the `on:` directive or an attribute starting with `on`
|
|
|
|
|
* @param {{name: string; modifiers: string[]; expression: Expression | null; delegated?: import('#compiler').DelegatedEvent | null; }} node
|
|
|
|
|
* @param {{name: string;modifiers: string[];expression: Expression | null;delegated?: import('#compiler').DelegatedEvent | null;}} node
|
|
|
|
|
* @param {null | { contains_call_expression: boolean; dynamic: boolean; }} metadata
|
|
|
|
|
* @param {import('../types.js').ComponentContext} context
|
|
|
|
|
*/
|
|
|
|
|
function serialize_event(node, context) {
|
|
|
|
|
function serialize_event(node, metadata, context) {
|
|
|
|
|
const state = context.state;
|
|
|
|
|
|
|
|
|
|
/** @type {Statement} */
|
|
|
|
|
let statement;
|
|
|
|
|
|
|
|
|
|
if (node.expression) {
|
|
|
|
|
let handler = serialize_event_handler(node, context);
|
|
|
|
|
let handler = serialize_event_handler(node, metadata, context);
|
|
|
|
|
const event_name = node.name;
|
|
|
|
|
const delegated = node.delegated;
|
|
|
|
|
|
|
|
|
|
@ -1305,7 +1310,12 @@ function serialize_event(node, context) {
|
|
|
|
|
statement = b.stmt(b.call('$.event', ...args));
|
|
|
|
|
} else {
|
|
|
|
|
statement = b.stmt(
|
|
|
|
|
b.call('$.event', b.literal(node.name), state.node, serialize_event_handler(node, context))
|
|
|
|
|
b.call(
|
|
|
|
|
'$.event',
|
|
|
|
|
b.literal(node.name),
|
|
|
|
|
state.node,
|
|
|
|
|
serialize_event_handler(node, metadata, context)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1343,6 +1353,7 @@ function serialize_event_attribute(node, context) {
|
|
|
|
|
modifiers,
|
|
|
|
|
delegated: node.metadata.delegated
|
|
|
|
|
},
|
|
|
|
|
!Array.isArray(node.value) && node.value?.type === 'ExpressionTag' ? node.value.metadata : null,
|
|
|
|
|
context
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
@ -2817,7 +2828,7 @@ export const template_visitors = {
|
|
|
|
|
context.next({ ...context.state, in_constructor: false });
|
|
|
|
|
},
|
|
|
|
|
OnDirective(node, context) {
|
|
|
|
|
serialize_event(node, context);
|
|
|
|
|
serialize_event(node, null, context);
|
|
|
|
|
},
|
|
|
|
|
UseDirective(node, { state, next, visit }) {
|
|
|
|
|
const params = [b.id('$$node')];
|
|
|
|
|
|