0
0
mirror of https://github.com/sveltejs/svelte.git synced 2024-11-30 08:56:14 +01:00

support dynamic simple if-blocks

This commit is contained in:
Rich-Harris 2017-05-01 08:48:42 -04:00
parent 26ed67267c
commit dfe00d8627
5 changed files with 112 additions and 45 deletions

View File

@ -63,13 +63,12 @@ export default function visitElement ( generator, block, state, node ) {
});
if ( intro || outro ) addTransitions( generator, block, childState, node, intro, outro );
}
if ( !outro && !state.parentNode ) {
// TODO this probably doesn't belong here. We eventually need to consider
// what happens to elements that belong to the same outgroup as an
// outroing element...
block.builders.detach.addLine( `${generator.helper( 'detachNode' )}( ${name} );` );
}
if ( !state.parentNode ) {
// TODO we eventually need to consider what happens to elements
// that belong to the same outgroup as an outroing element...
block.builders.detach.addLine( `${generator.helper( 'detachNode' )}( ${name} );` );
}
if ( node.name !== 'select' ) {

View File

@ -22,7 +22,6 @@ export default function addTransitions ( generator, block, state, node, intro, o
block.builders.outro.addBlock( deindent`
${name}.run( ${name}.t, 0, function () {
${generator.helper( 'detachNode' )}( ${state.name} );
${block.component}.fire( 'outro.end', { node: ${state.name} });
if ( --${block.alias( 'outros' )} === 0 ) ${block.alias( 'outrocallback' )}();
${name} = null;
@ -60,10 +59,11 @@ export default function addTransitions ( generator, block, state, node, intro, o
const fn = `${generator.alias( 'template' )}.transitions.${outro.name}`;
// 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} = ${wrapTransition}( ${state.name}, ${fn}, ${snippet}, false, null );
${outroName}.run( 1, 0, function () {
${generator.helper( 'detachNode' )}( ${state.name} );
${block.component}.fire( 'outro.end', { node: ${state.name} });
if ( --${block.alias( 'outros' )} === 0 ) ${block.alias( 'outrocallback' )}();
});

View File

@ -86,6 +86,39 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
const parentNode = state.parentNode || `${anchor}.parentNode`;
const enter = dynamic ?
( branch.hasIntroTransitions ?
deindent`
if ( ${name} ) {
${name}.update( changed, ${params} );
} else {
${name} = ${branch.block}( ${params}, ${block.component} );
}
${name}.intro( ${parentNode}, ${anchor} );
` :
deindent`
if ( ${name} ) {
${name}.update( changed, ${params} );
} else {
${name} = ${branch.block}( ${params}, ${block.component} );
${name}.mount( ${parentNode}, ${anchor} );
}
` ) :
( branch.hasIntroTransitions ?
deindent`
if ( !${name} ) ${name} = ${branch.block}( ${params}, ${block.component} );
${name}.intro( ${parentNode}, ${anchor} );
` :
deindent`
if ( !${name} ) {
${name} = ${branch.block}( ${params}, ${block.component} );
${name}.mount( ${parentNode}, ${anchor} );
}
` );
// no `update()` here — we don't want to update outroing nodes,
// as that will typically result in glitching
const exit = branch.hasOutroTransitions ?
deindent`
${name}.outro( function () {
@ -98,44 +131,13 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
${name} = null;
`;
if ( dynamic ) {
if ( branch.hasIntroTransitions ) {
throw new Error( 'TODO simple dynamic if-block with intro transitions' );
block.builders.update.addBlock( deindent`
if ( ${branch.condition} ) {
${enter}
} else if ( ${name} ) {
${exit}
}
block.builders.update.addBlock( deindent`
if ( ${branch.condition} ) {
if ( ${name} ) {
${name}.update( changed, ${params} );
} else {
${name} = ${branch.block}( ${params}, ${block.component} );
${name}.mount( ${parentNode}, ${anchor} );
}
} else if ( ${name} ) {
${exit}
}
` );
} else {
const enter = branch.hasIntroTransitions ?
deindent`
if ( !${name} ) ${name} = ${branch.block}( ${params}, ${block.component} );
${name}.intro( ${parentNode}, ${anchor} );
` :
deindent`
if ( !${name} ) {
${name} = ${branch.block}( ${params}, ${block.component} );
${name}.mount( ${parentNode}, ${anchor} );
}
`;
block.builders.update.addBlock( deindent`
if ( ${branch.condition} ) {
${enter}
} else if ( ${name} ) {
${exit}
}
` );
}
` );
}
function compound ( generator, block, state, node, branches, dynamic, { name, anchor, params } ) {

View File

@ -0,0 +1,47 @@
export default {
data: {
name: 'world'
},
test ( assert, component, target, window ) {
global.count = 0;
let now = 0;
let callback;
window.performance = { now: () => now };
global.requestAnimationFrame = cb => callback = cb;
component.set({ visible: true });
assert.equal( global.count, 1 );
const div = target.querySelector( 'div' );
assert.equal( div.foo, 0 );
now = 300;
callback();
component.set({ name: 'everybody' });
assert.equal( div.foo, 0.75 );
assert.htmlEqual( div.innerHTML, 'hello everybody!' );
component.set({ visible: false, name: 'again' });
assert.htmlEqual( div.innerHTML, 'hello everybody!' );
now = 500;
callback();
assert.equal( div.foo, 0.25 );
component.set({ visible: true });
now = 700;
callback();
assert.equal( div.foo, 0.75 );
assert.htmlEqual( div.innerHTML, 'hello again!' );
now = 800;
callback();
assert.equal( div.foo, 1 );
now = 900;
callback();
component.destroy();
}
};

View File

@ -0,0 +1,19 @@
{{#if visible}}
<div transition:foo>hello {{name}}!</div>
{{/if}}
<script>
export default {
transitions: {
foo: function ( node, params ) {
global.count += 1;
return {
duration: 400,
tick: t => {
node.foo = t;
}
};
}
}
};
</script>