pull/573/head
Rich-Harris 8 years ago
parent dc82db609c
commit 4486b93d88

@ -176,7 +176,7 @@ export default class Generator {
};
}
findDependencies ( contextDependencies, indexes, expression ) {
findDependencies ( contextDependencies: Map<string, string[]>, indexes: Map<string, string>, expression: Node ) {
if ( expression._dependencies ) return expression._dependencies;
let scope = annotateWithScopes( expression );
@ -340,23 +340,23 @@ export default class Generator {
removeNode( this.code, js.content, node );
imports.push( node );
node.specifiers.forEach( specifier => {
node.specifiers.forEach( ( specifier: Node ) => {
this.importedNames.add( specifier.local.name );
});
}
}
const defaultExport = body.find( node => node.type === 'ExportDefaultDeclaration' );
const defaultExport = body.find( ( node: Node ) => node.type === 'ExportDefaultDeclaration' );
if ( defaultExport ) {
defaultExport.declaration.properties.forEach( prop => {
defaultExport.declaration.properties.forEach( ( prop: Node ) => {
templateProperties[ prop.key.name ] = prop;
});
}
[ 'helpers', 'events', 'components', 'transitions' ].forEach( key => {
if ( templateProperties[ key ] ) {
templateProperties[ key ].value.properties.forEach( prop => {
templateProperties[ key ].value.properties.forEach( ( prop: node ) => {
this[ key ].add( prop.key.name );
});
}
@ -365,11 +365,11 @@ export default class Generator {
if ( templateProperties.computed ) {
const dependencies = new Map();
templateProperties.computed.value.properties.forEach( prop => {
templateProperties.computed.value.properties.forEach( ( prop: Node ) => {
const key = prop.key.name;
const value = prop.value;
const deps = value.params.map( param => param.type === 'AssignmentPattern' ? param.left.name : param.name );
const deps = value.params.map( ( param: Node ) => param.type === 'AssignmentPattern' ? param.left.name : param.name );
dependencies.set( key, deps );
});
@ -387,7 +387,7 @@ export default class Generator {
computations.push({ key, deps });
}
templateProperties.computed.value.properties.forEach( prop => visit( prop.key.name ) );
templateProperties.computed.value.properties.forEach( ( prop: Node ) => visit( prop.key.name ) );
}
if ( templateProperties.namespace ) {
@ -399,7 +399,7 @@ export default class Generator {
if ( templateProperties.components ) {
let hasNonImportedComponent = false;
templateProperties.components.value.properties.forEach( property => {
templateProperties.components.value.properties.forEach( ( property: Node ) => {
const key = property.key.name;
const value = source.slice( property.value.start, property.value.end );
if ( this.importedNames.has( value ) ) {

@ -4,11 +4,20 @@ import { DomGenerator } from './index';
import { Node } from '../../interfaces';
export interface BlockOptions {
generator: DomGenerator;
name: string;
expression: Node;
context: string;
key: string;
generator?: DomGenerator;
expression?: Node;
context?: string;
key?: string;
contexts?: Map<string, string>;
indexes?: Map<string, string>;
contextDependencies?: Map<string, string[]>;
params?: string[];
indexNames?: Map<string, string>;
listNames?: Map<string, string>;
indexName?: string;
listName?: string;
dependencies?: Set<string>;
}
export default class Block {
@ -16,7 +25,19 @@ export default class Block {
name: string;
expression: Node;
context: string;
key: string;
first: string;
contexts: Map<string, string>;
indexes: Map<string, string>;
contextDependencies: Map<string, string[]>;
dependencies: Set<string>;
params: string[];
indexNames: Map<string, string>;
listNames: Map<string, string>;
indexName: string;
listName: string;
builders: {
create: CodeBuilder;
@ -41,6 +62,7 @@ export default class Block {
target: string;
hasUpdateMethod: boolean;
autofocus: string;
constructor ( options: BlockOptions ) {
this.generator = options.generator;
@ -95,7 +117,7 @@ export default class Block {
});
}
addElement ( name: string, renderStatement: string, parentNode, needsIdentifier = false ) {
addElement ( name: string, renderStatement: string, parentNode: string, needsIdentifier = false ) {
const isToplevel = !parentNode;
if ( needsIdentifier || isToplevel ) {
this.builders.create.addLine(

@ -18,6 +18,10 @@ export class DomGenerator extends Generator {
readonly: Set<string>;
metaBindings: string[];
hasIntroTransitions: boolean;
hasOutroTransitions: boolean;
hasComplexBindings: boolean;
constructor ( parsed: Parsed, source: string, name: string, options: CompileOptions ) {
super( parsed, source, name, options );
this.blocks = [];
@ -48,13 +52,7 @@ export default function dom ( parsed: Parsed, source: string, options: CompileOp
const { computations, hasJs, templateProperties, namespace } = generator.parseJs();
const state = {
namespace,
parentNode: null,
isTopLevel: true
};
const block = preprocess( generator, state, parsed.html );
const { block, state } = preprocess( generator, namespace, parsed.html );
parsed.html.children.forEach( ( node: Node ) => {
visit( generator, block, state, node );

@ -0,0 +1,10 @@
export interface State {
namespace: string;
parentNode: string;
isTopLevel: boolean
parentNodeName?: string;
basename?: string;
inEachBlock?: boolean;
allUsedContexts?: string[];
usesComponent?: boolean;
}

@ -3,12 +3,13 @@ import { trimStart, trimEnd } from '../../utils/trim';
import { assign } from '../../shared/index.js';
import { DomGenerator } from './index';
import { Node } from '../../interfaces';
import { State } from './interfaces';
function isElseIf ( node: Node ) {
return node && node.children.length === 1 && node.children[0].type === 'IfBlock';
}
function getChildState ( parent, child = {} ) {
function getChildState ( parent: State, child = {} ) {
return assign( {}, parent, { name: null, parentNode: null }, child || {} );
}
@ -27,7 +28,7 @@ const elementsWithoutText = new Set([
]);
const preprocessors = {
MustacheTag: ( generator: DomGenerator, block, state, node: Node ) => {
MustacheTag: ( generator: DomGenerator, block: Block, state: State, node: Node ) => {
const dependencies = block.findDependencies( node.expression );
block.addDependencies( dependencies );
@ -36,7 +37,7 @@ const preprocessors = {
});
},
RawMustacheTag: ( generator: DomGenerator, block, state, node: Node ) => {
RawMustacheTag: ( generator: DomGenerator, block: Block, state: State, node: Node ) => {
const dependencies = block.findDependencies( node.expression );
block.addDependencies( dependencies );
@ -46,7 +47,7 @@ const preprocessors = {
node._state = getChildState( state, { basename, name });
},
Text: ( generator: DomGenerator, block, state, node: Node ) => {
Text: ( generator: DomGenerator, block: Block, state: State, node: Node ) => {
node._state = getChildState( state );
if ( !/\S/.test( node.data ) ) {
@ -58,8 +59,8 @@ const preprocessors = {
node._state.name = block.getUniqueName( `text` );
},
IfBlock: ( generator: DomGenerator, block, state, node: Node ) => {
const blocks = [];
IfBlock: ( generator: DomGenerator, block: Block, state: State, node: Node ) => {
const blocks: Block[] = [];
let dynamic = false;
let hasIntros = false;
let hasOutros = false;
@ -115,7 +116,7 @@ const preprocessors = {
generator.blocks.push( ...blocks );
},
EachBlock: ( generator: DomGenerator, block, state, node: Node ) => {
EachBlock: ( generator: DomGenerator, block: Block, state: State, node: Node ) => {
const dependencies = block.findDependencies( node.expression );
block.addDependencies( dependencies );
@ -177,7 +178,7 @@ const preprocessors = {
}
},
Element: ( generator: DomGenerator, block, state, node: Node ) => {
Element: ( generator: DomGenerator, block: Block, state: State, node: Node ) => {
const isComponent = generator.components.has( node.name ) || node.name === ':Self';
if ( isComponent ) {
@ -240,7 +241,7 @@ const preprocessors = {
}
};
function preprocessChildren ( generator: DomGenerator, block, state, node: Node, isTopLevel: boolean ) {
function preprocessChildren ( generator: DomGenerator, block: Block, state: State, node: Node, isTopLevel: boolean = false ) {
// glue text nodes together
const cleaned: Node[] = [];
let lastChild: Node;
@ -294,7 +295,7 @@ function preprocessChildren ( generator: DomGenerator, block, state, node: Node,
node.children = cleaned;
}
export default function preprocess ( generator: DomGenerator, state, node ) {
export default function preprocess ( generator: DomGenerator, namespace: string, node: Node ) {
const block = new Block({
generator,
name: generator.alias( 'create_main_fragment' ),
@ -311,9 +312,15 @@ export default function preprocess ( generator: DomGenerator, state, node ) {
dependencies: new Set()
});
const state: State = {
namespace,
parentNode: null,
isTopLevel: true
};
generator.blocks.push( block );
preprocessChildren( generator, block, state, node, true );
block.hasUpdateMethod = block.dependencies.size > 0;
return block;
return { block, state };
}

@ -1,8 +1,9 @@
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function visitAttribute ( generator: DomGenerator, block: Block, state, node: Node, attribute, local ) {
export default function visitAttribute ( generator: DomGenerator, block: Block, state: State, node: Node, attribute, local ) {
if ( attribute.value === true ) {
// attributes without values, e.g. <textarea readonly>
local.staticAttributes.push({

@ -4,8 +4,9 @@ import getSetter from '../shared/binding/getSetter';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function visitBinding ( generator: DomGenerator, block: Block, state, node: Node, attribute, local ) {
export default function visitBinding ( generator: DomGenerator, block: Block, state: State, node: Node, attribute, local ) {
const { name } = flattenReference( attribute.value );
const { snippet, contexts, dependencies } = block.contextualise( attribute.value );

@ -8,8 +8,9 @@ import visitRef from './Ref';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
function stringifyProps ( props ) {
function stringifyProps ( props: string[] ) {
if ( !props.length ) return '{}';
const joined = props.join( ', ' );
@ -35,7 +36,7 @@ const visitors = {
Ref: visitRef
};
export default function visitComponent ( generator: DomGenerator, block: Block, state, node: Node ) {
export default function visitComponent ( generator: DomGenerator, block: Block, state: State, node: Node ) {
const hasChildren = node.children.length > 0;
const name = block.getUniqueName( ( node.name === ':Self' ? generator.name : node.name ).toLowerCase() );
@ -123,7 +124,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
componentInitProperties.push( `_yield: ${yieldFragment}`);
}
const statements = [];
const statements: string[] = [];
if ( local.staticAttributes.length || local.dynamicAttributes.length || local.bindings.length ) {
const initialProps = local.staticAttributes

@ -2,14 +2,15 @@ import deindent from '../../../../utils/deindent.js';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function visitEventHandler ( generator: DomGenerator, block: Block, state, node: Node, attribute, local ) {
export default function visitEventHandler ( generator: DomGenerator, block: Block, state: State, node: Node, attribute: Node, local ) {
// TODO verify that it's a valid callee (i.e. built-in or declared method)
generator.addSourcemapLocations( attribute.expression );
generator.code.prependRight( attribute.expression.start, `${block.component}.` );
const usedContexts = [];
attribute.expression.arguments.forEach( arg => {
const usedContexts: string[] = [];
attribute.expression.arguments.forEach( ( arg: Node ) => {
const { contexts } = block.contextualise( arg, null, true );
contexts.forEach( context => {

@ -2,8 +2,9 @@ import deindent from '../../../../utils/deindent.js';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function visitRef ( generator: DomGenerator, block: Block, state, node: Node, attribute, local ) {
export default function visitRef ( generator: DomGenerator, block: Block, state: State, node: Node, attribute: Node, local ) {
generator.usesRefs = true;
local.create.addLine(

@ -3,8 +3,9 @@ import visit from '../visit';
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
import { State } from '../interfaces';
export default function visitEachBlock ( generator: DomGenerator, block: Block, state, node: Node ) {
export default function visitEachBlock ( generator: DomGenerator, block: Block, state: State, node: Node ) {
const each_block = generator.getUniqueName( `each_block` );
const create_each_block = node._block.name;
const each_block_value = node._block.listName;
@ -100,7 +101,7 @@ export default function visitEachBlock ( generator: DomGenerator, block: Block,
}
}
function keyed ( generator: DomGenerator, block: Block, state, node: Node, snippet, { each_block, create_each_block, each_block_value, i, params, anchor, mountOrIntro } ) {
function keyed ( generator: DomGenerator, block: Block, state: State, node: Node, snippet, { each_block, create_each_block, each_block_value, i, params, anchor, mountOrIntro } ) {
const key = block.getUniqueName( 'key' );
const lookup = block.getUniqueName( `${each_block}_lookup` );
const iteration = block.getUniqueName( `${each_block}_iteration` );
@ -274,7 +275,7 @@ function keyed ( generator: DomGenerator, block: Block, state, node: Node, snipp
` );
}
function unkeyed ( generator: DomGenerator, block: Block, state, node: Node, snippet, { create_each_block, each_block_value, iterations, i, params, anchor, mountOrIntro } ) {
function unkeyed ( generator: DomGenerator, block: Block, state: State, node: Node, snippet, { create_each_block, each_block_value, iterations, i, params, anchor, mountOrIntro } ) {
block.builders.create.addBlock( deindent`
var ${iterations} = [];

@ -4,8 +4,9 @@ import getStaticAttributeValue from './getStaticAttributeValue';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function visitAttribute ( generator: DomGenerator, block: Block, state, node: Node, attribute ) {
export default function visitAttribute ( generator: DomGenerator, block: Block, state: State, node: Node, attribute: Node ) {
const name = attribute.name;
let metadata = state.namespace ? null : attributeLookup[ name ];
@ -35,7 +36,7 @@ export default function visitAttribute ( generator: DomGenerator, block: Block,
} else {
// '{{foo}} {{bar}}' — treat as string concatenation
value = ( attribute.value[0].type === 'Text' ? '' : `"" + ` ) + (
attribute.value.map( chunk => {
attribute.value.map( ( chunk: Node ) => {
if ( chunk.type === 'Text' ) {
return JSON.stringify( chunk.data );
} else {

@ -5,8 +5,9 @@ import getStaticAttributeValue from './getStaticAttributeValue';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function visitBinding ( generator: DomGenerator, block: Block, state, node: Node, attribute ) {
export default function visitBinding ( generator: DomGenerator, block: Block, state: State, node: Node, attribute: Node ) {
const { name, parts } = flattenReference( attribute.value );
const { snippet, contexts, dependencies } = block.contextualise( attribute.value );
@ -18,7 +19,7 @@ export default function visitBinding ( generator: DomGenerator, block: Block, st
const eventName = getBindingEventName( node, attribute );
const handler = block.getUniqueName( `${state.parentNode}_${eventName}_handler` );
const isMultipleSelect = node.name === 'select' && node.attributes.find( attr => attr.name.toLowerCase() === 'multiple' ); // TODO use getStaticAttributeValue
const isMultipleSelect = node.name === 'select' && node.attributes.find( ( attr: Node ) => attr.name.toLowerCase() === 'multiple' ); // TODO use getStaticAttributeValue
const type = getStaticAttributeValue( node, 'type' );
const bindingGroup = attribute.name === 'group' ? getBindingGroup( generator, parts.join( '.' ) ) : null;
const value = getBindingValue( generator, block, state, node, attribute, isMultipleSelect, bindingGroup, type );
@ -144,9 +145,9 @@ export default function visitBinding ( generator: DomGenerator, block: Block, st
}
}
function getBindingEventName ( node, attribute ) {
function getBindingEventName ( node: Node, attribute: Node ) {
if ( node.name === 'input' ) {
const typeAttribute = node.attributes.find( attr => attr.type === 'Attribute' && attr.name === 'type' );
const typeAttribute = node.attributes.find( ( attr: Node ) => attr.type === 'Attribute' && attr.name === 'type' );
const type = typeAttribute ? typeAttribute.value[0].data : 'text'; // TODO in validation, should throw if type attribute is not static
return type === 'checkbox' || type === 'radio' ? 'change' : 'input';
@ -160,7 +161,7 @@ function getBindingEventName ( node, attribute ) {
return 'change';
}
function getBindingValue ( generator, block, state, node, attribute, isMultipleSelect, bindingGroup, type ) {
function getBindingValue ( generator: DomGenerator, block: Block, state: State, node: Node, attribute: Node, isMultipleSelect: boolean, bindingGroup: number, type: string ) {
// <select multiple bind:value='selected>
if ( isMultipleSelect ) {
return `[].map.call( ${state.parentNode}.querySelectorAll(':checked'), function ( option ) { return option.__value; })`;
@ -189,7 +190,7 @@ function getBindingValue ( generator, block, state, node, attribute, isMultipleS
return `${state.parentNode}.${attribute.name}`;
}
function getBindingGroup ( generator, keypath ) {
function getBindingGroup ( generator: DomGenerator, keypath: string ) {
// TODO handle contextual bindings — `keypath` should include unique ID of
// each block that provides context
let index = generator.bindingGroups.indexOf( keypath );

@ -10,6 +10,7 @@ import addTransitions from './addTransitions';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
const meta = {
':Window': visitWindow
@ -29,7 +30,7 @@ const visitors = {
Ref: visitRef
};
export default function visitElement ( generator: DomGenerator, block: Block, state, node: Node ) {
export default function visitElement ( generator: DomGenerator, block: Block, state: State, node: Node ) {
if ( node.name in meta ) {
return meta[ node.name ]( generator, block, node );
}
@ -54,8 +55,8 @@ export default function visitElement ( generator: DomGenerator, block: Block, st
let outro;
node.attributes
.sort( ( a, b ) => order[ a.type ] - order[ b.type ] )
.forEach( attribute => {
.sort( ( a: Node, b: Node ) => order[ a.type ] - order[ b.type ] )
.forEach( ( attribute: Node ) => {
if ( attribute.type === 'Transition' ) {
if ( attribute.intro ) intro = attribute;
if ( attribute.outro ) outro = attribute;
@ -68,14 +69,14 @@ export default function visitElement ( generator: DomGenerator, block: Block, st
if ( intro || outro ) addTransitions( generator, block, childState, node, intro, outro );
if ( childState.allUsedContexts.length || childState.usesComponent ) {
const initialProps = [];
const updates = [];
const initialProps: string[] = [];
const updates: string[] = [];
if ( childState.usesComponent ) {
initialProps.push( `component: ${block.component}` );
}
childState.allUsedContexts.forEach( contextName => {
childState.allUsedContexts.forEach( ( contextName: string ) => {
if ( contextName === 'state' ) return;
const listName = block.listNames.get( contextName );
@ -112,12 +113,12 @@ export default function visitElement ( generator: DomGenerator, block: Block, st
}
// 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
if ( node.name === 'option' && !node.attributes.find( ( attribute: Node ) => attribute.type === 'Attribute' && attribute.name === 'value' ) ) { // TODO check it's bound
const statement = `${name}.__value = ${name}.textContent;`;
node.initialUpdate = node.lateUpdate = statement;
}
node.children.forEach( child => {
node.children.forEach( ( child: Node ) => {
visit( generator, block, childState, child );
});
@ -134,7 +135,7 @@ export default function visitElement ( generator: DomGenerator, block: Block, st
}
}
function getRenderStatement ( generator: DomGenerator, namespace, name ) {
function getRenderStatement ( generator: DomGenerator, namespace: string, name: string ) {
if ( namespace === 'http://www.w3.org/2000/svg' ) {
return `${generator.helper( 'createSvgElement' )}( '${name}' )`;
}

@ -3,8 +3,9 @@ import flattenReference from '../../../../utils/flattenReference';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function visitEventHandler ( generator: DomGenerator, block: Block, state, node: Node, attribute ) {
export default function visitEventHandler ( generator: DomGenerator, block: Block, state: State, node: Node, attribute: Node ) {
const name = attribute.name;
const isCustomEvent = generator.events.has( name );
const shouldHoist = !isCustomEvent && state.inEachBlock;
@ -20,8 +21,8 @@ export default function visitEventHandler ( generator: DomGenerator, block: Bloc
}
const context = shouldHoist ? null : state.parentNode;
const usedContexts = [];
attribute.expression.arguments.forEach( arg => {
const usedContexts: string[] = [];
attribute.expression.arguments.forEach( ( arg: Node ) => {
const { contexts } = block.contextualise( arg, context, true );
contexts.forEach( context => {

@ -2,8 +2,9 @@ import deindent from '../../../../utils/deindent.js';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function visitRef ( generator: DomGenerator, block: Block, state, node: Node, attribute ) {
export default function visitRef ( generator: DomGenerator, block: Block, state: State, node: Node, attribute: Node ) {
const name = attribute.name;
block.builders.create.addLine(

@ -2,8 +2,9 @@ import deindent from '../../../../utils/deindent.js';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
import { State } from '../../interfaces';
export default function addTransitions ( generator: DomGenerator, block: Block, state, node: Node, intro, outro ) {
export default function addTransitions ( generator: DomGenerator, block: Block, state: State, node: Node, intro, outro ) {
const wrapTransition = generator.helper( 'wrapTransition' );
if ( intro === outro ) {

@ -3,6 +3,7 @@ import visit from '../visit';
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
import { State } from '../interfaces';
function isElseIf ( node: Node ) {
return node && node.children.length === 1 && node.children[0].type === 'IfBlock';
@ -12,7 +13,7 @@ function isElseBranch ( branch ) {
return branch.block && !branch.condition;
}
function getBranches ( generator: DomGenerator, block: Block, state, node: Node ) {
function getBranches ( generator: DomGenerator, block: Block, state: State, node: Node ) {
const branches = [{
condition: block.contextualise( node.expression ).snippet,
block: node._block.name,
@ -44,13 +45,13 @@ function getBranches ( generator: DomGenerator, block: Block, state, node: Node
return branches;
}
function visitChildren ( generator: DomGenerator, block: Block, state, node: Node ) {
function visitChildren ( generator: DomGenerator, block: Block, state: State, node: Node ) {
node.children.forEach( ( child: Node ) => {
visit( generator, node._block, node._state, child );
});
}
export default function visitIfBlock ( generator: DomGenerator, block: Block, state, node: Node ) {
export default function visitIfBlock ( generator: DomGenerator, block: Block, state: State, node: Node ) {
const name = generator.getUniqueName( `if_block` );
const anchor = node.needsAnchor ? block.getUniqueName( `${name}_anchor` ) : ( node.next && node.next._state.name ) || 'null';
const params = block.params.join( ', ' );
@ -82,7 +83,7 @@ export default function visitIfBlock ( generator: DomGenerator, block: Block, st
}
}
function simple ( generator: DomGenerator, block: Block, state, node: Node, branch, dynamic, { name, anchor, params, if_name } ) {
function simple ( generator: DomGenerator, block: Block, state: State, node: Node, branch, dynamic, { name, anchor, params, if_name } ) {
block.builders.create.addBlock( deindent`
var ${name} = (${branch.condition}) && ${branch.block}( ${params}, ${block.component} );
` );
@ -156,7 +157,7 @@ function simple ( generator: DomGenerator, block: Block, state, node: Node, bran
);
}
function compound ( generator: DomGenerator, block: Block, state, node: Node, branches, dynamic, { name, anchor, params, hasElse, if_name } ) {
function compound ( generator: DomGenerator, block: Block, state: State, node: Node, branches, dynamic, { name, anchor, params, hasElse, if_name } ) {
const get_block = block.getUniqueName( `get_block` );
const current_block = block.getUniqueName( `current_block` );
const current_block_and = hasElse ? '' : `${current_block} && `;
@ -212,7 +213,7 @@ function compound ( generator: DomGenerator, block: Block, state, node: Node, br
// if any of the siblings have outros, we need to keep references to the blocks
// (TODO does this only apply to bidi transitions?)
function compoundWithOutros ( generator: DomGenerator, block: Block, state, node: Node, branches, dynamic, { name, anchor, params, hasElse } ) {
function compoundWithOutros ( generator: DomGenerator, block: Block, state: State, node: Node, branches, dynamic, { name, anchor, params, hasElse } ) {
const get_block = block.getUniqueName( `get_block` );
const current_block_index = block.getUniqueName( `current_block_index` );
const previous_block_index = block.getUniqueName( `previous_block_index` );

@ -2,8 +2,9 @@ import deindent from '../../../utils/deindent.js';
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
import { State } from '../interfaces';
export default function visitMustacheTag ( generator: DomGenerator, block: Block, state, node: Node ) {
export default function visitMustacheTag ( generator: DomGenerator, block: Block, state: State, node: Node ) {
const name = node._state.name;
const value = block.getUniqueName( `${name}_value` );

@ -2,8 +2,9 @@ import deindent from '../../../utils/deindent.js';
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
import { State } from '../interfaces';
export default function visitRawMustacheTag ( generator: DomGenerator, block: Block, state, node: Node ) {
export default function visitRawMustacheTag ( generator: DomGenerator, block: Block, state: State, node: Node ) {
const name = node._state.basename;
const before = node._state.name;
const value = block.getUniqueName( `${name}_value` );

@ -1,8 +1,9 @@
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
import { State } from '../interfaces';
export default function visitText ( generator: DomGenerator, block: Block, state, node: Node ) {
export default function visitText ( generator: DomGenerator, block: Block, state: State, node: Node ) {
if ( !node._state.shouldCreate ) return;
block.addElement( node._state.name, `${generator.helper( 'createText' )}( ${JSON.stringify( node.data )} )`, state.parentNode, node.usedAsAnchor );
}

@ -1,7 +1,8 @@
import { DomGenerator } from '../index';
import Block from '../Block';
import { State } from '../interfaces';
export default function visitYieldTag ( generator: DomGenerator, block: Block, state ) {
export default function visitYieldTag ( generator: DomGenerator, block: Block, state: State ) {
const parentNode = state.parentNode || block.target;
( state.parentNode ? block.builders.create : block.builders.mount ).addLine(

@ -2,20 +2,24 @@ import deindent from '../../utils/deindent.js';
import Generator from '../Generator';
import Block from './Block';
import visit from './visit';
import { Parsed, Node, CompileOptions } from '../../interfaces';
class SsrGenerator extends Generator {
constructor ( parsed, source, name, options ) {
export class SsrGenerator extends Generator {
bindings: string[];
renderCode: string;
constructor ( parsed: Parsed, source: string, name: string, options: CompileOptions ) {
super( parsed, source, name, options );
this.bindings = [];
this.renderCode = '';
}
append ( code ) {
append ( code: string ) {
this.renderCode += code;
}
}
export default function ssr ( parsed, source, options ) {
export default function ssr ( parsed: Parsed, source: string, options: CompileOptions ) {
const format = options.format || 'cjs';
const name = options.name || 'SvelteComponent';
@ -31,7 +35,7 @@ export default function ssr ( parsed, source, options ) {
conditions: []
});
parsed.html.children.forEach( node => {
parsed.html.children.forEach( ( node: Node ) => {
visit( generator, mainBlock, node );
});

@ -48,7 +48,7 @@ export function compile ( source: string, _options: CompileOptions ) {
return compiler( parsed, source, options );
}
export function create ( source, _options = {} ) {
export function create ( source: string, _options: CompileOptions ) {
_options.format = 'eval';
const compiled = compile( source, _options );

@ -36,6 +36,7 @@ export interface CompileOptions {
format?: string;
name?: string;
filename?: string;
generate?: string;
dev?: boolean;
shared?: boolean | string;

Loading…
Cancel
Save