expressions in if and each blocks

pull/31/head
Rich-Harris 8 years ago
parent c02e849cb5
commit c1204e57b0

@ -155,7 +155,7 @@ export default function generate ( parsed, template ) {
else { else {
// dynamic but potentially non-string attributes // dynamic but potentially non-string attributes
contextualise( value.expression ); contextualise( code, value.expression, current.contexts );
result = `[✂${value.expression.start}-${value.expression.end}✂]`; result = `[✂${value.expression.start}-${value.expression.end}✂]`;
if ( metadata ) { if ( metadata ) {
@ -338,19 +338,46 @@ export default function generate ( parsed, template ) {
const name = `ifBlock_${i}`; const name = `ifBlock_${i}`;
const renderer = `renderIfBlock_${i}`; const renderer = `renderIfBlock_${i}`;
const expression = flattenExpression( node.expression, current.contexts );
current.initStatements.push( deindent` current.initStatements.push( deindent`
var ${name}_anchor = document.createComment( '#if ${template.slice( node.expression.start, node.expression.end )}' ); var ${name}_anchor = document.createComment( ${JSON.stringify( `#if ${template.slice( node.expression.start, node.expression.end )}` )} );
${current.target}.appendChild( ${name}_anchor ); ${current.target}.appendChild( ${name}_anchor );
var ${name} = null; var ${name} = null;
` ); ` );
current.updateStatements.push( deindent` const usedContexts = contextualise( code, node.expression, current.contexts );
if ( ${expression} && !${name} ) { const snippet = `[✂${node.expression.start}-${node.expression.end}✂]`;
${name} = ${renderer}( component, ${current.target}, ${name}_anchor );
} let expression;
if ( isReference( node.expression ) ) {
const reference = `${template.slice( node.expression.start, node.expression.end )}`;
expression = usedContexts[0] === 'root' ? `root.${reference}` : reference;
current.updateStatements.push( deindent`
if ( ${snippet} && !${name} ) {
${name} = ${renderer}( component, ${current.target}, ${name}_anchor );
}
` );
} else {
const expressionFunction = getName( 'expression' );
expressionFunctions.push( deindent`
function ${expressionFunction} ( ${usedContexts.join( ', ' )} ) {
return ${snippet};
}
` );
expression = `${name}_value`;
current.updateStatements.push( deindent`
var ${expression} = ${expressionFunction}( ${usedContexts.join( ', ' )} );
if ( ${expression} && !${name} ) {
${name} = ${renderer}( component, ${current.target}, ${name}_anchor );
}
` );
}
current.updateStatements.push( deindent`
else if ( !${expression} && ${name} ) { else if ( !${expression} && ${name} ) {
${name}.teardown(); ${name}.teardown();
${name} = null; ${name} = null;
@ -363,6 +390,7 @@ export default function generate ( parsed, template ) {
current.teardownStatements.push( deindent` current.teardownStatements.push( deindent`
if ( ${name} ) ${name}.teardown(); if ( ${name} ) ${name}.teardown();
${name}_anchor.parentNode.removeChild( ${name}_anchor );
` ); ` );
current = { current = {
@ -394,31 +422,49 @@ export default function generate ( parsed, template ) {
const name = `eachBlock_${i}`; const name = `eachBlock_${i}`;
const renderer = `renderEachBlock_${i}`; const renderer = `renderEachBlock_${i}`;
const expression = flattenExpression( node.expression, current.contexts );
current.initStatements.push( deindent` current.initStatements.push( deindent`
var ${name}_anchor = document.createComment( '#each ${template.slice( node.expression.start, node.expression.end )}' ); var ${name}_anchor = document.createComment( ${JSON.stringify( `#each ${template.slice( node.expression.start, node.expression.end )}` )} );
${current.target}.appendChild( ${name}_anchor ); ${current.target}.appendChild( ${name}_anchor );
var ${name}_iterations = []; var ${name}_iterations = [];
const ${name}_fragment = document.createDocumentFragment(); const ${name}_fragment = document.createDocumentFragment();
` ); ` );
const usedContexts = contextualise( code, node.expression, current.contexts );
const snippet = `[✂${node.expression.start}-${node.expression.end}✂]`;
let expression;
if ( isReference( node.expression ) ) {
expression = snippet;
} else {
const expressionFunction = getName( 'expression' );
expressionFunctions.push( deindent`
function ${expressionFunction} ( ${usedContexts.join( ', ' )} ) {
return ${snippet};
}
` );
expression = `${expressionFunction}( ${usedContexts.join( ', ' )} )`;
}
current.updateStatements.push( deindent` current.updateStatements.push( deindent`
for ( var i = 0; i < ${expression}.length; i += 1 ) { var ${name}_value = ${expression};
for ( var i = 0; i < ${name}_value.length; i += 1 ) {
if ( !${name}_iterations[i] ) { if ( !${name}_iterations[i] ) {
${name}_iterations[i] = ${renderer}( component, ${name}_fragment ); ${name}_iterations[i] = ${renderer}( component, ${name}_fragment );
} }
const iteration = ${name}_iterations[i]; const iteration = ${name}_iterations[i];
${name}_iterations[i].update( ${current.contextChain.join( ', ' )}, ${expression}[i]${node.index ? `, i` : ''} ); ${name}_iterations[i].update( ${current.contextChain.join( ', ' )}, ${name}_value[i]${node.index ? `, i` : ''} );
} }
for ( var i = ${expression}.length; i < ${name}_iterations.length; i += 1 ) { for ( var i = ${name}_value.length; i < ${name}_iterations.length; i += 1 ) {
${name}_iterations[i].teardown(); ${name}_iterations[i].teardown();
} }
${name}_anchor.parentNode.insertBefore( ${name}_fragment, ${name}_anchor ); ${name}_anchor.parentNode.insertBefore( ${name}_fragment, ${name}_anchor );
${name}_iterations.length = ${expression}.length; ${name}_iterations.length = ${name}_value.length;
` ); ` );
current.teardownStatements.push( deindent` current.teardownStatements.push( deindent`

@ -0,0 +1,3 @@
export default {
html: `<p>a</p><p>b</p><p>c</p><!--#each [ 'a', 'b', 'c' ]-->`
};

@ -0,0 +1,3 @@
{{#each [ 'a', 'b', 'c' ] as letter}}
<p>{{letter}}</p>
{{/each}}

@ -0,0 +1,3 @@
export default {
html: '<p>two is greater than one</p><!--#if 2 > 1-->'
};

@ -0,0 +1,3 @@
{{#if 2 > 1}}
<p>two is greater than one</p>
{{/if}}
Loading…
Cancel
Save