From ad11c5087fa34310111f512726a1bf17fbd6f808 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 2 Apr 2024 05:16:43 -0400 Subject: [PATCH] fix: ensure correct context for action update/destroy functions (#11023) --- .changeset/curvy-flies-exercise.md | 5 ++++ .../internal/client/dom/elements/actions.js | 9 +++--- .../samples/action-context/_config.js | 22 +++++++++++++++ .../samples/action-context/log.js | 2 ++ .../samples/action-context/main.svelte | 28 +++++++++++++++++++ 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 .changeset/curvy-flies-exercise.md create mode 100644 packages/svelte/tests/runtime-runes/samples/action-context/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/action-context/log.js create mode 100644 packages/svelte/tests/runtime-runes/samples/action-context/main.svelte diff --git a/.changeset/curvy-flies-exercise.md b/.changeset/curvy-flies-exercise.md new file mode 100644 index 0000000000..bcdbe1b448 --- /dev/null +++ b/.changeset/curvy-flies-exercise.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure correct context for action update/destroy functions diff --git a/packages/svelte/src/internal/client/dom/elements/actions.js b/packages/svelte/src/internal/client/dom/elements/actions.js index 669a14c057..50f946b93a 100644 --- a/packages/svelte/src/internal/client/dom/elements/actions.js +++ b/packages/svelte/src/internal/client/dom/elements/actions.js @@ -11,9 +11,8 @@ import { deep_read_state, untrack } from '../../runtime.js'; export function action(dom, action, get_value) { effect(() => { var payload = untrack(() => action(dom, get_value?.()) || {}); - var update = payload?.update; - if (get_value && update) { + if (get_value && payload?.update) { var inited = false; render_effect(() => { @@ -25,13 +24,15 @@ export function action(dom, action, get_value) { deep_read_state(value); if (inited) { - /** @type {Function} */ (update)(value); + /** @type {Function} */ (payload.update)(value); } }); inited = true; } - return payload?.destroy; + if (payload?.destroy) { + return () => /** @type {Function} */ (payload.destroy)(); + } }); } diff --git a/packages/svelte/tests/runtime-runes/samples/action-context/_config.js b/packages/svelte/tests/runtime-runes/samples/action-context/_config.js new file mode 100644 index 0000000000..87e9842d9a --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/action-context/_config.js @@ -0,0 +1,22 @@ +import { ok, test } from '../../test'; +import { flushSync, tick } from 'svelte'; +import { log } from './log.js'; + +export default test({ + html: ``, + + before_test() { + log.length = 0; + }, + + async test({ assert, target }) { + const btn = target.querySelector('button'); + ok(btn); + + flushSync(() => btn.click()); + assert.deepEqual(log, ['update', 0, 1]); + + flushSync(() => btn.click()); + assert.deepEqual(log, ['update', 0, 1, 'destroy', 1]); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/action-context/log.js b/packages/svelte/tests/runtime-runes/samples/action-context/log.js new file mode 100644 index 0000000000..d3df521f4d --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/action-context/log.js @@ -0,0 +1,2 @@ +/** @type {any[]} */ +export const log = []; diff --git a/packages/svelte/tests/runtime-runes/samples/action-context/main.svelte b/packages/svelte/tests/runtime-runes/samples/action-context/main.svelte new file mode 100644 index 0000000000..ef8f7894cc --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/action-context/main.svelte @@ -0,0 +1,28 @@ + + +{#if count < 2} + +{/if}