From 484d8a894e8fbc78a3123c5f7aee4fb5323f76a1 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 31 Jul 2024 17:41:40 +0200 Subject: [PATCH] fix: always synchronously call `bind:this` fixes #12673 #12591 wrongfully applied the "wrap in effect if an action on this element" logic for `bind:this` --- .changeset/smooth-pens-exist.md | 5 + .../3-transform/client/visitors/template.js | 9 +- .../apply-directives-in-order-2/_config.js | 1 + .../apply-directives-in-order-2/main.svelte | 95 +++++++++++++++---- 4 files changed, 86 insertions(+), 24 deletions(-) create mode 100644 .changeset/smooth-pens-exist.md diff --git a/.changeset/smooth-pens-exist.md b/.changeset/smooth-pens-exist.md new file mode 100644 index 000000000000..fcf1b9145689 --- /dev/null +++ b/.changeset/smooth-pens-exist.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: always synchronously call `bind:this` diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index dfe3e9374329..e9fa7ba8997f 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -3164,16 +3164,15 @@ export const template_visitors = { } const parent = /** @type {import('#compiler').SvelteNode} */ (context.path.at(-1)); - const has_action_directive = - parent.type === 'RegularElement' && parent.attributes.find((a) => a.type === 'UseDirective'); // Bindings need to happen after attribute updates, therefore after the render effect, and in order with events/actions. // bind:this is a special case as it's one-way and could influence the render effect. if (node.name === 'this') { - state.init.push( - b.stmt(has_action_directive ? b.call('$.effect', b.thunk(call_expr)) : call_expr) - ); + state.init.push(b.stmt(call_expr)); } else { + const has_action_directive = + parent.type === 'RegularElement' && + parent.attributes.find((a) => a.type === 'UseDirective'); state.after_update.push( b.stmt(has_action_directive ? b.call('$.effect', b.thunk(call_expr)) : call_expr) ); diff --git a/packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/_config.js b/packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/_config.js index bdf3e70919f4..98022d73edd1 100644 --- a/packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/_config.js @@ -22,6 +22,7 @@ export default test({ } assert.deepEqual(value, [ + 'bind:this true', '1', '2', '3', diff --git a/packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/main.svelte b/packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/main.svelte index e91c4b6a1497..c536d722b537 100644 --- a/packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/main.svelte +++ b/packages/svelte/tests/runtime-legacy/samples/apply-directives-in-order-2/main.svelte @@ -1,29 +1,86 @@ @@ -31,4 +88,4 @@ - +