move some code into generator.init

pull/204/head
Rich-Harris 9 years ago
parent 865a184adc
commit 7493b6c49b

@ -14,14 +14,21 @@ export default class Generator {
this.names = names;
this.visitors = visitors;
this.renderers = [];
this.code = new MagicString( source );
this.imports = [];
this.templateProperties = {};
this.helpers = {};
this.components = {};
this.events = {};
this.helpers = {};
this.renderers = [];
this.code = new MagicString( source );
this.getUniqueName = counter( names );
this.cssId = parsed.css ? `svelte-${parsed.hash}` : '';
this.usesRefs = false;
this._callbacks = {};
this.init();
}
addElement ( name, renderStatement, needsIdentifier = false ) {
@ -165,6 +172,15 @@ export default class Generator {
}
}
fire ( eventName, data ) {
const handlers = eventName in this._callbacks && this._callbacks[ eventName ].slice();
if ( !handlers ) return;
for ( let i = 0; i < handlers.length; i += 1 ) {
handlers[i].call( this, data );
}
}
generateBlock ( node, name ) {
this.push({
name,
@ -196,6 +212,71 @@ export default class Generator {
return counter( this.names );
}
init () {
const { imports, source } = this;
const { js } = this.parsed;
if ( js ) {
this.addSourcemapLocations( js.content );
// imports need to be hoisted out of the IIFE
for ( let i = 0; i < js.content.body.length; i += 1 ) {
const node = js.content.body[i];
if ( node.type === 'ImportDeclaration' ) {
let a = node.start;
let b = node.end;
while ( /[ \t]/.test( source[ a - 1 ] ) ) a -= 1;
while ( source[b] === '\n' ) b += 1;
//imports.push( source.slice( a, b ).replace( /^\s/, '' ) );
imports.push( node );
this.code.remove( a, b );
}
}
const defaultExport = js.content.body.find( node => node.type === 'ExportDefaultDeclaration' );
if ( defaultExport ) {
const finalNode = js.content.body[ js.content.body.length - 1 ];
if ( defaultExport === finalNode ) {
// export is last property, we can just return it
this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `return ` );
} else {
// TODO ensure `template` isn't already declared
this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `var template = ` );
let i = defaultExport.start;
while ( /\s/.test( source[ i - 1 ] ) ) i--;
const indentation = source.slice( i, defaultExport.start );
this.code.appendLeft( finalNode.end, `\n\n${indentation}return template;` );
}
defaultExport.declaration.properties.forEach( prop => {
this.templateProperties[ prop.key.name ] = prop.value;
});
this.code.prependRight( js.content.start, 'var template = (function () {' );
} else {
this.code.prependRight( js.content.start, '(function () {' );
}
this.code.appendLeft( js.content.end, '}());' );
[ 'helpers', 'events', 'components' ].forEach( key => {
if ( this.templateProperties[ key ] ) {
this.templateProperties[ key ].properties.forEach( prop => {
this[ key ][ prop.key.name ] = prop.value;
});
}
});
}
}
on ( eventName, handler ) {
const handlers = this._callbacks[ eventName ] || ( this._callbacks[ eventName ] = [] );
handlers.push( handler );
}
pop () {
const tail = this.current;
this.current = tail.parent;

@ -13,64 +13,7 @@ export default function dom ( parsed, source, options, names ) {
const generator = new Generator( parsed, source, names, visitors );
const templateProperties = {};
const imports = [];
if ( parsed.js ) {
generator.addSourcemapLocations( parsed.js.content );
// imports need to be hoisted out of the IIFE
for ( let i = 0; i < parsed.js.content.body.length; i += 1 ) {
const node = parsed.js.content.body[i];
if ( node.type === 'ImportDeclaration' ) {
let a = node.start;
let b = node.end;
while ( /[ \t]/.test( source[ a - 1 ] ) ) a -= 1;
while ( source[b] === '\n' ) b += 1;
//imports.push( source.slice( a, b ).replace( /^\s/, '' ) );
imports.push( node );
generator.code.remove( a, b );
}
}
const defaultExport = parsed.js.content.body.find( node => node.type === 'ExportDefaultDeclaration' );
if ( defaultExport ) {
const finalNode = parsed.js.content.body[ parsed.js.content.body.length - 1 ];
if ( defaultExport === finalNode ) {
// export is last property, we can just return it
generator.code.overwrite( defaultExport.start, defaultExport.declaration.start, `return ` );
} else {
// TODO ensure `template` isn't already declared
generator.code.overwrite( defaultExport.start, defaultExport.declaration.start, `var template = ` );
let i = defaultExport.start;
while ( /\s/.test( source[ i - 1 ] ) ) i--;
const indentation = source.slice( i, defaultExport.start );
generator.code.appendLeft( finalNode.end, `\n\n${indentation}return template;` );
}
defaultExport.declaration.properties.forEach( prop => {
templateProperties[ prop.key.name ] = prop.value;
});
generator.code.prependRight( parsed.js.content.start, 'var template = (function () {' );
} else {
generator.code.prependRight( parsed.js.content.start, '(function () {' );
}
generator.code.appendLeft( parsed.js.content.end, '}());' );
[ 'helpers', 'events', 'components' ].forEach( key => {
if ( templateProperties[ key ] ) {
templateProperties[ key ].properties.forEach( prop => {
generator[ key ][ prop.key.name ] = prop.value;
});
}
});
}
const { templateProperties, imports } = generator;
let namespace = null;
if ( templateProperties.namespace ) {

Loading…
Cancel
Save