From 53b17b4cd39a608daeb94f1ae5591ba8afc6c910 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 26 Jan 2019 21:58:51 -0500 Subject: [PATCH] track whether transition is local --- src/compile/nodes/Transition.ts | 2 + src/compile/render-dom/Block.ts | 4 +- src/compile/render-dom/wrappers/EachBlock.ts | 18 +++--- .../render-dom/wrappers/Element/index.ts | 59 +++++++++++++++---- src/compile/render-dom/wrappers/IfBlock.ts | 12 ++-- .../wrappers/InlineComponent/index.ts | 20 ++++--- src/internal/await-block.js | 4 +- src/internal/keyed-each.js | 4 +- 8 files changed, 84 insertions(+), 39 deletions(-) diff --git a/src/compile/nodes/Transition.ts b/src/compile/nodes/Transition.ts index b77b57f21b..a0e42d939e 100644 --- a/src/compile/nodes/Transition.ts +++ b/src/compile/nodes/Transition.ts @@ -7,6 +7,7 @@ export default class Transition extends Node { name: string; directive: string; expression: Expression; + is_local: boolean; constructor(component: Component, parent, scope, info) { super(component, parent, scope, info); @@ -15,6 +16,7 @@ export default class Transition extends Node { this.name = info.name; this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out'; + this.is_local = info.modifiers.includes('local'); if ((info.intro && parent.intro) || (info.outro && parent.outro)) { const parentTransition = (parent.intro || parent.outro); diff --git a/src/compile/render-dom/Block.ts b/src/compile/render-dom/Block.ts index bf4823f863..f115201b62 100644 --- a/src/compile/render-dom/Block.ts +++ b/src/compile/render-dom/Block.ts @@ -327,7 +327,7 @@ export default class Block { properties.addLine(`i: @noop,`); } else { properties.addBlock(deindent` - ${dev ? 'i: function intro' : 'i'}() { + ${dev ? 'i: function intro' : 'i'}(#local) { ${this.hasOutros && `if (#current) return;`} ${this.builders.intro} }, @@ -338,7 +338,7 @@ export default class Block { properties.addLine(`o: @noop,`); } else { properties.addBlock(deindent` - ${dev ? 'o: function outro' : 'o'}() { + ${dev ? 'o: function outro' : 'o'}(#local) { ${this.builders.outro} }, `); diff --git a/src/compile/render-dom/wrappers/EachBlock.ts b/src/compile/render-dom/wrappers/EachBlock.ts index 39f3407020..7ec9941d5e 100644 --- a/src/compile/render-dom/wrappers/EachBlock.ts +++ b/src/compile/render-dom/wrappers/EachBlock.ts @@ -403,7 +403,7 @@ 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) { + function ${outroBlock}(i, detach, local) { if (${iterations}[i]) { if (detach) { @on_outro(() => { @@ -412,7 +412,7 @@ export default class EachBlockWrapper extends Wrapper { }); } - ${iterations}[i].o(); + ${iterations}[i].o(local); } } `); @@ -434,27 +434,27 @@ export default class EachBlockWrapper extends Wrapper { ${iterations}[#i].c(); ${iterations}[#i].m(${updateMountNode}, ${anchor}); } - ${has_transitions && `${iterations}[#i].i();`} + ${has_transitions && `${iterations}[#i].i(1);`} ` : deindent` ${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i].c(); ${iterations}[#i].m(${updateMountNode}, ${anchor}); - ${has_transitions && `${iterations}[#i].i();`} + ${has_transitions && `${iterations}[#i].i(1);`} `; const start = this.block.hasUpdateMethod ? '0' : `${iterations}.length`; - let destroy; + let remove_old_blocks; if (this.block.hasOutros) { - destroy = deindent` + remove_old_blocks = deindent` @group_outros(); - for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1); + for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1, 1); @check_outros(); `; } else { - destroy = deindent` + remove_old_blocks = deindent` for (${this.block.hasUpdateMethod ? `` : `#i = ${this.vars.each_block_value}.${length}`}; #i < ${iterations}.length; #i += 1) { ${iterations}[#i].d(1); } @@ -471,7 +471,7 @@ export default class EachBlockWrapper extends Wrapper { ${forLoopBody} } - ${destroy} + ${remove_old_blocks} `; block.builders.update.addBlock(deindent` diff --git a/src/compile/render-dom/wrappers/Element/index.ts b/src/compile/render-dom/wrappers/Element/index.ts index 97654fd19c..d5433f176a 100644 --- a/src/compile/render-dom/wrappers/Element/index.ts +++ b/src/compile/render-dom/wrappers/Element/index.ts @@ -622,17 +622,34 @@ export default class ElementWrapper extends Wrapper { const fn = component.qualify(intro.name); - block.builders.intro.addBlock(deindent` + const intro_block = deindent` @add_render_callback(() => { if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, true); ${name}.run(1); }); - `); + `; - block.builders.outro.addBlock(deindent` + const outro_block = deindent` if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, false); ${name}.run(0); - `); + `; + + if (intro.is_local) { + block.builders.intro.addBlock(deindent` + if (#local) { + ${intro_block} + } + `); + + block.builders.outro.addBlock(deindent` + if (#local) { + ${outro_block} + } + `); + } else { + block.builders.intro.addBlock(intro_block); + block.builders.outro.addBlock(outro_block); + } block.builders.destroy.addConditional('detach', `if (${name}) ${name}.end();`); } @@ -649,25 +666,37 @@ export default class ElementWrapper extends Wrapper { const fn = component.qualify(intro.name); + let intro_block; + if (outro) { - block.builders.intro.addBlock(deindent` + intro_block = deindent` @add_render_callback(() => { if (!${introName}) ${introName} = @create_in_transition(${this.var}, ${fn}, ${snippet}); ${introName}.start(); }); - `); + `; block.builders.outro.addLine(`if (${introName}) ${introName}.invalidate()`); } else { - block.builders.intro.addBlock(deindent` + intro_block = deindent` if (!${introName}) { @add_render_callback(() => { ${introName} = @create_in_transition(${this.var}, ${fn}, ${snippet}); ${introName}.start(); }); } - `); + `; + } + + if (intro.is_local) { + intro_block = deindent` + if (#local) { + ${intro_block} + } + `; } + + block.builders.intro.addBlock(intro_block); } if (outro) { @@ -684,9 +713,19 @@ 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` + let outro_block = deindent` ${outroName} = @create_out_transition(${this.var}, ${fn}, ${snippet}); - `); + `; + + if (outro_block) { + outro_block = deindent` + if (#local) { + ${outro_block} + } + `; + } + + block.builders.outro.addBlock(outro_block); 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 3d12c589ac..58ff2e7744 100644 --- a/src/compile/render-dom/wrappers/IfBlock.ts +++ b/src/compile/render-dom/wrappers/IfBlock.ts @@ -239,7 +239,7 @@ export default class IfBlockWrapper extends Wrapper { if (${name}) { ${name}.c(); ${name}.m(${updateMountNode}, ${anchor}); - ${has_transitions && `${name}.i();`} + ${has_transitions && `${name}.i(1);`} } `; @@ -327,7 +327,7 @@ export default class IfBlockWrapper extends Wrapper { ${if_blocks}[${previous_block_index}].d(1); ${if_blocks}[${previous_block_index}] = null; }); - ${name}.o(); + ${name}.o(1); @check_outros(); `; @@ -338,7 +338,7 @@ export default class IfBlockWrapper extends Wrapper { ${name}.c(); } ${name}.m(${updateMountNode}, ${anchor}); - ${has_transitions && `${name}.i();`} + ${has_transitions && `${name}.i(1);`} `; const changeBlock = hasElse @@ -415,7 +415,7 @@ export default class IfBlockWrapper extends Wrapper { ${name}.c(); ${name}.m(${updateMountNode}, ${anchor}); } - ${has_transitions && `${name}.i();`} + ${has_transitions && `${name}.i(1);`} ` : deindent` if (!${name}) { @@ -423,7 +423,7 @@ export default class IfBlockWrapper extends Wrapper { ${name}.c(); ${name}.m(${updateMountNode}, ${anchor}); } - ${has_transitions && `${name}.i();`} + ${has_transitions && `${name}.i(1);`} `; // no `p()` here — we don't want to update outroing nodes, @@ -436,7 +436,7 @@ export default class IfBlockWrapper extends Wrapper { ${name} = null; }); - ${name}.o(); + ${name}.o(1); @check_outros(); ` : deindent` diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index 5a97be48eb..67de8adf58 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -397,7 +397,7 @@ export default class InlineComponentWrapper extends Wrapper { @on_outro(() => { old_component.$destroy(); }); - old_component.$$.fragment.o(); + old_component.$$.fragment.o(1); @check_outros(); } @@ -409,7 +409,7 @@ export default class InlineComponentWrapper extends Wrapper { ${name}.$$.fragment.c(); @mount_component(${name}, ${updateMountNode}, ${anchor}); - ${name}.$$.fragment.i(); + ${name}.$$.fragment.i(1); } else { ${name} = null; } @@ -417,7 +417,7 @@ export default class InlineComponentWrapper extends Wrapper { `); block.builders.intro.addBlock(deindent` - if (${name}) ${name}.$$.fragment.i(); + if (${name}) ${name}.$$.fragment.i(#local); `); if (updates.length) { @@ -430,6 +430,10 @@ export default class InlineComponentWrapper extends Wrapper { `); } + block.builders.outro.addLine( + `if (${name}) ${name}.$$.fragment.o(#local);` + ); + block.builders.destroy.addLine(`if (${name}) ${name}.$destroy(${parentNode ? '' : 'detach'});`); } else { const expression = this.node.name === 'svelte:self' @@ -459,7 +463,7 @@ export default class InlineComponentWrapper extends Wrapper { ); block.builders.intro.addBlock(deindent` - ${name}.$$.fragment.i(); + ${name}.$$.fragment.i(#local); `); if (updates.length) { @@ -473,11 +477,11 @@ export default class InlineComponentWrapper extends Wrapper { block.builders.destroy.addBlock(deindent` ${name}.$destroy(${parentNode ? '' : 'detach'}); `); - } - block.builders.outro.addLine( - `if (${name}) ${name}.$$.fragment.o();` - ); + block.builders.outro.addLine( + `${name}.$$.fragment.o(#local);` + ); + } } } diff --git a/src/internal/await-block.js b/src/internal/await-block.js index 2e10250b4c..143694b04a 100644 --- a/src/internal/await-block.js +++ b/src/internal/await-block.js @@ -22,7 +22,7 @@ export function handlePromise(promise, info) { block.d(1); info.blocks[i] = null; }); - block.o(); + block.o(1); check_outros(); } }); @@ -32,7 +32,7 @@ export function handlePromise(promise, info) { block.c(); block.m(info.mount(), info.anchor); - if (block.i) block.i(); + if (block.i) block.i(1); flush(); } diff --git a/src/internal/keyed-each.js b/src/internal/keyed-each.js index 76e233f2ed..1ef9e27437 100644 --- a/src/internal/keyed-each.js +++ b/src/internal/keyed-each.js @@ -10,7 +10,7 @@ export function outroAndDestroyBlock(block, lookup) { destroyBlock(block, lookup); }); - block.o(); + block.o(1); } export function fixAndOutroAndDestroyBlock(block, lookup) { @@ -53,7 +53,7 @@ export function updateKeyedEach(old_blocks, changed, get_key, dynamic, ctx, list function insert(block) { block.m(node, next); - if (block.i) block.i(); + if (block.i) block.i(1); lookup[block.key] = block; next = block.first; n--;