Skip to content

Commit

Permalink
fix: apply dynamic event fixes to OnDirective (#12582)
Browse files Browse the repository at this point in the history
* fix: apply dynamic event fixes to OnDirective

* build
  • Loading branch information
trueadm authored Jul 24, 2024
1 parent 528d346 commit 37f58cf
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/honest-phones-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: apply dynamic event fixes to OnDirective
6 changes: 5 additions & 1 deletion packages/svelte/src/compiler/phases/1-parse/state/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,11 @@ function read_attribute(parser) {
type,
name: directive_name,
modifiers,
expression
expression,
metadata: {
dynamic: false,
contains_call_expression: false
}
};

if (directive.type === 'ClassDirective') {
Expand Down
6 changes: 4 additions & 2 deletions packages/svelte/src/compiler/phases/2-analyze/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,9 @@ const common_visitors = {
CallExpression(node, context) {
const { expression, render_tag } = context.state;
if (
(expression?.type === 'ExpressionTag' || expression?.type === 'SpreadAttribute') &&
(expression?.type === 'ExpressionTag' ||
expression?.type === 'SpreadAttribute' ||
expression?.type === 'OnDirective') &&
!is_known_safe_call(node, context)
) {
expression.metadata.contains_call_expression = true;
Expand Down Expand Up @@ -1367,7 +1369,7 @@ const common_visitors = {
if (parent?.type === 'SvelteElement' || parent?.type === 'RegularElement') {
state.analysis.event_directive_node ??= node;
}
next();
next({ ...state, expression: node });
},
BindDirective(node, context) {
let i = context.path.length;
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/src/compiler/phases/2-analyze/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { ComponentAnalysis, ReactiveStatement } from '../types.js';
import type {
ClassDirective,
ExpressionTag,
OnDirective,
RenderTag,
SpreadAttribute,
SvelteNode,
Expand All @@ -20,7 +21,7 @@ export interface AnalysisState {
/** Which slots the current parent component has */
component_slots: Set<string>;
/** The current {expression}, if any */
expression: ExpressionTag | ClassDirective | SpreadAttribute | null;
expression: ExpressionTag | ClassDirective | OnDirective | SpreadAttribute | null;
/** The current {@render ...} tag, if any */
render_tag: null | RenderTag;
private_derived_state: string[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2838,7 +2838,7 @@ export const template_visitors = {
context.next({ ...context.state, in_constructor: false });
},
OnDirective(node, context) {
serialize_event(node, null, context);
serialize_event(node, node.metadata, context);
},
UseDirective(node, { state, next, visit }) {
const params = [b.id('$$node')];
Expand Down
4 changes: 4 additions & 0 deletions packages/svelte/src/compiler/types/template.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ export interface OnDirective extends BaseNode {
/** The 'y' in `on:x={y}` */
expression: null | Expression;
modifiers: string[]; // TODO specify
metadata: {
contains_call_expression: boolean;
dynamic: boolean;
};
}

export type DelegatedEvent =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { test } from '../../test';

export default test({
html: '<button>Tama</button><button>Pochi</button><br><button>Change Function</button>',

test({ assert, logs, target }) {
const [b1, b2, b3] = target.querySelectorAll('button');

b1?.click();
b2?.click();
b3?.click();
b1?.click();
b2?.click();

assert.deepEqual(logs, [
'creating "Hello" handler for Tama',
'Hello Tama',
'creating "Hello" handler for Pochi',
'Hello Pochi',
'creating "Bye" handler for Tama',
'Bye Tama',
'creating "Bye" handler for Pochi',
'Bye Pochi'
]);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
let saySomething = $state(name => {
console.log('creating "Hello" handler for ' + name);
return { handler: () => console.log('Hello ' + name) };
});
function change() {
saySomething = name => {
console.log('creating "Bye" handler for ' + name);
return { handler: () => console.log('Bye ' + name) };
}
}
</script>

<button on:click={saySomething('Tama').handler}>Tama</button>
<button on:click={saySomething('Pochi').handler}>Pochi</button>

<br>
<button on:click={change}>Change Function</button>
4 changes: 4 additions & 0 deletions packages/svelte/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,10 @@ declare module 'svelte/compiler' {
/** The 'y' in `on:x={y}` */
expression: null | Expression;
modifiers: string[]; // TODO specify
metadata: {
contains_call_expression: boolean;
dynamic: boolean;
};
}

type DelegatedEvent =
Expand Down

0 comments on commit 37f58cf

Please sign in to comment.