From b8705a5b0c0f54699b2cf596c2abb2e8207468cb Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 4 Apr 2017 23:17:02 -0400 Subject: [PATCH] turn dom generator visitors into functions --- src/generators/dom/visit.js | 4 +- src/generators/dom/visitors/Comment.js | 4 +- src/generators/dom/visitors/Component.js | 232 ++++++------ src/generators/dom/visitors/EachBlock.js | 334 +++++++++--------- src/generators/dom/visitors/Element.js | 179 +++++----- src/generators/dom/visitors/IfBlock.js | 80 ++--- src/generators/dom/visitors/MustacheTag.js | 28 +- src/generators/dom/visitors/RawMustacheTag.js | 60 ++-- src/generators/dom/visitors/Text.js | 16 +- src/generators/dom/visitors/YieldTag.js | 22 +- src/generators/dom/visitors/meta/Window.js | 120 ++++--- 11 files changed, 526 insertions(+), 553 deletions(-) diff --git a/src/generators/dom/visit.js b/src/generators/dom/visit.js index 5f688e76ac..e9837098c4 100644 --- a/src/generators/dom/visit.js +++ b/src/generators/dom/visit.js @@ -2,7 +2,5 @@ import visitors from './visitors/index.js'; export default function visit ( node, generator ) { const visitor = visitors[ node.type ]; - - if ( visitor.enter ) visitor.enter( generator, node ); - if ( visitor.leave ) visitor.leave( generator, node ); + visitor( generator, node ); } \ No newline at end of file diff --git a/src/generators/dom/visitors/Comment.js b/src/generators/dom/visitors/Comment.js index f32a1e64a8..4d3477d7ef 100644 --- a/src/generators/dom/visitors/Comment.js +++ b/src/generators/dom/visitors/Comment.js @@ -1,3 +1,3 @@ -export default { +export default function visitComment () { // do nothing -}; +} diff --git a/src/generators/dom/visitors/Component.js b/src/generators/dom/visitors/Component.js index d9a8e0daa5..1733886fda 100644 --- a/src/generators/dom/visitors/Component.js +++ b/src/generators/dom/visitors/Component.js @@ -19,163 +19,161 @@ function stringifyProps ( props ) { return `{ ${joined} }`; } -export default { - enter ( generator, node ) { - const hasChildren = node.children.length > 0; - const { current } = generator; - const name = current.getUniqueName( capDown( node.name === ':Self' ? generator.name : node.name ) ); +export default function visitComponent ( generator, node ) { + const hasChildren = node.children.length > 0; + const { current } = generator; + const name = current.getUniqueName( capDown( node.name === ':Self' ? generator.name : node.name ) ); - const local = { - name, - namespace: current.namespace, - isComponent: true, + const local = { + name, + namespace: current.namespace, + isComponent: true, - allUsedContexts: [], + allUsedContexts: [], - init: new CodeBuilder(), - update: new CodeBuilder() - }; + init: new CodeBuilder(), + update: new CodeBuilder() + }; - const isToplevel = current.localElementDepth === 0; + const isToplevel = current.localElementDepth === 0; - generator.hasComponents = true; + generator.hasComponents = true; - addComponentAttributes( generator, node, local ); + addComponentAttributes( generator, node, local ); - if ( local.allUsedContexts.length ) { - const initialProps = local.allUsedContexts.map( contextName => { - if ( contextName === 'root' ) return `root: root`; + if ( local.allUsedContexts.length ) { + const initialProps = local.allUsedContexts.map( contextName => { + if ( contextName === 'root' ) return `root: root`; - const listName = current.listNames.get( contextName ); - const indexName = current.indexNames.get( contextName ); + const listName = current.listNames.get( contextName ); + const indexName = current.indexNames.get( contextName ); - return `${listName}: ${listName},\n${indexName}: ${indexName}`; - }).join( ',\n' ); + return `${listName}: ${listName},\n${indexName}: ${indexName}`; + }).join( ',\n' ); - const updates = local.allUsedContexts.map( contextName => { - if ( contextName === 'root' ) return `${name}._context.root = root;`; + const updates = local.allUsedContexts.map( contextName => { + if ( contextName === 'root' ) return `${name}._context.root = root;`; - const listName = current.listNames.get( contextName ); - const indexName = current.indexNames.get( contextName ); + const listName = current.listNames.get( contextName ); + const indexName = current.indexNames.get( contextName ); - return `${name}._context.${listName} = ${listName};\n${name}._context.${indexName} = ${indexName};`; - }).join( '\n' ); + return `${name}._context.${listName} = ${listName};\n${name}._context.${indexName} = ${indexName};`; + }).join( '\n' ); - local.init.addBlock( deindent` - ${name}._context = { - ${initialProps} - }; - ` ); + local.init.addBlock( deindent` + ${name}._context = { + ${initialProps} + }; + ` ); - local.update.addBlock( updates ); - } + local.update.addBlock( updates ); + } - const componentInitProperties = [ - `target: ${!isToplevel ? current.target: 'null'}`, - `_root: ${current.component}._root || ${current.component}` - ]; + const componentInitProperties = [ + `target: ${!isToplevel ? current.target: 'null'}`, + `_root: ${current.component}._root || ${current.component}` + ]; - // Component has children, put them in a separate {{yield}} block - if ( hasChildren ) { - const yieldName = generator.getUniqueName( `render_${name}_yield_fragment` ); - const params = current.params.join( ', ' ); + // Component has children, put them in a separate {{yield}} block + if ( hasChildren ) { + const yieldName = generator.getUniqueName( `render_${name}_yield_fragment` ); + const params = current.params.join( ', ' ); - generator.generateBlock( node, yieldName, 'block' ); + generator.generateBlock( node, yieldName, 'block' ); - const yieldFragment = current.getUniqueName( `${name}_yield_fragment` ); + const yieldFragment = current.getUniqueName( `${name}_yield_fragment` ); - current.builders.init.addLine( - `var ${yieldFragment} = ${yieldName}( ${params}, ${current.component} );` - ); + current.builders.init.addLine( + `var ${yieldFragment} = ${yieldName}( ${params}, ${current.component} );` + ); - current.builders.update.addLine( - `${yieldFragment}.update( changed, ${params} );` - ); + current.builders.update.addLine( + `${yieldFragment}.update( changed, ${params} );` + ); - componentInitProperties.push( `_yield: ${yieldFragment}`); - } + componentInitProperties.push( `_yield: ${yieldFragment}`); + } - const statements = []; + const statements = []; - if ( local.staticAttributes.length || local.dynamicAttributes.length || local.bindings.length ) { - const initialProps = local.staticAttributes - .concat( local.dynamicAttributes ) - .map( attribute => `${attribute.name}: ${attribute.value}` ); + if ( local.staticAttributes.length || local.dynamicAttributes.length || local.bindings.length ) { + const initialProps = local.staticAttributes + .concat( local.dynamicAttributes ) + .map( attribute => `${attribute.name}: ${attribute.value}` ); - const initialPropString = stringifyProps( initialProps ); + const initialPropString = stringifyProps( initialProps ); - if ( local.bindings.length ) { - const initialData = current.getUniqueName( `${name}_initial_data` ); + if ( local.bindings.length ) { + const initialData = current.getUniqueName( `${name}_initial_data` ); - statements.push( `var ${name}_initial_data = ${initialPropString};` ); + statements.push( `var ${name}_initial_data = ${initialPropString};` ); - local.bindings.forEach( binding => { - statements.push( `if ( ${binding.prop} in ${binding.obj} ) ${initialData}.${binding.name} = ${binding.value};` ); - }); + local.bindings.forEach( binding => { + statements.push( `if ( ${binding.prop} in ${binding.obj} ) ${initialData}.${binding.name} = ${binding.value};` ); + }); - componentInitProperties.push( `data: ${initialData}` ); - } else if ( initialProps.length ) { - componentInitProperties.push( `data: ${initialPropString}` ); - } + componentInitProperties.push( `data: ${initialData}` ); + } else if ( initialProps.length ) { + componentInitProperties.push( `data: ${initialPropString}` ); } + } - const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${generator.alias( 'template' )}.components.${node.name}`; + const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${generator.alias( 'template' )}.components.${node.name}`; - local.init.addBlockAtStart( deindent` - ${statements.join( '\n' )} - var ${name} = new ${expression}({ - ${componentInitProperties.join(',\n')} - }); - ` ); + local.init.addBlockAtStart( deindent` + ${statements.join( '\n' )} + var ${name} = new ${expression}({ + ${componentInitProperties.join(',\n')} + }); + ` ); - if ( isToplevel ) { - current.builders.mount.addLine( `${name}._fragment.mount( target, anchor );` ); - } + if ( isToplevel ) { + current.builders.mount.addLine( `${name}._fragment.mount( target, anchor );` ); + } - if ( local.dynamicAttributes.length ) { - const updates = local.dynamicAttributes.map( attribute => { - if ( attribute.dependencies.length ) { - return deindent` - if ( ${attribute.dependencies.map( dependency => `'${dependency}' in changed` ).join( '||' )} ) ${name}_changes.${attribute.name} = ${attribute.value}; - `; - } - - // TODO this is an odd situation to encounter – I *think* it should only happen with - // each block indices, in which case it may be possible to optimise this - return `${name}_changes.${attribute.name} = ${attribute.value};`; - }); + if ( local.dynamicAttributes.length ) { + const updates = local.dynamicAttributes.map( attribute => { + if ( attribute.dependencies.length ) { + return deindent` + if ( ${attribute.dependencies.map( dependency => `'${dependency}' in changed` ).join( '||' )} ) ${name}_changes.${attribute.name} = ${attribute.value}; + `; + } - local.update.addBlock( deindent` - var ${name}_changes = {}; + // TODO this is an odd situation to encounter – I *think* it should only happen with + // each block indices, in which case it may be possible to optimise this + return `${name}_changes.${attribute.name} = ${attribute.value};`; + }); - ${updates.join( '\n' )} + local.update.addBlock( deindent` + var ${name}_changes = {}; - if ( Object.keys( ${name}_changes ).length ) ${name}.set( ${name}_changes ); - ` ); - } + ${updates.join( '\n' )} - current.builders.teardown.addLine( `${name}.destroy( ${isToplevel ? 'detach' : 'false'} );` ); + if ( Object.keys( ${name}_changes ).length ) ${name}.set( ${name}_changes ); + ` ); + } - current.builders.init.addBlock( local.init ); - if ( !local.update.isEmpty() ) current.builders.update.addBlock( local.update ); + current.builders.teardown.addLine( `${name}.destroy( ${isToplevel ? 'detach' : 'false'} );` ); - generator.push({ - type: 'component', - namespace: local.namespace, - target: name, - parent: current, - localElementDepth: current.localElementDepth + 1, - key: null - }); + current.builders.init.addBlock( local.init ); + if ( !local.update.isEmpty() ) current.builders.update.addBlock( local.update ); - generator.elementDepth += 1; + generator.push({ + type: 'component', + namespace: local.namespace, + target: name, + parent: current, + localElementDepth: current.localElementDepth + 1, + key: null + }); - node.children.forEach( child => { - visit( child, generator ); - }); + generator.elementDepth += 1; - generator.elementDepth -= 1; + node.children.forEach( child => { + visit( child, generator ); + }); - generator.pop(); - } -}; + generator.elementDepth -= 1; + + generator.pop(); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/EachBlock.js b/src/generators/dom/visitors/EachBlock.js index 716c5c1e34..d60c69ec8b 100644 --- a/src/generators/dom/visitors/EachBlock.js +++ b/src/generators/dom/visitors/EachBlock.js @@ -3,224 +3,222 @@ import deindent from '../../../utils/deindent.js'; import getBuilders from '../utils/getBuilders.js'; import visit from '../visit.js'; -export default { - enter ( generator, node ) { - const name = generator.getUniqueName( `each_block` ); - const renderer = generator.getUniqueName( `render_each_block` ); - const elseName = generator.getUniqueName( `${name}_else` ); - const renderElse = generator.getUniqueName( `${renderer}_else` ); - const i = generator.current.getUniqueName( `i` ); - const params = generator.current.params.join( ', ' ); +export default function visitEachBlock ( generator, node ) { + const name = generator.getUniqueName( `each_block` ); + const renderer = generator.getUniqueName( `render_each_block` ); + const elseName = generator.getUniqueName( `${name}_else` ); + const renderElse = generator.getUniqueName( `${renderer}_else` ); + const i = generator.current.getUniqueName( `i` ); + const params = generator.current.params.join( ', ' ); - const listName = generator.current.getUniqueName( `${name}_value` ); + const listName = generator.current.getUniqueName( `${name}_value` ); - const isToplevel = generator.current.localElementDepth === 0; + const isToplevel = generator.current.localElementDepth === 0; - generator.addSourcemapLocations( node.expression ); + generator.addSourcemapLocations( node.expression ); - const { dependencies, snippet } = generator.contextualise( node.expression ); + const { dependencies, snippet } = generator.contextualise( node.expression ); - const anchor = generator.current.getUniqueName( `${name}_anchor` ); - generator.createAnchor( anchor ); + const anchor = generator.current.getUniqueName( `${name}_anchor` ); + generator.createAnchor( anchor ); - const localVars = {}; + const localVars = {}; - localVars.iteration = generator.current.getUniqueName( `${name}_iteration` ); - localVars.iterations = generator.current.getUniqueName( `${name}_iterations` ); - localVars._iterations = generator.current.getUniqueName( `_${name}_iterations` ); - localVars.lookup = generator.current.getUniqueName( `${name}_lookup` ); - localVars._lookup = generator.current.getUniqueName( `_${name}_lookup` ); + localVars.iteration = generator.current.getUniqueName( `${name}_iteration` ); + localVars.iterations = generator.current.getUniqueName( `${name}_iterations` ); + localVars._iterations = generator.current.getUniqueName( `_${name}_iterations` ); + localVars.lookup = generator.current.getUniqueName( `${name}_lookup` ); + localVars._lookup = generator.current.getUniqueName( `_${name}_lookup` ); - generator.current.builders.init.addLine( `var ${listName} = ${snippet};` ); - generator.current.builders.init.addLine( `var ${localVars.iterations} = [];` ); - if ( node.key ) generator.current.builders.init.addLine( `var ${localVars.lookup} = Object.create( null );` ); - if ( node.else ) generator.current.builders.init.addLine( `var ${elseName} = null;` ); + generator.current.builders.init.addLine( `var ${listName} = ${snippet};` ); + generator.current.builders.init.addLine( `var ${localVars.iterations} = [];` ); + if ( node.key ) generator.current.builders.init.addLine( `var ${localVars.lookup} = Object.create( null );` ); + if ( node.else ) generator.current.builders.init.addLine( `var ${elseName} = null;` ); - const initialRender = new CodeBuilder(); + const initialRender = new CodeBuilder(); - if ( node.key ) { - localVars.fragment = generator.current.getUniqueName( 'fragment' ); - localVars.value = generator.current.getUniqueName( 'value' ); - localVars.key = generator.current.getUniqueName( 'key' ); + if ( node.key ) { + localVars.fragment = generator.current.getUniqueName( 'fragment' ); + localVars.value = generator.current.getUniqueName( 'value' ); + localVars.key = generator.current.getUniqueName( 'key' ); - initialRender.addBlock( deindent` - var ${localVars.key} = ${listName}[${i}].${node.key}; - ${localVars.iterations}[${i}] = ${localVars.lookup}[ ${localVars.key} ] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component}${node.key ? `, ${localVars.key}` : `` } ); - ` ); - } else { - initialRender.addLine( - `${localVars.iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component} );` - ); - } + initialRender.addBlock( deindent` + var ${localVars.key} = ${listName}[${i}].${node.key}; + ${localVars.iterations}[${i}] = ${localVars.lookup}[ ${localVars.key} ] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component}${node.key ? `, ${localVars.key}` : `` } ); + ` ); + } else { + initialRender.addLine( + `${localVars.iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component} );` + ); + } - if ( !isToplevel ) { - initialRender.addLine( - `${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );` - ); + if ( !isToplevel ) { + initialRender.addLine( + `${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );` + ); + } + + generator.current.builders.init.addBlock( deindent` + for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { + ${initialRender} } + ` ); + if ( node.else ) { generator.current.builders.init.addBlock( deindent` - for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { - ${initialRender} + if ( !${listName}.length ) { + ${elseName} = ${renderElse}( ${params}, ${generator.current.component} ); + ${!isToplevel ? `${elseName}.mount( ${anchor}.parentNode, ${anchor} );` : ''} } ` ); + } + if ( isToplevel ) { + generator.current.builders.mount.addBlock( deindent` + for ( var ${i} = 0; ${i} < ${localVars.iterations}.length; ${i} += 1 ) { + ${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} ); + } + ` ); if ( node.else ) { - generator.current.builders.init.addBlock( deindent` - if ( !${listName}.length ) { - ${elseName} = ${renderElse}( ${params}, ${generator.current.component} ); - ${!isToplevel ? `${elseName}.mount( ${anchor}.parentNode, ${anchor} );` : ''} - } - ` ); - } - - if ( isToplevel ) { generator.current.builders.mount.addBlock( deindent` - for ( var ${i} = 0; ${i} < ${localVars.iterations}.length; ${i} += 1 ) { - ${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} ); + if ( ${elseName} ) { + ${elseName}.mount( ${anchor}.parentNode, ${anchor} ); } ` ); - if ( node.else ) { - generator.current.builders.mount.addBlock( deindent` - if ( ${elseName} ) { - ${elseName}.mount( ${anchor}.parentNode, ${anchor} ); - } - ` ); - } } + } - if ( node.key ) { - generator.current.builders.update.addBlock( deindent` - var ${listName} = ${snippet}; - var ${localVars._iterations} = []; - var ${localVars._lookup} = Object.create( null ); + if ( node.key ) { + generator.current.builders.update.addBlock( deindent` + var ${listName} = ${snippet}; + var ${localVars._iterations} = []; + var ${localVars._lookup} = Object.create( null ); - var ${localVars.fragment} = document.createDocumentFragment(); + var ${localVars.fragment} = document.createDocumentFragment(); - // create new iterations as necessary - for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { - var ${localVars.value} = ${listName}[${i}]; - var ${localVars.key} = ${localVars.value}.${node.key}; + // create new iterations as necessary + for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { + var ${localVars.value} = ${listName}[${i}]; + var ${localVars.key} = ${localVars.value}.${node.key}; + + if ( ${localVars.lookup}[ ${localVars.key} ] ) { + ${localVars._iterations}[${i}] = ${localVars._lookup}[ ${localVars.key} ] = ${localVars.lookup}[ ${localVars.key} ]; + ${localVars._lookup}[ ${localVars.key} ].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} ); + } else { + ${localVars._iterations}[${i}] = ${localVars._lookup}[ ${localVars.key} ] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component}${node.key ? `, ${localVars.key}` : `` } ); + } - if ( ${localVars.lookup}[ ${localVars.key} ] ) { - ${localVars._iterations}[${i}] = ${localVars._lookup}[ ${localVars.key} ] = ${localVars.lookup}[ ${localVars.key} ]; - ${localVars._lookup}[ ${localVars.key} ].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} ); - } else { - ${localVars._iterations}[${i}] = ${localVars._lookup}[ ${localVars.key} ] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component}${node.key ? `, ${localVars.key}` : `` } ); - } + ${localVars._iterations}[${i}].mount( ${localVars.fragment}, null ); + } - ${localVars._iterations}[${i}].mount( ${localVars.fragment}, null ); + // remove old iterations + for ( var ${i} = 0; ${i} < ${localVars.iterations}.length; ${i} += 1 ) { + var ${localVars.iteration} = ${localVars.iterations}[${i}]; + if ( !${localVars._lookup}[ ${localVars.iteration}.key ] ) { + ${localVars.iteration}.teardown( true ); } + } - // remove old iterations - for ( var ${i} = 0; ${i} < ${localVars.iterations}.length; ${i} += 1 ) { - var ${localVars.iteration} = ${localVars.iterations}[${i}]; - if ( !${localVars._lookup}[ ${localVars.iteration}.key ] ) { - ${localVars.iteration}.teardown( true ); - } - } + ${anchor}.parentNode.insertBefore( ${localVars.fragment}, ${anchor} ); - ${anchor}.parentNode.insertBefore( ${localVars.fragment}, ${anchor} ); + ${localVars.iterations} = ${localVars._iterations}; + ${localVars.lookup} = ${localVars._lookup}; + ` ); + } else { + generator.current.builders.update.addBlock( deindent` + var ${listName} = ${snippet}; - ${localVars.iterations} = ${localVars._iterations}; - ${localVars.lookup} = ${localVars._lookup}; - ` ); - } else { - generator.current.builders.update.addBlock( deindent` - var ${listName} = ${snippet}; - - for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { - if ( !${localVars.iterations}[${i}] ) { - ${localVars.iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component} ); - ${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} ); - } else { - ${localVars.iterations}[${i}].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} ); - } + for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { + if ( !${localVars.iterations}[${i}] ) { + ${localVars.iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component} ); + ${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} ); + } else { + ${localVars.iterations}[${i}].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} ); } + } - teardownEach( ${localVars.iterations}, true, ${listName}.length ); + teardownEach( ${localVars.iterations}, true, ${listName}.length ); - ${localVars.iterations}.length = ${listName}.length; - ` ); - } + ${localVars.iterations}.length = ${listName}.length; + ` ); + } - if ( node.else ) { - generator.current.builders.update.addBlock( deindent` - if ( !${listName}.length && ${elseName} ) { - ${elseName}.update( changed, ${params} ); - } else if ( !${listName}.length ) { - ${elseName} = ${renderElse}( ${params}, ${generator.current.component} ); - ${elseName}.mount( ${anchor}.parentNode, ${anchor} ); - } else if ( ${elseName} ) { - ${elseName}.teardown( true ); - } - ` ); - } + if ( node.else ) { + generator.current.builders.update.addBlock( deindent` + if ( !${listName}.length && ${elseName} ) { + ${elseName}.update( changed, ${params} ); + } else if ( !${listName}.length ) { + ${elseName} = ${renderElse}( ${params}, ${generator.current.component} ); + ${elseName}.mount( ${anchor}.parentNode, ${anchor} ); + } else if ( ${elseName} ) { + ${elseName}.teardown( true ); + } + ` ); + } - generator.current.builders.teardown.addBlock( - `${generator.helper( 'teardownEach' )}( ${localVars.iterations}, ${isToplevel ? 'detach' : 'false'} );` ); + generator.current.builders.teardown.addBlock( + `${generator.helper( 'teardownEach' )}( ${localVars.iterations}, ${isToplevel ? 'detach' : 'false'} );` ); - if ( node.else ) { - generator.current.builders.teardown.addBlock( deindent` - if ( ${elseName} ) { - ${elseName}.teardown( ${isToplevel ? 'detach' : 'false'} ); - } - ` ); - } + if ( node.else ) { + generator.current.builders.teardown.addBlock( deindent` + if ( ${elseName} ) { + ${elseName}.teardown( ${isToplevel ? 'detach' : 'false'} ); + } + ` ); + } - if ( node.else ) { - generator.generateBlock( node.else, renderElse, 'block' ); - } + if ( node.else ) { + generator.generateBlock( node.else, renderElse, 'block' ); + } - const indexNames = new Map( generator.current.indexNames ); - const indexName = node.index || generator.current.getUniqueName( `${node.context}_index` ); - indexNames.set( node.context, indexName ); + const indexNames = new Map( generator.current.indexNames ); + const indexName = node.index || generator.current.getUniqueName( `${node.context}_index` ); + indexNames.set( node.context, indexName ); - const listNames = new Map( generator.current.listNames ); - listNames.set( node.context, listName ); + const listNames = new Map( generator.current.listNames ); + listNames.set( node.context, listName ); - const context = generator.getUniqueName( node.context ); - const contexts = new Map( generator.current.contexts ); - contexts.set( node.context, context ); + const context = generator.getUniqueName( node.context ); + const contexts = new Map( generator.current.contexts ); + contexts.set( node.context, context ); - const indexes = new Map( generator.current.indexes ); - if ( node.index ) indexes.set( indexName, node.context ); + const indexes = new Map( generator.current.indexes ); + if ( node.index ) indexes.set( indexName, node.context ); - const contextDependencies = new Map( generator.current.contextDependencies ); - contextDependencies.set( node.context, dependencies ); + const contextDependencies = new Map( generator.current.contextDependencies ); + contextDependencies.set( node.context, dependencies ); - const blockParams = generator.current.params.concat( listName, context, indexName ); + const blockParams = generator.current.params.concat( listName, context, indexName ); - const getUniqueName = generator.getUniqueNameMaker( blockParams ); + const getUniqueName = generator.getUniqueNameMaker( blockParams ); - generator.push({ - type: 'block', - name: renderer, - target: 'target', - expression: node.expression, - context: node.context, - key: node.key, - localElementDepth: 0, + generator.push({ + type: 'block', + name: renderer, + target: 'target', + expression: node.expression, + context: node.context, + key: node.key, + localElementDepth: 0, - component: getUniqueName( 'component' ), + component: getUniqueName( 'component' ), - contextDependencies, - contexts, - indexes, + contextDependencies, + contexts, + indexes, - indexNames, - listNames, - params: blockParams, + indexNames, + listNames, + params: blockParams, - builders: getBuilders(), - getUniqueName, - }); + builders: getBuilders(), + getUniqueName, + }); - node.children.forEach( child => { - visit( child, generator ); - }); + node.children.forEach( child => { + visit( child, generator ); + }); - generator.addRenderer( generator.current ); - generator.pop(); - } -}; + generator.addRenderer( generator.current ); + generator.pop(); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/Element.js b/src/generators/dom/visitors/Element.js index a224f0ffce..21f81c8eb9 100644 --- a/src/generators/dom/visitors/Element.js +++ b/src/generators/dom/visitors/Element.js @@ -2,131 +2,122 @@ import CodeBuilder from '../../../utils/CodeBuilder.js'; import deindent from '../../../utils/deindent.js'; import visit from '../visit.js'; import addElementAttributes from './attributes/addElementAttributes.js'; -import Component from './Component.js'; -import Window from './meta/Window.js'; +import visitComponent from './Component.js'; +import visitWindow from './meta/Window.js'; const meta = { - ':Window': Window + ':Window': visitWindow }; -export default { - enter ( generator, node ) { - if ( node.name in meta ) { - return meta[ node.name ].enter( generator, node ); - } - - const isComponent = generator.components.has( node.name ) || node.name === ':Self'; +export default function visitElement ( generator, node ) { + if ( node.name in meta ) { + return meta[ node.name ]( generator, node ); + } - if ( isComponent ) { - return Component.enter( generator, node ); - } + if ( generator.components.has( node.name ) || node.name === ':Self' ) { + return visitComponent( generator, node ); + } - const name = generator.current.getUniqueName( node.name ); + const name = generator.current.getUniqueName( node.name ); - const local = { - name, - namespace: node.name === 'svg' ? 'http://www.w3.org/2000/svg' : generator.current.namespace, - isComponent: false, + const local = { + name, + namespace: node.name === 'svg' ? 'http://www.w3.org/2000/svg' : generator.current.namespace, + isComponent: false, - allUsedContexts: [], + allUsedContexts: [], - init: new CodeBuilder(), - update: new CodeBuilder(), - teardown: new CodeBuilder() - }; + init: new CodeBuilder(), + update: new CodeBuilder(), + teardown: new CodeBuilder() + }; - const isToplevel = generator.current.localElementDepth === 0; + const isToplevel = generator.current.localElementDepth === 0; - addElementAttributes( generator, node, local ); + addElementAttributes( generator, node, local ); - if ( local.allUsedContexts.length ) { - const initialProps = local.allUsedContexts.map( contextName => { - if ( contextName === 'root' ) return `root: root`; + if ( local.allUsedContexts.length ) { + const initialProps = local.allUsedContexts.map( contextName => { + if ( contextName === 'root' ) return `root: root`; - const listName = generator.current.listNames.get( contextName ); - const indexName = generator.current.indexNames.get( contextName ); + const listName = generator.current.listNames.get( contextName ); + const indexName = generator.current.indexNames.get( contextName ); - return `${listName}: ${listName},\n${indexName}: ${indexName}`; - }).join( ',\n' ); + return `${listName}: ${listName},\n${indexName}: ${indexName}`; + }).join( ',\n' ); - const updates = local.allUsedContexts.map( contextName => { - if ( contextName === 'root' ) return `${name}.__svelte.root = root;`; + const updates = local.allUsedContexts.map( contextName => { + if ( contextName === 'root' ) return `${name}.__svelte.root = root;`; - const listName = generator.current.listNames.get( contextName ); - const indexName = generator.current.indexNames.get( contextName ); + const listName = generator.current.listNames.get( contextName ); + const indexName = generator.current.indexNames.get( contextName ); - return `${name}.__svelte.${listName} = ${listName};\n${name}.__svelte.${indexName} = ${indexName};`; - }).join( '\n' ); + return `${name}.__svelte.${listName} = ${listName};\n${name}.__svelte.${indexName} = ${indexName};`; + }).join( '\n' ); - local.init.addBlock( deindent` - ${name}.__svelte = { - ${initialProps} - }; - ` ); + local.init.addBlock( deindent` + ${name}.__svelte = { + ${initialProps} + }; + ` ); - local.update.addBlock( updates ); - } + local.update.addBlock( updates ); + } - let render; + let render; - if ( local.namespace ) { - if ( local.namespace === 'http://www.w3.org/2000/svg' ) { - render = `var ${name} = ${generator.helper( 'createSvgElement' )}( '${node.name}' )`; - } else { - render = `var ${name} = document.createElementNS( '${local.namespace}', '${node.name}' );`; - } + if ( local.namespace ) { + if ( local.namespace === 'http://www.w3.org/2000/svg' ) { + render = `var ${name} = ${generator.helper( 'createSvgElement' )}( '${node.name}' )`; } else { - render = `var ${name} = ${generator.helper( 'createElement' )}( '${node.name}' );`; - } - - if ( generator.cssId && !generator.elementDepth ) { - render += `\n${generator.helper( 'setAttribute' )}( ${name}, '${generator.cssId}', '' );`; - } - - local.init.addLineAtStart( render ); - if ( isToplevel ) { - generator.current.builders.detach.addLine( `${generator.helper( 'detachNode' )}( ${name} );` ); + render = `var ${name} = document.createElementNS( '${local.namespace}', '${node.name}' );`; } + } else { + render = `var ${name} = ${generator.helper( 'createElement' )}( '${node.name}' );`; + } - // special case – bound