abort transitions

pull/525/head
Rich-Harris 8 years ago
parent 7f76ab24f9
commit aa67f8b8c4

@ -24,6 +24,7 @@ export default class Block {
create: new CodeBuilder(), create: new CodeBuilder(),
mount: new CodeBuilder(), mount: new CodeBuilder(),
update: new CodeBuilder(), update: new CodeBuilder(),
intro: new CodeBuilder(),
outro: new CodeBuilder(), outro: new CodeBuilder(),
detach: new CodeBuilder(), detach: new CodeBuilder(),
detachRaw: new CodeBuilder(), detachRaw: new CodeBuilder(),
@ -105,6 +106,12 @@ export default class Block {
} }
render () { render () {
let introing;
if ( this.hasIntroTransitions ) {
introing = this.getUniqueName( 'introing' );
this.addVariable( introing );
}
let outroing; let outroing;
if ( this.hasOutroTransitions ) { if ( this.hasOutroTransitions ) {
outroing = this.getUniqueName( 'outroing' ); outroing = this.getUniqueName( 'outroing' );
@ -168,6 +175,24 @@ export default class Block {
} }
} }
if ( this.hasIntroTransitions ) {
if ( this.builders.outro.isEmpty() ) {
properties.addBlock( `intro: ${this.generator.helper( 'noop' )},` );
} else {
properties.addBlock( deindent`
intro: function ( ${this.target}, anchor ) {
if ( ${introing} ) return;
${introing} = true;
${this.hasOutroTransitions && `${outroing} = false;`}
${this.builders.intro}
this.mount( ${this.target}, anchor );
},
` );
}
}
if ( this.hasOutroTransitions ) { if ( this.hasOutroTransitions ) {
if ( this.builders.outro.isEmpty() ) { if ( this.builders.outro.isEmpty() ) {
properties.addBlock( `outro: ${this.generator.helper( 'noop' )},` ); properties.addBlock( `outro: ${this.generator.helper( 'noop' )},` );
@ -176,6 +201,7 @@ export default class Block {
outro: function ( ${this.alias( 'outrocallback' )} ) { outro: function ( ${this.alias( 'outrocallback' )} ) {
if ( ${outroing} ) return; if ( ${outroing} ) return;
${outroing} = true; ${outroing} = true;
${this.hasIntroTransitions && `${introing} = false;`}
var ${this.alias( 'outros' )} = ${this.outros}; var ${this.alias( 'outros' )} = ${this.outros};

@ -17,7 +17,11 @@ export default function addTransitions ( generator, block, state, node, intro, o
const fn = `${generator.alias( 'template' )}.transitions.${intro.name}`; // TODO add built-in transitions? const fn = `${generator.alias( 'template' )}.transitions.${intro.name}`; // TODO add built-in transitions?
block.builders.create.addBlock( deindent` if ( outro ) {
block.builders.intro.addBlock( `if ( ${outroName} ) ${outroName}.abort();` );
}
block.builders.intro.addBlock( deindent`
${block.component}._renderHooks.push( function () { ${block.component}._renderHooks.push( function () {
${introName} = ${wrapTransition}( ${state.name}, ${fn}, ${introSnippet}, true, null, function () { ${introName} = ${wrapTransition}( ${state.name}, ${fn}, ${introSnippet}, true, null, function () {
${block.component}.fire( 'intro.end', { node: ${state.name} }); ${block.component}.fire( 'intro.end', { node: ${state.name} });

@ -10,6 +10,7 @@ function getBranches ( generator, block, state, node ) {
condition: block.contextualise( node.expression ).snippet, condition: block.contextualise( node.expression ).snippet,
block: node._block.name, block: node._block.name,
dynamic: node._block.dependencies.size > 0, dynamic: node._block.dependencies.size > 0,
hasIntroTransitions: node._block.hasIntroTransitions,
hasOutroTransitions: node._block.hasOutroTransitions hasOutroTransitions: node._block.hasOutroTransitions
}]; }];
@ -24,6 +25,7 @@ function getBranches ( generator, block, state, node ) {
condition: null, condition: null,
block: node.else ? node.else._block.name : null, block: node.else ? node.else._block.name : null,
dynamic: node.else ? node.else._block.dependencies.size > 0 : false, dynamic: node.else ? node.else._block.dependencies.size > 0 : false,
hasIntroTransitions: node.else ? node.else._block.hasIntroTransitions : false,
hasOutroTransitions: node.else ? node.else._block.hasOutroTransitions : false hasOutroTransitions: node.else ? node.else._block.hasOutroTransitions : false
}); });
@ -74,16 +76,17 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
` ); ` );
const isToplevel = !state.parentNode; const isToplevel = !state.parentNode;
const mountOrIntro = branch.hasIntroTransitions ? 'intro' : 'mount';
if ( isToplevel ) { if ( isToplevel ) {
block.builders.mount.addLine( `if ( ${name} ) ${name}.mount( ${block.target}, null );` ); block.builders.mount.addLine( `if ( ${name} ) ${name}.${mountOrIntro}( ${block.target}, null );` );
} else { } else {
block.builders.create.addLine( `if ( ${name} ) ${name}.mount( ${state.parentNode}, null );` ); block.builders.create.addLine( `if ( ${name} ) ${name}.${mountOrIntro}( ${state.parentNode}, null );` );
} }
const parentNode = state.parentNode || `${anchor}.parentNode`; const parentNode = state.parentNode || `${anchor}.parentNode`;
const remove = branch.hasOutroTransitions ? const exit = branch.hasOutroTransitions ?
deindent` deindent`
${name}.outro( function () { ${name}.outro( function () {
${name} = null; ${name} = null;
@ -95,6 +98,10 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
`; `;
if ( dynamic ) { if ( dynamic ) {
if ( branch.hasIntroTransitions ) {
throw new Error( 'TODO simple dynamic if-block with intro transitions' );
}
block.builders.update.addBlock( deindent` block.builders.update.addBlock( deindent`
if ( ${branch.condition} ) { if ( ${branch.condition} ) {
if ( ${name} ) { if ( ${name} ) {
@ -104,18 +111,27 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
${name}.mount( ${parentNode}, ${anchor} ); ${name}.mount( ${parentNode}, ${anchor} );
} }
} else if ( ${name} ) { } else if ( ${name} ) {
${remove} ${exit}
} }
` ); ` );
} else { } else {
block.builders.update.addBlock( deindent` const enter = branch.hasIntroTransitions ?
if ( ${branch.condition} ) { deindent`
if ( !${name} ) ${name} = ${branch.block}( ${params}, ${block.component} );
${name}.intro( ${parentNode}, ${anchor} );
` :
deindent`
if ( !${name} ) { if ( !${name} ) {
${name} = ${branch.block}( ${params}, ${block.component} ); ${name} = ${branch.block}( ${params}, ${block.component} );
${name}.mount( ${parentNode}, ${anchor} ); ${name}.mount( ${parentNode}, ${anchor} );
} }
`;
block.builders.update.addBlock( deindent`
if ( ${branch.condition} ) {
${enter}
} else if ( ${name} ) { } else if ( ${name} ) {
${remove} ${exit}
} }
` ); ` );
} }

@ -27,7 +27,10 @@ export function wrapTransition ( node, fn, params, intro, outgroup, callback ) {
obj.tick( intro ? 1 : 0 ); obj.tick( intro ? 1 : 0 );
callback(); callback();
}, },
abort: noop abort: function () {
if ( !intro ) obj.tick( 1 ); // reset styles for intro
this.aborted = true;
}
}; };
} else { } else {
// CSS transition // CSS transition
@ -71,6 +74,7 @@ export function wrapTransition ( node, fn, params, intro, outgroup, callback ) {
}, },
abort: function () { abort: function () {
node.style.cssText = getComputedStyle( node ).cssText; node.style.cssText = getComputedStyle( node ).cssText;
this.aborted = true;
} }
}; };
} }
@ -105,12 +109,13 @@ export var transitionManager = {
while ( i-- ) { while ( i-- ) {
var transition = transitionManager.transitions[i]; var transition = transitionManager.transitions[i];
if ( now >= transition.end ) {
transition.done(); if ( now < transition.end && !transition.aborted ) {
transitionManager.transitions.splice( i, 1 );
} else {
if ( now > transition.start ) transition.update( now ); if ( now > transition.start ) transition.update( now );
transitionManager.running = true; transitionManager.running = true;
} else {
if ( !transition.aborted ) transition.done();
transitionManager.transitions.splice( i, 1 );
} }
} }

Loading…
Cancel
Save