From 2969b4c9d17e6864674e6fc3c0660058d2847f87 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 5 Jan 2019 21:21:30 -0500 Subject: [PATCH] eliminate need to pass outro callbacks around --- src/compile/render-dom/Block.ts | 6 ++---- src/compile/render-dom/wrappers/AwaitBlock.ts | 5 +---- src/compile/render-dom/wrappers/EachBlock.ts | 21 ++++++++++--------- .../render-dom/wrappers/Element/index.ts | 3 +-- src/compile/render-dom/wrappers/IfBlock.ts | 19 ++++++++--------- .../wrappers/InlineComponent/index.ts | 6 ++++-- src/internal/keyed-each.js | 6 +++++- src/internal/transitions.js | 13 ++++++++++-- src/internal/utils.js | 7 ------- .../_config.js | 2 +- 10 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/compile/render-dom/Block.ts b/src/compile/render-dom/Block.ts index 947185d535..012fd30015 100644 --- a/src/compile/render-dom/Block.ts +++ b/src/compile/render-dom/Block.ts @@ -360,12 +360,10 @@ export default class Block { } if (this.builders.outro.isEmpty()) { - properties.addLine(`o: @run,`); + properties.addLine(`o: @noop,`); } else { properties.addBlock(deindent` - ${dev ? 'o: function outro' : 'o'}(#outrocallback) { - ${this.outros > 1 && `#outrocallback = @callAfter(#outrocallback, ${this.outros});`} - + ${dev ? 'o: function outro' : 'o'}() { ${this.builders.outro} }, `); diff --git a/src/compile/render-dom/wrappers/AwaitBlock.ts b/src/compile/render-dom/wrappers/AwaitBlock.ts index ca1fdcc64e..3d0c0be7a2 100644 --- a/src/compile/render-dom/wrappers/AwaitBlock.ts +++ b/src/compile/render-dom/wrappers/AwaitBlock.ts @@ -208,13 +208,10 @@ export default class AwaitBlockWrapper extends Wrapper { } if (this.pending.block.hasOutroMethod) { - const countdown = block.getUniqueName('countdown'); block.builders.outro.addBlock(deindent` - const ${countdown} = @callAfter(#outrocallback, 3); for (let #i = 0; #i < 3; #i += 1) { const block = ${info}.blocks[#i]; - if (block) block.o(${countdown}); - else ${countdown}(); + if (block) block.o(); } `); } diff --git a/src/compile/render-dom/wrappers/EachBlock.ts b/src/compile/render-dom/wrappers/EachBlock.ts index 4f56a4c6c9..fe248696d0 100644 --- a/src/compile/render-dom/wrappers/EachBlock.ts +++ b/src/compile/render-dom/wrappers/EachBlock.ts @@ -345,13 +345,13 @@ export default class EachBlockWrapper extends Wrapper { ${this.node.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].r();`} ${blocks} = @updateKeyedEach(${blocks}, $$, changed, ${get_key}, ${dynamic ? '1' : '0'}, ctx, ${this.vars.each_block_value}, ${lookup}, ${updateMountNode}, ${destroy}, ${create_each_block}, "${mountOrIntro}", ${anchor}, ${this.vars.get_each_context}); ${this.node.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].a();`} + ${this.block.hasOutros && `@check_outros();`} `); if (this.block.hasOutros) { const countdown = block.getUniqueName('countdown'); block.builders.outro.addBlock(deindent` - const ${countdown} = @callAfter(#outrocallback, ${blocks}.length); - for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].o(${countdown}); + for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].o(); `); } @@ -415,15 +415,16 @@ export default class EachBlockWrapper extends Wrapper { const outroBlock = this.block.hasOutros && block.getUniqueName('outroBlock') if (outroBlock) { block.builders.init.addBlock(deindent` - function ${outroBlock}(i, detach, fn) { + function ${outroBlock}(i, detach) { if (${iterations}[i]) { - ${iterations}[i].o(() => { - if (detach) { + if (detach) { + @on_outro(() => { ${iterations}[i].d(detach); ${iterations}[i] = null; - } - if (fn) fn(); - }); + }); + } + + ${iterations}[i].o(); } } `); @@ -468,6 +469,7 @@ export default class EachBlockWrapper extends Wrapper { destroy = deindent` @group_outros(); for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1); + @check_outros(); `; } else { destroy = deindent` @@ -501,8 +503,7 @@ export default class EachBlockWrapper extends Wrapper { const countdown = block.getUniqueName('countdown'); block.builders.outro.addBlock(deindent` ${iterations} = ${iterations}.filter(Boolean); - const ${countdown} = @callAfter(#outrocallback, ${iterations}.length); - for (let #i = 0; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 0, ${countdown});` + for (let #i = 0; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 0);` ); } diff --git a/src/compile/render-dom/wrappers/Element/index.ts b/src/compile/render-dom/wrappers/Element/index.ts index 0bf1dfa002..436716e4a7 100644 --- a/src/compile/render-dom/wrappers/Element/index.ts +++ b/src/compile/render-dom/wrappers/Element/index.ts @@ -606,7 +606,6 @@ export default class ElementWrapper extends Wrapper { block.builders.outro.addBlock(deindent` if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, false); ${name}.run(0, () => { - #outrocallback(); ${name} = null; }); `); @@ -659,7 +658,7 @@ export default class ElementWrapper extends Wrapper { // 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} = @create_out_transition(${this.var}, ${fn}, ${snippet}, #outrocallback); + ${outroName} = @create_out_transition(${this.var}, ${fn}, ${snippet}); `); block.builders.destroy.addConditional('detach', `if (${outroName}) ${outroName}.end();`); diff --git a/src/compile/render-dom/wrappers/IfBlock.ts b/src/compile/render-dom/wrappers/IfBlock.ts index 9ed1acddf3..a50b905a3c 100644 --- a/src/compile/render-dom/wrappers/IfBlock.ts +++ b/src/compile/render-dom/wrappers/IfBlock.ts @@ -161,10 +161,7 @@ export default class IfBlockWrapper extends Wrapper { if (hasOutros) { this.renderCompoundWithOutros(block, parentNode, parentNodes, dynamic, vars); - block.builders.outro.addBlock(deindent` - if (${name}) ${name}.o(#outrocallback); - else #outrocallback(); - `); + block.builders.outro.addLine(`if (${name}) ${name}.o();`); } else { this.renderCompound(block, parentNode, parentNodes, dynamic, vars); } @@ -172,10 +169,7 @@ export default class IfBlockWrapper extends Wrapper { this.renderSimple(block, parentNode, parentNodes, dynamic, vars); if (hasOutros) { - block.builders.outro.addBlock(deindent` - if (${name}) ${name}.o(#outrocallback); - else #outrocallback(); - `); + block.builders.outro.addLine(`if (${name}) ${name}.o();`); } } @@ -323,10 +317,12 @@ export default class IfBlockWrapper extends Wrapper { const destroyOldBlock = deindent` @group_outros(); - ${name}.o(function() { + @on_outro(() => { ${if_blocks}[${previous_block_index}].d(1); ${if_blocks}[${previous_block_index}] = null; }); + ${name}.o(); + @check_outros(); `; const createNewBlock = deindent` @@ -446,10 +442,13 @@ export default class IfBlockWrapper extends Wrapper { const exit = branch.block.hasOutroMethod ? deindent` @group_outros(); - ${name}.o(function() { + @on_outro(() => { ${name}.d(1); ${name} = null; }); + + ${name}.o(); + @check_outros(); ` : deindent` ${name}.d(1); diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index f156ded8d5..254e8b592c 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -364,9 +364,11 @@ export default class InlineComponentWrapper extends Wrapper { if (${name}) { @group_outros(); const old_component = ${name}; - old_component.$$.fragment.o(() => { + @on_outro(() => { old_component.$destroy(); }); + old_component.$$.fragment.o(); + @check_outros(); } if (${switch_value}) { @@ -440,7 +442,7 @@ export default class InlineComponentWrapper extends Wrapper { } block.builders.outro.addLine( - `if (${name}) ${name}.$$.fragment.o(#outrocallback);` + `if (${name}) ${name}.$$.fragment.o();` ); } diff --git a/src/internal/keyed-each.js b/src/internal/keyed-each.js index 745ead6ff2..8429e2961d 100644 --- a/src/internal/keyed-each.js +++ b/src/internal/keyed-each.js @@ -1,12 +1,16 @@ +import { on_outro } from './transitions.js'; + export function destroyBlock(block, lookup) { block.d(1); lookup[block.key] = null; } export function outroAndDestroyBlock(block, lookup) { - block.o(function() { + on_outro(() => { destroyBlock(block, lookup); }); + + block.o(); } export function fixAndOutroAndDestroyBlock(block, lookup) { diff --git a/src/internal/transitions.js b/src/internal/transitions.js index 806e107b5a..0d65f4d8b7 100644 --- a/src/internal/transitions.js +++ b/src/internal/transitions.js @@ -24,6 +24,16 @@ export function group_outros() { }; } +export function check_outros() { + if (!outros.remaining) { + run_all(outros.callbacks); + } +} + +export function on_outro(callback) { + outros.callbacks.push(callback); +} + export function create_in_transition(node, fn, params) { let config = fn(node, params); let running = true; @@ -87,7 +97,7 @@ export function create_in_transition(node, fn, params) { }; } -export function create_out_transition(node, fn, params, callback) { +export function create_out_transition(node, fn, params) { let config = fn(node, params); let running = true; let animation_name; @@ -95,7 +105,6 @@ export function create_out_transition(node, fn, params, callback) { const group = outros; group.remaining += 1; - group.callbacks.push(callback); // TODO do we even need multiple callbacks? can we just have the one? function go() { if (typeof config === 'function') config = config(); diff --git a/src/internal/utils.js b/src/internal/utils.js index 9559ce9d24..a46385190d 100644 --- a/src/internal/utils.js +++ b/src/internal/utils.js @@ -16,13 +16,6 @@ export function isPromise(value) { return value && typeof value.then === 'function'; } -export function callAfter(fn, i) { - if (i === 0) fn(); - return () => { - if (!--i) fn(); - }; -} - export function addLoc(element, file, line, column, char) { element.__svelte_meta = { loc: { file, line, column, char } diff --git a/test/runtime/samples/nested-transition-detach-if-false/_config.js b/test/runtime/samples/nested-transition-detach-if-false/_config.js index b76eb5cd32..d2ae78ffe3 100644 --- a/test/runtime/samples/nested-transition-detach-if-false/_config.js +++ b/test/runtime/samples/nested-transition-detach-if-false/_config.js @@ -13,7 +13,7 @@ export default { `, - test({ assert, component, target, window, raf }) { + test({ assert, component, target }) { component.folder.open = false; assert.htmlEqual(target.innerHTML, `