diff --git a/src/compiler/compile/render-dom/wrappers/IfBlock.ts b/src/compiler/compile/render-dom/wrappers/IfBlock.ts index 46f17653a1..9a090c8dc0 100644 --- a/src/compiler/compile/render-dom/wrappers/IfBlock.ts +++ b/src/compiler/compile/render-dom/wrappers/IfBlock.ts @@ -146,13 +146,14 @@ export default class IfBlockWrapper extends Wrapper { const has_else = !(this.branches[this.branches.length - 1].condition); const if_name = has_else ? '' : `if (${name}) `; + const outroing = block.get_unique_name(`outroing_${this.var}`); const dynamic = this.branches[0].block.has_update_method; // can use [0] as proxy for all, since they necessarily have the same value const has_intros = this.branches[0].block.has_intro_method; const has_outros = this.branches[0].block.has_outro_method; const has_transitions = has_intros || has_outros; - const vars = { name, anchor, if_name, has_else, has_transitions }; + const vars = { name, anchor, if_name, has_else, has_transitions, outroing }; const detaching = (parent_node && parent_node !== 'document.head') ? '' : 'detaching'; @@ -392,11 +393,16 @@ export default class IfBlockWrapper extends Wrapper { parent_node: string, _parent_nodes: string, dynamic, - { name, anchor, if_name, has_transitions }, + { name, outroing, anchor, if_name, has_transitions }, detaching ) { const branch = this.branches[0]; + if (branch.block.has_outro_method) { + // TODO this probably belongs in the main render method? + block.add_variable(outroing); + } + block.builders.init.add_block(deindent` var ${name} = (${branch.condition}) && ${branch.block.name}(ctx); `); @@ -454,7 +460,8 @@ export default class IfBlockWrapper extends Wrapper { block.builders.update.add_block(deindent` if (${branch.condition}) { ${enter} - } else if (${name}) { + } else if (${name} && !${outroing}) { + ${outroing} = true; ${exit} } `); diff --git a/test/js/samples/transition-repeated-outro/expected.js b/test/js/samples/transition-repeated-outro/expected.js new file mode 100644 index 0000000000..b1db972c67 --- /dev/null +++ b/test/js/samples/transition-repeated-outro/expected.js @@ -0,0 +1,132 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + check_outros, + create_out_transition, + detach, + element, + empty, + group_outros, + init, + insert, + on_outro, + safe_not_equal +} from "svelte/internal"; +import { fade } from "svelte/transition"; + +// (7:0) {#if num < 5} +function create_if_block(ctx) { + var div, div_outro, current; + + return { + c() { + div = element("div"); + div.innerHTML = `

wheeee

`; + }, + + m(target, anchor) { + insert(target, div, anchor); + current = true; + }, + + i(local) { + if (current) return; + if (div_outro) div_outro.end(1); + + current = true; + }, + + o(local) { + div_outro = create_out_transition(div, fade, {}); + + current = false; + }, + + d(detaching) { + if (detaching) { + detach(div); + if (div_outro) div_outro.end(); + } + } + }; +} + +function create_fragment(ctx) { + var outroing_if_block, if_block_anchor, current; + + var if_block = (ctx.num < 5) && create_if_block(ctx); + + return { + c() { + if (if_block) if_block.c(); + if_block_anchor = empty(); + }, + + m(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert(target, if_block_anchor, anchor); + current = true; + }, + + p(changed, ctx) { + if (ctx.num < 5) { + if (!if_block) { + if_block = create_if_block(ctx); + if_block.c(); + if_block.i(1); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } else { + if_block.i(1); + } + } else if (if_block && !outroing_if_block) { + outroing_if_block = true; + group_outros(); + on_outro(() => { + if_block.d(1); + if_block = null; + }); + + if_block.o(1); + check_outros(); + } + }, + + i(local) { + if (current) return; + if (if_block) if_block.i(); + current = true; + }, + + o(local) { + if (if_block) if_block.o(); + current = false; + }, + + d(detaching) { + if (if_block) if_block.d(detaching); + + if (detaching) { + detach(if_block_anchor); + } + } + }; +} + +function instance($$self, $$props, $$invalidate) { + let { num = 1 } = $$props; + + $$self.$set = $$props => { + if ('num' in $$props) $$invalidate('num', num = $$props.num); + }; + + return { num }; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, ["num"]); + } +} + +export default Component; \ No newline at end of file diff --git a/test/js/samples/transition-repeated-outro/input.svelte b/test/js/samples/transition-repeated-outro/input.svelte new file mode 100644 index 0000000000..d5114846b8 --- /dev/null +++ b/test/js/samples/transition-repeated-outro/input.svelte @@ -0,0 +1,11 @@ + + +{#if num < 5} +
+

wheeee

+
+{/if} \ No newline at end of file