Skip to content

Commit

Permalink
Remove closures from fragments, naively
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkishi committed Dec 6, 2016
1 parent 2616dc0 commit 266e894
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 125 deletions.
46 changes: 24 additions & 22 deletions compiler/generate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,29 @@ export default function generate ( parsed, source, options, names ) {
const isToplevel = generator.current.localElementDepth === 0;
if ( needsIdentifier || isToplevel ) {
generator.current.initStatements.push( deindent`
var ${name} = ${renderStatement};
this.${name} = ${renderStatement};
` );
generator.createMountStatement( name );
} else {
generator.current.initStatements.push( deindent`
${generator.current.target}.appendChild( ${renderStatement} );
this.${generator.current.target}.appendChild( ${renderStatement} );
` );
}
if ( isToplevel ) {
generator.current.detachStatements.push( deindent`
${name}.parentNode.removeChild( ${name} );
this.${name}.parentNode.removeChild( this.${name} );
` );
}
},

createMountStatement ( name ) {
if ( generator.current.target === 'target' ) {
generator.current.mountStatements.push( deindent`
target.insertBefore( ${name}, anchor );
target.insertBefore( this.${name}, anchor );
` );
} else {
generator.current.initStatements.push( deindent`
${generator.current.target}.appendChild( ${name} );
this.${generator.current.target}.appendChild( this.${name} );
` );
}
},
Expand All @@ -54,7 +54,7 @@ export default function generate ( parsed, source, options, names ) {

addRenderer ( fragment ) {
if ( fragment.autofocus ) {
fragment.initStatements.push( `${fragment.autofocus}.focus();` );
fragment.initStatements.push( `this.${fragment.autofocus}.focus();` );
}

const detachStatements = fragment.detachStatements.join( '\n\n' );
Expand All @@ -72,22 +72,24 @@ export default function generate ( parsed, source, options, names ) {

renderers.push( deindent`
function ${fragment.name} ( ${fragment.params}, component ) {
this.component = component;
${fragment.initStatements.join( '\n\n' )}
}
return {
mount: function ( target, anchor ) {
${fragment.mountStatements.join( '\n\n' )}
},
${fragment.name}.prototype = {
mount: function mount ( target, anchor ) {
${fragment.mountStatements.join( '\n\n' )}
},
update: function ( changed, ${fragment.params} ) {
${fragment.updateStatements.join( '\n\n' )}
},
update: function update ( changed, ${fragment.params} ) {
${fragment.updateStatements.join( '\n\n' )}
},
teardown: function ( detach ) {
${teardownBlock}
}
};
}
teardown: function teardown ( detach ) {
${teardownBlock}
}
};
` );
},

Expand Down Expand Up @@ -257,7 +259,7 @@ export default function generate ( parsed, source, options, names ) {

generator.push({
useAnchor: false,
name: 'renderMainFragment',
name: 'MainFragment',
namespace: null,
target: 'target',
elementDepth: 0,
Expand Down Expand Up @@ -394,15 +396,15 @@ export default function generate ( parsed, source, options, names ) {
if ( generator.hasComplexBindings ) {
initStatements.push( deindent`
this.__bindings = [];
this.mainFragment = renderMainFragment( this.state, this );
this.mainFragment = new MainFragment( this.state, this );
if ( options.target ) this.mount( options.target );
while ( this.__bindings.length ) this.__bindings.pop()();
` );

setStatements.push( `while ( this.__bindings.length ) this.__bindings.pop()();` );
} else {
initStatements.push( deindent`
this.mainFragment = renderMainFragment( this.state, this );
this.mainFragment = new MainFragment( this.state, this );
if ( options.target ) this.mount( options.target );
` );
}
Expand Down Expand Up @@ -448,7 +450,7 @@ export default function generate ( parsed, source, options, names ) {
${initStatements.join( '\n\n' )}
}
${constructorName}.prototype = {
dispatchObservers: function dispatchObservers ( group, newState, oldState ) {
Expand Down
18 changes: 9 additions & 9 deletions compiler/generate/visitors/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ export default {
addComponentAttributes( generator, node, local );

const componentInitProperties = [
`target: ${!isToplevel ? generator.current.target: 'null'}`,
`target: ${!isToplevel ? `this.${generator.current.target}` : 'null'}`,
'root: component.root || component'
];
// Component has children
if ( hasChildren ) {
const yieldName = generator.current.getUniqueName( `render${name}YieldFragment` );
const yieldName = generator.current.getUniqueName( `${name}YieldFragment` );

// {{YIELD STUFF}}
generator.push({
Expand All @@ -57,10 +57,10 @@ export default {
// Don't render children twice
node.children = [];

generator.current.initStatements.push(`var ${name}_yieldFragment = ${yieldName}( root, component );`);
generator.current.updateStatements.push(`${name}_yieldFragment.update ( changed, root );`);
generator.current.initStatements.push(`this.${name}_yieldFragment = new ${yieldName}( root, component );`);
generator.current.updateStatements.push(`this.${name}_yieldFragment.update ( changed, root );`);

componentInitProperties.push(`yield: ${name}_yieldFragment`);
componentInitProperties.push(`yield: this.${name}_yieldFragment`);
}

const statements = [];
Expand Down Expand Up @@ -94,13 +94,13 @@ export default {

local.init.unshift( deindent`
${statements.join( '\n\n' )}
var ${name} = new template.components.${node.name}({
this.${name} = new template.components.${node.name}({
${componentInitProperties.join(',\n')}
});
` );

if ( isToplevel ) {
local.mount.unshift( `${name}.mount( target, anchor );` );
local.mount.unshift( `this.${name}.mount( target, anchor );` );
}

if ( local.dynamicAttributes.length ) {
Expand All @@ -121,11 +121,11 @@ export default {
${updates.join( '\n' )}
if ( Object.keys( ${name}_changes ).length ) ${name}.set( ${name}_changes );
if ( Object.keys( ${name}_changes ).length ) this.${name}.set( ${name}_changes );
` );
}

local.teardown.push( `${name}.teardown( ${isToplevel ? 'detach' : 'false'} );` );
local.teardown.push( `this.${name}.teardown( ${isToplevel ? 'detach' : 'false'} );` );

generator.current.initStatements.push( local.init.join( '\n' ) );
if ( local.update.length ) generator.current.updateStatements.push( local.update.join( '\n' ) );
Expand Down
56 changes: 28 additions & 28 deletions compiler/generate/visitors/EachBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import deindent from '../utils/deindent.js';
export default {
enter ( generator, node ) {
const name = generator.getUniqueName( `eachBlock` );
const renderer = generator.getUniqueName( `renderEachBlock` );
const renderer = generator.getUniqueName( `EachBlock` );
const elseName = `${name}_else`;
const iterations = `${name}_iterations`;
const renderElse = `${renderer}_else`;
Expand All @@ -22,33 +22,33 @@ export default {

generator.current.initStatements.push( deindent`
var ${name}_value = ${snippet};
var ${iterations} = [];
${node.else ? `var ${elseName} = null;` : ''}
this.${iterations} = [];
${node.else ? `this.${elseName} = null;` : ''}
for ( var ${i} = 0; ${i} < ${name}_value.length; ${i} += 1 ) {
${iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, component );
${!isToplevel ? `${iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );` : ''}
this.${iterations}[${i}] = new ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, component );
${!isToplevel ? `this.${iterations}[${i}].mount( this.${anchor}.parentNode, this.${anchor} );` : ''}
}
` );
if ( node.else ) {
generator.current.initStatements.push( deindent`
if ( !${name}_value.length ) {
${elseName} = ${renderElse}( ${params}, component );
${!isToplevel ? `${elseName}.mount( ${anchor}.parentNode, ${anchor} );` : ''}
this.${elseName} = new ${renderElse}( ${params}, component );
${!isToplevel ? `${elseName}.mount( this.${anchor}.parentNode, this.${anchor} );` : ''}
}
` );
}

if ( isToplevel ) {
generator.current.mountStatements.push( deindent`
for ( var ${i} = 0; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );
for ( var ${i} = 0; ${i} < this.${iterations}.length; ${i} += 1 ) {
this.${iterations}[${i}].mount( this.${anchor}.parentNode, this.${anchor} );
}
` );
if ( node.else ) {
generator.current.mountStatements.push( deindent`
if ( ${elseName} ) {
${elseName}.mount( ${anchor}.parentNode, ${anchor} );
if ( this.${elseName} ) {
this.${elseName}.mount( this.${anchor}.parentNode, this.${anchor} );
}
` );
}
Expand All @@ -58,44 +58,44 @@ export default {
var ${name}_value = ${snippet};
for ( var ${i} = 0; ${i} < ${name}_value.length; ${i} += 1 ) {
if ( !${iterations}[${i}] ) {
${iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, component );
${iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );
if ( !this.${iterations}[${i}] ) {
this.${iterations}[${i}] = new ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, this.component );
this.${iterations}[${i}].mount( this.${anchor}.parentNode, this.${anchor} );
} else {
${iterations}[${i}].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} );
this.${iterations}[${i}].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} );
}
}
for ( var ${i} = ${name}_value.length; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[${i}].teardown( true );
for ( var ${i} = ${name}_value.length; ${i} < this.${iterations}.length; ${i} += 1 ) {
this.${iterations}[${i}].teardown( true );
}
${iterations}.length = ${listName}.length;
this.${iterations}.length = ${listName}.length;
` );

if ( node.else ) {
generator.current.updateStatements.push( deindent`
if ( !${name}_value.length && ${elseName} ) {
${elseName}.update( changed, ${params} );
if ( !${name}_value.length && this.${elseName} ) {
this.${elseName}.update( changed, ${params} );
} else if ( !${name}_value.length ) {
${elseName} = ${renderElse}( ${params}, component );
${elseName}.mount( ${anchor}.parentNode, ${anchor} );
} else if ( ${elseName} ) {
${elseName}.teardown( true );
this.${elseName} = new ${renderElse}( ${params}, this.component );
this.${elseName}.mount( this.${anchor}.parentNode, this.${anchor} );
} else if ( this.${elseName} ) {
this.${elseName}.teardown( true );
}
` );
}

generator.current.teardownStatements.push( deindent`
for ( var ${i} = 0; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[${i}].teardown( ${isToplevel ? 'detach' : 'false'} );
for ( var ${i} = 0; ${i} < this.${iterations}.length; ${i} += 1 ) {
this.${iterations}[${i}].teardown( ${isToplevel ? 'detach' : 'false'} );
}
` );

if ( node.else ) {
generator.current.teardownStatements.push( deindent`
if ( ${elseName} ) {
${elseName}.teardown( ${isToplevel ? 'detach' : 'false'} );
if ( this.${elseName} ) {
this.${elseName}.teardown( ${isToplevel ? 'detach' : 'false'} );
}
` );
}
Expand Down
16 changes: 8 additions & 8 deletions compiler/generate/visitors/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ export default {
}).join( ',\n' );

const updates = contextNames.map( contextName => {
if ( contextName === 'root' ) return `${name}.__svelte.root = root;`;
if ( contextName === 'root' ) return `this.${name}.__svelte.root = root;`;

const listName = generator.current.listNames[ contextName ];
const indexName = generator.current.indexNames[ contextName ];

return `${name}.__svelte.${listName} = ${listName};\n${name}.__svelte.${indexName} = ${indexName};`;
return `this.${name}.__svelte.${listName} = ${listName};\nthis.${name}.__svelte.${indexName} = ${indexName};`;
}).join( '\n' );

local.init.push( deindent`
${name}.__svelte = {
this.${name}.__svelte = {
${initialProps}
};
` );
Expand All @@ -60,23 +60,23 @@ export default {
}

let render = local.namespace ?
`var ${name} = document.createElementNS( '${local.namespace}', '${node.name}' );` :
`var ${name} = document.createElement( '${node.name}' );`;
`this.${name} = document.createElementNS( '${local.namespace}', '${node.name}' );` :
`this.${name} = document.createElement( '${node.name}' );`;

if ( generator.cssId && !generator.current.elementDepth ) {
render += `\n${name}.setAttribute( '${generator.cssId}', '' );`;
render += `\nthis.${name}.setAttribute( '${generator.cssId}', '' );`;
}

local.init.unshift( render );
if ( isToplevel ) {
local.detach.push( `${name}.parentNode.removeChild( ${name} );` );
local.detach.push( `this.${name}.parentNode.removeChild( this.${name} );` );
}

// special case – bound <option> without a value attribute
if ( node.name === 'option' && !node.attributes.find( attribute => attribute.type === 'Attribute' && attribute.name === 'value' ) ) { // TODO check it's bound
// const dynamic = node.children.length > 1 || node.children[0].type !== 'Text';
// TODO do this in init for static values... have to do it in `leave`, because they don't exist yet
local.update.push( `${name}.__value = ${name}.textContent` );
local.update.push( `this.${name}.__value = this.${name}.textContent` );
}

generator.current.initStatements.push( local.init.join( '\n' ) );
Expand Down
26 changes: 13 additions & 13 deletions compiler/generate/visitors/IfBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,42 +59,42 @@ export default {
const currentBlock = generator.getUniqueName( `currentBlock` );

const isToplevel = generator.current.localElementDepth === 0;
const conditionsAndBlocks = getConditionsAndBlocks( generator, node, generator.getUniqueName( `renderIfBlock` ) );
const conditionsAndBlocks = getConditionsAndBlocks( generator, node, generator.getUniqueName( `IfBlock` ) );

const anchor = generator.createAnchor( name, `#if ${generator.source.slice( node.expression.start, node.expression.end )}` );

generator.current.initStatements.push( deindent`
function ${getBlock} ( ${params} ) {
this.${getBlock} = function ( ${params} ) {
${conditionsAndBlocks.map( ({ condition, block }) => {
return `${condition ? `if ( ${condition} ) ` : ''}return ${block};`;
} ).join( '\n' )}
}
var ${currentBlock} = ${getBlock}( ${params} );
var ${name} = ${currentBlock} && ${currentBlock}( ${params}, component );
this.${currentBlock} = this.${getBlock}( ${params} );
this.${name} = this.${currentBlock} && new this.${currentBlock}( ${params}, component );
` );

const mountStatement = `if ( ${name} ) ${name}.mount( ${anchor}.parentNode, ${anchor} );`;
const mountStatement = `if ( this.${name} ) this.${name}.mount( this.${anchor}.parentNode, this.${anchor} );`;
if ( isToplevel ) {
generator.current.mountStatements.push( mountStatement );
} else {
generator.current.initStatements.push( mountStatement );
}

generator.current.updateStatements.push( deindent`
var _${currentBlock} = ${currentBlock};
${currentBlock} = ${getBlock}( ${params} );
if ( _${currentBlock} === ${currentBlock} && ${name}) {
${name}.update( changed, ${params} );
var _${currentBlock} = this.${currentBlock};
this.${currentBlock} = this.${getBlock}( ${params} );
if ( _${currentBlock} === this.${currentBlock} && this.${name}) {
this.${name}.update( changed, ${params} );
} else {
if ( ${name} ) ${name}.teardown( true );
${name} = ${currentBlock} && ${currentBlock}( ${params}, component );
if ( ${name} ) ${name}.mount( ${anchor}.parentNode, ${anchor} );
if ( this.${name} ) this.${name}.teardown( true );
this.${name} = this.${currentBlock} && new this.${currentBlock}( ${params}, this.component );
if ( this.${name} ) this.${name}.mount( this.${anchor}.parentNode, this.${anchor} );
}
` );

generator.current.teardownStatements.push( deindent`
if ( ${name} ) ${name}.teardown( ${isToplevel ? 'detach' : 'false'} );
if ( this.${name} ) this.${name}.teardown( ${isToplevel ? 'detach' : 'false'} );
` );
}
};
Loading

0 comments on commit 266e894

Please sign in to comment.