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
pull/16180/head
Simon Holthausen 3 months ago
parent 931f211b25
commit 600a7ad48b

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: keep spread non-delegated event handlers up to date

@ -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<string | symbol, any>} */
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) {

@ -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, '<button>change handlers</button><button>1 / 1</button>');
change.click();
flushSync();
increment.click();
flushSync();
assert.htmlEqual(target.innerHTML, '<button>change handlers</button><button>3 / 3</button>');
}
});

@ -0,0 +1,27 @@
<script>
let delegated = $state(0);
let non_delegated = $state(0);
let attrs = $state({
onclick: () => {
delegated += 1;
},
onclickcapture: () => {
non_delegated += 1;
}
});
</script>
<button
onclick={() =>
(attrs = {
onclick: () => {
delegated += 2;
},
onclickcapture: () => {
non_delegated += 2;
}
})}
>
change handlers
</button>
<button {...attrs}>{delegated} / {non_delegated}</button>
Loading…
Cancel
Save