move render logic into fragment

pull/453/head
Rich-Harris 8 years ago
parent 858c6b5e82
commit bd85ffbf28

@ -1,4 +1,5 @@
import CodeBuilder from '../../utils/CodeBuilder.js';
import deindent from '../../utils/deindent.js';
export default class Fragment {
constructor ({ generator, name, key, expression, context, contextDependencies, component, contexts, indexes, params, indexNames, listNames, getUniqueName }) {
@ -62,4 +63,72 @@ export default class Fragment {
this.builders.mount.addLine( `${this.generator.helper( 'insertNode' )}( ${name}, target, anchor );` );
}
}
render () {
if ( this.autofocus ) {
this.builders.create.addLine( `${this.autofocus}.focus();` );
}
// minor hack we need to ensure that any {{{triples}}} are detached
// first, so we append normal detach statements to detachRaw
this.builders.detachRaw.addBlock( this.builders.detach );
if ( !this.builders.detachRaw.isEmpty() ) {
this.builders.destroy.addBlock( deindent`
if ( detach ) {
${this.builders.detachRaw}
}
` );
}
const properties = new CodeBuilder();
let localKey;
if ( this.key ) {
localKey = this.getUniqueName( 'key' );
properties.addBlock( `key: ${localKey},` );
}
if ( this.builders.mount.isEmpty() ) {
properties.addBlock( `mount: ${this.generator.helper( 'noop' )},` );
} else {
properties.addBlock( deindent`
mount: function ( target, anchor ) {
${this.builders.mount}
},
` );
}
if ( this.builders.update.isEmpty() ) {
properties.addBlock( `update: ${this.generator.helper( 'noop' )},` );
} else {
properties.addBlock( deindent`
update: function ( changed, ${this.params.join( ', ' )} ) {
${this.tmp ? `var ${this.tmp};` : ''}
${this.builders.update}
},
` );
}
if ( this.builders.destroy.isEmpty() ) {
properties.addBlock( `destroy: ${this.generator.helper( 'noop' )},` );
} else {
properties.addBlock( deindent`
destroy: function ( detach ) {
${this.builders.destroy}
}
` );
}
return deindent`
function ${this.name} ( ${this.params.join( ', ' )}, ${this.component}${this.key ? `, ${localKey}` : ''} ) {
${this.builders.create}
return {
${properties}
};
}
`;
}
}

@ -8,7 +8,7 @@ import * as shared from '../../shared/index.js';
class DomGenerator extends Generator {
constructor ( parsed, source, name, options ) {
super( parsed, source, name, options );
this.renderers = [];
this.blocks = [];
this.uses = new Set();
// initial values for e.g. window.innerWidth, if there's a <:Window> meta tag
@ -17,72 +17,8 @@ class DomGenerator extends Generator {
};
}
addRenderer ( fragment ) {
if ( fragment.autofocus ) {
fragment.builders.create.addLine( `${fragment.autofocus}.focus();` );
}
// minor hack we need to ensure that any {{{triples}}} are detached
// first, so we append normal detach statements to detachRaw
fragment.builders.detachRaw.addBlock( fragment.builders.detach );
if ( !fragment.builders.detachRaw.isEmpty() ) {
fragment.builders.destroy.addBlock( deindent`
if ( detach ) {
${fragment.builders.detachRaw}
}
` );
}
const properties = new CodeBuilder();
let localKey;
if ( fragment.key ) {
localKey = fragment.getUniqueName( 'key' );
properties.addBlock( `key: ${localKey},` );
}
if ( fragment.builders.mount.isEmpty() ) {
properties.addBlock( `mount: ${this.helper( 'noop' )},` );
} else {
properties.addBlock( deindent`
mount: function ( target, anchor ) {
${fragment.builders.mount}
},
` );
}
if ( fragment.builders.update.isEmpty() ) {
properties.addBlock( `update: ${this.helper( 'noop' )},` );
} else {
properties.addBlock( deindent`
update: function ( changed, ${fragment.params.join( ', ' )} ) {
${fragment.tmp ? `var ${fragment.tmp};` : ''}
${fragment.builders.update}
},
` );
}
if ( fragment.builders.destroy.isEmpty() ) {
properties.addBlock( `destroy: ${this.helper( 'noop' )},` );
} else {
properties.addBlock( deindent`
destroy: function ( detach ) {
${fragment.builders.destroy}
}
` );
}
this.renderers.push( deindent`
function ${fragment.name} ( ${fragment.params.join( ', ' )}, ${fragment.component}${fragment.key ? `, ${localKey}` : ''} ) {
${fragment.builders.create}
return {
${properties}
};
}
` );
addBlock ( fragment ) {
this.blocks.push( fragment );
}
helper ( name ) {
@ -134,7 +70,7 @@ export default function dom ( parsed, source, options ) {
visit( generator, mainFragment, state, node );
});
generator.addRenderer( mainFragment );
generator.addBlock( mainFragment );
const builders = {
main: new CodeBuilder(),
@ -198,8 +134,8 @@ export default function dom ( parsed, source, options ) {
` );
}
let i = generator.renderers.length;
while ( i-- ) builders.main.addBlock( generator.renderers[i] );
let i = generator.blocks.length;
while ( i-- ) builders.main.addBlock( generator.blocks[i].render() );
builders.init.addLine( `this._torndown = false;` );

@ -101,7 +101,7 @@ export default function visitComponent ( generator, fragment, state, node ) {
componentInitProperties.push( `_yield: ${yieldFragment}`);
generator.addRenderer( childFragment );
generator.addBlock( childFragment );
}
const statements = [];

@ -214,7 +214,7 @@ export default function visitEachBlock ( generator, fragment, state, node ) {
visit( generator, childFragment, childState, child );
});
generator.addRenderer( childFragment );
generator.addBlock( childFragment );
if ( node.else ) {
const childFragment = fragment.child({
@ -226,6 +226,6 @@ export default function visitEachBlock ( generator, fragment, state, node ) {
visit( generator, childFragment, childState, child );
});
generator.addRenderer( childFragment );
generator.addBlock( childFragment );
}
}

@ -45,7 +45,7 @@ function generateBlock ( generator, fragment, state, node, name ) {
visit( generator, childFragment, childState, node );
});
generator.addRenderer( childFragment );
generator.addBlock( childFragment );
}
export default function visitIfBlock ( generator, fragment, state, node ) {

Loading…
Cancel
Save