deconflict names. fixes #88

pull/134/head
Rich Harris 8 years ago
parent 0e64f26712
commit 659eb32bc5

@ -9,7 +9,7 @@ import getOutro from './utils/getOutro.js';
import visitors from './visitors/index.js'; import visitors from './visitors/index.js';
import processCss from './css/process.js'; import processCss from './css/process.js';
export default function generate ( parsed, source, options ) { export default function generate ( parsed, source, options, names ) {
const format = options.format || 'es'; const format = options.format || 'es';
const renderers = []; const renderers = [];
@ -149,15 +149,13 @@ export default function generate ( parsed, source, options ) {
}; };
}, },
// TODO use getName instead of counters
counters: {
if: 0,
each: 0
},
events: {}, events: {},
getName: counter(), getUniqueName: counter( names ),
getUniqueNameMaker () {
return counter( names );
},
cssId: parsed.css ? `svelte-${parsed.hash}` : '', cssId: parsed.css ? `svelte-${parsed.hash}` : '',
@ -278,7 +276,7 @@ export default function generate ( parsed, source, options ) {
indexNames: {}, indexNames: {},
listNames: {}, listNames: {},
counter: counter() getUniqueName: generator.getUniqueNameMaker()
}); });
parsed.html.children.forEach( generator.visit ); parsed.html.children.forEach( generator.visit );

@ -1,12 +1,14 @@
export default function counter () { export default function counter ( used ) {
const counts = {}; const counts = {};
return function ( label ) { used.forEach( name => counts[ name ] = 1 );
if ( label in counts ) {
return `${label}${counts[ label ]++}`; return function ( name ) {
if ( name in counts ) {
return `${name}${counts[ name ]++}`;
} }
counts[ label ] = 1; counts[ name ] = 1;
return label; return name;
}; };
} }

@ -1,11 +1,10 @@
import deindent from '../utils/deindent.js'; import deindent from '../utils/deindent.js';
import addComponentAttributes from './attributes/addComponentAttributes.js'; import addComponentAttributes from './attributes/addComponentAttributes.js';
import counter from '../utils/counter.js';
export default { export default {
enter ( generator, node ) { enter ( generator, node ) {
const hasChildren = node.children.length > 0; const hasChildren = node.children.length > 0;
const name = generator.current.counter( `${node.name[0].toLowerCase()}${node.name.slice( 1 )}` ); const name = generator.current.getUniqueName( `${node.name[0].toLowerCase()}${node.name.slice( 1 )}` );
const local = { const local = {
name, name,
@ -33,12 +32,12 @@ export default {
]; ];
// Component has children // Component has children
if ( hasChildren ) { if ( hasChildren ) {
const yieldName = `render${name}YieldFragment`; const yieldName = generator.current.getUniqueName( `render${name}YieldFragment` );
// {{YIELD STUFF}} // {{YIELD STUFF}}
generator.push({ generator.push({
useAnchor: true, useAnchor: true,
name: generator.current.counter(yieldName), name: yieldName,
target: 'target', target: 'target',
localElementDepth: 0, localElementDepth: 0,
@ -48,7 +47,7 @@ export default {
detachStatements: [], detachStatements: [],
teardownStatements: [], teardownStatements: [],
counter: counter() getUniqueName: generator.getUniqueNameMaker()
}); });
node.children.forEach( generator.visit ); node.children.forEach( generator.visit );

@ -1,14 +1,13 @@
import deindent from '../utils/deindent.js'; import deindent from '../utils/deindent.js';
import counter from '../utils/counter.js';
export default { export default {
enter ( generator, node ) { enter ( generator, node ) {
const i = generator.counters.each++; const name = generator.getUniqueName( `eachBlock` );
const name = `eachBlock_${i}`; const renderer = generator.getUniqueName( `renderEachBlock` );
const elseName = `${name}_else`; const elseName = `${name}_else`;
const iterations = `${name}_iterations`; const iterations = `${name}_iterations`;
const renderer = `renderEachBlock_${i}`;
const renderElse = `${renderer}_else`; const renderElse = `${renderer}_else`;
const i = generator.current.getUniqueName( `i` );
const { params } = generator.current; const { params } = generator.current;
const listName = `${name}_value`; const listName = `${name}_value`;
@ -26,9 +25,9 @@ export default {
var ${iterations} = []; var ${iterations} = [];
${node.else ? `var ${elseName} = null;` : ''} ${node.else ? `var ${elseName} = null;` : ''}
for ( var i = 0; i < ${name}_value.length; i += 1 ) { for ( var ${i} = 0; ${i} < ${name}_value.length; ${i} += 1 ) {
${iterations}[i] = ${renderer}( ${params}, ${listName}, ${listName}[i], i, component ); ${iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, component );
${!isToplevel ? `${iterations}[i].mount( ${anchor}.parentNode, ${anchor} );` : ''} ${!isToplevel ? `${iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );` : ''}
} }
` ); ` );
if ( node.else ) { if ( node.else ) {
@ -42,8 +41,8 @@ export default {
if ( isToplevel ) { if ( isToplevel ) {
generator.current.mountStatements.push( deindent` generator.current.mountStatements.push( deindent`
for ( var i = 0; i < ${iterations}.length; i += 1 ) { for ( var ${i} = 0; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[i].mount( ${anchor}.parentNode, ${anchor} ); ${iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );
} }
` ); ` );
if ( node.else ) { if ( node.else ) {
@ -58,21 +57,22 @@ export default {
generator.current.updateStatements.push( deindent` generator.current.updateStatements.push( deindent`
var ${name}_value = ${snippet}; var ${name}_value = ${snippet};
for ( var i = 0; i < ${name}_value.length; i += 1 ) { for ( var ${i} = 0; ${i} < ${name}_value.length; ${i} += 1 ) {
if ( !${iterations}[i] ) { if ( !${iterations}[${i}] ) {
${iterations}[i] = ${renderer}( ${params}, ${listName}, ${listName}[i], i, component ); ${iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, component );
${iterations}[i].mount( ${anchor}.parentNode, ${anchor} ); ${iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );
} else { } else {
${iterations}[i].update( changed, ${params}, ${listName}, ${listName}[i], i ); ${iterations}[${i}].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} );
} }
} }
for ( var i = ${name}_value.length; i < ${iterations}.length; i += 1 ) { for ( var ${i} = ${name}_value.length; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[i].teardown( true ); ${iterations}[${i}].teardown( true );
} }
${iterations}.length = ${listName}.length; ${iterations}.length = ${listName}.length;
` ); ` );
if ( node.else ) { if ( node.else ) {
generator.current.updateStatements.push( deindent` generator.current.updateStatements.push( deindent`
if ( !${name}_value.length && ${elseName} ) { if ( !${name}_value.length && ${elseName} ) {
@ -87,10 +87,11 @@ export default {
} }
generator.current.teardownStatements.push( deindent` generator.current.teardownStatements.push( deindent`
for ( var i = 0; i < ${iterations}.length; i += 1 ) { for ( var ${i} = 0; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[i].teardown( ${isToplevel ? 'detach' : 'false'} ); ${iterations}[${i}].teardown( ${isToplevel ? 'detach' : 'false'} );
} }
` ); ` );
if ( node.else ) { if ( node.else ) {
generator.current.teardownStatements.push( deindent` generator.current.teardownStatements.push( deindent`
if ( ${elseName} ) { if ( ${elseName} ) {
@ -112,7 +113,7 @@ export default {
detachStatements: [], detachStatements: [],
teardownStatements: [], teardownStatements: [],
counter: counter() getUniqueName: generator.getUniqueNameMaker()
}); });
node.else.children.forEach( generator.visit ); node.else.children.forEach( generator.visit );
generator.addRenderer( generator.current ); generator.addRenderer( generator.current );
@ -163,9 +164,7 @@ export default {
detachStatements: [], detachStatements: [],
teardownStatements: [], teardownStatements: [],
counter: counter(), getUniqueName: generator.getUniqueNameMaker()
parent: generator.current
}); });
}, },

@ -9,7 +9,7 @@ export default {
return Component.enter( generator, node ); return Component.enter( generator, node );
} }
const name = generator.current.counter( node.name ); const name = generator.current.getUniqueName( node.name );
const local = { const local = {
name, name,

@ -1,5 +1,4 @@
import deindent from '../utils/deindent.js'; import deindent from '../utils/deindent.js';
import counter from '../utils/counter.js';
// collect all the conditions and blocks in the if/elseif/else chain // collect all the conditions and blocks in the if/elseif/else chain
function generateBlock ( generator, node, name ) { function generateBlock ( generator, node, name ) {
@ -16,7 +15,7 @@ function generateBlock ( generator, node, name ) {
detachStatements: [], detachStatements: [],
teardownStatements: [], teardownStatements: [],
counter: counter() getUniqueName: generator.getUniqueNameMaker()
}); });
node.children.forEach( generator.visit ); node.children.forEach( generator.visit );
generator.addRenderer( generator.current ); generator.addRenderer( generator.current );
@ -54,15 +53,13 @@ function getConditionsAndBlocks ( generator, node, _name, i = 0 ) {
export default { export default {
enter ( generator, node ) { enter ( generator, node ) {
const i = generator.counters.if++;
const { params } = generator.current; const { params } = generator.current;
const name = `ifBlock_${i}`; const name = generator.getUniqueName( `ifBlock` );
const getBlock = `getBlock_${i}`; const getBlock = generator.getUniqueName( `getBlock` );
const currentBlock = `currentBlock_${i}`; const currentBlock = generator.getUniqueName( `currentBlock` );
const isToplevel = generator.current.localElementDepth === 0; const isToplevel = generator.current.localElementDepth === 0;
const conditionsAndBlocks = getConditionsAndBlocks( generator, node, `renderIfBlock_${i}` ); const conditionsAndBlocks = getConditionsAndBlocks( generator, node, generator.getUniqueName( `renderIfBlock` ) );
const anchor = generator.createAnchor( name, `#if ${generator.source.slice( node.expression.start, node.expression.end )}` ); const anchor = generator.createAnchor( name, `#if ${generator.source.slice( node.expression.start, node.expression.end )}` );

@ -2,7 +2,7 @@ import deindent from '../utils/deindent.js';
export default { export default {
enter ( generator, node ) { enter ( generator, node ) {
const name = generator.current.counter( 'text' ); const name = generator.current.getUniqueName( 'text' );
generator.addSourcemapLocations( node.expression ); generator.addSourcemapLocations( node.expression );
const { snippet } = generator.contextualise( node.expression ); const { snippet } = generator.contextualise( node.expression );

@ -2,7 +2,7 @@ import deindent from '../utils/deindent.js';
export default { export default {
enter ( generator, node ) { enter ( generator, node ) {
const name = generator.current.counter( 'raw' ); const name = generator.current.getUniqueName( 'raw' );
generator.addSourcemapLocations( node.expression ); generator.addSourcemapLocations( node.expression );
const { snippet } = generator.contextualise( node.expression ); const { snippet } = generator.contextualise( node.expression );
@ -25,7 +25,7 @@ export default {
} }
`; `;
if ( isToplevel ) { if ( isToplevel ) {
generator.current.mountStatements.push(mountStatement); generator.current.mountStatements.push(mountStatement);
} else { } else {
generator.current.initStatements.push(mountStatement); generator.current.initStatements.push(mountStatement);

@ -1,6 +1,6 @@
export default { export default {
enter ( generator, node ) { enter ( generator, node ) {
const name = generator.current.counter( `text` ); const name = generator.current.getUniqueName( `text` );
generator.addElement( name, `document.createTextNode( ${JSON.stringify( node.data )} )` ); generator.addElement( name, `document.createTextNode( ${JSON.stringify( node.data )} )` );
} }
}; };

@ -138,7 +138,7 @@ export default function addElementAttributes ( generator, node, local ) {
return `var ${listName} = this.__svelte.${listName}, ${indexName} = this.__svelte.${indexName}, ${name} = ${listName}[${indexName}]`; return `var ${listName} = this.__svelte.${listName}, ${indexName} = this.__svelte.${indexName}, ${name} = ${listName}[${indexName}]`;
}); });
const handlerName = generator.current.counter( `${attribute.name}Handler` ); const handlerName = generator.current.getUniqueName( `${attribute.name}Handler` );
const handlerBody = ( declarations.length ? declarations.join( '\n' ) + '\n\n' : '' ) + `[✂${attribute.expression.start}-${attribute.expression.end}✂];`; const handlerBody = ( declarations.length ? declarations.join( '\n' ) + '\n\n' : '' ) + `[✂${attribute.expression.start}-${attribute.expression.end}✂];`;
if ( attribute.name in generator.events ) { if ( attribute.name in generator.events ) {

@ -17,7 +17,7 @@ export default function createBinding ( generator, node, attribute, current, loc
}); });
} }
const handler = current.counter( `${local.name}ChangeHandler` ); const handler = current.getUniqueName( `${local.name}ChangeHandler` );
let setter; let setter;
let eventName = 'change'; let eventName = 'change';

@ -0,0 +1 @@
<p>{{index + 1}}: {{widget.name}}</p>

@ -0,0 +1,14 @@
export default {
html: `<p>1: foo</p><p>2: bar</p><p>3: baz</p>`,
test ( assert, component, target ) {
component.set({
widgets: [
{ name: 'bish' },
{ name: 'bosh' }
]
});
assert.htmlEqual( target.innerHTML, `<p>1: bish</p><p>2: bosh</p>` );
}
};

@ -0,0 +1,21 @@
{{#each widgets as widget, i}}
<Widget widget='{{widget}}' index='{{i}}'/>
{{/each}}
<script>
import Widget from './Widget.html';
export default {
data () {
return {
widgets: [
{ name: 'foo' },
{ name: 'bar' },
{ name: 'baz' }
]
};
},
components: { Widget }
};
</script>
Loading…
Cancel
Save