From bd85ffbf2886adca86683bbde2dcf629b45e551a Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 8 Apr 2017 16:22:20 -0400 Subject: [PATCH] move render logic into fragment --- src/generators/dom/Fragment.js | 69 +++++++++++++++++++++ src/generators/dom/index.js | 76 ++---------------------- src/generators/dom/visitors/Component.js | 2 +- src/generators/dom/visitors/EachBlock.js | 4 +- src/generators/dom/visitors/IfBlock.js | 2 +- 5 files changed, 79 insertions(+), 74 deletions(-) diff --git a/src/generators/dom/Fragment.js b/src/generators/dom/Fragment.js index b32b12e69b..07adab0ba4 100644 --- a/src/generators/dom/Fragment.js +++ b/src/generators/dom/Fragment.js @@ -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} + }; + } + `; + } } \ No newline at end of file diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index a9506599e7..ff9670ba2a 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -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;` ); diff --git a/src/generators/dom/visitors/Component.js b/src/generators/dom/visitors/Component.js index 27d13c1d9e..342f531bfa 100644 --- a/src/generators/dom/visitors/Component.js +++ b/src/generators/dom/visitors/Component.js @@ -101,7 +101,7 @@ export default function visitComponent ( generator, fragment, state, node ) { componentInitProperties.push( `_yield: ${yieldFragment}`); - generator.addRenderer( childFragment ); + generator.addBlock( childFragment ); } const statements = []; diff --git a/src/generators/dom/visitors/EachBlock.js b/src/generators/dom/visitors/EachBlock.js index 1985ee780b..5b4aac6c51 100644 --- a/src/generators/dom/visitors/EachBlock.js +++ b/src/generators/dom/visitors/EachBlock.js @@ -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 ); } } \ No newline at end of file diff --git a/src/generators/dom/visitors/IfBlock.js b/src/generators/dom/visitors/IfBlock.js index e24215f69a..e2090e68b9 100644 --- a/src/generators/dom/visitors/IfBlock.js +++ b/src/generators/dom/visitors/IfBlock.js @@ -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 ) {