eliminate need to pass outro callbacks around

pull/1971/head
Richard Harris 7 years ago
parent fe81d603c4
commit 2969b4c9d1

@ -360,12 +360,10 @@ export default class Block {
} }
if (this.builders.outro.isEmpty()) { if (this.builders.outro.isEmpty()) {
properties.addLine(`o: @run,`); properties.addLine(`o: @noop,`);
} else { } else {
properties.addBlock(deindent` properties.addBlock(deindent`
${dev ? 'o: function outro' : 'o'}(#outrocallback) { ${dev ? 'o: function outro' : 'o'}() {
${this.outros > 1 && `#outrocallback = @callAfter(#outrocallback, ${this.outros});`}
${this.builders.outro} ${this.builders.outro}
}, },
`); `);

@ -208,13 +208,10 @@ export default class AwaitBlockWrapper extends Wrapper {
} }
if (this.pending.block.hasOutroMethod) { if (this.pending.block.hasOutroMethod) {
const countdown = block.getUniqueName('countdown');
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
const ${countdown} = @callAfter(#outrocallback, 3);
for (let #i = 0; #i < 3; #i += 1) { for (let #i = 0; #i < 3; #i += 1) {
const block = ${info}.blocks[#i]; const block = ${info}.blocks[#i];
if (block) block.o(${countdown}); if (block) block.o();
else ${countdown}();
} }
`); `);
} }

@ -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();`} ${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}); ${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.node.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].a();`}
${this.block.hasOutros && `@check_outros();`}
`); `);
if (this.block.hasOutros) { if (this.block.hasOutros) {
const countdown = block.getUniqueName('countdown'); const countdown = block.getUniqueName('countdown');
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
const ${countdown} = @callAfter(#outrocallback, ${blocks}.length); for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].o();
for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].o(${countdown});
`); `);
} }
@ -415,15 +415,16 @@ export default class EachBlockWrapper extends Wrapper {
const outroBlock = this.block.hasOutros && block.getUniqueName('outroBlock') const outroBlock = this.block.hasOutros && block.getUniqueName('outroBlock')
if (outroBlock) { if (outroBlock) {
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
function ${outroBlock}(i, detach, fn) { function ${outroBlock}(i, detach) {
if (${iterations}[i]) { if (${iterations}[i]) {
${iterations}[i].o(() => { if (detach) {
if (detach) { @on_outro(() => {
${iterations}[i].d(detach); ${iterations}[i].d(detach);
${iterations}[i] = null; ${iterations}[i] = null;
} });
if (fn) fn(); }
});
${iterations}[i].o();
} }
} }
`); `);
@ -468,6 +469,7 @@ export default class EachBlockWrapper extends Wrapper {
destroy = deindent` destroy = deindent`
@group_outros(); @group_outros();
for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1); for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1);
@check_outros();
`; `;
} else { } else {
destroy = deindent` destroy = deindent`
@ -501,8 +503,7 @@ export default class EachBlockWrapper extends Wrapper {
const countdown = block.getUniqueName('countdown'); const countdown = block.getUniqueName('countdown');
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
${iterations} = ${iterations}.filter(Boolean); ${iterations} = ${iterations}.filter(Boolean);
const ${countdown} = @callAfter(#outrocallback, ${iterations}.length); for (let #i = 0; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 0);`
for (let #i = 0; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 0, ${countdown});`
); );
} }

@ -606,7 +606,6 @@ export default class ElementWrapper extends Wrapper {
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, false); if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, false);
${name}.run(0, () => { ${name}.run(0, () => {
#outrocallback();
${name} = null; ${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 // TODO hide elements that have outro'd (unless they belong to a still-outroing
// group) prior to their removal from the DOM // group) prior to their removal from the DOM
block.builders.outro.addBlock(deindent` 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();`); block.builders.destroy.addConditional('detach', `if (${outroName}) ${outroName}.end();`);

@ -161,10 +161,7 @@ export default class IfBlockWrapper extends Wrapper {
if (hasOutros) { if (hasOutros) {
this.renderCompoundWithOutros(block, parentNode, parentNodes, dynamic, vars); this.renderCompoundWithOutros(block, parentNode, parentNodes, dynamic, vars);
block.builders.outro.addBlock(deindent` block.builders.outro.addLine(`if (${name}) ${name}.o();`);
if (${name}) ${name}.o(#outrocallback);
else #outrocallback();
`);
} else { } else {
this.renderCompound(block, parentNode, parentNodes, dynamic, vars); this.renderCompound(block, parentNode, parentNodes, dynamic, vars);
} }
@ -172,10 +169,7 @@ export default class IfBlockWrapper extends Wrapper {
this.renderSimple(block, parentNode, parentNodes, dynamic, vars); this.renderSimple(block, parentNode, parentNodes, dynamic, vars);
if (hasOutros) { if (hasOutros) {
block.builders.outro.addBlock(deindent` block.builders.outro.addLine(`if (${name}) ${name}.o();`);
if (${name}) ${name}.o(#outrocallback);
else #outrocallback();
`);
} }
} }
@ -323,10 +317,12 @@ export default class IfBlockWrapper extends Wrapper {
const destroyOldBlock = deindent` const destroyOldBlock = deindent`
@group_outros(); @group_outros();
${name}.o(function() { @on_outro(() => {
${if_blocks}[${previous_block_index}].d(1); ${if_blocks}[${previous_block_index}].d(1);
${if_blocks}[${previous_block_index}] = null; ${if_blocks}[${previous_block_index}] = null;
}); });
${name}.o();
@check_outros();
`; `;
const createNewBlock = deindent` const createNewBlock = deindent`
@ -446,10 +442,13 @@ export default class IfBlockWrapper extends Wrapper {
const exit = branch.block.hasOutroMethod const exit = branch.block.hasOutroMethod
? deindent` ? deindent`
@group_outros(); @group_outros();
${name}.o(function() { @on_outro(() => {
${name}.d(1); ${name}.d(1);
${name} = null; ${name} = null;
}); });
${name}.o();
@check_outros();
` `
: deindent` : deindent`
${name}.d(1); ${name}.d(1);

@ -364,9 +364,11 @@ export default class InlineComponentWrapper extends Wrapper {
if (${name}) { if (${name}) {
@group_outros(); @group_outros();
const old_component = ${name}; const old_component = ${name};
old_component.$$.fragment.o(() => { @on_outro(() => {
old_component.$destroy(); old_component.$destroy();
}); });
old_component.$$.fragment.o();
@check_outros();
} }
if (${switch_value}) { if (${switch_value}) {
@ -440,7 +442,7 @@ export default class InlineComponentWrapper extends Wrapper {
} }
block.builders.outro.addLine( block.builders.outro.addLine(
`if (${name}) ${name}.$$.fragment.o(#outrocallback);` `if (${name}) ${name}.$$.fragment.o();`
); );
} }

@ -1,12 +1,16 @@
import { on_outro } from './transitions.js';
export function destroyBlock(block, lookup) { export function destroyBlock(block, lookup) {
block.d(1); block.d(1);
lookup[block.key] = null; lookup[block.key] = null;
} }
export function outroAndDestroyBlock(block, lookup) { export function outroAndDestroyBlock(block, lookup) {
block.o(function() { on_outro(() => {
destroyBlock(block, lookup); destroyBlock(block, lookup);
}); });
block.o();
} }
export function fixAndOutroAndDestroyBlock(block, lookup) { export function fixAndOutroAndDestroyBlock(block, lookup) {

@ -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) { export function create_in_transition(node, fn, params) {
let config = fn(node, params); let config = fn(node, params);
let running = true; 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 config = fn(node, params);
let running = true; let running = true;
let animation_name; let animation_name;
@ -95,7 +105,6 @@ export function create_out_transition(node, fn, params, callback) {
const group = outros; const group = outros;
group.remaining += 1; group.remaining += 1;
group.callbacks.push(callback); // TODO do we even need multiple callbacks? can we just have the one?
function go() { function go() {
if (typeof config === 'function') config = config(); if (typeof config === 'function') config = config();

@ -16,13 +16,6 @@ export function isPromise(value) {
return value && typeof value.then === 'function'; 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) { export function addLoc(element, file, line, column, char) {
element.__svelte_meta = { element.__svelte_meta = {
loc: { file, line, column, char } loc: { file, line, column, char }

@ -13,7 +13,7 @@ export default {
</li> </li>
`, `,
test({ assert, component, target, window, raf }) { test({ assert, component, target }) {
component.folder.open = false; component.folder.open = false;
assert.htmlEqual(target.innerHTML, ` assert.htmlEqual(target.innerHTML, `
<li> <li>

Loading…
Cancel
Save