From 600a7ad48b6fd55b4bf79125611fcfe31ef9a83e Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Mon, 16 Jun 2025 17:03:53 +0200 Subject: [PATCH 1/2] fix: keep spread non-delegated event handlers up to date #15961 introduced a regression where non-delegated events that were spread and updated were not getting updated. This fixes that by ensuring prev is actually updated to the most recent value --- .changeset/odd-readers-laugh.md | 5 ++++ .../client/dom/elements/attributes.js | 8 +++--- .../event-attribute-spread-update/_config.js | 18 +++++++++++++ .../event-attribute-spread-update/main.svelte | 27 +++++++++++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 .changeset/odd-readers-laugh.md create mode 100644 packages/svelte/tests/runtime-runes/samples/event-attribute-spread-update/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/event-attribute-spread-update/main.svelte diff --git a/.changeset/odd-readers-laugh.md b/.changeset/odd-readers-laugh.md new file mode 100644 index 000000000000..e1401fdf1063 --- /dev/null +++ b/.changeset/odd-readers-laugh.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: keep spread non-delegated event handlers up to date diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index fcce0b444f49..b33b403e757a 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -483,8 +483,8 @@ export function attribute_effect( block(() => { var next = fn(...deriveds.map(get)); - - set_attributes(element, prev, next, css_hash, skip_warning); + /** @type {Record} */ + var current = set_attributes(element, prev, next, css_hash, skip_warning); if (inited && is_select && 'value' in next) { select_option(/** @type {HTMLSelectElement} */ (element), next.value, false); @@ -495,7 +495,7 @@ export function attribute_effect( } for (let symbol of Object.getOwnPropertySymbols(next)) { - var n = next[symbol]; + var n = (current[symbol] = next[symbol]); if (symbol.description === ATTACHMENT_KEY && (!prev || n !== prev[symbol])) { if (effects[symbol]) destroy_effect(effects[symbol]); @@ -503,7 +503,7 @@ export function attribute_effect( } } - prev = next; + prev = current; }); if (is_select) { diff --git a/packages/svelte/tests/runtime-runes/samples/event-attribute-spread-update/_config.js b/packages/svelte/tests/runtime-runes/samples/event-attribute-spread-update/_config.js new file mode 100644 index 000000000000..af03eed4c9e5 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/event-attribute-spread-update/_config.js @@ -0,0 +1,18 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + test({ assert, target }) { + const [change, increment] = target.querySelectorAll('button'); + + increment.click(); + flushSync(); + assert.htmlEqual(target.innerHTML, ''); + + change.click(); + flushSync(); + increment.click(); + flushSync(); + assert.htmlEqual(target.innerHTML, ''); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/event-attribute-spread-update/main.svelte b/packages/svelte/tests/runtime-runes/samples/event-attribute-spread-update/main.svelte new file mode 100644 index 000000000000..32d4b242cc55 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/event-attribute-spread-update/main.svelte @@ -0,0 +1,27 @@ + + + + From ffded128e918ca43a3cf9d33746dba7b88b186d2 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 17 Jun 2025 22:48:23 +0200 Subject: [PATCH 2/2] fix --- .../svelte/src/internal/client/dom/elements/attributes.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index b33b403e757a..a663450b4a5c 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -495,12 +495,14 @@ export function attribute_effect( } for (let symbol of Object.getOwnPropertySymbols(next)) { - var n = (current[symbol] = next[symbol]); + var n = next[symbol]; if (symbol.description === ATTACHMENT_KEY && (!prev || n !== prev[symbol])) { if (effects[symbol]) destroy_effect(effects[symbol]); effects[symbol] = branch(() => attach(element, () => n)); } + + current[symbol] = n; } prev = current;