Skip to content

Implement local transitions #2008

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/compile/nodes/Transition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions src/compile/render-dom/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,15 @@ export default class Block {
}
}

addIntro() {
addIntro(local?: boolean) {
this.hasIntros = this.hasIntroMethod = this.renderer.hasIntroTransitions = true;
if (!local && this.parent) this.parent.addIntro();
}

addOutro() {
addOutro(local?: boolean) {
this.hasOutros = this.hasOutroMethod = this.renderer.hasOutroTransitions = true;
this.outros += 1;
if (!local && this.parent) this.parent.addOutro();
}

addAnimation() {
Expand Down Expand Up @@ -327,7 +329,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}
},
Expand All @@ -338,7 +340,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}
},
`);
Expand Down
18 changes: 9 additions & 9 deletions src/compile/render-dom/wrappers/EachBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand All @@ -412,7 +412,7 @@ export default class EachBlockWrapper extends Wrapper {
});
}

${iterations}[i].o();
${iterations}[i].o(local);
}
}
`);
Expand All @@ -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);
}
Expand All @@ -471,7 +471,7 @@ export default class EachBlockWrapper extends Wrapper {
${forLoopBody}
}

${destroy}
${remove_old_blocks}
`;

block.builders.update.addBlock(deindent`
Expand Down
63 changes: 51 additions & 12 deletions src/compile/render-dom/wrappers/Element/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ export default class ElementWrapper extends Wrapper {
this.bindings = this.node.bindings.map(binding => new Binding(block, binding, this));

if (node.intro || node.outro) {
if (node.intro) block.addIntro();
if (node.outro) block.addOutro();
if (node.intro) block.addIntro(node.intro.is_local);
if (node.outro) block.addOutro(node.outro.is_local);
}

if (node.animation) {
Expand Down Expand Up @@ -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();`);
}
Expand All @@ -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) {
Expand All @@ -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();`);
}
Expand Down
15 changes: 6 additions & 9 deletions src/compile/render-dom/wrappers/IfBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ export default class IfBlockWrapper extends Wrapper {

createBranches(this.node);

if (hasIntros) block.addIntro();
if (hasOutros) block.addOutro();

blocks.forEach(block => {
block.hasUpdateMethod = isDynamic;
block.hasIntroMethod = hasIntros;
Expand Down Expand Up @@ -239,7 +236,7 @@ export default class IfBlockWrapper extends Wrapper {
if (${name}) {
${name}.c();
${name}.m(${updateMountNode}, ${anchor});
${has_transitions && `${name}.i();`}
${has_transitions && `${name}.i(1);`}
}
`;

Expand Down Expand Up @@ -327,7 +324,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();
`;

Expand All @@ -338,7 +335,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
Expand Down Expand Up @@ -415,15 +412,15 @@ export default class IfBlockWrapper extends Wrapper {
${name}.c();
${name}.m(${updateMountNode}, ${anchor});
}
${has_transitions && `${name}.i();`}
${has_transitions && `${name}.i(1);`}
`
: deindent`
if (!${name}) {
${name} = ${branch.block.name}(ctx);
${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,
Expand All @@ -436,7 +433,7 @@ export default class IfBlockWrapper extends Wrapper {
${name} = null;
});

${name}.o();
${name}.o(1);
@check_outros();
`
: deindent`
Expand Down
20 changes: 12 additions & 8 deletions src/compile/render-dom/wrappers/InlineComponent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand All @@ -409,15 +409,15 @@ export default class InlineComponentWrapper extends Wrapper {

${name}.$$.fragment.c();
@mount_component(${name}, ${updateMountNode}, ${anchor});
${name}.$$.fragment.i();
${name}.$$.fragment.i(1);
} else {
${name} = null;
}
}
`);

block.builders.intro.addBlock(deindent`
if (${name}) ${name}.$$.fragment.i();
if (${name}) ${name}.$$.fragment.i(#local);
`);

if (updates.length) {
Expand All @@ -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'
Expand Down Expand Up @@ -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) {
Expand All @@ -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);`
);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/internal/await-block.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function handlePromise(promise, info) {
block.d(1);
info.blocks[i] = null;
});
block.o();
block.o(1);
check_outros();
}
});
Expand All @@ -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();
}
Expand Down
4 changes: 2 additions & 2 deletions src/internal/keyed-each.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function outroAndDestroyBlock(block, lookup) {
destroyBlock(block, lookup);
});

block.o();
block.o(1);
}

export function fixAndOutroAndDestroyBlock(block, lookup) {
Expand Down Expand Up @@ -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--;
Expand Down
Loading