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/Element.ts b/src/compile/nodes/Element.ts index f0c352f02e..a3fb34e7e6 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -702,16 +702,13 @@ export default class Element extends Node { block.builders.intro.addBlock(deindent` #component.root._aftercreate.push(() => { - if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true, null); - ${name}.run(true, () => { - #component.fire("intro.end", { node: ${this.var} }); - }); + if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true); + ${name}.run(1); }); `); block.builders.outro.addBlock(deindent` - ${name}.run(false, () => { - #component.fire("outro.end", { node: ${this.var} }); + ${name}.run(0, () => { ${block.outros > 1 ? `if (--#outros === 0) #outrocallback();` : `#outrocallback();`} ${name} = null; }); @@ -737,10 +734,8 @@ export default class Element extends Node { block.builders.intro.addBlock(deindent` #component.root._aftercreate.push(() => { - ${introName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true, null); - ${introName}.run(true, () => { - #component.fire("intro.end", { node: ${this.var} }); - }); + ${introName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true); + ${introName}.run(1); }); `); } @@ -756,9 +751,8 @@ export default class Element extends Node { // TODO hide elements that have outro'd (unless they belong to a still-outroing // group) prior to their removal from the DOM block.builders.outro.addBlock(deindent` - ${outroName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, false, null); - ${outroName}.run(false, () => { - #component.fire("outro.end", { node: ${this.var} }); + ${outroName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, false); + ${outroName}.run(0, () => { ${block.outros > 1 ? `if (--#outros === 0) #outrocallback();` : `#outrocallback();`} }); `); 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 63172d0658..dcc0bb83b1 100644 --- a/src/shared/transitions.js +++ b/src/shared/transitions.js @@ -1,48 +1,35 @@ import { createElement } from './dom.js'; +import { noop } from './utils.js'; export function linear(t) { return t; } -export function generateRule( - a, - b, - delta, - duration, - ease, - fn -) { - var keyframes = '{\n'; - - for (var p = 0; p <= 1; p += 16.666 / duration) { - var t = a + delta * ease(p); - keyframes += p * 100 + '%{' + fn(t) + '}\n'; +export function generateRule({ a, b, delta, duration }, ease, fn) { + let keyframes = '{\n'; + + for (let p = 0; p <= 1; p += 16.666 / duration) { + const t = a + delta * ease(p); + keyframes += p * 100 + `%{${fn(t)}}\n`; } - return keyframes + '100% {' + fn(b) + '}\n}'; + return keyframes + `100% {${fn(b)}}\n}`; } // https://github.com/darkskyapp/string-hash/blob/master/index.js export function hash(str) { - var hash = 5381; - var i = str.length; + let hash = 5381; + let i = str.length; while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i); return hash >>> 0; } -export function wrapTransition(component, node, fn, params, intro, outgroup) { - var obj = fn(node, params); - var duration = obj.duration || 300; - var ease = obj.easing || linear; - var cssText; - - // TODO share