diff --git a/src/compile/nodes/EachBlock.ts b/src/compile/nodes/EachBlock.ts index e0bfa8fd34..5747b753a0 100644 --- a/src/compile/nodes/EachBlock.ts +++ b/src/compile/nodes/EachBlock.ts @@ -418,6 +418,7 @@ export default class EachBlock extends Node { } } + @transitionManager.groupOutros(); for (; #i < ${iterations}.length; #i += 1) ${outro}(#i); ` : deindent` diff --git a/src/compile/nodes/IfBlock.ts b/src/compile/nodes/IfBlock.ts index 56bee30538..a9b91bf98e 100644 --- a/src/compile/nodes/IfBlock.ts +++ b/src/compile/nodes/IfBlock.ts @@ -283,6 +283,7 @@ export default class IfBlock extends Node { const updateMountNode = this.getUpdateMountNode(anchor); const destroyOldBlock = deindent` + @transitionManager.groupOutros(); ${name}.o(function() { ${if_blocks}[ ${previous_block_index} ].d(1); ${if_blocks}[ ${previous_block_index} ] = null; @@ -406,6 +407,7 @@ export default class IfBlock extends Node { // as that will typically result in glitching const exit = branch.hasOutroMethod ? deindent` + @transitionManager.groupOutros(); ${name}.o(function() { ${name}.d(1); ${name} = null; diff --git a/src/shared/await-block.js b/src/shared/await-block.js index d58bb4a27e..f5aceaf163 100644 --- a/src/shared/await-block.js +++ b/src/shared/await-block.js @@ -1,4 +1,5 @@ import { assign, isPromise } from './utils.js'; +import { transitionManager } from './transitions.js'; export function handlePromise(promise, info) { var token = info.token = {}; @@ -14,10 +15,13 @@ export function handlePromise(promise, info) { if (info.block) { if (info.blocks) { info.blocks.forEach((block, i) => { - if (i !== index && block) block.o(() => { - block.d(1); - info.blocks[i] = null; - }); + if (i !== index && block) { + transitionManager.groupOutros(); + block.o(() => { + block.d(1); + info.blocks[i] = null; + }); + } }); } else { info.block.d(1); diff --git a/src/shared/keyed-each.js b/src/shared/keyed-each.js index dac16930ee..60b0fe8bcd 100644 --- a/src/shared/keyed-each.js +++ b/src/shared/keyed-each.js @@ -1,3 +1,5 @@ +import { transitionManager } from './transitions.js'; + export function destroyBlock(block, lookup) { block.d(1); lookup[block.key] = null; @@ -43,6 +45,7 @@ export function updateKeyedEach(old_blocks, component, changed, get_key, dynamic var did_move = {}; var destroy = has_outro ? outroAndDestroyBlock : destroyBlock; + if (has_outro) transitionManager.groupOutros(); function insert(block) { block[intro_method](node, next); diff --git a/src/shared/transitions.js b/src/shared/transitions.js index 05fe0cc9d6..1f62fd7050 100644 --- a/src/shared/transitions.js +++ b/src/shared/transitions.js @@ -67,6 +67,11 @@ export function wrapTransition(component, node, fn, params, intro) { callback: callback || noop }; + if (!intro) { + program.group = transitionManager.outros; + transitionManager.outros.remaining += 1; + } + if (obj.delay) { this.pending = program; } else { @@ -127,10 +132,22 @@ export function wrapTransition(component, node, fn, params, intro) { this.t = program.b; if (obj.tick) obj.tick(this.t); - if (obj.css) transitionManager.deleteRule(node, program.name); component.fire(`${program.intro ? 'intro' : 'outro'}.end`, { node }); - program.callback(); + + if (!program.intro) { + program.group.callbacks.push(() => { + program.callback(); + if (obj.css) transitionManager.deleteRule(node, program.name); + }); + + if (--program.group.remaining === 0) { + program.group.callbacks.forEach(fn => { + fn(); + }); + } + } + this.program = null; this.running = !!this.pending; }, @@ -206,5 +223,12 @@ export var transitionManager = { .split(', ') .filter(anim => anim.indexOf(name) === -1) .join(', '); + }, + + groupOutros() { + this.outros = { + remaining: 0, + callbacks: [] + }; } };