From 47e68bd188ed3b751fe69ad1a30e0cae6a7181ff Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 5 Jan 2021 04:50:22 +0800 Subject: [PATCH] fix removing elements that are currently transitioning out (#5849) --- CHANGELOG.md | 1 + .../compile/render_dom/wrappers/IfBlock.ts | 11 +++--- .../_config.js | 38 +++++++++++++++++++ .../main.svelte | 18 +++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 test/runtime/samples/transition-js-if-else-block-not-dynamic-outro/_config.js create mode 100644 test/runtime/samples/transition-js-if-else-block-not-dynamic-outro/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index e77f65dea8..8f8b50324f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Rework SSR store handling to subscribe and unsubscribe as in DOM mode ([#3375](https://github.com/sveltejs/svelte/issues/3375), [#3582](https://github.com/sveltejs/svelte/issues/3582), [#3636](https://github.com/sveltejs/svelte/issues/3636)) +* Fix error when removing elements that are already transitioning out ([#5789](https://github.com/sveltejs/svelte/issues/5789), [#5808](https://github.com/sveltejs/svelte/issues/5808)) ## 3.31.1 diff --git a/src/compiler/compile/render_dom/wrappers/IfBlock.ts b/src/compiler/compile/render_dom/wrappers/IfBlock.ts index a95f64f4d2..7db221d6c6 100644 --- a/src/compiler/compile/render_dom/wrappers/IfBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/IfBlock.ts @@ -448,7 +448,7 @@ export default class IfBlockWrapper extends Wrapper { ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx); ${name}.c(); } else { - ${name}.p(#ctx, #dirty); + ${dynamic && b`${name}.p(#ctx, #dirty);`} } ${has_transitions && b`@transition_in(${name}, 1);`} ${name}.m(${update_mount_node}, ${anchor}); @@ -472,10 +472,13 @@ export default class IfBlockWrapper extends Wrapper { } `; + block.chunks.update.push(b` + let ${previous_block_index} = ${current_block_type_index}; + ${current_block_type_index} = ${select_block_type}(#ctx, #dirty); + `); + if (dynamic) { block.chunks.update.push(b` - let ${previous_block_index} = ${current_block_type_index}; - ${current_block_type_index} = ${select_block_type}(#ctx, #dirty); if (${current_block_type_index} === ${previous_block_index}) { ${if_current_block_type_index(b`${if_blocks}[${current_block_type_index}].p(#ctx, #dirty);`)} } else { @@ -484,8 +487,6 @@ export default class IfBlockWrapper extends Wrapper { `); } else { block.chunks.update.push(b` - let ${previous_block_index} = ${current_block_type_index}; - ${current_block_type_index} = ${select_block_type}(#ctx, #dirty); if (${current_block_type_index} !== ${previous_block_index}) { ${change_block} } diff --git a/test/runtime/samples/transition-js-if-else-block-not-dynamic-outro/_config.js b/test/runtime/samples/transition-js-if-else-block-not-dynamic-outro/_config.js new file mode 100644 index 0000000000..1c0c6e0543 --- /dev/null +++ b/test/runtime/samples/transition-js-if-else-block-not-dynamic-outro/_config.js @@ -0,0 +1,38 @@ +export default { + async test({ assert, component, target, window, raf }) { + const t = target.querySelector('#t'); + + await (component.condition = false); + + let time = 0; + raf.tick(time += 25); + + assert.htmlEqual(target.innerHTML, ` +
TRUE
+
FALSE
+ `); + + // toggling back in the middle of the out transition + // will reuse the previous element + await (component.condition = true); + + assert.htmlEqual(target.innerHTML, ` +
FALSE
+
TRUE
+ `); + assert.equal(target.querySelector('#t'), t); + + raf.tick(time += 25); + + assert.htmlEqual(target.innerHTML, ` +
FALSE
+
TRUE
+ `); + + raf.tick(time += 75); + + assert.htmlEqual(target.innerHTML, ` +
TRUE
+ `); + } +}; diff --git a/test/runtime/samples/transition-js-if-else-block-not-dynamic-outro/main.svelte b/test/runtime/samples/transition-js-if-else-block-not-dynamic-outro/main.svelte new file mode 100644 index 0000000000..93205aeaac --- /dev/null +++ b/test/runtime/samples/transition-js-if-else-block-not-dynamic-outro/main.svelte @@ -0,0 +1,18 @@ + + +{#if condition} +
TRUE
+{:else} +
FALSE
+{/if} \ No newline at end of file