diff --git a/.changeset/nasty-candles-press.md b/.changeset/nasty-candles-press.md new file mode 100644 index 000000000000..8010a973a94e --- /dev/null +++ b/.changeset/nasty-candles-press.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: avoid forward the transition property inside EffectNodes in HMR diff --git a/packages/svelte/src/internal/client/dev/hmr.js b/packages/svelte/src/internal/client/dev/hmr.js index 73dba95f9b6c..a85bd86814ac 100644 --- a/packages/svelte/src/internal/client/dev/hmr.js +++ b/packages/svelte/src/internal/client/dev/hmr.js @@ -5,7 +5,8 @@ import { hydrate_node, hydrating } from '../dom/hydration.js'; import { block, branch, destroy_effect } from '../reactivity/effects.js'; import { set, source } from '../reactivity/sources.js'; import { set_should_intro } from '../render.js'; -import { active_effect, get } from '../runtime.js'; +import { get } from '../runtime.js'; +import { assign_nodes } from '../dom/template.js'; /** * @template {(anchor: Comment, props: any) => any} Component @@ -60,7 +61,10 @@ export function hmr(fn) { // Forward the nodes from the inner effect to the outer active effect which would // get them if the HMR wrapper wasn't there. Do this inside the block not outside // so that HMR updates to the component will also update the nodes on the active effect. - /** @type {Effect} */ (active_effect).nodes = effect.nodes; + if (effect.nodes) { + // only forward the start and end node + assign_nodes(effect.nodes.start, effect.nodes.end); + } }, EFFECT_TRANSPARENT); ran = true; diff --git a/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/Drawer.svelte b/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/Drawer.svelte new file mode 100644 index 000000000000..89d5865d94e3 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/Drawer.svelte @@ -0,0 +1,16 @@ + +

console.log('introstart')} + onintroend={() => console.log('introend')} + onoutrostart={() => console.log('outrostart')} + onoutroend={() => console.log('outroend')} +>delayed fade

\ No newline at end of file diff --git a/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/_config.js b/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/_config.js new file mode 100644 index 000000000000..b142b7355708 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/_config.js @@ -0,0 +1,36 @@ +import { flushSync, tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + compileOptions: { + dev: true, + hmr: true + }, + test({ assert, raf, target, logs }) { + const [btn] = target.querySelectorAll('button'); + + // in + flushSync(() => btn.click()); + assert.deepEqual(logs, []); + raf.tick(1); + assert.deepEqual(logs, []); + + raf.tick(100); + assert.deepEqual(logs, ['introstart']); + + raf.tick(200); + assert.deepEqual(logs, ['introstart', 'introend']); + + // out + flushSync(() => btn.click()); + assert.deepEqual(logs, ['introstart', 'introend']); + raf.tick(201); + assert.deepEqual(logs, ['introstart', 'introend']); + + raf.tick(300); + assert.deepEqual(logs, ['introstart', 'introend', 'outrostart']); + + raf.tick(400); + assert.deepEqual(logs, ['introstart', 'introend', 'outrostart', 'outroend']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/main.svelte b/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/main.svelte new file mode 100644 index 000000000000..d85286cef54c --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/hmr-transition-events/main.svelte @@ -0,0 +1,12 @@ + + + + +{#if visible} + +{/if}