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 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 renderers = [];
@ -149,15 +149,13 @@ export default function generate ( parsed, source, options ) {
};
},
// TODO use getName instead of counters
counters: {
if: 0,
each: 0
},
events: {},
getName: counter(),
getUniqueName: counter( names ),
getUniqueNameMaker () {
return counter( names );
},
cssId: parsed.css ? `svelte-${parsed.hash}` : '',
@ -278,7 +276,7 @@ export default function generate ( parsed, source, options ) {
indexNames: {},
listNames: {},
counter: counter()
getUniqueName: generator.getUniqueNameMaker()
});
parsed.html.children.forEach( generator.visit );

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

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

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

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

@ -1,5 +1,4 @@
import deindent from '../utils/deindent.js';
import counter from '../utils/counter.js';
// collect all the conditions and blocks in the if/elseif/else chain
function generateBlock ( generator, node, name ) {
@ -16,7 +15,7 @@ function generateBlock ( generator, node, name ) {
detachStatements: [],
teardownStatements: [],
counter: counter()
getUniqueName: generator.getUniqueNameMaker()
});
node.children.forEach( generator.visit );
generator.addRenderer( generator.current );
@ -54,15 +53,13 @@ function getConditionsAndBlocks ( generator, node, _name, i = 0 ) {
export default {
enter ( generator, node ) {
const i = generator.counters.if++;
const { params } = generator.current;
const name = `ifBlock_${i}`;
const getBlock = `getBlock_${i}`;
const currentBlock = `currentBlock_${i}`;
const name = generator.getUniqueName( `ifBlock` );
const getBlock = generator.getUniqueName( `getBlock` );
const currentBlock = generator.getUniqueName( `currentBlock` );
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 )}` );

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

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

@ -1,6 +1,6 @@
export default {
enter ( generator, node ) {
const name = generator.current.counter( `text` );
const name = generator.current.getUniqueName( `text` );
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}]`;
});
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}✂];`;
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 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