pull/573/head
Rich-Harris 8 years ago
parent 0b8cf4cef7
commit 5cbe6b764a

@ -1,12 +1,25 @@
import deindent from '../../utils/deindent.js'; import deindent from '../../utils/deindent.js';
import flattenReference from '../../utils/flattenReference'; import flattenReference from '../../utils/flattenReference';
import { SsrGenerator } from './index';
import { Node } from '../../interfaces';
interface BlockOptions {
// TODO
}
export default class Block { export default class Block {
constructor ( options ) { generator: SsrGenerator;
conditions: string[];
contexts: Map<string, string>;
indexes: Map<string, string>;
contextDependencies: Map<string, string[]>;
constructor ( options: BlockOptions ) {
Object.assign( this, options ); Object.assign( this, options );
} }
addBinding ( binding, name ) { addBinding ( binding: Node, name: string ) {
const conditions = [ `!( '${binding.name}' in state )`].concat( // TODO handle contextual bindings... const conditions = [ `!( '${binding.name}' in state )`].concat( // TODO handle contextual bindings...
this.conditions.map( c => `(${c})` ) this.conditions.map( c => `(${c})` )
); );
@ -24,11 +37,11 @@ export default class Block {
` ); ` );
} }
child ( options ) { child ( options: BlockOptions ) {
return new Block( Object.assign( {}, this, options, { parent: this } ) ); return new Block( Object.assign( {}, this, options, { parent: this } ) );
} }
contextualise ( expression, context, isEventHandler ) { contextualise ( expression: Node, context?: string, isEventHandler?: boolean ) {
return this.generator.contextualise( this, expression, context, isEventHandler ); return this.generator.contextualise( this, expression, context, isEventHandler );
} }
} }

@ -7,6 +7,7 @@ import { Parsed, Node, CompileOptions } from '../../interfaces';
export class SsrGenerator extends Generator { export class SsrGenerator extends Generator {
bindings: string[]; bindings: string[];
renderCode: string; renderCode: string;
elementDepth: number;
constructor ( parsed: Parsed, source: string, name: string, options: CompileOptions ) { constructor ( parsed: Parsed, source: string, name: string, options: CompileOptions ) {
super( parsed, source, name, options ); super( parsed, source, name, options );

@ -1,6 +1,9 @@
import visitors from './visitors/index'; import visitors from './visitors/index';
import { SsrGenerator } from './index';
import Block from './Block';
import { Node } from '../../interfaces';
export default function visit ( generator, fragment, node ) { export default function visit ( generator: SsrGenerator, block: Block, node: Node ) {
const visitor = visitors[ node.type ]; const visitor = visitors[ node.type ];
visitor( generator, fragment, node ); visitor( generator, block, node );
} }

@ -1,8 +1,11 @@
import flattenReference from '../../../utils/flattenReference'; import flattenReference from '../../../utils/flattenReference';
import visit from '../visit'; import visit from '../visit';
import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitComponent ( generator, block, node ) { export default function visitComponent ( generator: SsrGenerator, block: Block, node: Node ) {
function stringify ( chunk ) { function stringify ( chunk: Node ) {
if ( chunk.type === 'Text' ) return chunk.data; if ( chunk.type === 'Text' ) return chunk.data;
if ( chunk.type === 'MustacheTag' ) { if ( chunk.type === 'MustacheTag' ) {
const { snippet } = block.contextualise( chunk.expression ); const { snippet } = block.contextualise( chunk.expression );
@ -10,10 +13,10 @@ export default function visitComponent ( generator, block, node ) {
} }
} }
const attributes = []; const attributes: Node[] = [];
const bindings = []; const bindings: Node[] = [];
node.attributes.forEach( attribute => { node.attributes.forEach( ( attribute: Node ) => {
if ( attribute.type === 'Attribute' ) { if ( attribute.type === 'Attribute' ) {
attributes.push( attribute ); attributes.push( attribute );
} else if ( attribute.type === 'Binding' ) { } else if ( attribute.type === 'Binding' ) {
@ -66,7 +69,7 @@ export default function visitComponent ( generator, block, node ) {
generator.elementDepth += 1; generator.elementDepth += 1;
node.children.forEach( child => { node.children.forEach( ( child: Node ) => {
visit( generator, block, child ); visit( generator, block, child );
}); });

@ -1,6 +1,9 @@
import visit from '../visit'; import visit from '../visit';
import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitEachBlock ( generator, block, node ) { export default function visitEachBlock ( generator: SsrGenerator, block: Block, node: Node ) {
const { dependencies, snippet } = block.contextualise( node.expression ); const { dependencies, snippet } = block.contextualise( node.expression );
const open = `\${ ${snippet}.map( ${ node.index ? `( ${node.context}, ${node.index} )` : node.context} => \``; const open = `\${ ${snippet}.map( ${ node.index ? `( ${node.context}, ${node.index} )` : node.context} => \``;
@ -23,7 +26,7 @@ export default function visitEachBlock ( generator, block, node ) {
contextDependencies contextDependencies
}); });
node.children.forEach( child => { node.children.forEach( ( child: Node ) => {
visit( generator, childBlock, child ); visit( generator, childBlock, child );
}); });

@ -2,12 +2,15 @@ import visitComponent from './Component';
import isVoidElementName from '../../../utils/isVoidElementName'; import isVoidElementName from '../../../utils/isVoidElementName';
import visit from '../visit'; import visit from '../visit';
import visitWindow from './meta/Window'; import visitWindow from './meta/Window';
import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
const meta = { const meta = {
':Window': visitWindow ':Window': visitWindow
}; };
export default function visitElement ( generator, block, node ) { export default function visitElement ( generator: SsrGenerator, block: Block, node: Node ) {
if ( node.name in meta ) { if ( node.name in meta ) {
return meta[ node.name ]( generator, block, node ); return meta[ node.name ]( generator, block, node );
} }
@ -19,13 +22,13 @@ export default function visitElement ( generator, block, node ) {
let openingTag = `<${node.name}`; let openingTag = `<${node.name}`;
node.attributes.forEach( attribute => { node.attributes.forEach( ( attribute: Node ) => {
if ( attribute.type !== 'Attribute' ) return; if ( attribute.type !== 'Attribute' ) return;
let str = ` ${attribute.name}`; let str = ` ${attribute.name}`;
if ( attribute.value !== true ) { if ( attribute.value !== true ) {
str += `="` + attribute.value.map( chunk => { str += `="` + attribute.value.map( ( chunk: Node ) => {
if ( chunk.type === 'Text' ) { if ( chunk.type === 'Text' ) {
return chunk.data; return chunk.data;
} }
@ -48,7 +51,7 @@ export default function visitElement ( generator, block, node ) {
generator.elementDepth += 1; generator.elementDepth += 1;
node.children.forEach( child => { node.children.forEach( ( child: Node ) => {
visit( generator, block, child ); visit( generator, block, child );
}); });

@ -1,6 +1,9 @@
import visit from '../visit'; import visit from '../visit';
import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitIfBlock ( generator, block, node ) { export default function visitIfBlock ( generator: SsrGenerator, block: Block, node: Node ) {
const { snippet } = block.contextualise( node.expression ); const { snippet } = block.contextualise( node.expression );
generator.append( '${ ' + snippet + ' ? `' ); generator.append( '${ ' + snippet + ' ? `' );
@ -9,14 +12,14 @@ export default function visitIfBlock ( generator, block, node ) {
conditions: block.conditions.concat( snippet ) conditions: block.conditions.concat( snippet )
}); });
node.children.forEach( child => { node.children.forEach( ( child: Node ) => {
visit( generator, childBlock, child ); visit( generator, childBlock, child );
}); });
generator.append( '` : `' ); generator.append( '` : `' );
if ( node.else ) { if ( node.else ) {
node.else.children.forEach( child => { node.else.children.forEach( ( child: Node ) => {
visit( generator, childBlock, child ); visit( generator, childBlock, child );
}); });
} }

@ -1,4 +1,8 @@
export default function visitMustacheTag ( generator, block, node ) { import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitMustacheTag ( generator: SsrGenerator, block: Block, node: Node ) {
const { snippet } = block.contextualise( node.expression ); const { snippet } = block.contextualise( node.expression );
generator.append( '${__escape( ' + snippet + ' )}' ); generator.append( '${__escape( ' + snippet + ' )}' );
} }

@ -1,4 +1,8 @@
export default function visitRawMustacheTag ( generator, block, node ) { import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitRawMustacheTag ( generator: SsrGenerator, block: Block, node: Node ) {
const { snippet } = block.contextualise( node.expression ); const { snippet } = block.contextualise( node.expression );
generator.append( '${' + snippet + '}' ); generator.append( '${' + snippet + '}' );
} }

@ -1,3 +1,7 @@
export default function visitText ( generator, block, node ) { import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitText ( generator: SsrGenerator, block: Block, node: Node ) {
generator.append( node.data.replace( /\${/g, '\\${' ) ); generator.append( node.data.replace( /\${/g, '\\${' ) );
} }

@ -1,3 +1,5 @@
export default function visitYieldTag ( generator ) { import { SsrGenerator } from '../index';
export default function visitYieldTag ( generator: SsrGenerator ) {
generator.append( `\${options && options.yield ? options.yield() : ''}` ); generator.append( `\${options && options.yield ? options.yield() : ''}` );
} }
Loading…
Cancel
Save