diff --git a/.eslintignore b/.eslintignore index a84efdafe36f..effb19af4547 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,5 @@ src/shared shared.js -test/test.js \ No newline at end of file +test/test.js +**/_actual.js +**/expected.js \ No newline at end of file diff --git a/src/generators/Generator.js b/src/generators/Generator.js index 65b391d20b8c..37d8de90b663 100644 --- a/src/generators/Generator.js +++ b/src/generators/Generator.js @@ -12,11 +12,10 @@ import processCss from './shared/processCss.js'; import annotateWithScopes from './annotateWithScopes.js'; export default class Generator { - constructor ( parsed, source, name, visitors, options ) { + constructor ( parsed, source, name, options ) { this.parsed = parsed; this.source = source; this.name = name; - this.visitors = visitors; this.options = options; this.imports = []; @@ -31,8 +30,6 @@ export default class Generator { // in dev mode this.expectedProperties = new Set(); - this.elementDepth = 0; - this.code = new MagicString( source ); this.css = parsed.css ? processCss( parsed, this.code ) : null; this.cssId = parsed.css ? `svelte-${parsed.hash}` : ''; @@ -43,8 +40,6 @@ export default class Generator { this.importedNames = new Set(); this._aliases = new Map(); this._usedNames = new Set(); - - this._callbacks = new Map(); } addSourcemapLocations ( node ) { @@ -65,14 +60,14 @@ export default class Generator { return alias; } - contextualise ( expression, isEventHandler ) { + contextualise ( fragment, expression, isEventHandler ) { this.addSourcemapLocations( expression ); const usedContexts = []; const dependencies = []; const { code, helpers } = this; - const { contextDependencies, contexts, indexes } = this.current; + const { contextDependencies, contexts, indexes } = fragment; let scope = annotateWithScopes( expression ); @@ -154,15 +149,6 @@ export default class Generator { }; } - fire ( eventName, data ) { - const handlers = this._callbacks.has( eventName ) && this._callbacks.get( eventName ).slice(); - if ( !handlers ) return; - - for ( let i = 0; i < handlers.length; i += 1 ) { - handlers[i].call( this, data ); - } - } - generate ( result, options, { name, format } ) { if ( this.imports.length ) { const statements = []; @@ -430,50 +416,4 @@ export default class Generator { templateProperties }; } - - on ( eventName, handler ) { - if ( this._callbacks.has( eventName ) ) { - this._callbacks.get( eventName ).push( handler ); - } else { - this._callbacks.set( eventName, [ handler ] ); - } - } - - pop () { - const tail = this.current; - this.current = tail.parent; - - return tail; - } - - push ( fragment ) { - const newFragment = Object.assign( {}, this.current, fragment, { - parent: this.current - }); - - this.current = newFragment; - } - - visit ( node ) { - const visitor = this.visitors[ node.type ]; - if ( !visitor ) throw new Error( `Not implemented: ${node.type}` ); - - if ( visitor.enter ) visitor.enter( this, node ); - - if ( visitor.type === 'Element' ) { - this.elementDepth += 1; - } - - if ( node.children ) { - node.children.forEach( child => { - this.visit( child ); - }); - } - - if ( visitor.type === 'Element' ) { - this.elementDepth -= 1; - } - - if ( visitor.leave ) visitor.leave( this, node ); - } } diff --git a/src/generators/dom/Block.js b/src/generators/dom/Block.js new file mode 100644 index 000000000000..3f5b838bbbb4 --- /dev/null +++ b/src/generators/dom/Block.js @@ -0,0 +1,140 @@ +import CodeBuilder from '../../utils/CodeBuilder.js'; +import deindent from '../../utils/deindent.js'; + +export default class Block { + constructor ({ generator, name, key, expression, context, contextDependencies, contexts, indexes, params, indexNames, listNames }) { + this.generator = generator; + this.name = name; + this.key = key; + this.expression = expression; + this.context = context; + + this.contexts = contexts; + this.indexes = indexes; + this.contextDependencies = contextDependencies; + + this.params = params; + this.indexNames = indexNames; + this.listNames = listNames; + + this.builders = { + create: new CodeBuilder(), + mount: new CodeBuilder(), + update: new CodeBuilder(), + detach: new CodeBuilder(), + detachRaw: new CodeBuilder(), + destroy: new CodeBuilder() + }; + + this.getUniqueName = generator.getUniqueNameMaker( params ); + + // unique names + this.component = this.getUniqueName( 'component' ); + } + + addElement ( name, renderStatement, parentNode, needsIdentifier = false ) { + const isToplevel = !parentNode; + if ( needsIdentifier || isToplevel ) { + this.builders.create.addLine( + `var ${name} = ${renderStatement};` + ); + + this.createMountStatement( name, parentNode ); + } else { + this.builders.create.addLine( `${this.generator.helper( 'appendNode' )}( ${renderStatement}, ${parentNode} );` ); + } + + if ( isToplevel ) { + this.builders.detach.addLine( `${this.generator.helper( 'detachNode' )}( ${name} );` ); + } + } + + child ( options ) { + return new Block( Object.assign( {}, this, options, { parent: this } ) ); + } + + createAnchor ( name, parentNode ) { + const renderStatement = `${this.generator.helper( 'createComment' )}()`; + this.addElement( name, renderStatement, parentNode, true ); + } + + createMountStatement ( name, parentNode ) { + if ( parentNode ) { + this.builders.create.addLine( `${this.generator.helper( 'appendNode' )}( ${name}, ${parentNode} );` ); + } else { + this.builders.mount.addLine( `${this.generator.helper( 'insertNode' )}( ${name}, target, anchor );` ); + } + } + + render () { + if ( this.autofocus ) { + this.builders.create.addLine( `${this.autofocus}.focus();` ); + } + + // minor hack – we need to ensure that any {{{triples}}} are detached + // first, so we append normal detach statements to detachRaw + this.builders.detachRaw.addBlock( this.builders.detach ); + + if ( !this.builders.detachRaw.isEmpty() ) { + this.builders.destroy.addBlock( deindent` + if ( detach ) { + ${this.builders.detachRaw} + } + ` ); + } + + const properties = new CodeBuilder(); + + let localKey; + if ( this.key ) { + localKey = this.getUniqueName( 'key' ); + properties.addBlock( `key: ${localKey},` ); + } + + if ( this.builders.mount.isEmpty() ) { + properties.addBlock( `mount: ${this.generator.helper( 'noop' )},` ); + } else { + properties.addBlock( deindent` + mount: function ( target, anchor ) { + ${this.builders.mount} + }, + ` ); + } + + if ( this.builders.update.isEmpty() ) { + properties.addBlock( `update: ${this.generator.helper( 'noop' )},` ); + } else { + if ( this._tmp ) this.builders.update.addBlockAtStart( `var ${this._tmp};` ); + properties.addBlock( deindent` + update: function ( changed, ${this.params.join( ', ' )} ) { + ${this.builders.update} + }, + ` ); + } + + if ( this.builders.destroy.isEmpty() ) { + properties.addBlock( `destroy: ${this.generator.helper( 'noop' )}` ); + } else { + properties.addBlock( deindent` + destroy: function ( detach ) { + ${this.builders.destroy} + } + ` ); + } + + return deindent` + function ${this.name} ( ${this.params.join( ', ' )}, ${this.component}${this.key ? `, ${localKey}` : ''} ) { + ${this.builders.create} + + return { + ${properties} + }; + } + `; + } + + tmp () { + if ( !this._tmp ) this._tmp = this.getUniqueName( 'tmp' ); + return this._tmp; + } +} \ No newline at end of file diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index ee08ab439411..fcb540d6799c 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -1,14 +1,14 @@ import deindent from '../../utils/deindent.js'; -import getBuilders from './utils/getBuilders.js'; import CodeBuilder from '../../utils/CodeBuilder.js'; -import visitors from './visitors/index.js'; +import visit from './visit.js'; import Generator from '../Generator.js'; +import Block from './Block.js'; import * as shared from '../../shared/index.js'; class DomGenerator extends Generator { - constructor ( parsed, source, name, visitors, options ) { - super( parsed, source, name, visitors, options ); - this.renderers = []; + constructor ( parsed, source, name, options ) { + super( parsed, source, name, options ); + this.blocks = []; this.uses = new Set(); // initial values for e.g. window.innerWidth, if there's a <:Window> meta tag @@ -17,121 +17,8 @@ class DomGenerator extends Generator { }; } - addElement ( name, renderStatement, needsIdentifier = false ) { - const isToplevel = this.current.localElementDepth === 0; - if ( needsIdentifier || isToplevel ) { - this.current.builders.init.addLine( - `var ${name} = ${renderStatement};` - ); - - this.createMountStatement( name ); - } else { - this.current.builders.init.addLine( `${this.helper( 'appendNode' )}( ${renderStatement}, ${this.current.target} );` ); - } - - if ( isToplevel ) { - this.current.builders.detach.addLine( `${this.helper( 'detachNode' )}( ${name} );` ); - } - } - - addRenderer ( fragment ) { - if ( fragment.autofocus ) { - fragment.builders.init.addLine( `${fragment.autofocus}.focus();` ); - } - - // minor hack – we need to ensure that any {{{triples}}} are detached - // first, so we append normal detach statements to detachRaw - fragment.builders.detachRaw.addBlock( fragment.builders.detach ); - - if ( !fragment.builders.detachRaw.isEmpty() ) { - fragment.builders.teardown.addBlock( deindent` - if ( detach ) { - ${fragment.builders.detachRaw} - } - ` ); - } - - const properties = new CodeBuilder(); - - let localKey; - if ( fragment.key ) { - localKey = fragment.getUniqueName( 'key' ); - properties.addBlock( `key: ${localKey},` ); - } - - if ( fragment.builders.mount.isEmpty() ) { - properties.addBlock( `mount: ${this.helper( 'noop' )},` ); - } else { - properties.addBlock( deindent` - mount: function ( target, anchor ) { - ${fragment.builders.mount} - }, - ` ); - } - - if ( fragment.builders.update.isEmpty() ) { - properties.addBlock( `update: ${this.helper( 'noop' )},` ); - } else { - properties.addBlock( deindent` - update: function ( changed, ${fragment.params.join( ', ' )} ) { - ${fragment.tmp ? `var ${fragment.tmp};` : ''} - - ${fragment.builders.update} - }, - ` ); - } - - if ( fragment.builders.teardown.isEmpty() ) { - properties.addBlock( `teardown: ${this.helper( 'noop' )},` ); - } else { - properties.addBlock( deindent` - teardown: function ( detach ) { - ${fragment.builders.teardown} - } - ` ); - } - - this.renderers.push( deindent` - function ${fragment.name} ( ${fragment.params.join( ', ' )}, ${fragment.component}${fragment.key ? `, ${localKey}` : ''} ) { - ${fragment.builders.init} - - return { - ${properties} - }; - } - ` ); - } - - createAnchor ( name ) { - const renderStatement = `${this.helper( 'createComment' )}()`; - this.addElement( name, renderStatement, true ); - } - - createMountStatement ( name ) { - if ( this.current.target === 'target' ) { - this.current.builders.mount.addLine( `${this.helper( 'insertNode' )}( ${name}, target, anchor );` ); - } else { - this.current.builders.init.addLine( `${this.helper( 'appendNode' )}( ${name}, ${this.current.target} );` ); - } - } - - generateBlock ( node, name, type ) { - this.push({ - type, - name, - target: 'target', - localElementDepth: 0, - builders: getBuilders(), - getUniqueName: this.getUniqueNameMaker( this.current.params ) - }); - - // walk the children here - node.children.forEach( node => this.visit( node ) ); - this.addRenderer( this.current ); - this.pop(); - - // unset the children, to avoid them being visited again - node.children = []; + addBlock ( block ) { + this.blocks.push( block ); } helper ( name ) { @@ -149,19 +36,16 @@ export default function dom ( parsed, source, options ) { const format = options.format || 'es'; const name = options.name || 'SvelteComponent'; - const generator = new DomGenerator( parsed, source, name, visitors, options ); + const generator = new DomGenerator( parsed, source, name, options ); const { computations, hasJs, templateProperties, namespace } = generator.parseJs(); const getUniqueName = generator.getUniqueNameMaker( [ 'root' ] ); const component = getUniqueName( 'component' ); - generator.push({ - type: 'block', - name: generator.alias( 'render_main_fragment' ), - namespace, - target: 'target', - localElementDepth: 0, + const mainBlock = new Block({ + generator, + name: generator.alias( 'create_main_fragment' ), key: null, component, @@ -173,13 +57,20 @@ export default function dom ( parsed, source, options ) { indexNames: new Map(), listNames: new Map(), - builders: getBuilders(), - getUniqueName, + getUniqueName }); - parsed.html.children.forEach( node => generator.visit( node ) ); + const state = { + namespace, + parentNode: null, + isTopLevel: true + }; + + parsed.html.children.forEach( node => { + visit( generator, mainBlock, state, node ); + }); - generator.addRenderer( generator.pop() ); + generator.addBlock( mainBlock ); const builders = { main: new CodeBuilder(), @@ -243,8 +134,8 @@ export default function dom ( parsed, source, options ) { ` ); } - let i = generator.renderers.length; - while ( i-- ) builders.main.addBlock( generator.renderers[i] ); + let i = generator.blocks.length; + while ( i-- ) builders.main.addBlock( generator.blocks[i].render() ); builders.init.addLine( `this._torndown = false;` ); @@ -259,7 +150,7 @@ export default function dom ( parsed, source, options ) { if ( generator.hasComplexBindings ) { builders.init.addBlock( deindent` this._bindings = []; - this._fragment = ${generator.alias( 'render_main_fragment' )}( this._state, this ); + this._fragment = ${generator.alias( 'create_main_fragment' )}( this._state, this ); if ( options.target ) this._fragment.mount( options.target, null ); while ( this._bindings.length ) this._bindings.pop()(); ` ); @@ -267,7 +158,7 @@ export default function dom ( parsed, source, options ) { builders._set.addLine( `while ( this._bindings.length ) this._bindings.pop()();` ); } else { builders.init.addBlock( deindent` - this._fragment = ${generator.alias( 'render_main_fragment' )}( this._state, this ); + this._fragment = ${generator.alias( 'create_main_fragment' )}( this._state, this ); if ( options.target ) this._fragment.mount( options.target, null ); ` ); } @@ -367,7 +258,7 @@ export default function dom ( parsed, source, options ) { ${name}.prototype.teardown = ${name}.prototype.destroy = function destroy ( detach ) { this.fire( 'destroy' );${templateProperties.ondestroy ? `\n${generator.alias( 'template' )}.ondestroy.call( this );` : ``} - this._fragment.teardown( detach !== false ); + this._fragment.destroy( detach !== false ); this._fragment = null; this._state = {}; diff --git a/src/generators/dom/utils/findBlock.js b/src/generators/dom/utils/findBlock.js deleted file mode 100644 index 59f71e35527e..000000000000 --- a/src/generators/dom/utils/findBlock.js +++ /dev/null @@ -1,4 +0,0 @@ -export default function findBlock ( fragment ) { - while ( fragment.type !== 'block' ) fragment = fragment.parent; - return fragment; -} \ No newline at end of file diff --git a/src/generators/dom/utils/getBuilders.js b/src/generators/dom/utils/getBuilders.js deleted file mode 100644 index ca66c1bec5ea..000000000000 --- a/src/generators/dom/utils/getBuilders.js +++ /dev/null @@ -1,12 +0,0 @@ -import CodeBuilder from '../../../utils/CodeBuilder.js'; - -export default function getBuilders () { - return { - init: new CodeBuilder(), - mount: new CodeBuilder(), - update: new CodeBuilder(), - detach: new CodeBuilder(), - detachRaw: new CodeBuilder(), - teardown: new CodeBuilder() - }; -} diff --git a/src/generators/dom/visit.js b/src/generators/dom/visit.js new file mode 100644 index 000000000000..22a040af06c7 --- /dev/null +++ b/src/generators/dom/visit.js @@ -0,0 +1,6 @@ +import visitors from './visitors/index.js'; + +export default function visit ( generator, block, state, node ) { + const visitor = visitors[ node.type ]; + visitor( generator, block, state, node ); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/Comment.js b/src/generators/dom/visitors/Comment.js index f32a1e64a8bd..4d3477d7ef0d 100644 --- a/src/generators/dom/visitors/Comment.js +++ b/src/generators/dom/visitors/Comment.js @@ -1,3 +1,3 @@ -export default { +export default function visitComment () { // do nothing -}; +} diff --git a/src/generators/dom/visitors/Component.js b/src/generators/dom/visitors/Component.js index 69e2e3c2acf0..d4c5a86dc6c0 100644 --- a/src/generators/dom/visitors/Component.js +++ b/src/generators/dom/visitors/Component.js @@ -1,5 +1,6 @@ import deindent from '../../../utils/deindent.js'; import CodeBuilder from '../../../utils/CodeBuilder.js'; +import visit from '../visit.js'; import addComponentAttributes from './attributes/addComponentAttributes.js'; function capDown ( name ) { @@ -18,157 +19,152 @@ function stringifyProps ( props ) { return `{ ${joined} }`; } -export default { - enter ( generator, node ) { - const hasChildren = node.children.length > 0; - const { current } = generator; - const name = current.getUniqueName( capDown( node.name === ':Self' ? generator.name : node.name ) ); +export default function visitComponent ( generator, block, state, node ) { + const hasChildren = node.children.length > 0; + const name = block.getUniqueName( capDown( node.name === ':Self' ? generator.name : node.name ) ); - const local = { - name, - namespace: current.namespace, - isComponent: true, + const local = { + name, + namespace: state.namespace, + isComponent: true, - allUsedContexts: [], + allUsedContexts: [], - init: new CodeBuilder(), - update: new CodeBuilder() - }; + create: new CodeBuilder(), + update: new CodeBuilder() + }; - const isToplevel = current.localElementDepth === 0; + const isToplevel = !state.parentNode; - generator.hasComponents = true; + generator.hasComponents = true; - addComponentAttributes( generator, node, local ); + addComponentAttributes( generator, block, node, local ); - if ( local.allUsedContexts.length ) { - const initialProps = local.allUsedContexts.map( contextName => { - if ( contextName === 'root' ) return `root: root`; + if ( local.allUsedContexts.length ) { + const initialProps = local.allUsedContexts.map( contextName => { + if ( contextName === 'root' ) return `root: root`; - const listName = current.listNames.get( contextName ); - const indexName = current.indexNames.get( contextName ); + const listName = block.listNames.get( contextName ); + const indexName = block.indexNames.get( contextName ); - return `${listName}: ${listName},\n${indexName}: ${indexName}`; - }).join( ',\n' ); + return `${listName}: ${listName},\n${indexName}: ${indexName}`; + }).join( ',\n' ); - const updates = local.allUsedContexts.map( contextName => { - if ( contextName === 'root' ) return `${name}._context.root = root;`; + const updates = local.allUsedContexts.map( contextName => { + if ( contextName === 'root' ) return `${name}._context.root = root;`; - const listName = current.listNames.get( contextName ); - const indexName = current.indexNames.get( contextName ); + const listName = block.listNames.get( contextName ); + const indexName = block.indexNames.get( contextName ); - return `${name}._context.${listName} = ${listName};\n${name}._context.${indexName} = ${indexName};`; - }).join( '\n' ); + return `${name}._context.${listName} = ${listName};\n${name}._context.${indexName} = ${indexName};`; + }).join( '\n' ); - local.init.addBlock( deindent` - ${name}._context = { - ${initialProps} - }; - ` ); + local.create.addBlock( deindent` + ${name}._context = { + ${initialProps} + }; + ` ); - local.update.addBlock( updates ); - } + local.update.addBlock( updates ); + } - const componentInitProperties = [ - `target: ${!isToplevel ? current.target: 'null'}`, - `_root: ${current.component}._root || ${current.component}` - ]; + const componentInitProperties = [ + `target: ${!isToplevel ? state.parentNode: 'null'}`, + `_root: ${block.component}._root || ${block.component}` + ]; - // Component has children, put them in a separate {{yield}} block - if ( hasChildren ) { - const yieldName = generator.getUniqueName( `render_${name}_yield_fragment` ); - const params = current.params.join( ', ' ); + // Component has children, put them in a separate {{yield}} block + if ( hasChildren ) { + const params = block.params.join( ', ' ); - generator.generateBlock( node, yieldName, 'block' ); + const childBlock = block.child({ + name: generator.getUniqueName( `create_${name}_yield_fragment` ) // TODO should getUniqueName happen inside Fragment? probably + }); - const yieldFragment = current.getUniqueName( `${name}_yield_fragment` ); + const childState = Object.assign( {}, state, { + parentNode: null + }); - current.builders.init.addLine( - `var ${yieldFragment} = ${yieldName}( ${params}, ${current.component} );` - ); + node.children.forEach( child => { + visit( generator, childBlock, childState, child ); + }); - current.builders.update.addLine( - `${yieldFragment}.update( changed, ${params} );` - ); + const yieldFragment = block.getUniqueName( `${name}_yield_fragment` ); - componentInitProperties.push( `_yield: ${yieldFragment}`); - } + block.builders.create.addLine( + `var ${yieldFragment} = ${childBlock.name}( ${params}, ${block.component} );` + ); - const statements = []; + block.builders.update.addLine( + `${yieldFragment}.update( changed, ${params} );` + ); - if ( local.staticAttributes.length || local.dynamicAttributes.length || local.bindings.length ) { - const initialProps = local.staticAttributes - .concat( local.dynamicAttributes ) - .map( attribute => `${attribute.name}: ${attribute.value}` ); + componentInitProperties.push( `_yield: ${yieldFragment}`); - const initialPropString = stringifyProps( initialProps ); + generator.addBlock( childBlock ); + } - if ( local.bindings.length ) { - const initialData = current.getUniqueName( `${name}_initial_data` ); + const statements = []; - statements.push( `var ${name}_initial_data = ${initialPropString};` ); + if ( local.staticAttributes.length || local.dynamicAttributes.length || local.bindings.length ) { + const initialProps = local.staticAttributes + .concat( local.dynamicAttributes ) + .map( attribute => `${attribute.name}: ${attribute.value}` ); - local.bindings.forEach( binding => { - statements.push( `if ( ${binding.prop} in ${binding.obj} ) ${initialData}.${binding.name} = ${binding.value};` ); - }); + const initialPropString = stringifyProps( initialProps ); - componentInitProperties.push( `data: ${initialData}` ); - } else if ( initialProps.length ) { - componentInitProperties.push( `data: ${initialPropString}` ); - } - } + if ( local.bindings.length ) { + const initialData = block.getUniqueName( `${name}_initial_data` ); - const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${generator.alias( 'template' )}.components.${node.name}`; + statements.push( `var ${name}_initial_data = ${initialPropString};` ); - local.init.addBlockAtStart( deindent` - ${statements.join( '\n' )} - var ${name} = new ${expression}({ - ${componentInitProperties.join(',\n')} + local.bindings.forEach( binding => { + statements.push( `if ( ${binding.prop} in ${binding.obj} ) ${initialData}.${binding.name} = ${binding.value};` ); }); - ` ); - if ( isToplevel ) { - current.builders.mount.addLine( `${name}._fragment.mount( target, anchor );` ); + componentInitProperties.push( `data: ${initialData}` ); + } else if ( initialProps.length ) { + componentInitProperties.push( `data: ${initialPropString}` ); } + } - if ( local.dynamicAttributes.length ) { - const updates = local.dynamicAttributes.map( attribute => { - if ( attribute.dependencies.length ) { - return deindent` - if ( ${attribute.dependencies.map( dependency => `'${dependency}' in changed` ).join( '||' )} ) ${name}_changes.${attribute.name} = ${attribute.value}; - `; - } - - // TODO this is an odd situation to encounter – I *think* it should only happen with - // each block indices, in which case it may be possible to optimise this - return `${name}_changes.${attribute.name} = ${attribute.value};`; - }); + const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${generator.alias( 'template' )}.components.${node.name}`; - local.update.addBlock( deindent` - var ${name}_changes = {}; + local.create.addBlockAtStart( deindent` + ${statements.join( '\n' )} + var ${name} = new ${expression}({ + ${componentInitProperties.join(',\n')} + }); + ` ); - ${updates.join( '\n' )} + if ( isToplevel ) { + block.builders.mount.addLine( `${name}._fragment.mount( target, anchor );` ); + } - if ( Object.keys( ${name}_changes ).length ) ${name}.set( ${name}_changes ); - ` ); - } + if ( local.dynamicAttributes.length ) { + const updates = local.dynamicAttributes.map( attribute => { + if ( attribute.dependencies.length ) { + return deindent` + if ( ${attribute.dependencies.map( dependency => `'${dependency}' in changed` ).join( '||' )} ) ${name}_changes.${attribute.name} = ${attribute.value}; + `; + } - current.builders.teardown.addLine( `${name}.destroy( ${isToplevel ? 'detach' : 'false'} );` ); + // TODO this is an odd situation to encounter – I *think* it should only happen with + // each block indices, in which case it may be possible to optimise this + return `${name}_changes.${attribute.name} = ${attribute.value};`; + }); - current.builders.init.addBlock( local.init ); - if ( !local.update.isEmpty() ) current.builders.update.addBlock( local.update ); + local.update.addBlock( deindent` + var ${name}_changes = {}; - generator.push({ - type: 'component', - namespace: local.namespace, - target: name, - parent: current, - localElementDepth: current.localElementDepth + 1, - key: null - }); - }, + ${updates.join( '\n' )} - leave ( generator ) { - generator.pop(); + if ( Object.keys( ${name}_changes ).length ) ${name}.set( ${name}_changes ); + ` ); } -}; + + block.builders.destroy.addLine( `${name}.destroy( ${isToplevel ? 'detach' : 'false'} );` ); + + block.builders.create.addBlock( local.create ); + if ( !local.update.isEmpty() ) block.builders.update.addBlock( local.update ); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/EachBlock.js b/src/generators/dom/visitors/EachBlock.js index df9936197fc4..cef7478dfc55 100644 --- a/src/generators/dom/visitors/EachBlock.js +++ b/src/generators/dom/visitors/EachBlock.js @@ -1,223 +1,220 @@ import CodeBuilder from '../../../utils/CodeBuilder.js'; import deindent from '../../../utils/deindent.js'; -import getBuilders from '../utils/getBuilders.js'; +import visit from '../visit.js'; -export default { - enter ( generator, node ) { - const name = generator.getUniqueName( `each_block` ); - const renderer = generator.getUniqueName( `render_each_block` ); - const elseName = generator.getUniqueName( `${name}_else` ); - const renderElse = generator.getUniqueName( `${renderer}_else` ); - const i = generator.current.getUniqueName( `i` ); - const params = generator.current.params.join( ', ' ); +export default function visitEachBlock ( generator, block, state, node ) { + const name = generator.getUniqueName( `each_block` ); + const renderer = generator.getUniqueName( `create_each_block` ); + const elseName = generator.getUniqueName( `${name}_else` ); + const renderElse = generator.getUniqueName( `${renderer}_else` ); + const i = block.getUniqueName( `i` ); + const params = block.params.join( ', ' ); - const listName = generator.current.getUniqueName( `${name}_value` ); + const listName = block.getUniqueName( `${name}_value` ); - const isToplevel = generator.current.localElementDepth === 0; + const isToplevel = !state.parentNode; - generator.addSourcemapLocations( node.expression ); + const { dependencies, snippet } = generator.contextualise( block, node.expression ); - const { dependencies, snippet } = generator.contextualise( node.expression ); + const anchor = block.getUniqueName( `${name}_anchor` ); + block.createAnchor( anchor, state.parentNode ); - const anchor = generator.current.getUniqueName( `${name}_anchor` ); - generator.createAnchor( anchor ); + const localVars = {}; - const localVars = {}; + localVars.iteration = block.getUniqueName( `${name}_iteration` ); + localVars.iterations = block.getUniqueName( `${name}_iterations` ); + localVars._iterations = block.getUniqueName( `_${name}_iterations` ); + localVars.lookup = block.getUniqueName( `${name}_lookup` ); + localVars._lookup = block.getUniqueName( `_${name}_lookup` ); - localVars.iteration = generator.current.getUniqueName( `${name}_iteration` ); - localVars.iterations = generator.current.getUniqueName( `${name}_iterations` ); - localVars._iterations = generator.current.getUniqueName( `_${name}_iterations` ); - localVars.lookup = generator.current.getUniqueName( `${name}_lookup` ); - localVars._lookup = generator.current.getUniqueName( `_${name}_lookup` ); + block.builders.create.addLine( `var ${listName} = ${snippet};` ); + block.builders.create.addLine( `var ${localVars.iterations} = [];` ); + if ( node.key ) block.builders.create.addLine( `var ${localVars.lookup} = Object.create( null );` ); + if ( node.else ) block.builders.create.addLine( `var ${elseName} = null;` ); - generator.current.builders.init.addLine( `var ${listName} = ${snippet};` ); - generator.current.builders.init.addLine( `var ${localVars.iterations} = [];` ); - if ( node.key ) generator.current.builders.init.addLine( `var ${localVars.lookup} = Object.create( null );` ); - if ( node.else ) generator.current.builders.init.addLine( `var ${elseName} = null;` ); + const initialRender = new CodeBuilder(); - const initialRender = new CodeBuilder(); + if ( node.key ) { + localVars.fragment = block.getUniqueName( 'fragment' ); + localVars.value = block.getUniqueName( 'value' ); + localVars.key = block.getUniqueName( 'key' ); - if ( node.key ) { - localVars.fragment = generator.current.getUniqueName( 'fragment' ); - localVars.value = generator.current.getUniqueName( 'value' ); - localVars.key = generator.current.getUniqueName( 'key' ); + initialRender.addBlock( deindent` + var ${localVars.key} = ${listName}[${i}].${node.key}; + ${localVars.iterations}[${i}] = ${localVars.lookup}[ ${localVars.key} ] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${block.component}${node.key ? `, ${localVars.key}` : `` } ); + ` ); + } else { + initialRender.addLine( + `${localVars.iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${block.component} );` + ); + } - initialRender.addBlock( deindent` - var ${localVars.key} = ${listName}[${i}].${node.key}; - ${localVars.iterations}[${i}] = ${localVars.lookup}[ ${localVars.key} ] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component}${node.key ? `, ${localVars.key}` : `` } ); - ` ); - } else { - initialRender.addLine( - `${localVars.iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component} );` - ); - } + if ( !isToplevel ) { + initialRender.addLine( + `${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );` + ); + } - if ( !isToplevel ) { - initialRender.addLine( - `${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );` - ); + block.builders.create.addBlock( deindent` + for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { + ${initialRender} } + ` ); - generator.current.builders.init.addBlock( deindent` - for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { - ${initialRender} + if ( node.else ) { + block.builders.create.addBlock( deindent` + if ( !${listName}.length ) { + ${elseName} = ${renderElse}( ${params}, ${block.component} ); + ${!isToplevel ? `${elseName}.mount( ${anchor}.parentNode, ${anchor} );` : ''} } ` ); + } + if ( isToplevel ) { + block.builders.mount.addBlock( deindent` + for ( var ${i} = 0; ${i} < ${localVars.iterations}.length; ${i} += 1 ) { + ${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} ); + } + ` ); if ( node.else ) { - generator.current.builders.init.addBlock( deindent` - if ( !${listName}.length ) { - ${elseName} = ${renderElse}( ${params}, ${generator.current.component} ); - ${!isToplevel ? `${elseName}.mount( ${anchor}.parentNode, ${anchor} );` : ''} - } - ` ); - } - - if ( isToplevel ) { - generator.current.builders.mount.addBlock( deindent` - for ( var ${i} = 0; ${i} < ${localVars.iterations}.length; ${i} += 1 ) { - ${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} ); + block.builders.mount.addBlock( deindent` + if ( ${elseName} ) { + ${elseName}.mount( ${anchor}.parentNode, ${anchor} ); } ` ); - if ( node.else ) { - generator.current.builders.mount.addBlock( deindent` - if ( ${elseName} ) { - ${elseName}.mount( ${anchor}.parentNode, ${anchor} ); - } - ` ); - } } + } - if ( node.key ) { - generator.current.builders.update.addBlock( deindent` - var ${listName} = ${snippet}; - var ${localVars._iterations} = []; - var ${localVars._lookup} = Object.create( null ); + if ( node.key ) { + block.builders.update.addBlock( deindent` + var ${listName} = ${snippet}; + var ${localVars._iterations} = []; + var ${localVars._lookup} = Object.create( null ); - var ${localVars.fragment} = document.createDocumentFragment(); + var ${localVars.fragment} = document.createDocumentFragment(); - // create new iterations as necessary - for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { - var ${localVars.value} = ${listName}[${i}]; - var ${localVars.key} = ${localVars.value}.${node.key}; + // create new iterations as necessary + for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { + var ${localVars.value} = ${listName}[${i}]; + var ${localVars.key} = ${localVars.value}.${node.key}; + + if ( ${localVars.lookup}[ ${localVars.key} ] ) { + ${localVars._iterations}[${i}] = ${localVars._lookup}[ ${localVars.key} ] = ${localVars.lookup}[ ${localVars.key} ]; + ${localVars._lookup}[ ${localVars.key} ].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} ); + } else { + ${localVars._iterations}[${i}] = ${localVars._lookup}[ ${localVars.key} ] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${block.component}${node.key ? `, ${localVars.key}` : `` } ); + } - if ( ${localVars.lookup}[ ${localVars.key} ] ) { - ${localVars._iterations}[${i}] = ${localVars._lookup}[ ${localVars.key} ] = ${localVars.lookup}[ ${localVars.key} ]; - ${localVars._lookup}[ ${localVars.key} ].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} ); - } else { - ${localVars._iterations}[${i}] = ${localVars._lookup}[ ${localVars.key} ] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component}${node.key ? `, ${localVars.key}` : `` } ); - } + ${localVars._iterations}[${i}].mount( ${localVars.fragment}, null ); + } - ${localVars._iterations}[${i}].mount( ${localVars.fragment}, null ); + // remove old iterations + for ( var ${i} = 0; ${i} < ${localVars.iterations}.length; ${i} += 1 ) { + var ${localVars.iteration} = ${localVars.iterations}[${i}]; + if ( !${localVars._lookup}[ ${localVars.iteration}.key ] ) { + ${localVars.iteration}.destroy( true ); } + } - // remove old iterations - for ( var ${i} = 0; ${i} < ${localVars.iterations}.length; ${i} += 1 ) { - var ${localVars.iteration} = ${localVars.iterations}[${i}]; - if ( !${localVars._lookup}[ ${localVars.iteration}.key ] ) { - ${localVars.iteration}.teardown( true ); - } - } + ${anchor}.parentNode.insertBefore( ${localVars.fragment}, ${anchor} ); - ${anchor}.parentNode.insertBefore( ${localVars.fragment}, ${anchor} ); + ${localVars.iterations} = ${localVars._iterations}; + ${localVars.lookup} = ${localVars._lookup}; + ` ); + } else { + block.builders.update.addBlock( deindent` + var ${listName} = ${snippet}; - ${localVars.iterations} = ${localVars._iterations}; - ${localVars.lookup} = ${localVars._lookup}; - ` ); - } else { - generator.current.builders.update.addBlock( deindent` - var ${listName} = ${snippet}; - - for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { - if ( !${localVars.iterations}[${i}] ) { - ${localVars.iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${generator.current.component} ); - ${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} ); - } else { - ${localVars.iterations}[${i}].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} ); - } + for ( var ${i} = 0; ${i} < ${listName}.length; ${i} += 1 ) { + if ( !${localVars.iterations}[${i}] ) { + ${localVars.iterations}[${i}] = ${renderer}( ${params}, ${listName}, ${listName}[${i}], ${i}, ${block.component} ); + ${localVars.iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} ); + } else { + ${localVars.iterations}[${i}].update( changed, ${params}, ${listName}, ${listName}[${i}], ${i} ); } + } - teardownEach( ${localVars.iterations}, true, ${listName}.length ); + destroyEach( ${localVars.iterations}, true, ${listName}.length ); - ${localVars.iterations}.length = ${listName}.length; - ` ); - } + ${localVars.iterations}.length = ${listName}.length; + ` ); + } - if ( node.else ) { - generator.current.builders.update.addBlock( deindent` - if ( !${listName}.length && ${elseName} ) { - ${elseName}.update( changed, ${params} ); - } else if ( !${listName}.length ) { - ${elseName} = ${renderElse}( ${params}, ${generator.current.component} ); - ${elseName}.mount( ${anchor}.parentNode, ${anchor} ); - } else if ( ${elseName} ) { - ${elseName}.teardown( true ); - } - ` ); - } + if ( node.else ) { + block.builders.update.addBlock( deindent` + if ( !${listName}.length && ${elseName} ) { + ${elseName}.update( changed, ${params} ); + } else if ( !${listName}.length ) { + ${elseName} = ${renderElse}( ${params}, ${block.component} ); + ${elseName}.mount( ${anchor}.parentNode, ${anchor} ); + } else if ( ${elseName} ) { + ${elseName}.destroy( true ); + } + ` ); + } - generator.current.builders.teardown.addBlock( - `${generator.helper( 'teardownEach' )}( ${localVars.iterations}, ${isToplevel ? 'detach' : 'false'} );` ); + block.builders.destroy.addBlock( + `${generator.helper( 'destroyEach' )}( ${localVars.iterations}, ${isToplevel ? 'detach' : 'false'} );` ); - if ( node.else ) { - generator.current.builders.teardown.addBlock( deindent` - if ( ${elseName} ) { - ${elseName}.teardown( ${isToplevel ? 'detach' : 'false'} ); - } - ` ); - } + if ( node.else ) { + block.builders.destroy.addBlock( deindent` + if ( ${elseName} ) { + ${elseName}.destroy( ${isToplevel ? 'detach' : 'false'} ); + } + ` ); + } - if ( node.else ) { - generator.generateBlock( node.else, renderElse, 'block' ); - } + const indexNames = new Map( block.indexNames ); + const indexName = node.index || block.getUniqueName( `${node.context}_index` ); + indexNames.set( node.context, indexName ); - const indexNames = new Map( generator.current.indexNames ); - const indexName = node.index || generator.current.getUniqueName( `${node.context}_index` ); - indexNames.set( node.context, indexName ); + const listNames = new Map( block.listNames ); + listNames.set( node.context, listName ); - const listNames = new Map( generator.current.listNames ); - listNames.set( node.context, listName ); + const context = generator.getUniqueName( node.context ); + const contexts = new Map( block.contexts ); + contexts.set( node.context, context ); - const context = generator.getUniqueName( node.context ); - const contexts = new Map( generator.current.contexts ); - contexts.set( node.context, context ); + const indexes = new Map( block.indexes ); + if ( node.index ) indexes.set( indexName, node.context ); - const indexes = new Map( generator.current.indexes ); - if ( node.index ) indexes.set( indexName, node.context ); + const contextDependencies = new Map( block.contextDependencies ); + contextDependencies.set( node.context, dependencies ); - const contextDependencies = new Map( generator.current.contextDependencies ); - contextDependencies.set( node.context, dependencies ); + const childBlock = block.child({ + name: renderer, + expression: node.expression, + context: node.context, + key: node.key, - const blockParams = generator.current.params.concat( listName, context, indexName ); + contextDependencies, + contexts, + indexes, - const getUniqueName = generator.getUniqueNameMaker( blockParams ); + indexNames, + listNames, + params: block.params.concat( listName, context, indexName ) + }); - generator.push({ - type: 'block', - name: renderer, - target: 'target', - expression: node.expression, - context: node.context, - key: node.key, - localElementDepth: 0, + const childState = Object.assign( {}, state, { + parentNode: null + }); - component: getUniqueName( 'component' ), + node.children.forEach( child => { + visit( generator, childBlock, childState, child ); + }); - contextDependencies, - contexts, - indexes, + generator.addBlock( childBlock ); - indexNames, - listNames, - params: blockParams, + if ( node.else ) { + const childBlock = block.child({ + name: renderElse + }); - builders: getBuilders(), - getUniqueName, + node.else.children.forEach( child => { + visit( generator, childBlock, childState, child ); }); - }, - leave ( generator ) { - generator.addRenderer( generator.current ); - generator.pop(); + generator.addBlock( childBlock ); } -}; +} \ No newline at end of file diff --git a/src/generators/dom/visitors/Element.js b/src/generators/dom/visitors/Element.js index 566a535bab7b..7f3b8d4e65e6 100644 --- a/src/generators/dom/visitors/Element.js +++ b/src/generators/dom/visitors/Element.js @@ -1,131 +1,114 @@ import CodeBuilder from '../../../utils/CodeBuilder.js'; import deindent from '../../../utils/deindent.js'; +import visit from '../visit.js'; import addElementAttributes from './attributes/addElementAttributes.js'; -import Component from './Component.js'; -import Window from './meta/Window.js'; +import visitComponent from './Component.js'; +import visitWindow from './meta/Window.js'; const meta = { - ':Window': Window + ':Window': visitWindow }; -export default { - enter ( generator, node ) { - if ( node.name in meta ) { - return meta[ node.name ].enter( generator, node ); - } - - const isComponent = generator.components.has( node.name ) || node.name === ':Self'; +export default function visitElement ( generator, block, state, node ) { + if ( node.name in meta ) { + return meta[ node.name ]( generator, block, node ); + } - if ( isComponent ) { - return Component.enter( generator, node ); - } + if ( generator.components.has( node.name ) || node.name === ':Self' ) { + return visitComponent( generator, block, state, node ); + } - const name = generator.current.getUniqueName( node.name ); + const name = block.getUniqueName( node.name ); - const local = { - name, - namespace: node.name === 'svg' ? 'http://www.w3.org/2000/svg' : generator.current.namespace, - isComponent: false, + const local = { + name, + namespace: node.name === 'svg' ? 'http://www.w3.org/2000/svg' : state.namespace, + isComponent: false, - allUsedContexts: [], + allUsedContexts: [], - init: new CodeBuilder(), - update: new CodeBuilder(), - teardown: new CodeBuilder() - }; + create: new CodeBuilder(), + update: new CodeBuilder(), + destroy: new CodeBuilder() + }; - const isToplevel = generator.current.localElementDepth === 0; + const isToplevel = !state.parentNode; - addElementAttributes( generator, node, local ); + addElementAttributes( generator, block, node, local ); - if ( local.allUsedContexts.length ) { - const initialProps = local.allUsedContexts.map( contextName => { - if ( contextName === 'root' ) return `root: root`; + if ( local.allUsedContexts.length ) { + const initialProps = local.allUsedContexts.map( contextName => { + if ( contextName === 'root' ) return `root: root`; - const listName = generator.current.listNames.get( contextName ); - const indexName = generator.current.indexNames.get( contextName ); + const listName = block.listNames.get( contextName ); + const indexName = block.indexNames.get( contextName ); - return `${listName}: ${listName},\n${indexName}: ${indexName}`; - }).join( ',\n' ); + return `${listName}: ${listName},\n${indexName}: ${indexName}`; + }).join( ',\n' ); - const updates = local.allUsedContexts.map( contextName => { - if ( contextName === 'root' ) return `${name}.__svelte.root = root;`; + const updates = local.allUsedContexts.map( contextName => { + if ( contextName === 'root' ) return `${name}.__svelte.root = root;`; - const listName = generator.current.listNames.get( contextName ); - const indexName = generator.current.indexNames.get( contextName ); + const listName = block.listNames.get( contextName ); + const indexName = block.indexNames.get( contextName ); - return `${name}.__svelte.${listName} = ${listName};\n${name}.__svelte.${indexName} = ${indexName};`; - }).join( '\n' ); + return `${name}.__svelte.${listName} = ${listName};\n${name}.__svelte.${indexName} = ${indexName};`; + }).join( '\n' ); - local.init.addBlock( deindent` - ${name}.__svelte = { - ${initialProps} - }; - ` ); + local.create.addBlock( deindent` + ${name}.__svelte = { + ${initialProps} + }; + ` ); - local.update.addBlock( updates ); - } + local.update.addBlock( updates ); + } - let render; + let render; - if ( local.namespace ) { - if ( local.namespace === 'http://www.w3.org/2000/svg' ) { - render = `var ${name} = ${generator.helper( 'createSvgElement' )}( '${node.name}' )`; - } else { - render = `var ${name} = document.createElementNS( '${local.namespace}', '${node.name}' );`; - } + if ( local.namespace ) { + if ( local.namespace === 'http://www.w3.org/2000/svg' ) { + render = `var ${name} = ${generator.helper( 'createSvgElement' )}( '${node.name}' )`; } else { - render = `var ${name} = ${generator.helper( 'createElement' )}( '${node.name}' );`; + render = `var ${name} = document.createElementNS( '${local.namespace}', '${node.name}' );`; } + } else { + render = `var ${name} = ${generator.helper( 'createElement' )}( '${node.name}' );`; + } - if ( generator.cssId && !generator.elementDepth ) { - render += `\n${generator.helper( 'setAttribute' )}( ${name}, '${generator.cssId}', '' );`; - } + if ( generator.cssId && state.isTopLevel ) { + render += `\n${generator.helper( 'setAttribute' )}( ${name}, '${generator.cssId}', '' );`; + } - local.init.addLineAtStart( render ); - if ( isToplevel ) { - generator.current.builders.detach.addLine( `${generator.helper( 'detachNode' )}( ${name} );` ); - } + local.create.addLineAtStart( render ); + if ( isToplevel ) { + block.builders.detach.addLine( `${generator.helper( 'detachNode' )}( ${name} );` ); + } - // special case – bound without a value attribute - if ( node.name === 'option' && !node.attributes.find( attribute => attribute.type === 'Attribute' && attribute.name === 'value' ) ) { // TODO check it's bound - const statement = `${name}.__value = ${name}.textContent;`; - local.update.addLine( statement ); - node.initialUpdate = statement; - } + // special case – bound without a value attribute + if ( node.name === 'option' && !node.attributes.find( attribute => attribute.type === 'Attribute' && attribute.name === 'value' ) ) { // TODO check it's bound + const statement = `${name}.__value = ${name}.textContent;`; + local.update.addLine( statement ); + node.initialUpdate = statement; + } - generator.current.builders.init.addBlock( local.init ); - if ( !local.update.isEmpty() ) generator.current.builders.update.addBlock( local.update ); - if ( !local.teardown.isEmpty() ) generator.current.builders.teardown.addBlock( local.teardown ); - - generator.createMountStatement( name ); - - generator.push({ - type: 'element', - namespace: local.namespace, - target: name, - parent: generator.current, - localElementDepth: generator.current.localElementDepth + 1, - key: null - }); - }, - - leave ( generator, node ) { - if ( node.name in meta ) { - if ( meta[ node.name ].leave ) meta[ node.name ].leave( generator, node ); - return; - } + block.builders.create.addBlock( local.create ); + if ( !local.update.isEmpty() ) block.builders.update.addBlock( local.update ); + if ( !local.destroy.isEmpty() ) block.builders.destroy.addBlock( local.destroy ); - const isComponent = generator.components.has( node.name ); + block.createMountStatement( name, state.parentNode ); - if ( isComponent ) { - return Component.leave( generator, node ); - } + const childState = Object.assign( {}, state, { + isTopLevel: false, + parentNode: name, + namespace: local.namespace + }); - if ( node.initialUpdate ) { - generator.current.builders.init.addBlock( node.initialUpdate ); - } + node.children.forEach( child => { + visit( generator, block, childState, child ); + }); - generator.pop(); + if ( node.initialUpdate ) { + block.builders.create.addBlock( node.initialUpdate ); } -}; +} \ No newline at end of file diff --git a/src/generators/dom/visitors/IfBlock.js b/src/generators/dom/visitors/IfBlock.js index 0de7e936b28d..837fa559fef3 100644 --- a/src/generators/dom/visitors/IfBlock.js +++ b/src/generators/dom/visitors/IfBlock.js @@ -1,20 +1,20 @@ import deindent from '../../../utils/deindent.js'; +import visit from '../visit.js'; -function getConditionsAndBlocks ( generator, node, _name, i = 0 ) { - generator.addSourcemapLocations( node.expression ); +function getConditionsAndBlocks ( generator, block, state, node, _name, i = 0 ) { const name = generator.getUniqueName( `${_name}_${i}` ); const conditionsAndBlocks = [{ - condition: generator.contextualise( node.expression ).snippet, + condition: generator.contextualise( block, node.expression ).snippet, block: name }]; - generator.generateBlock( node, name, 'block' ); + generateBlock( generator, block, state, node, name ); if ( node.else && node.else.children.length === 1 && node.else.children[0].type === 'IfBlock' ) { conditionsAndBlocks.push( - ...getConditionsAndBlocks( generator, node.else.children[0], _name, i + 1 ) + ...getConditionsAndBlocks( generator, block, state, node.else.children[0], _name, i + 1 ) ); } else { const name = generator.getUniqueName( `${_name}_${i + 1}` ); @@ -24,58 +24,72 @@ function getConditionsAndBlocks ( generator, node, _name, i = 0 ) { }); if ( node.else ) { - generator.generateBlock( node.else, name, 'block' ); + generateBlock( generator, block, state, node.else, name ); } } return conditionsAndBlocks; } -export default { - enter ( generator, node ) { - const params = generator.current.params.join( ', ' ); - const name = generator.getUniqueName( `if_block` ); - const getBlock = generator.current.getUniqueName( `get_block` ); - const currentBlock = generator.current.getUniqueName( `current_block` ); - const _currentBlock = generator.current.getUniqueName( `_current_block` ); - - const isToplevel = generator.current.localElementDepth === 0; - const conditionsAndBlocks = getConditionsAndBlocks( generator, node, generator.getUniqueName( `render_if_block` ) ); - - const anchor = `${name}_anchor`; - generator.createAnchor( anchor ); - - generator.current.builders.init.addBlock( deindent` - function ${getBlock} ( ${params} ) { - ${conditionsAndBlocks.map( ({ condition, block }) => { - return `${condition ? `if ( ${condition} ) ` : ''}return ${block};`; - } ).join( '\n' )} - } - - var ${currentBlock} = ${getBlock}( ${params} ); - var ${name} = ${currentBlock} && ${currentBlock}( ${params}, ${generator.current.component} ); - ` ); - - const mountStatement = `if ( ${name} ) ${name}.mount( ${anchor}.parentNode, ${anchor} );`; - if ( isToplevel ) { - generator.current.builders.mount.addLine( mountStatement ); - } else { - generator.current.builders.init.addLine( mountStatement ); +function generateBlock ( generator, block, state, node, name ) { + const childBlock = block.child({ + name + }); + + const childState = Object.assign( {}, state, { + parentNode: null + }); + + node.children.forEach( node => { + visit( generator, childBlock, childState, node ); + }); + + generator.addBlock( childBlock ); +} + +export default function visitIfBlock ( generator, block, state, node ) { + const params = block.params.join( ', ' ); + const name = generator.getUniqueName( `if_block` ); + const getBlock = block.getUniqueName( `get_block` ); + const currentBlock = block.getUniqueName( `current_block` ); + const _currentBlock = block.getUniqueName( `_current_block` ); + + const isToplevel = !state.parentNode; + const conditionsAndBlocks = getConditionsAndBlocks( generator, block, state, node, generator.getUniqueName( `create_if_block` ) ); + + const anchor = `${name}_anchor`; + block.createAnchor( anchor, state.parentNode ); + + block.builders.create.addBlock( deindent` + function ${getBlock} ( ${params} ) { + ${conditionsAndBlocks.map( ({ condition, block }) => { + return `${condition ? `if ( ${condition} ) ` : ''}return ${block};`; + } ).join( '\n' )} } - generator.current.builders.update.addBlock( deindent` - var ${_currentBlock} = ${currentBlock}; - ${currentBlock} = ${getBlock}( ${params} ); - if ( ${_currentBlock} === ${currentBlock} && ${name}) { - ${name}.update( changed, ${params} ); - } else { - if ( ${name} ) ${name}.teardown( true ); - ${name} = ${currentBlock} && ${currentBlock}( ${params}, ${generator.current.component} ); - if ( ${name} ) ${name}.mount( ${anchor}.parentNode, ${anchor} ); - } - ` ); - - generator.current.builders.teardown.addLine( - `if ( ${name} ) ${name}.teardown( ${isToplevel ? 'detach' : 'false'} );` - ); + var ${currentBlock} = ${getBlock}( ${params} ); + var ${name} = ${currentBlock} && ${currentBlock}( ${params}, ${block.component} ); + ` ); + + const mountStatement = `if ( ${name} ) ${name}.mount( ${anchor}.parentNode, ${anchor} );`; + if ( isToplevel ) { + block.builders.mount.addLine( mountStatement ); + } else { + block.builders.create.addLine( mountStatement ); } -}; + + block.builders.update.addBlock( deindent` + var ${_currentBlock} = ${currentBlock}; + ${currentBlock} = ${getBlock}( ${params} ); + if ( ${_currentBlock} === ${currentBlock} && ${name}) { + ${name}.update( changed, ${params} ); + } else { + if ( ${name} ) ${name}.destroy( true ); + ${name} = ${currentBlock} && ${currentBlock}( ${params}, ${block.component} ); + if ( ${name} ) ${name}.mount( ${anchor}.parentNode, ${anchor} ); + } + ` ); + + block.builders.destroy.addLine( + `if ( ${name} ) ${name}.destroy( ${isToplevel ? 'detach' : 'false'} );` + ); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/MustacheTag.js b/src/generators/dom/visitors/MustacheTag.js index 6e0ba72e637f..e6b6ee593a03 100644 --- a/src/generators/dom/visitors/MustacheTag.js +++ b/src/generators/dom/visitors/MustacheTag.js @@ -1,22 +1,16 @@ import deindent from '../../../utils/deindent.js'; -import findBlock from '../utils/findBlock.js'; -export default { - enter ( generator, node ) { - const name = generator.current.getUniqueName( 'text' ); +export default function visitMustacheTag ( generator, block, state, node ) { + const name = block.getUniqueName( 'text' ); - const { snippet } = generator.contextualise( node.expression ); + const { snippet } = generator.contextualise( block, node.expression ); - generator.current.builders.init.addLine( `var last_${name} = ${snippet};` ); - generator.addElement( name, `${generator.helper( 'createText' )}( last_${name} )`, true ); + block.builders.create.addLine( `var last_${name} = ${snippet};` ); + block.addElement( name, `${generator.helper( 'createText' )}( last_${name} )`, state.parentNode, true ); - const fragment = findBlock( generator.current ); - if ( !fragment.tmp ) fragment.tmp = fragment.getUniqueName( 'tmp' ); - - generator.current.builders.update.addBlock( deindent` - if ( ( ${fragment.tmp} = ${snippet} ) !== last_${name} ) { - ${name}.data = last_${name} = ${fragment.tmp}; - } - ` ); - } -}; + block.builders.update.addBlock( deindent` + if ( ( ${block.tmp()} = ${snippet} ) !== last_${name} ) { + ${name}.data = last_${name} = ${block.tmp()}; + } + ` ); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/RawMustacheTag.js b/src/generators/dom/visitors/RawMustacheTag.js index 2a5cf4638135..13a939805625 100644 --- a/src/generators/dom/visitors/RawMustacheTag.js +++ b/src/generators/dom/visitors/RawMustacheTag.js @@ -1,43 +1,37 @@ import deindent from '../../../utils/deindent.js'; -import findBlock from '../utils/findBlock.js'; -export default { - enter ( generator, node ) { - const name = generator.current.getUniqueName( 'raw' ); +export default function visitRawMustacheTag ( generator, block, state, node ) { + const name = block.getUniqueName( 'raw' ); - const { snippet } = generator.contextualise( node.expression ); + const { snippet } = generator.contextualise( block, node.expression ); - // we would have used comments here, but the `insertAdjacentHTML` api only - // exists for `Element`s. - const before = `${name}_before`; - generator.addElement( before, `${generator.helper( 'createElement' )}( 'noscript' )`, true ); + // we would have used comments here, but the `insertAdjacentHTML` api only + // exists for `Element`s. + const before = `${name}_before`; + block.addElement( before, `${generator.helper( 'createElement' )}( 'noscript' )`, state.parentNode, true ); - const after = `${name}_after`; - generator.addElement( after, `${generator.helper( 'createElement' )}( 'noscript' )`, true ); + const after = `${name}_after`; + block.addElement( after, `${generator.helper( 'createElement' )}( 'noscript' )`, state.parentNode, true ); - const isToplevel = generator.current.localElementDepth === 0; + const isToplevel = !state.parentNode; - generator.current.builders.init.addLine( `var last_${name} = ${snippet};` ); - const mountStatement = `${before}.insertAdjacentHTML( 'afterend', last_${name} );`; - const detachStatement = `${generator.helper( 'detachBetween' )}( ${before}, ${after} );`; + block.builders.create.addLine( `var last_${name} = ${snippet};` ); + const mountStatement = `${before}.insertAdjacentHTML( 'afterend', last_${name} );`; + const detachStatement = `${generator.helper( 'detachBetween' )}( ${before}, ${after} );`; - if ( isToplevel ) { - generator.current.builders.mount.addLine( mountStatement ); - } else { - generator.current.builders.init.addLine( mountStatement ); - } - - const fragment = findBlock( generator.current ); - if ( !fragment.tmp ) fragment.tmp = fragment.getUniqueName( 'tmp' ); + if ( isToplevel ) { + block.builders.mount.addLine( mountStatement ); + } else { + block.builders.create.addLine( mountStatement ); + } - generator.current.builders.update.addBlock( deindent` - if ( ( ${fragment.tmp} = ${snippet} ) !== last_${name} ) { - last_${name} = ${fragment.tmp}; - ${detachStatement} - ${mountStatement} - } - ` ); + block.builders.update.addBlock( deindent` + if ( ( ${block.tmp()} = ${snippet} ) !== last_${name} ) { + last_${name} = ${block.tmp()}; + ${detachStatement} + ${mountStatement} + } + ` ); - generator.current.builders.detachRaw.addBlock( detachStatement ); - } -}; + block.builders.detachRaw.addBlock( detachStatement ); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/Text.js b/src/generators/dom/visitors/Text.js index ac1207bc862a..aae2dae3e50c 100644 --- a/src/generators/dom/visitors/Text.js +++ b/src/generators/dom/visitors/Text.js @@ -1,10 +1,8 @@ -export default { - enter ( generator, node ) { - if ( generator.current.namespace && !/\S/.test( node.data ) ) { - return; - } - - const name = generator.current.getUniqueName( `text` ); - generator.addElement( name, `${generator.helper( 'createText' )}( ${JSON.stringify( node.data )} )`, false ); +export default function visitText ( generator, block, state, node ) { + if ( state.namespace && !/\S/.test( node.data ) ) { + return; } -}; + + const name = block.getUniqueName( `text` ); + block.addElement( name, `${generator.helper( 'createText' )}( ${JSON.stringify( node.data )} )`, state.parentNode, false ); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/YieldTag.js b/src/generators/dom/visitors/YieldTag.js index 46dc3152c901..f64b12f92c8b 100644 --- a/src/generators/dom/visitors/YieldTag.js +++ b/src/generators/dom/visitors/YieldTag.js @@ -1,14 +1,12 @@ -export default { - enter ( generator ) { - const anchor = `yield_anchor`; - generator.createAnchor( anchor ); +export default function visitYieldTag ( generator, block, state ) { + const anchor = `yield_anchor`; + block.createAnchor( anchor, state.parentNode ); - generator.current.builders.mount.addLine( - `${generator.current.component}._yield && ${generator.current.component}._yield.mount( ${generator.current.target}, ${anchor} );` - ); + block.builders.mount.addLine( + `${block.component}._yield && ${block.component}._yield.mount( ${state.parentNode || 'target'}, ${anchor} );` + ); - generator.current.builders.teardown.addLine( - `${generator.current.component}._yield && ${generator.current.component}._yield.teardown( detach );` - ); - } -}; + block.builders.destroy.addLine( + `${block.component}._yield && ${block.component}._yield.destroy( detach );` + ); +} \ No newline at end of file diff --git a/src/generators/dom/visitors/attributes/addComponentAttributes.js b/src/generators/dom/visitors/attributes/addComponentAttributes.js index d2e0d48443bb..b659592d5254 100644 --- a/src/generators/dom/visitors/attributes/addComponentAttributes.js +++ b/src/generators/dom/visitors/attributes/addComponentAttributes.js @@ -1,7 +1,7 @@ import addComponentBinding from './addComponentBinding.js'; import deindent from '../../../../utils/deindent.js'; -export default function addComponentAttributes ( generator, node, local ) { +export default function addComponentAttributes ( generator, block, node, local ) { local.staticAttributes = []; local.dynamicAttributes = []; local.bindings = []; @@ -37,7 +37,7 @@ export default function addComponentAttributes ( generator, node, local ) { else { // simple dynamic attributes - const { dependencies, string } = generator.contextualise( value.expression ); + const { dependencies, string } = generator.contextualise( block, value.expression ); // TODO only update attributes that have changed local.dynamicAttributes.push({ @@ -57,7 +57,7 @@ export default function addComponentAttributes ( generator, node, local ) { if ( chunk.type === 'Text' ) { return JSON.stringify( chunk.data ); } else { - const { dependencies, string } = generator.contextualise( chunk.expression ); + const { dependencies, string } = generator.contextualise( block, chunk.expression ); dependencies.forEach( dependency => { if ( !~allDependencies.indexOf( dependency ) ) allDependencies.push( dependency ); }); @@ -78,11 +78,11 @@ export default function addComponentAttributes ( generator, node, local ) { else if ( attribute.type === 'EventHandler' ) { // 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, `${generator.current.component}.` ); + generator.code.prependRight( attribute.expression.start, `${block.component}.` ); const usedContexts = []; attribute.expression.arguments.forEach( arg => { - const { contexts } = generator.contextualise( arg, true ); + const { contexts } = generator.contextualise( block, arg, true ); contexts.forEach( context => { if ( !~usedContexts.indexOf( context ) ) usedContexts.push( context ); @@ -94,15 +94,15 @@ export default function addComponentAttributes ( generator, node, local ) { const declarations = usedContexts.map( name => { if ( name === 'root' ) return 'var root = this._context.root;'; - const listName = generator.current.listNames.get( name ); - const indexName = generator.current.indexNames.get( name ); + const listName = block.listNames.get( name ); + const indexName = block.indexNames.get( name ); return `var ${listName} = this._context.${listName}, ${indexName} = this._context.${indexName}, ${name} = ${listName}[${indexName}]`; }); const handlerBody = ( declarations.length ? declarations.join( '\n' ) + '\n\n' : '' ) + `[✂${attribute.expression.start}-${attribute.expression.end}✂];`; - local.init.addBlock( deindent` + local.create.addBlock( deindent` ${local.name}.on( '${attribute.name}', function ( event ) { ${handlerBody} }); @@ -110,18 +110,18 @@ export default function addComponentAttributes ( generator, node, local ) { } else if ( attribute.type === 'Binding' ) { - addComponentBinding( generator, node, attribute, generator.current, local ); + addComponentBinding( generator, node, attribute, block, local ); } else if ( attribute.type === 'Ref' ) { generator.usesRefs = true; - local.init.addLine( - `${generator.current.component}.refs.${attribute.name} = ${local.name};` + local.create.addLine( + `${block.component}.refs.${attribute.name} = ${local.name};` ); - generator.current.builders.teardown.addLine( deindent` - if ( ${generator.current.component}.refs.${attribute.name} === ${local.name} ) ${generator.current.component}.refs.${attribute.name} = null; + block.builders.destroy.addLine( deindent` + if ( ${block.component}.refs.${attribute.name} === ${local.name} ) ${block.component}.refs.${attribute.name} = null; ` ); } diff --git a/src/generators/dom/visitors/attributes/addComponentBinding.js b/src/generators/dom/visitors/attributes/addComponentBinding.js index 07ae7fefe811..10482fee5c2a 100644 --- a/src/generators/dom/visitors/attributes/addComponentBinding.js +++ b/src/generators/dom/visitors/attributes/addComponentBinding.js @@ -2,9 +2,9 @@ import deindent from '../../../../utils/deindent.js'; import flattenReference from '../../../../utils/flattenReference.js'; import getSetter from './binding/getSetter.js'; -export default function createBinding ( generator, node, attribute, current, local ) { +export default function addComponentBinding ( generator, node, attribute, block, local ) { const { name, keypath } = flattenReference( attribute.value ); - const { snippet, contexts, dependencies } = generator.contextualise( attribute.value ); + const { snippet, contexts, dependencies } = generator.contextualise( block, attribute.value ); if ( dependencies.length > 1 ) throw new Error( 'An unexpected situation arose. Please raise an issue at https://github.com/sveltejs/svelte/issues — thanks!' ); @@ -12,14 +12,14 @@ export default function createBinding ( generator, node, attribute, current, loc if ( !~local.allUsedContexts.indexOf( context ) ) local.allUsedContexts.push( context ); }); - const contextual = current.contexts.has( name ); + const contextual = block.contexts.has( name ); let obj; let prop; if ( contextual ) { - obj = current.listNames.get( name ); - prop = current.indexNames.get( name ); + obj = block.listNames.get( name ); + prop = block.indexNames.get( name ); } else if ( attribute.value.type === 'MemberExpression' ) { prop = `'[✂${attribute.value.property.start}-${attribute.value.property.end}✂]'`; obj = `[✂${attribute.value.object.start}-${attribute.value.object.end}✂]`; @@ -35,16 +35,16 @@ export default function createBinding ( generator, node, attribute, current, loc prop }); - const setter = getSetter({ current, name, keypath, context: '_context', attribute, dependencies, value: 'value' }); + const setter = getSetter({ block, name, keypath, context: '_context', attribute, dependencies, value: 'value' }); generator.hasComplexBindings = true; - const updating = generator.current.getUniqueName( `${local.name}_updating` ); + const updating = block.getUniqueName( `${local.name}_updating` ); - local.init.addBlock( deindent` + local.create.addBlock( deindent` var ${updating} = false; - ${generator.current.component}._bindings.push( function () { + ${block.component}._bindings.push( function () { if ( ${local.name}._torndown ) return; ${local.name}.observe( '${attribute.name}', function ( value ) { if ( ${updating} ) return; diff --git a/src/generators/dom/visitors/attributes/addElementAttributes.js b/src/generators/dom/visitors/attributes/addElementAttributes.js index 2d96cc73bf44..8936db3d1795 100644 --- a/src/generators/dom/visitors/attributes/addElementAttributes.js +++ b/src/generators/dom/visitors/attributes/addElementAttributes.js @@ -3,9 +3,8 @@ import addElementBinding from './addElementBinding'; import deindent from '../../../../utils/deindent.js'; import flattenReference from '../../../../utils/flattenReference.js'; import getStaticAttributeValue from './binding/getStaticAttributeValue.js'; -import findBlock from '../../utils/findBlock.js'; -export default function addElementAttributes ( generator, node, local ) { +export default function addElementAttributes ( generator, block, node, local ) { node.attributes.forEach( attribute => { const name = attribute.name; @@ -32,28 +31,28 @@ export default function addElementAttributes ( generator, node, local ) { if ( attribute.value === true ) { // attributes without values, e.g. if ( propertyName ) { - local.init.addLine( + local.create.addLine( `${local.name}.${propertyName} = true;` ); } else { - local.init.addLine( + local.create.addLine( `${generator.helper( method )}( ${local.name}, '${name}', true );` ); } // special case – autofocus. has to be handled in a bit of a weird way if ( name === 'autofocus' ) { - generator.current.autofocus = local.name; + block.autofocus = local.name; } } else if ( attribute.value.length === 0 ) { if ( propertyName ) { - local.init.addLine( + local.create.addLine( `${local.name}.${propertyName} = '';` ); } else { - local.init.addLine( + local.create.addLine( `${generator.helper( method )}( ${local.name}, '${name}', '' );` ); } @@ -75,7 +74,7 @@ export default function addElementAttributes ( generator, node, local ) { local.namespace = value.data; addAttribute = true; } else if ( propertyName ) { - local.init.addLine( + local.create.addLine( `${local.name}.${propertyName} = ${result};` ); } else { @@ -83,7 +82,7 @@ export default function addElementAttributes ( generator, node, local ) { } if ( addAttribute ) { - local.init.addLine( + local.create.addLine( `${generator.helper( method )}( ${local.name}, '${name}', ${result} );` ); } @@ -93,10 +92,10 @@ export default function addElementAttributes ( generator, node, local ) { dynamic = true; // dynamic – but potentially non-string – attributes - const { snippet } = generator.contextualise( value.expression ); + const { snippet } = generator.contextualise( block, value.expression ); const last = `last_${local.name}_${name.replace( /-/g, '_')}`; - local.init.addLine( `var ${last} = ${snippet};` ); + local.create.addLine( `var ${last} = ${snippet};` ); let updater; if ( propertyName ) { @@ -105,13 +104,11 @@ export default function addElementAttributes ( generator, node, local ) { updater = `${generator.helper( method )}( ${local.name}, '${name}', ${last} );`; } - local.init.addLine( updater ); - const fragment = findBlock( generator.current ); - if ( !fragment.tmp ) fragment.tmp = fragment.getUniqueName( 'tmp' ); + local.create.addLine( updater ); local.update.addBlock( deindent` - if ( ( ${fragment.tmp} = ${snippet} ) !== ${last} ) { - ${last} = ${fragment.tmp}; + if ( ( ${block.tmp()} = ${snippet} ) !== ${last} ) { + ${last} = ${block.tmp()}; ${updater} } ` ); @@ -126,7 +123,7 @@ export default function addElementAttributes ( generator, node, local ) { if ( chunk.type === 'Text' ) { return JSON.stringify( chunk.data ); } else { - const { snippet } = generator.contextualise( chunk.expression ); + const { snippet } = generator.contextualise( block, chunk.expression ); return `( ${snippet} )`; } }).join( ' + ' ) @@ -139,14 +136,14 @@ export default function addElementAttributes ( generator, node, local ) { updater = `${generator.helper( method )}( ${local.name}, '${name}', ${value} );`; } - local.init.addLine( updater ); + local.create.addLine( updater ); local.update.addLine( updater ); } if ( isIndirectlyBoundValue ) { const updateValue = `${local.name}.value = ${local.name}.__value;`; - local.init.addLine( updateValue ); + local.create.addLine( updateValue ); if ( dynamic ) local.update.addLine( updateValue ); } } @@ -158,12 +155,12 @@ export default function addElementAttributes ( generator, node, local ) { const flattened = flattenReference( attribute.expression.callee ); if ( flattened.name !== 'event' && flattened.name !== 'this' ) { // allow event.stopPropagation(), this.select() etc - generator.code.prependRight( attribute.expression.start, `${generator.current.component}.` ); + generator.code.prependRight( attribute.expression.start, `${block.component}.` ); } const usedContexts = []; attribute.expression.arguments.forEach( arg => { - const { contexts } = generator.contextualise( arg, true ); + const { contexts } = generator.contextualise( block, arg, true ); contexts.forEach( context => { if ( !~usedContexts.indexOf( context ) ) usedContexts.push( context ); @@ -175,27 +172,27 @@ export default function addElementAttributes ( generator, node, local ) { const declarations = usedContexts.map( name => { if ( name === 'root' ) return 'var root = this.__svelte.root;'; - const listName = generator.current.listNames.get( name ); - const indexName = generator.current.indexNames.get( name ); + const listName = block.listNames.get( name ); + const indexName = block.indexNames.get( name ); return `var ${listName} = this.__svelte.${listName}, ${indexName} = this.__svelte.${indexName}, ${name} = ${listName}[${indexName}]`; }); - const handlerName = generator.current.getUniqueName( `${name}_handler` ); + const handlerName = block.getUniqueName( `${name}_handler` ); const handlerBody = ( declarations.length ? declarations.join( '\n' ) + '\n\n' : '' ) + `[✂${attribute.expression.start}-${attribute.expression.end}✂];`; if ( generator.events.has( name ) ) { - local.init.addBlock( deindent` - var ${handlerName} = ${generator.alias( 'template' )}.events.${name}.call( ${generator.current.component}, ${local.name}, function ( event ) { + local.create.addBlock( deindent` + var ${handlerName} = ${generator.alias( 'template' )}.events.${name}.call( ${block.component}, ${local.name}, function ( event ) { ${handlerBody} }.bind( ${local.name} ) ); ` ); - generator.current.builders.teardown.addLine( deindent` + block.builders.destroy.addLine( deindent` ${handlerName}.teardown(); ` ); } else { - local.init.addBlock( deindent` + local.create.addBlock( deindent` function ${handlerName} ( event ) { ${handlerBody} } @@ -203,25 +200,25 @@ export default function addElementAttributes ( generator, node, local ) { ${generator.helper( 'addEventListener' )}( ${local.name}, '${name}', ${handlerName} ); ` ); - generator.current.builders.teardown.addLine( deindent` + block.builders.destroy.addLine( deindent` ${generator.helper( 'removeEventListener' )}( ${local.name}, '${name}', ${handlerName} ); ` ); } } else if ( attribute.type === 'Binding' ) { - addElementBinding( generator, node, attribute, generator.current, local ); + addElementBinding( generator, node, attribute, block, local ); } else if ( attribute.type === 'Ref' ) { generator.usesRefs = true; - local.init.addLine( - `${generator.current.component}.refs.${name} = ${local.name};` + local.create.addLine( + `${block.component}.refs.${name} = ${local.name};` ); - generator.current.builders.teardown.addLine( deindent` - if ( ${generator.current.component}.refs.${name} === ${local.name} ) ${generator.current.component}.refs.${name} = null; + block.builders.destroy.addLine( deindent` + if ( ${block.component}.refs.${name} === ${local.name} ) ${block.component}.refs.${name} = null; ` ); } diff --git a/src/generators/dom/visitors/attributes/addElementBinding.js b/src/generators/dom/visitors/attributes/addElementBinding.js index eea65eda9395..9ef82b303f13 100644 --- a/src/generators/dom/visitors/attributes/addElementBinding.js +++ b/src/generators/dom/visitors/attributes/addElementBinding.js @@ -3,9 +3,9 @@ import flattenReference from '../../../../utils/flattenReference.js'; import getSetter from './binding/getSetter.js'; import getStaticAttributeValue from './binding/getStaticAttributeValue.js'; -export default function createBinding ( generator, node, attribute, current, local ) { +export default function addElementBinding ( generator, node, attribute, block, local ) { const { name, keypath } = flattenReference( attribute.value ); - const { snippet, contexts, dependencies } = generator.contextualise( attribute.value ); + const { snippet, contexts, dependencies } = generator.contextualise( block, attribute.value ); if ( dependencies.length > 1 ) throw new Error( 'An unexpected situation arose. Please raise an issue at https://github.com/sveltejs/svelte/issues — thanks!' ); @@ -13,15 +13,15 @@ export default function createBinding ( generator, node, attribute, current, loc if ( !~local.allUsedContexts.indexOf( context ) ) local.allUsedContexts.push( context ); }); - const handler = current.getUniqueName( `${local.name}_change_handler` ); + const handler = block.getUniqueName( `${local.name}_change_handler` ); const isMultipleSelect = node.name === 'select' && node.attributes.find( attr => attr.name.toLowerCase() === 'multiple' ); // TODO use getStaticAttributeValue const type = getStaticAttributeValue( node, 'type' ); - const bindingGroup = attribute.name === 'group' ? getBindingGroup( generator, current, attribute, keypath ) : null; - const value = getBindingValue( generator, local, node, attribute, isMultipleSelect, bindingGroup, type ); + const bindingGroup = attribute.name === 'group' ? getBindingGroup( generator, keypath ) : null; + const value = getBindingValue( generator, block, local, node, attribute, isMultipleSelect, bindingGroup, type ); const eventName = getBindingEventName( node ); - let setter = getSetter({ current, name, keypath, context: '__svelte', attribute, dependencies, value }); + let setter = getSetter({ block, name, keypath, context: '__svelte', attribute, dependencies, value }); let updateElement; // special case @@ -30,9 +30,9 @@ export default function createBinding ( generator, node, attribute, current, loc setter = `var selectedOption = ${local.name}.selectedOptions[0] || ${local.name}.options[0];\n${setter}`; } - const value = current.getUniqueName( 'value' ); - const i = current.getUniqueName( 'i' ); - const option = current.getUniqueName( 'option' ); + const value = block.getUniqueName( 'value' ); + const i = block.getUniqueName( 'i' ); + const option = block.getUniqueName( 'option' ); const ifStatement = isMultipleSelect ? deindent` @@ -66,12 +66,12 @@ export default function createBinding ( generator, node, attribute, current, loc `~${snippet}.indexOf( ${local.name}.__value )` : `${local.name}.__value === ${snippet}`; - local.init.addLine( - `${current.component}._bindingGroups[${bindingGroup}].push( ${local.name} );` + local.create.addLine( + `${block.component}._bindingGroups[${bindingGroup}].push( ${local.name} );` ); - local.teardown.addBlock( - `${current.component}._bindingGroups[${bindingGroup}].splice( ${current.component}._bindingGroups[${bindingGroup}].indexOf( ${local.name} ), 1 );` + local.destroy.addBlock( + `${block.component}._bindingGroups[${bindingGroup}].splice( ${block.component}._bindingGroups[${bindingGroup}].indexOf( ${local.name} ), 1 );` ); updateElement = `${local.name}.checked = ${condition};`; @@ -82,9 +82,9 @@ export default function createBinding ( generator, node, attribute, current, loc updateElement = `${local.name}.${attribute.name} = ${snippet};`; } - const updating = generator.current.getUniqueName( `${local.name}_updating` ); + const updating = block.getUniqueName( `${local.name}_updating` ); - local.init.addBlock( deindent` + local.create.addBlock( deindent` var ${updating} = false; function ${handler} () { @@ -104,7 +104,7 @@ export default function createBinding ( generator, node, attribute, current, loc } ` ); - current.builders.teardown.addLine( deindent` + block.builders.destroy.addLine( deindent` ${generator.helper( 'removeEventListener' )}( ${local.name}, '${eventName}', ${handler} ); ` ); } @@ -124,7 +124,7 @@ function getBindingEventName ( node ) { return 'change'; } -function getBindingValue ( generator, local, node, attribute, isMultipleSelect, bindingGroup, type ) { +function getBindingValue ( generator, block, local, node, attribute, isMultipleSelect, bindingGroup, type ) { // if ( attribute.name === 'group' ) { if ( type === 'checkbox' ) { - return `${generator.helper( 'getBindingGroupValue' )}( ${generator.current.component}._bindingGroups[${bindingGroup}] )`; + return `${generator.helper( 'getBindingGroupValue' )}( ${block.component}._bindingGroups[${bindingGroup}] )`; } return `${local.name}.__value`; @@ -153,7 +153,7 @@ function getBindingValue ( generator, local, node, attribute, isMultipleSelect, return `${local.name}.${attribute.name}`; } -function getBindingGroup ( generator, current, attribute, keypath ) { +function getBindingGroup ( generator, keypath ) { // TODO handle contextual bindings — `keypath` should include unique ID of // each block that provides context let index = generator.bindingGroups.indexOf( keypath ); diff --git a/src/generators/dom/visitors/attributes/binding/getSetter.js b/src/generators/dom/visitors/attributes/binding/getSetter.js index c6bf99c0c229..852ea83fa7f3 100644 --- a/src/generators/dom/visitors/attributes/binding/getSetter.js +++ b/src/generators/dom/visitors/attributes/binding/getSetter.js @@ -1,28 +1,28 @@ import deindent from '../../../../../utils/deindent.js'; -export default function getSetter ({ current, name, keypath, context, attribute, dependencies, value }) { - if ( current.contexts.has( name ) ) { +export default function getSetter ({ block, name, keypath, context, attribute, dependencies, value }) { + if ( block.contexts.has( name ) ) { const prop = dependencies[0]; const tail = attribute.value.type === 'MemberExpression' ? getTailSnippet( attribute.value ) : ''; return deindent` - var list = this.${context}.${current.listNames.get( name )}; - var index = this.${context}.${current.indexNames.get( name )}; + var list = this.${context}.${block.listNames.get( name )}; + var index = this.${context}.${block.indexNames.get( name )}; list[index]${tail} = ${value}; - ${current.component}._set({ ${prop}: ${current.component}.get( '${prop}' ) }); + ${block.component}._set({ ${prop}: ${block.component}.get( '${prop}' ) }); `; } if ( attribute.value.type === 'MemberExpression' ) { return deindent` - var ${name} = ${current.component}.get( '${name}' ); + var ${name} = ${block.component}.get( '${name}' ); ${keypath} = ${value}; - ${current.component}._set({ ${name}: ${name} }); + ${block.component}._set({ ${name}: ${name} }); `; } - return `${current.component}._set({ ${name}: ${value} });`; + return `${block.component}._set({ ${name}: ${value} });`; } function getTailSnippet ( node ) { diff --git a/src/generators/dom/visitors/meta/Window.js b/src/generators/dom/visitors/meta/Window.js index e1d5cb7b4369..e9ae4f6f371f 100644 --- a/src/generators/dom/visitors/meta/Window.js +++ b/src/generators/dom/visitors/meta/Window.js @@ -11,74 +11,72 @@ const associatedEvents = { scrollY: 'scroll' }; -export default { - enter ( generator, node ) { - const events = {}; - - node.attributes.forEach( attribute => { - if ( attribute.type === 'EventHandler' ) { - // TODO verify that it's a valid callee (i.e. built-in or declared method) - generator.addSourcemapLocations( attribute.expression ); - - const flattened = flattenReference( attribute.expression.callee ); - if ( flattened.name !== 'event' && flattened.name !== 'this' ) { - // allow event.stopPropagation(), this.select() etc - generator.code.prependRight( attribute.expression.start, 'component.' ); - } - - const handlerName = generator.current.getUniqueName( `onwindow${attribute.name}` ); - - generator.current.builders.init.addBlock( deindent` - var ${handlerName} = function ( event ) { - [✂${attribute.expression.start}-${attribute.expression.end}✂]; - }; - window.addEventListener( '${attribute.name}', ${handlerName} ); - ` ); - - generator.current.builders.teardown.addBlock( deindent` - window.removeEventListener( '${attribute.name}', ${handlerName} ); - ` ); +export default function visitWindow ( generator, block, node ) { + const events = {}; + + node.attributes.forEach( attribute => { + if ( attribute.type === 'EventHandler' ) { + // TODO verify that it's a valid callee (i.e. built-in or declared method) + generator.addSourcemapLocations( attribute.expression ); + + const flattened = flattenReference( attribute.expression.callee ); + if ( flattened.name !== 'event' && flattened.name !== 'this' ) { + // allow event.stopPropagation(), this.select() etc + generator.code.prependRight( attribute.expression.start, 'component.' ); } - if ( attribute.type === 'Binding' ) { - const associatedEvent = associatedEvents[ attribute.name ]; + const handlerName = block.getUniqueName( `onwindow${attribute.name}` ); - if ( !associatedEvent ) { - throw new Error( `Cannot bind to ${attribute.name} on <:Window>` ); - } + block.builders.create.addBlock( deindent` + var ${handlerName} = function ( event ) { + [✂${attribute.expression.start}-${attribute.expression.end}✂]; + }; + window.addEventListener( '${attribute.name}', ${handlerName} ); + ` ); - if ( attribute.value.type !== 'Identifier' ) { - const { parts, keypath } = flattenReference( attribute.value ); - throw new Error( `Bindings on <:Window/> must be to top-level properties, e.g. '${parts.pop()}' rather than '${keypath}'` ); - } + block.builders.destroy.addBlock( deindent` + window.removeEventListener( '${attribute.name}', ${handlerName} ); + ` ); + } - if ( !events[ associatedEvent ] ) events[ associatedEvent ] = []; - events[ associatedEvent ].push( `${attribute.value.name}: this.${attribute.name}` ); + if ( attribute.type === 'Binding' ) { + const associatedEvent = associatedEvents[ attribute.name ]; - // add initial value - generator.builders.metaBindings.addLine( - `this._state.${attribute.value.name} = window.${attribute.name};` - ); + if ( !associatedEvent ) { + throw new Error( `Cannot bind to ${attribute.name} on <:Window>` ); } - }); - - Object.keys( events ).forEach( event => { - const handlerName = generator.current.getUniqueName( `onwindow${event}` ); - - const props = events[ event ].join( ',\n' ); - generator.current.builders.init.addBlock( deindent` - var ${handlerName} = function ( event ) { - component.set({ - ${props} - }); - }; - window.addEventListener( '${event}', ${handlerName} ); - ` ); + if ( attribute.value.type !== 'Identifier' ) { + const { parts, keypath } = flattenReference( attribute.value ); + throw new Error( `Bindings on <:Window/> must be to top-level properties, e.g. '${parts.pop()}' rather than '${keypath}'` ); + } - generator.current.builders.teardown.addBlock( deindent` - window.removeEventListener( '${event}', ${handlerName} ); - ` ); - }); - } -}; + if ( !events[ associatedEvent ] ) events[ associatedEvent ] = []; + events[ associatedEvent ].push( `${attribute.value.name}: this.${attribute.name}` ); + + // add initial value + generator.builders.metaBindings.addLine( + `this._state.${attribute.value.name} = window.${attribute.name};` + ); + } + }); + + Object.keys( events ).forEach( event => { + const handlerName = block.getUniqueName( `onwindow${event}` ); + + const props = events[ event ].join( ',\n' ); + + block.builders.create.addBlock( deindent` + var ${handlerName} = function ( event ) { + component.set({ + ${props} + }); + }; + window.addEventListener( '${event}', ${handlerName} ); + ` ); + + block.builders.destroy.addBlock( deindent` + window.removeEventListener( '${event}', ${handlerName} ); + ` ); + }); +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/Block.js b/src/generators/server-side-rendering/Block.js new file mode 100644 index 000000000000..9f9a21345378 --- /dev/null +++ b/src/generators/server-side-rendering/Block.js @@ -0,0 +1,30 @@ +import deindent from '../../utils/deindent.js'; +import flattenReference from '../../utils/flattenReference.js'; + +export default class Block { + constructor ( options ) { + Object.assign( this, options ); + } + + addBinding ( binding, name ) { + const conditions = [ `!( '${binding.name}' in root )`].concat( // TODO handle contextual bindings... + this.conditions.map( c => `(${c})` ) + ); + + const { keypath } = flattenReference( binding.value ); + + this.generator.bindings.push( deindent` + if ( ${conditions.join( '&&' )} ) { + tmp = ${name}.data(); + if ( '${keypath}' in tmp ) { + root.${binding.name} = tmp.${keypath}; + settled = false; + } + } + ` ); + } + + child ( options ) { + return new Block( Object.assign( {}, this, options, { parent: this } ) ); + } +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/index.js b/src/generators/server-side-rendering/index.js index c28b4aeef9cb..80caa90f86f9 100644 --- a/src/generators/server-side-rendering/index.js +++ b/src/generators/server-side-rendering/index.js @@ -1,34 +1,16 @@ import deindent from '../../utils/deindent.js'; import CodeBuilder from '../../utils/CodeBuilder.js'; -import flattenReference from '../../utils/flattenReference.js'; -import visitors from './visitors/index.js'; import Generator from '../Generator.js'; +import Block from './Block.js'; +import visit from './visit.js'; class SsrGenerator extends Generator { - constructor ( parsed, source, name, visitors, options ) { - super( parsed, source, name, visitors, options ); + constructor ( parsed, source, name, options ) { + super( parsed, source, name, options ); this.bindings = []; this.renderCode = ''; } - addBinding ( binding, name ) { - const conditions = [ `!( '${binding.name}' in root )`].concat( // TODO handle contextual bindings... - this.current.conditions.map( c => `(${c})` ) - ); - - const { keypath } = flattenReference( binding.value ); - - this.bindings.push( deindent` - if ( ${conditions.join( '&&' )} ) { - tmp = ${name}.data(); - if ( '${keypath}' in tmp ) { - root.${binding.name} = tmp.${keypath}; - settled = false; - } - } - ` ); - } - append ( code ) { this.renderCode += code; } @@ -38,7 +20,7 @@ export default function ssr ( parsed, source, options ) { const format = options.format || 'cjs'; const name = options.name || 'SvelteComponent'; - const generator = new SsrGenerator( parsed, source, name, visitors, options ); + const generator = new SsrGenerator( parsed, source, name, options ); const { computations, hasJs, templateProperties } = generator.parseJs( true ); @@ -50,13 +32,16 @@ export default function ssr ( parsed, source, options ) { }; // create main render() function - generator.push({ + const mainBlock = new Block({ + generator, contexts: new Map(), indexes: new Map(), conditions: [] }); - parsed.html.children.forEach( node => generator.visit( node ) ); + parsed.html.children.forEach( node => { + visit( generator, mainBlock, node ); + }); builders.render.addLine( templateProperties.data ? `root = Object.assign( ${generator.alias( 'template' )}.data(), root || {} );` : `root = root || {};` diff --git a/src/generators/server-side-rendering/visit.js b/src/generators/server-side-rendering/visit.js new file mode 100644 index 000000000000..1b96ed510ba6 --- /dev/null +++ b/src/generators/server-side-rendering/visit.js @@ -0,0 +1,6 @@ +import visitors from './visitors/index.js'; + +export default function visit ( generator, fragment, node ) { + const visitor = visitors[ node.type ]; + visitor( generator, fragment, node ); +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/visitors/Comment.js b/src/generators/server-side-rendering/visitors/Comment.js index f32a1e64a8bd..4d3477d7ef0d 100644 --- a/src/generators/server-side-rendering/visitors/Comment.js +++ b/src/generators/server-side-rendering/visitors/Comment.js @@ -1,3 +1,3 @@ -export default { +export default function visitComment () { // do nothing -}; +} diff --git a/src/generators/server-side-rendering/visitors/Component.js b/src/generators/server-side-rendering/visitors/Component.js index aef098a02455..2c718484c56a 100644 --- a/src/generators/server-side-rendering/visitors/Component.js +++ b/src/generators/server-side-rendering/visitors/Component.js @@ -1,72 +1,77 @@ import flattenReference from '../../../utils/flattenReference.js'; +import visit from '../visit.js'; -export default { - enter ( generator, node ) { - function stringify ( chunk ) { - if ( chunk.type === 'Text' ) return chunk.data; - if ( chunk.type === 'MustacheTag' ) { - const { snippet } = generator.contextualise( chunk.expression ); - return '${__escape( ' + snippet + ')}'; - } +export default function visitComponent ( generator, block, node ) { + function stringify ( chunk ) { + if ( chunk.type === 'Text' ) return chunk.data; + if ( chunk.type === 'MustacheTag' ) { + const { snippet } = generator.contextualise( block, chunk.expression ); + return '${__escape( ' + snippet + ')}'; } + } - const attributes = []; - const bindings = []; + const attributes = []; + const bindings = []; - node.attributes.forEach( attribute => { - if ( attribute.type === 'Attribute' ) { - attributes.push( attribute ); - } else if ( attribute.type === 'Binding' ) { - bindings.push( attribute ); - } - }); + node.attributes.forEach( attribute => { + if ( attribute.type === 'Attribute' ) { + attributes.push( attribute ); + } else if ( attribute.type === 'Binding' ) { + bindings.push( attribute ); + } + }); - const props = attributes - .map( attribute => { - let value; + const props = attributes + .map( attribute => { + let value; - if ( attribute.value === true ) { - value = `true`; - } else if ( attribute.value.length === 0 ) { - value = `''`; - } else if ( attribute.value.length === 1 ) { - const chunk = attribute.value[0]; - if ( chunk.type === 'Text' ) { - value = isNaN( chunk.data ) ? JSON.stringify( chunk.data ) : chunk.data; - } else { - const { snippet } = generator.contextualise( chunk.expression ); - value = snippet; - } + if ( attribute.value === true ) { + value = `true`; + } else if ( attribute.value.length === 0 ) { + value = `''`; + } else if ( attribute.value.length === 1 ) { + const chunk = attribute.value[0]; + if ( chunk.type === 'Text' ) { + value = isNaN( chunk.data ) ? JSON.stringify( chunk.data ) : chunk.data; } else { - value = '`' + attribute.value.map( stringify ).join( '' ) + '`'; + const { snippet } = generator.contextualise( block, chunk.expression ); + value = snippet; } + } else { + value = '`' + attribute.value.map( stringify ).join( '' ) + '`'; + } - return `${attribute.name}: ${value}`; - }) - .concat( bindings.map( binding => { - const { name, keypath } = flattenReference( binding.value ); - const value = generator.current.contexts.has( name ) ? keypath : `root.${keypath}`; - return `${binding.name}: ${value}`; - })) - .join( ', ' ); + return `${attribute.name}: ${value}`; + }) + .concat( bindings.map( binding => { + const { name, keypath } = flattenReference( binding.value ); + const value = block.contexts.has( name ) ? keypath : `root.${keypath}`; + return `${binding.name}: ${value}`; + })) + .join( ', ' ); - const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${generator.alias( 'template' )}.components.${node.name}`; + const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${generator.alias( 'template' )}.components.${node.name}`; - bindings.forEach( binding => { - generator.addBinding( binding, expression ); - }); + bindings.forEach( binding => { + block.addBinding( binding, expression ); + }); - let open = `\${${expression}.render({${props}}`; + let open = `\${${expression}.render({${props}}`; - if ( node.children.length ) { - open += `, { yield: () => \``; - } + if ( node.children.length ) { + open += `, { yield: () => \``; + } - generator.append( open ); - }, + generator.append( open ); - leave ( generator, node ) { - const close = node.children.length ? `\` })}` : ')}'; - generator.append( close ); - } -}; + generator.elementDepth += 1; + + node.children.forEach( child => { + visit( generator, block, child ); + }); + + generator.elementDepth -= 1; + + const close = node.children.length ? `\` })}` : ')}'; + generator.append( close ); +} diff --git a/src/generators/server-side-rendering/visitors/EachBlock.js b/src/generators/server-side-rendering/visitors/EachBlock.js index 0fbe3ee9958f..5e59a10a4c2f 100644 --- a/src/generators/server-side-rendering/visitors/EachBlock.js +++ b/src/generators/server-side-rendering/visitors/EachBlock.js @@ -1,32 +1,32 @@ -export default { - enter ( generator, node ) { - const { dependencies, snippet } = generator.contextualise( node.expression ); - - const open = `\${ ${snippet}.map( ${ node.index ? `( ${node.context}, ${node.index} )` : node.context} => \``; - generator.append( open ); - - // TODO should this be the generator's job? It's duplicated between - // here and the equivalent DOM compiler visitor - const contexts = new Map( generator.current.contexts ); - contexts.set( node.context, node.context ); - - const indexes = new Map( generator.current.indexes ); - if ( node.index ) indexes.set( node.index, node.context ); - - const contextDependencies = new Map( generator.current.contextDependencies ); - contextDependencies.set( node.context, dependencies ); - - generator.push({ - contexts, - indexes, - contextDependencies - }); - }, - - leave ( generator ) { - const close = `\` ).join( '' )}`; - generator.append( close ); - - generator.pop(); - } -}; +import visit from '../visit.js'; + +export default function visitEachBlock ( generator, block, node ) { + const { dependencies, snippet } = generator.contextualise( block, node.expression ); + + const open = `\${ ${snippet}.map( ${ node.index ? `( ${node.context}, ${node.index} )` : node.context} => \``; + generator.append( open ); + + // TODO should this be the generator's job? It's duplicated between + // here and the equivalent DOM compiler visitor + const contexts = new Map( block.contexts ); + contexts.set( node.context, node.context ); + + const indexes = new Map( block.indexes ); + if ( node.index ) indexes.set( node.index, node.context ); + + const contextDependencies = new Map( block.contextDependencies ); + contextDependencies.set( node.context, dependencies ); + + const childBlock = block.child({ + contexts, + indexes, + contextDependencies + }); + + node.children.forEach( child => { + visit( generator, childBlock, child ); + }); + + const close = `\` ).join( '' )}`; + generator.append( close ); +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/visitors/Element.js b/src/generators/server-side-rendering/visitors/Element.js index d50f795b6c10..c473d6b62c88 100644 --- a/src/generators/server-side-rendering/visitors/Element.js +++ b/src/generators/server-side-rendering/visitors/Element.js @@ -1,65 +1,60 @@ -import Component from './Component.js'; +import visitComponent from './Component.js'; import isVoidElementName from '../../../utils/isVoidElementName.js'; -import Window from './meta/Window.js'; +import visit from '../visit.js'; +import visitWindow from './meta/Window.js'; const meta = { - ':Window': Window + ':Window': visitWindow }; -export default { - enter ( generator, node ) { - if ( node.name in meta ) { - return meta[ node.name ].enter( generator, node ); - } +export default function visitElement ( generator, block, node ) { + if ( node.name in meta ) { + return meta[ node.name ]( generator, block, node ); + } - if ( generator.components.has( node.name ) || node.name === ':Self' ) { - Component.enter( generator, node ); - return; - } + if ( generator.components.has( node.name ) || node.name === ':Self' ) { + visitComponent( generator, block, node ); + return; + } - let openingTag = `<${node.name}`; + let openingTag = `<${node.name}`; - node.attributes.forEach( attribute => { - if ( attribute.type !== 'Attribute' ) return; + node.attributes.forEach( attribute => { + if ( attribute.type !== 'Attribute' ) return; - let str = ` ${attribute.name}`; + let str = ` ${attribute.name}`; - if ( attribute.value !== true ) { - str += `="` + attribute.value.map( chunk => { - if ( chunk.type === 'Text' ) { - return chunk.data; - } + if ( attribute.value !== true ) { + str += `="` + attribute.value.map( chunk => { + if ( chunk.type === 'Text' ) { + return chunk.data; + } - const { snippet } = generator.contextualise( chunk.expression ); - return '${' + snippet + '}'; - }).join( '' ) + `"`; - } + const { snippet } = generator.contextualise( block, chunk.expression ); + return '${' + snippet + '}'; + }).join( '' ) + `"`; + } - openingTag += str; - }); + openingTag += str; + }); - if ( generator.cssId && !generator.elementDepth ) { - openingTag += ` ${generator.cssId}`; - } + if ( generator.cssId && !generator.elementDepth ) { + openingTag += ` ${generator.cssId}`; + } - openingTag += '>'; + openingTag += '>'; - generator.append( openingTag ); - }, + generator.append( openingTag ); - leave ( generator, node ) { - if ( node.name in meta ) { - if ( meta[ node.name ].leave ) meta[ node.name ].leave( generator, node ); - return; - } + generator.elementDepth += 1; - if ( generator.components.has( node.name ) || node.name === ':Self' ) { - Component.leave( generator, node ); - return; - } + node.children.forEach( child => { + visit( generator, block, child ); + }); - if ( !isVoidElementName( node.name ) ) { - generator.append( `${node.name}>` ); - } + generator.elementDepth -= 1; + + if ( !isVoidElementName( node.name ) ) { + generator.append( `${node.name}>` ); } -}; +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/visitors/IfBlock.js b/src/generators/server-side-rendering/visitors/IfBlock.js index dd21ff8b4f10..cd2575be6e38 100644 --- a/src/generators/server-side-rendering/visitors/IfBlock.js +++ b/src/generators/server-side-rendering/visitors/IfBlock.js @@ -1,19 +1,25 @@ -export default { - enter ( generator, node ) { - const { snippet } = generator.contextualise( node.expression ); +import visit from '../visit.js'; - generator.append( '${ ' + snippet + ' ? `' ); +export default function visitIfBlock ( generator, block, node ) { + const { snippet } = generator.contextualise( block, node.expression ); - generator.push({ - conditions: generator.current.conditions.concat( snippet ) - }); - }, + generator.append( '${ ' + snippet + ' ? `' ); + + const childBlock = block.child({ + conditions: block.conditions.concat( snippet ) + }); + + node.children.forEach( child => { + visit( generator, childBlock, child ); + }); - leave ( generator, node ) { - generator.append( '` : `' ); - if ( node.else ) node.else.children.forEach( child => generator.visit( child ) ); - generator.append( '` }' ); + generator.append( '` : `' ); - generator.pop(); + if ( node.else ) { + node.else.children.forEach( child => { + visit( generator, childBlock, child ); + }); } -}; + + generator.append( '` }' ); +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/visitors/MustacheTag.js b/src/generators/server-side-rendering/visitors/MustacheTag.js index 9052e2627fc3..d433d0f1cb86 100644 --- a/src/generators/server-side-rendering/visitors/MustacheTag.js +++ b/src/generators/server-side-rendering/visitors/MustacheTag.js @@ -1,6 +1,4 @@ -export default { - enter ( generator, node ) { - const { snippet } = generator.contextualise( node.expression ); - generator.append( '${__escape( ' + snippet + ' )}' ); - } -}; +export default function visitMustacheTag ( generator, block, node ) { + const { snippet } = generator.contextualise( block, node.expression ); + generator.append( '${__escape( ' + snippet + ' )}' ); +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/visitors/RawMustacheTag.js b/src/generators/server-side-rendering/visitors/RawMustacheTag.js index c84de16e2acb..27aa695fa104 100644 --- a/src/generators/server-side-rendering/visitors/RawMustacheTag.js +++ b/src/generators/server-side-rendering/visitors/RawMustacheTag.js @@ -1,6 +1,4 @@ -export default { - enter ( generator, node ) { - const { snippet } = generator.contextualise( node.expression ); - generator.append( '${' + snippet + '}' ); - } -}; +export default function visitRawMustacheTag ( generator, block, node ) { + const { snippet } = generator.contextualise( block, node.expression ); + generator.append( '${' + snippet + '}' ); +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/visitors/Text.js b/src/generators/server-side-rendering/visitors/Text.js index 16630a709d3d..d7e30d41c576 100644 --- a/src/generators/server-side-rendering/visitors/Text.js +++ b/src/generators/server-side-rendering/visitors/Text.js @@ -1,5 +1,3 @@ -export default { - enter ( generator, node ) { - generator.append( node.data.replace( /\${/g, '\\${' ) ); - } -}; +export default function visitText ( generator, block, node ) { + generator.append( node.data.replace( /\${/g, '\\${' ) ); +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/visitors/YieldTag.js b/src/generators/server-side-rendering/visitors/YieldTag.js index a9b35f777edf..bde5ab1a00b2 100644 --- a/src/generators/server-side-rendering/visitors/YieldTag.js +++ b/src/generators/server-side-rendering/visitors/YieldTag.js @@ -1,5 +1,3 @@ -export default { - enter ( generator ) { - generator.append( `\${options && options.yield ? options.yield() : ''}` ); - } -}; +export default function visitYieldTag ( generator ) { + generator.append( `\${options && options.yield ? options.yield() : ''}` ); +} \ No newline at end of file diff --git a/src/generators/server-side-rendering/visitors/meta/Window.js b/src/generators/server-side-rendering/visitors/meta/Window.js index 7df7d8bdaf61..4b4bf67ccce2 100644 --- a/src/generators/server-side-rendering/visitors/meta/Window.js +++ b/src/generators/server-side-rendering/visitors/meta/Window.js @@ -1,9 +1,3 @@ -export default { - enter () { - // noop - }, - - leave () { - // noop - } -}; +export default function visitWindow () { + // noop +} \ No newline at end of file diff --git a/src/shared/dom.js b/src/shared/dom.js index 5657a1133365..9a4ef3fb6810 100644 --- a/src/shared/dom.js +++ b/src/shared/dom.js @@ -16,9 +16,9 @@ export function detachBetween ( before, after ) { } } -export function teardownEach ( iterations, detach, start ) { +export function destroyEach ( iterations, detach, start ) { for ( var i = ( start || 0 ); i < iterations.length; i += 1 ) { - iterations[i].teardown( detach ); + iterations[i].destroy( detach ); } } diff --git a/src/validate/js/propValidators/methods.js b/src/validate/js/propValidators/methods.js index ddcffb38f432..23b10f03a58a 100644 --- a/src/validate/js/propValidators/methods.js +++ b/src/validate/js/propValidators/methods.js @@ -2,7 +2,7 @@ import checkForDupes from '../utils/checkForDupes.js'; import checkForComputedKeys from '../utils/checkForComputedKeys.js'; import usesThisOrArguments from '../utils/usesThisOrArguments.js'; -const builtin = new Set( [ 'set', 'get', 'on', 'fire', 'observe', 'teardown' ] ); +const builtin = new Set( [ 'set', 'get', 'on', 'fire', 'observe', 'destroy' ] ); export default function methods ( validator, prop ) { if ( prop.value.type !== 'ObjectExpression' ) { diff --git a/test/generator/samples/each-block-else/_config.js b/test/generator/samples/each-block-else/_config.js deleted file mode 100644 index 313b7fa7e35e..000000000000 --- a/test/generator/samples/each-block-else/_config.js +++ /dev/null @@ -1,17 +0,0 @@ -export default { - data: { - animals: [ 'alpaca', 'baboon', 'capybara' ], - foo: 'something else' - }, - html: 'before\nalpacababooncapybara\nafter', - test ( assert, component, target ) { - component.set({ animals: [] }); - assert.htmlEqual( target.innerHTML, 'before\nno animals, but rather something else\nafter' ); - - component.set({ foo: 'something other' }); - assert.htmlEqual( target.innerHTML, 'before\nno animals, but rather something other\nafter' ); - - component.set({ animals: ['wombat'] }); - assert.htmlEqual( target.innerHTML, 'before\nwombat\nafter' ); - } -}; diff --git a/test/js/README.md b/test/js/README.md new file mode 100644 index 000000000000..c43905123ea8 --- /dev/null +++ b/test/js/README.md @@ -0,0 +1 @@ +Use these tests sparingly, as they will need to be updated frequently as the code generation changes. \ No newline at end of file diff --git a/test/js/index.js b/test/js/index.js new file mode 100644 index 000000000000..cf8ab54bbd3a --- /dev/null +++ b/test/js/index.js @@ -0,0 +1,28 @@ +import assert from 'assert'; +import * as fs from 'fs'; +import * as path from 'path'; +import { svelte } from '../helpers.js'; + +describe( 'js', () => { + fs.readdirSync( 'test/js/samples' ).forEach( dir => { + if ( dir[0] === '.' ) return; + + // add .solo to a sample directory name to only run that test + const solo = /\.solo/.test( dir ); + + if ( solo && process.env.CI ) { + throw new Error( 'Forgot to remove `solo: true` from test' ); + } + + ( solo ? it.only : it )( dir, () => { + dir = path.resolve( 'test/js/samples', dir ); + const input = fs.readFileSync( `${dir}/input.html`, 'utf-8' ).replace( /\s+$/, '' ); + + const actual = svelte.compile( input ).code; + fs.writeFileSync( `${dir}/_actual.js`, actual ); + const expected = fs.readFileSync( `${dir}/expected.js`, 'utf-8' ); + + assert.equal( actual.trim(), expected.trim() ); + }); + }); +}); diff --git a/src/generators/dom/visitors/attributes/getStaticAttributeValue.js b/test/js/samples/.gitkeep similarity index 100% rename from src/generators/dom/visitors/attributes/getStaticAttributeValue.js rename to test/js/samples/.gitkeep diff --git a/test/generator/index.js b/test/runtime/index.js similarity index 90% rename from test/generator/index.js rename to test/runtime/index.js index ccce7e259e6b..f4926388c1f9 100644 --- a/test/generator/index.js +++ b/test/runtime/index.js @@ -32,13 +32,13 @@ require.extensions[ '.html' ] = function ( module, filename ) { const Object_assign = Object.assign; -describe( 'generate', () => { +describe( 'runtime', () => { before( setupHtmlEqual ); function runTest ( dir, shared ) { if ( dir[0] === '.' ) return; - const config = loadConfig( `./generator/samples/${dir}/_config.js` ); + const config = loadConfig( `./runtime/samples/${dir}/_config.js` ); if ( config.solo && process.env.CI ) { throw new Error( 'Forgot to remove `solo: true` from test' ); @@ -53,7 +53,7 @@ describe( 'generate', () => { compileOptions.dev = config.dev; try { - const source = fs.readFileSync( `test/generator/samples/${dir}/main.html`, 'utf-8' ); + const source = fs.readFileSync( `test/runtime/samples/${dir}/main.html`, 'utf-8' ); compiled = svelte.compile( source, compileOptions ); } catch ( err ) { if ( config.compileError ) { @@ -69,7 +69,8 @@ describe( 'generate', () => { // check that no ES2015+ syntax slipped in if ( !config.allowES2015 ) { try { - const startIndex = code.indexOf( 'function render_main_fragment' ); // may change! + const startIndex = code.indexOf( 'function create_main_fragment' ); // may change! + if ( startIndex === -1 ) throw new Error( 'missing create_main_fragment' ); const es5 = spaces( startIndex ) + code.slice( startIndex ).replace( /export default .+/, '' ); acorn.parse( es5, { ecmaVersion: 5 }); } catch ( err ) { @@ -117,6 +118,8 @@ describe( 'generate', () => { data: config.data }); + Object.assign = Object_assign; + console.warn = warn; if ( config.error ) { @@ -160,13 +163,13 @@ describe( 'generate', () => { } describe( 'inline helpers', () => { - fs.readdirSync( 'test/generator/samples' ).forEach( dir => { + fs.readdirSync( 'test/runtime/samples' ).forEach( dir => { runTest( dir, null ); }); }); describe( 'shared helpers', () => { - fs.readdirSync( 'test/generator/samples' ).forEach( dir => { + fs.readdirSync( 'test/runtime/samples' ).forEach( dir => { runTest( dir, path.resolve( 'shared.js' ) ); }); }); diff --git a/test/generator/samples/attribute-dynamic-multiple/_config.js b/test/runtime/samples/attribute-dynamic-multiple/_config.js similarity index 58% rename from test/generator/samples/attribute-dynamic-multiple/_config.js rename to test/runtime/samples/attribute-dynamic-multiple/_config.js index 1a0c602cb680..048c5130e570 100644 --- a/test/generator/samples/attribute-dynamic-multiple/_config.js +++ b/test/runtime/samples/attribute-dynamic-multiple/_config.js @@ -7,5 +7,9 @@ export default { ] }, - html: `123` + html: ` + 1 + 2 + 3 + ` }; diff --git a/test/generator/samples/attribute-dynamic-multiple/main.html b/test/runtime/samples/attribute-dynamic-multiple/main.html similarity index 100% rename from test/generator/samples/attribute-dynamic-multiple/main.html rename to test/runtime/samples/attribute-dynamic-multiple/main.html diff --git a/test/generator/samples/attribute-dynamic-reserved/_config.js b/test/runtime/samples/attribute-dynamic-reserved/_config.js similarity index 100% rename from test/generator/samples/attribute-dynamic-reserved/_config.js rename to test/runtime/samples/attribute-dynamic-reserved/_config.js diff --git a/test/generator/samples/attribute-dynamic-reserved/main.html b/test/runtime/samples/attribute-dynamic-reserved/main.html similarity index 100% rename from test/generator/samples/attribute-dynamic-reserved/main.html rename to test/runtime/samples/attribute-dynamic-reserved/main.html diff --git a/test/generator/samples/attribute-dynamic-shorthand/_config.js b/test/runtime/samples/attribute-dynamic-shorthand/_config.js similarity index 100% rename from test/generator/samples/attribute-dynamic-shorthand/_config.js rename to test/runtime/samples/attribute-dynamic-shorthand/_config.js diff --git a/test/generator/samples/attribute-dynamic-shorthand/main.html b/test/runtime/samples/attribute-dynamic-shorthand/main.html similarity index 100% rename from test/generator/samples/attribute-dynamic-shorthand/main.html rename to test/runtime/samples/attribute-dynamic-shorthand/main.html diff --git a/test/generator/samples/attribute-dynamic/_config.js b/test/runtime/samples/attribute-dynamic/_config.js similarity index 99% rename from test/generator/samples/attribute-dynamic/_config.js rename to test/runtime/samples/attribute-dynamic/_config.js index 2b92e8ed6067..9b33022e6207 100644 --- a/test/generator/samples/attribute-dynamic/_config.js +++ b/test/runtime/samples/attribute-dynamic/_config.js @@ -1,5 +1,6 @@ export default { html: `red`, + test ( assert, component, target ) { const div = target.querySelector( 'div' ); diff --git a/test/generator/samples/attribute-dynamic/main.html b/test/runtime/samples/attribute-dynamic/main.html similarity index 100% rename from test/generator/samples/attribute-dynamic/main.html rename to test/runtime/samples/attribute-dynamic/main.html diff --git a/test/generator/samples/attribute-empty-svg/_config.js b/test/runtime/samples/attribute-empty-svg/_config.js similarity index 100% rename from test/generator/samples/attribute-empty-svg/_config.js rename to test/runtime/samples/attribute-empty-svg/_config.js diff --git a/test/generator/samples/attribute-empty-svg/main.html b/test/runtime/samples/attribute-empty-svg/main.html similarity index 100% rename from test/generator/samples/attribute-empty-svg/main.html rename to test/runtime/samples/attribute-empty-svg/main.html diff --git a/test/generator/samples/attribute-empty/_config.js b/test/runtime/samples/attribute-empty/_config.js similarity index 100% rename from test/generator/samples/attribute-empty/_config.js rename to test/runtime/samples/attribute-empty/_config.js diff --git a/test/generator/samples/attribute-empty/main.html b/test/runtime/samples/attribute-empty/main.html similarity index 100% rename from test/generator/samples/attribute-empty/main.html rename to test/runtime/samples/attribute-empty/main.html diff --git a/test/generator/samples/attribute-partial-number/Component.html b/test/runtime/samples/attribute-partial-number/Component.html similarity index 100% rename from test/generator/samples/attribute-partial-number/Component.html rename to test/runtime/samples/attribute-partial-number/Component.html diff --git a/test/generator/samples/attribute-partial-number/_config.js b/test/runtime/samples/attribute-partial-number/_config.js similarity index 100% rename from test/generator/samples/attribute-partial-number/_config.js rename to test/runtime/samples/attribute-partial-number/_config.js diff --git a/test/generator/samples/attribute-partial-number/main.html b/test/runtime/samples/attribute-partial-number/main.html similarity index 100% rename from test/generator/samples/attribute-partial-number/main.html rename to test/runtime/samples/attribute-partial-number/main.html diff --git a/test/generator/samples/attribute-prefer-expression/_config.js b/test/runtime/samples/attribute-prefer-expression/_config.js similarity index 100% rename from test/generator/samples/attribute-prefer-expression/_config.js rename to test/runtime/samples/attribute-prefer-expression/_config.js diff --git a/test/generator/samples/attribute-prefer-expression/main.html b/test/runtime/samples/attribute-prefer-expression/main.html similarity index 100% rename from test/generator/samples/attribute-prefer-expression/main.html rename to test/runtime/samples/attribute-prefer-expression/main.html diff --git a/test/generator/samples/attribute-static-boolean/_config.js b/test/runtime/samples/attribute-static-boolean/_config.js similarity index 100% rename from test/generator/samples/attribute-static-boolean/_config.js rename to test/runtime/samples/attribute-static-boolean/_config.js diff --git a/test/generator/samples/attribute-static-boolean/main.html b/test/runtime/samples/attribute-static-boolean/main.html similarity index 100% rename from test/generator/samples/attribute-static-boolean/main.html rename to test/runtime/samples/attribute-static-boolean/main.html diff --git a/test/generator/samples/attribute-static/_config.js b/test/runtime/samples/attribute-static/_config.js similarity index 100% rename from test/generator/samples/attribute-static/_config.js rename to test/runtime/samples/attribute-static/_config.js diff --git a/test/generator/samples/attribute-static/main.html b/test/runtime/samples/attribute-static/main.html similarity index 100% rename from test/generator/samples/attribute-static/main.html rename to test/runtime/samples/attribute-static/main.html diff --git a/test/generator/samples/autofocus/_config.js b/test/runtime/samples/autofocus/_config.js similarity index 100% rename from test/generator/samples/autofocus/_config.js rename to test/runtime/samples/autofocus/_config.js diff --git a/test/generator/samples/autofocus/main.html b/test/runtime/samples/autofocus/main.html similarity index 100% rename from test/generator/samples/autofocus/main.html rename to test/runtime/samples/autofocus/main.html diff --git a/test/generator/samples/binding-input-checkbox-deep-contextual/_config.js b/test/runtime/samples/binding-input-checkbox-deep-contextual/_config.js similarity index 100% rename from test/generator/samples/binding-input-checkbox-deep-contextual/_config.js rename to test/runtime/samples/binding-input-checkbox-deep-contextual/_config.js diff --git a/test/generator/samples/binding-input-checkbox-deep-contextual/main.html b/test/runtime/samples/binding-input-checkbox-deep-contextual/main.html similarity index 100% rename from test/generator/samples/binding-input-checkbox-deep-contextual/main.html rename to test/runtime/samples/binding-input-checkbox-deep-contextual/main.html diff --git a/test/generator/samples/binding-input-checkbox-group/_config.js b/test/runtime/samples/binding-input-checkbox-group/_config.js similarity index 100% rename from test/generator/samples/binding-input-checkbox-group/_config.js rename to test/runtime/samples/binding-input-checkbox-group/_config.js diff --git a/test/generator/samples/binding-input-checkbox-group/main.html b/test/runtime/samples/binding-input-checkbox-group/main.html similarity index 100% rename from test/generator/samples/binding-input-checkbox-group/main.html rename to test/runtime/samples/binding-input-checkbox-group/main.html diff --git a/test/generator/samples/binding-input-checkbox/_config.js b/test/runtime/samples/binding-input-checkbox/_config.js similarity index 100% rename from test/generator/samples/binding-input-checkbox/_config.js rename to test/runtime/samples/binding-input-checkbox/_config.js diff --git a/test/generator/samples/binding-input-checkbox/main.html b/test/runtime/samples/binding-input-checkbox/main.html similarity index 100% rename from test/generator/samples/binding-input-checkbox/main.html rename to test/runtime/samples/binding-input-checkbox/main.html diff --git a/test/generator/samples/binding-input-number/_config.js b/test/runtime/samples/binding-input-number/_config.js similarity index 100% rename from test/generator/samples/binding-input-number/_config.js rename to test/runtime/samples/binding-input-number/_config.js diff --git a/test/generator/samples/binding-input-number/main.html b/test/runtime/samples/binding-input-number/main.html similarity index 100% rename from test/generator/samples/binding-input-number/main.html rename to test/runtime/samples/binding-input-number/main.html diff --git a/test/generator/samples/binding-input-radio-group/_config.js b/test/runtime/samples/binding-input-radio-group/_config.js similarity index 100% rename from test/generator/samples/binding-input-radio-group/_config.js rename to test/runtime/samples/binding-input-radio-group/_config.js diff --git a/test/generator/samples/binding-input-radio-group/main.html b/test/runtime/samples/binding-input-radio-group/main.html similarity index 100% rename from test/generator/samples/binding-input-radio-group/main.html rename to test/runtime/samples/binding-input-radio-group/main.html diff --git a/test/generator/samples/binding-input-range/_config.js b/test/runtime/samples/binding-input-range/_config.js similarity index 100% rename from test/generator/samples/binding-input-range/_config.js rename to test/runtime/samples/binding-input-range/_config.js diff --git a/test/generator/samples/binding-input-range/main.html b/test/runtime/samples/binding-input-range/main.html similarity index 100% rename from test/generator/samples/binding-input-range/main.html rename to test/runtime/samples/binding-input-range/main.html diff --git a/test/generator/samples/binding-input-text-contextual/_config.js b/test/runtime/samples/binding-input-text-contextual/_config.js similarity index 100% rename from test/generator/samples/binding-input-text-contextual/_config.js rename to test/runtime/samples/binding-input-text-contextual/_config.js diff --git a/test/generator/samples/binding-input-text-contextual/main.html b/test/runtime/samples/binding-input-text-contextual/main.html similarity index 100% rename from test/generator/samples/binding-input-text-contextual/main.html rename to test/runtime/samples/binding-input-text-contextual/main.html diff --git a/test/generator/samples/binding-input-text-deep-contextual/_config.js b/test/runtime/samples/binding-input-text-deep-contextual/_config.js similarity index 100% rename from test/generator/samples/binding-input-text-deep-contextual/_config.js rename to test/runtime/samples/binding-input-text-deep-contextual/_config.js diff --git a/test/generator/samples/binding-input-text-deep-contextual/main.html b/test/runtime/samples/binding-input-text-deep-contextual/main.html similarity index 100% rename from test/generator/samples/binding-input-text-deep-contextual/main.html rename to test/runtime/samples/binding-input-text-deep-contextual/main.html diff --git a/test/generator/samples/binding-input-text-deep/_config.js b/test/runtime/samples/binding-input-text-deep/_config.js similarity index 100% rename from test/generator/samples/binding-input-text-deep/_config.js rename to test/runtime/samples/binding-input-text-deep/_config.js diff --git a/test/generator/samples/binding-input-text-deep/main.html b/test/runtime/samples/binding-input-text-deep/main.html similarity index 100% rename from test/generator/samples/binding-input-text-deep/main.html rename to test/runtime/samples/binding-input-text-deep/main.html diff --git a/test/generator/samples/binding-input-text/_config.js b/test/runtime/samples/binding-input-text/_config.js similarity index 100% rename from test/generator/samples/binding-input-text/_config.js rename to test/runtime/samples/binding-input-text/_config.js diff --git a/test/generator/samples/binding-input-text/main.html b/test/runtime/samples/binding-input-text/main.html similarity index 100% rename from test/generator/samples/binding-input-text/main.html rename to test/runtime/samples/binding-input-text/main.html diff --git a/test/generator/samples/binding-select-initial-value/_config.js b/test/runtime/samples/binding-select-initial-value/_config.js similarity index 100% rename from test/generator/samples/binding-select-initial-value/_config.js rename to test/runtime/samples/binding-select-initial-value/_config.js diff --git a/test/generator/samples/binding-select-initial-value/main.html b/test/runtime/samples/binding-select-initial-value/main.html similarity index 100% rename from test/generator/samples/binding-select-initial-value/main.html rename to test/runtime/samples/binding-select-initial-value/main.html diff --git a/test/generator/samples/binding-select-multiple/_config.js b/test/runtime/samples/binding-select-multiple/_config.js similarity index 100% rename from test/generator/samples/binding-select-multiple/_config.js rename to test/runtime/samples/binding-select-multiple/_config.js diff --git a/test/generator/samples/binding-select-multiple/main.html b/test/runtime/samples/binding-select-multiple/main.html similarity index 100% rename from test/generator/samples/binding-select-multiple/main.html rename to test/runtime/samples/binding-select-multiple/main.html diff --git a/test/generator/samples/binding-select/_config.js b/test/runtime/samples/binding-select/_config.js similarity index 100% rename from test/generator/samples/binding-select/_config.js rename to test/runtime/samples/binding-select/_config.js diff --git a/test/generator/samples/binding-select/main.html b/test/runtime/samples/binding-select/main.html similarity index 100% rename from test/generator/samples/binding-select/main.html rename to test/runtime/samples/binding-select/main.html diff --git a/test/generator/samples/binding-textarea/_config.js b/test/runtime/samples/binding-textarea/_config.js similarity index 100% rename from test/generator/samples/binding-textarea/_config.js rename to test/runtime/samples/binding-textarea/_config.js diff --git a/test/generator/samples/binding-textarea/main.html b/test/runtime/samples/binding-textarea/main.html similarity index 100% rename from test/generator/samples/binding-textarea/main.html rename to test/runtime/samples/binding-textarea/main.html diff --git a/test/generator/samples/component-binding-conditional-b/Bar.html b/test/runtime/samples/component-binding-conditional-b/Bar.html similarity index 100% rename from test/generator/samples/component-binding-conditional-b/Bar.html rename to test/runtime/samples/component-binding-conditional-b/Bar.html diff --git a/test/generator/samples/component-binding-conditional-b/Baz.html b/test/runtime/samples/component-binding-conditional-b/Baz.html similarity index 100% rename from test/generator/samples/component-binding-conditional-b/Baz.html rename to test/runtime/samples/component-binding-conditional-b/Baz.html diff --git a/test/generator/samples/component-binding-conditional-b/Foo.html b/test/runtime/samples/component-binding-conditional-b/Foo.html similarity index 100% rename from test/generator/samples/component-binding-conditional-b/Foo.html rename to test/runtime/samples/component-binding-conditional-b/Foo.html diff --git a/test/generator/samples/component-binding-conditional-b/_config.js b/test/runtime/samples/component-binding-conditional-b/_config.js similarity index 100% rename from test/generator/samples/component-binding-conditional-b/_config.js rename to test/runtime/samples/component-binding-conditional-b/_config.js diff --git a/test/generator/samples/component-binding-conditional-b/main.html b/test/runtime/samples/component-binding-conditional-b/main.html similarity index 100% rename from test/generator/samples/component-binding-conditional-b/main.html rename to test/runtime/samples/component-binding-conditional-b/main.html diff --git a/test/generator/samples/component-binding-conditional/Bar.html b/test/runtime/samples/component-binding-conditional/Bar.html similarity index 100% rename from test/generator/samples/component-binding-conditional/Bar.html rename to test/runtime/samples/component-binding-conditional/Bar.html diff --git a/test/generator/samples/component-binding-conditional/Baz.html b/test/runtime/samples/component-binding-conditional/Baz.html similarity index 100% rename from test/generator/samples/component-binding-conditional/Baz.html rename to test/runtime/samples/component-binding-conditional/Baz.html diff --git a/test/generator/samples/component-binding-conditional/Foo.html b/test/runtime/samples/component-binding-conditional/Foo.html similarity index 100% rename from test/generator/samples/component-binding-conditional/Foo.html rename to test/runtime/samples/component-binding-conditional/Foo.html diff --git a/test/generator/samples/component-binding-conditional/_config.js b/test/runtime/samples/component-binding-conditional/_config.js similarity index 100% rename from test/generator/samples/component-binding-conditional/_config.js rename to test/runtime/samples/component-binding-conditional/_config.js diff --git a/test/generator/samples/component-binding-conditional/main.html b/test/runtime/samples/component-binding-conditional/main.html similarity index 100% rename from test/generator/samples/component-binding-conditional/main.html rename to test/runtime/samples/component-binding-conditional/main.html diff --git a/test/generator/samples/component-binding-deep-b/ComponentSelector.html b/test/runtime/samples/component-binding-deep-b/ComponentSelector.html similarity index 100% rename from test/generator/samples/component-binding-deep-b/ComponentSelector.html rename to test/runtime/samples/component-binding-deep-b/ComponentSelector.html diff --git a/test/generator/samples/component-binding-deep-b/Editor.html b/test/runtime/samples/component-binding-deep-b/Editor.html similarity index 100% rename from test/generator/samples/component-binding-deep-b/Editor.html rename to test/runtime/samples/component-binding-deep-b/Editor.html diff --git a/test/generator/samples/component-binding-deep-b/_config.js b/test/runtime/samples/component-binding-deep-b/_config.js similarity index 100% rename from test/generator/samples/component-binding-deep-b/_config.js rename to test/runtime/samples/component-binding-deep-b/_config.js diff --git a/test/generator/samples/component-binding-deep-b/main.html b/test/runtime/samples/component-binding-deep-b/main.html similarity index 100% rename from test/generator/samples/component-binding-deep-b/main.html rename to test/runtime/samples/component-binding-deep-b/main.html diff --git a/test/generator/samples/component-binding-deep/Widget.html b/test/runtime/samples/component-binding-deep/Widget.html similarity index 100% rename from test/generator/samples/component-binding-deep/Widget.html rename to test/runtime/samples/component-binding-deep/Widget.html diff --git a/test/generator/samples/component-binding-deep/_config.js b/test/runtime/samples/component-binding-deep/_config.js similarity index 100% rename from test/generator/samples/component-binding-deep/_config.js rename to test/runtime/samples/component-binding-deep/_config.js diff --git a/test/generator/samples/component-binding-deep/main.html b/test/runtime/samples/component-binding-deep/main.html similarity index 100% rename from test/generator/samples/component-binding-deep/main.html rename to test/runtime/samples/component-binding-deep/main.html diff --git a/test/generator/samples/component-binding-each-nested/Widget.html b/test/runtime/samples/component-binding-each-nested/Widget.html similarity index 100% rename from test/generator/samples/component-binding-each-nested/Widget.html rename to test/runtime/samples/component-binding-each-nested/Widget.html diff --git a/test/generator/samples/component-binding-each-nested/_config.js b/test/runtime/samples/component-binding-each-nested/_config.js similarity index 100% rename from test/generator/samples/component-binding-each-nested/_config.js rename to test/runtime/samples/component-binding-each-nested/_config.js diff --git a/test/generator/samples/component-binding-each-nested/main.html b/test/runtime/samples/component-binding-each-nested/main.html similarity index 100% rename from test/generator/samples/component-binding-each-nested/main.html rename to test/runtime/samples/component-binding-each-nested/main.html diff --git a/test/generator/samples/component-binding-each-object/Widget.html b/test/runtime/samples/component-binding-each-object/Widget.html similarity index 100% rename from test/generator/samples/component-binding-each-object/Widget.html rename to test/runtime/samples/component-binding-each-object/Widget.html diff --git a/test/generator/samples/component-binding-each-object/_config.js b/test/runtime/samples/component-binding-each-object/_config.js similarity index 100% rename from test/generator/samples/component-binding-each-object/_config.js rename to test/runtime/samples/component-binding-each-object/_config.js diff --git a/test/generator/samples/component-binding-each-object/main.html b/test/runtime/samples/component-binding-each-object/main.html similarity index 100% rename from test/generator/samples/component-binding-each-object/main.html rename to test/runtime/samples/component-binding-each-object/main.html diff --git a/test/generator/samples/component-binding-each/Widget.html b/test/runtime/samples/component-binding-each/Widget.html similarity index 100% rename from test/generator/samples/component-binding-each/Widget.html rename to test/runtime/samples/component-binding-each/Widget.html diff --git a/test/generator/samples/component-binding-each/_config.js b/test/runtime/samples/component-binding-each/_config.js similarity index 100% rename from test/generator/samples/component-binding-each/_config.js rename to test/runtime/samples/component-binding-each/_config.js diff --git a/test/generator/samples/component-binding-each/main.html b/test/runtime/samples/component-binding-each/main.html similarity index 100% rename from test/generator/samples/component-binding-each/main.html rename to test/runtime/samples/component-binding-each/main.html diff --git a/test/generator/samples/component-binding-infinite-loop/A.html b/test/runtime/samples/component-binding-infinite-loop/A.html similarity index 100% rename from test/generator/samples/component-binding-infinite-loop/A.html rename to test/runtime/samples/component-binding-infinite-loop/A.html diff --git a/test/generator/samples/component-binding-infinite-loop/B.html b/test/runtime/samples/component-binding-infinite-loop/B.html similarity index 100% rename from test/generator/samples/component-binding-infinite-loop/B.html rename to test/runtime/samples/component-binding-infinite-loop/B.html diff --git a/test/generator/samples/component-binding-infinite-loop/C.html b/test/runtime/samples/component-binding-infinite-loop/C.html similarity index 100% rename from test/generator/samples/component-binding-infinite-loop/C.html rename to test/runtime/samples/component-binding-infinite-loop/C.html diff --git a/test/generator/samples/component-binding-infinite-loop/_config.js b/test/runtime/samples/component-binding-infinite-loop/_config.js similarity index 100% rename from test/generator/samples/component-binding-infinite-loop/_config.js rename to test/runtime/samples/component-binding-infinite-loop/_config.js diff --git a/test/generator/samples/component-binding-infinite-loop/main.html b/test/runtime/samples/component-binding-infinite-loop/main.html similarity index 100% rename from test/generator/samples/component-binding-infinite-loop/main.html rename to test/runtime/samples/component-binding-infinite-loop/main.html diff --git a/test/generator/samples/component-binding-nested/Bar.html b/test/runtime/samples/component-binding-nested/Bar.html similarity index 100% rename from test/generator/samples/component-binding-nested/Bar.html rename to test/runtime/samples/component-binding-nested/Bar.html diff --git a/test/generator/samples/component-binding-nested/Baz.html b/test/runtime/samples/component-binding-nested/Baz.html similarity index 100% rename from test/generator/samples/component-binding-nested/Baz.html rename to test/runtime/samples/component-binding-nested/Baz.html diff --git a/test/generator/samples/component-binding-nested/Foo.html b/test/runtime/samples/component-binding-nested/Foo.html similarity index 100% rename from test/generator/samples/component-binding-nested/Foo.html rename to test/runtime/samples/component-binding-nested/Foo.html diff --git a/test/generator/samples/component-binding-nested/_config.js b/test/runtime/samples/component-binding-nested/_config.js similarity index 100% rename from test/generator/samples/component-binding-nested/_config.js rename to test/runtime/samples/component-binding-nested/_config.js diff --git a/test/generator/samples/component-binding-nested/main.html b/test/runtime/samples/component-binding-nested/main.html similarity index 100% rename from test/generator/samples/component-binding-nested/main.html rename to test/runtime/samples/component-binding-nested/main.html diff --git a/test/generator/samples/component-binding-parent-supercedes-child/Counter.html b/test/runtime/samples/component-binding-parent-supercedes-child/Counter.html similarity index 100% rename from test/generator/samples/component-binding-parent-supercedes-child/Counter.html rename to test/runtime/samples/component-binding-parent-supercedes-child/Counter.html diff --git a/test/generator/samples/component-binding-parent-supercedes-child/_config.js b/test/runtime/samples/component-binding-parent-supercedes-child/_config.js similarity index 100% rename from test/generator/samples/component-binding-parent-supercedes-child/_config.js rename to test/runtime/samples/component-binding-parent-supercedes-child/_config.js diff --git a/test/generator/samples/component-binding-parent-supercedes-child/main.html b/test/runtime/samples/component-binding-parent-supercedes-child/main.html similarity index 100% rename from test/generator/samples/component-binding-parent-supercedes-child/main.html rename to test/runtime/samples/component-binding-parent-supercedes-child/main.html diff --git a/test/generator/samples/component-binding/Counter.html b/test/runtime/samples/component-binding/Counter.html similarity index 100% rename from test/generator/samples/component-binding/Counter.html rename to test/runtime/samples/component-binding/Counter.html diff --git a/test/generator/samples/component-binding/_config.js b/test/runtime/samples/component-binding/_config.js similarity index 100% rename from test/generator/samples/component-binding/_config.js rename to test/runtime/samples/component-binding/_config.js diff --git a/test/generator/samples/component-binding/main.html b/test/runtime/samples/component-binding/main.html similarity index 100% rename from test/generator/samples/component-binding/main.html rename to test/runtime/samples/component-binding/main.html diff --git a/test/generator/samples/component-data-dynamic-late/Widget.html b/test/runtime/samples/component-data-dynamic-late/Widget.html similarity index 100% rename from test/generator/samples/component-data-dynamic-late/Widget.html rename to test/runtime/samples/component-data-dynamic-late/Widget.html diff --git a/test/generator/samples/component-data-dynamic-late/_config.js b/test/runtime/samples/component-data-dynamic-late/_config.js similarity index 100% rename from test/generator/samples/component-data-dynamic-late/_config.js rename to test/runtime/samples/component-data-dynamic-late/_config.js diff --git a/test/generator/samples/component-data-dynamic-late/main.html b/test/runtime/samples/component-data-dynamic-late/main.html similarity index 100% rename from test/generator/samples/component-data-dynamic-late/main.html rename to test/runtime/samples/component-data-dynamic-late/main.html diff --git a/test/generator/samples/component-data-dynamic-shorthand/Widget.html b/test/runtime/samples/component-data-dynamic-shorthand/Widget.html similarity index 100% rename from test/generator/samples/component-data-dynamic-shorthand/Widget.html rename to test/runtime/samples/component-data-dynamic-shorthand/Widget.html diff --git a/test/generator/samples/component-data-dynamic-shorthand/_config.js b/test/runtime/samples/component-data-dynamic-shorthand/_config.js similarity index 100% rename from test/generator/samples/component-data-dynamic-shorthand/_config.js rename to test/runtime/samples/component-data-dynamic-shorthand/_config.js diff --git a/test/generator/samples/component-data-dynamic-shorthand/main.html b/test/runtime/samples/component-data-dynamic-shorthand/main.html similarity index 100% rename from test/generator/samples/component-data-dynamic-shorthand/main.html rename to test/runtime/samples/component-data-dynamic-shorthand/main.html diff --git a/test/generator/samples/component-data-dynamic/Widget.html b/test/runtime/samples/component-data-dynamic/Widget.html similarity index 100% rename from test/generator/samples/component-data-dynamic/Widget.html rename to test/runtime/samples/component-data-dynamic/Widget.html diff --git a/test/generator/samples/component-data-dynamic/_config.js b/test/runtime/samples/component-data-dynamic/_config.js similarity index 100% rename from test/generator/samples/component-data-dynamic/_config.js rename to test/runtime/samples/component-data-dynamic/_config.js diff --git a/test/generator/samples/component-data-dynamic/main.html b/test/runtime/samples/component-data-dynamic/main.html similarity index 100% rename from test/generator/samples/component-data-dynamic/main.html rename to test/runtime/samples/component-data-dynamic/main.html diff --git a/test/generator/samples/component-data-empty/Widget.html b/test/runtime/samples/component-data-empty/Widget.html similarity index 100% rename from test/generator/samples/component-data-empty/Widget.html rename to test/runtime/samples/component-data-empty/Widget.html diff --git a/test/generator/samples/component-data-empty/_config.js b/test/runtime/samples/component-data-empty/_config.js similarity index 100% rename from test/generator/samples/component-data-empty/_config.js rename to test/runtime/samples/component-data-empty/_config.js diff --git a/test/generator/samples/component-data-empty/main.html b/test/runtime/samples/component-data-empty/main.html similarity index 100% rename from test/generator/samples/component-data-empty/main.html rename to test/runtime/samples/component-data-empty/main.html diff --git a/test/generator/samples/component-data-static-boolean/Foo.html b/test/runtime/samples/component-data-static-boolean/Foo.html similarity index 100% rename from test/generator/samples/component-data-static-boolean/Foo.html rename to test/runtime/samples/component-data-static-boolean/Foo.html diff --git a/test/generator/samples/component-data-static-boolean/_config.js b/test/runtime/samples/component-data-static-boolean/_config.js similarity index 100% rename from test/generator/samples/component-data-static-boolean/_config.js rename to test/runtime/samples/component-data-static-boolean/_config.js diff --git a/test/generator/samples/component-data-static-boolean/main.html b/test/runtime/samples/component-data-static-boolean/main.html similarity index 100% rename from test/generator/samples/component-data-static-boolean/main.html rename to test/runtime/samples/component-data-static-boolean/main.html diff --git a/test/generator/samples/component-data-static/Widget.html b/test/runtime/samples/component-data-static/Widget.html similarity index 100% rename from test/generator/samples/component-data-static/Widget.html rename to test/runtime/samples/component-data-static/Widget.html diff --git a/test/generator/samples/component-data-static/_config.js b/test/runtime/samples/component-data-static/_config.js similarity index 100% rename from test/generator/samples/component-data-static/_config.js rename to test/runtime/samples/component-data-static/_config.js diff --git a/test/generator/samples/component-data-static/main.html b/test/runtime/samples/component-data-static/main.html similarity index 100% rename from test/generator/samples/component-data-static/main.html rename to test/runtime/samples/component-data-static/main.html diff --git a/test/generator/samples/component-events-data/Widget.html b/test/runtime/samples/component-events-data/Widget.html similarity index 100% rename from test/generator/samples/component-events-data/Widget.html rename to test/runtime/samples/component-events-data/Widget.html diff --git a/test/generator/samples/component-events-data/_config.js b/test/runtime/samples/component-events-data/_config.js similarity index 100% rename from test/generator/samples/component-events-data/_config.js rename to test/runtime/samples/component-events-data/_config.js diff --git a/test/generator/samples/component-events-data/main.html b/test/runtime/samples/component-events-data/main.html similarity index 100% rename from test/generator/samples/component-events-data/main.html rename to test/runtime/samples/component-events-data/main.html diff --git a/test/generator/samples/component-events-each/Widget.html b/test/runtime/samples/component-events-each/Widget.html similarity index 100% rename from test/generator/samples/component-events-each/Widget.html rename to test/runtime/samples/component-events-each/Widget.html diff --git a/test/generator/samples/component-events-each/_config.js b/test/runtime/samples/component-events-each/_config.js similarity index 100% rename from test/generator/samples/component-events-each/_config.js rename to test/runtime/samples/component-events-each/_config.js diff --git a/test/generator/samples/component-events-each/main.html b/test/runtime/samples/component-events-each/main.html similarity index 100% rename from test/generator/samples/component-events-each/main.html rename to test/runtime/samples/component-events-each/main.html diff --git a/test/generator/samples/component-events/Widget.html b/test/runtime/samples/component-events/Widget.html similarity index 100% rename from test/generator/samples/component-events/Widget.html rename to test/runtime/samples/component-events/Widget.html diff --git a/test/generator/samples/component-events/_config.js b/test/runtime/samples/component-events/_config.js similarity index 100% rename from test/generator/samples/component-events/_config.js rename to test/runtime/samples/component-events/_config.js diff --git a/test/generator/samples/component-events/main.html b/test/runtime/samples/component-events/main.html similarity index 100% rename from test/generator/samples/component-events/main.html rename to test/runtime/samples/component-events/main.html diff --git a/test/generator/samples/component-not-void/Link.html b/test/runtime/samples/component-not-void/Link.html similarity index 100% rename from test/generator/samples/component-not-void/Link.html rename to test/runtime/samples/component-not-void/Link.html diff --git a/test/generator/samples/component-not-void/_config.js b/test/runtime/samples/component-not-void/_config.js similarity index 100% rename from test/generator/samples/component-not-void/_config.js rename to test/runtime/samples/component-not-void/_config.js diff --git a/test/generator/samples/component-not-void/main.html b/test/runtime/samples/component-not-void/main.html similarity index 100% rename from test/generator/samples/component-not-void/main.html rename to test/runtime/samples/component-not-void/main.html diff --git a/test/generator/samples/component-ref/Widget.html b/test/runtime/samples/component-ref/Widget.html similarity index 100% rename from test/generator/samples/component-ref/Widget.html rename to test/runtime/samples/component-ref/Widget.html diff --git a/test/generator/samples/component-ref/_config.js b/test/runtime/samples/component-ref/_config.js similarity index 100% rename from test/generator/samples/component-ref/_config.js rename to test/runtime/samples/component-ref/_config.js diff --git a/test/generator/samples/component-ref/main.html b/test/runtime/samples/component-ref/main.html similarity index 100% rename from test/generator/samples/component-ref/main.html rename to test/runtime/samples/component-ref/main.html diff --git a/test/generator/samples/component-yield-if/Widget.html b/test/runtime/samples/component-yield-if/Widget.html similarity index 100% rename from test/generator/samples/component-yield-if/Widget.html rename to test/runtime/samples/component-yield-if/Widget.html diff --git a/test/generator/samples/component-yield-if/_config.js b/test/runtime/samples/component-yield-if/_config.js similarity index 100% rename from test/generator/samples/component-yield-if/_config.js rename to test/runtime/samples/component-yield-if/_config.js diff --git a/test/generator/samples/component-yield-if/main.html b/test/runtime/samples/component-yield-if/main.html similarity index 100% rename from test/generator/samples/component-yield-if/main.html rename to test/runtime/samples/component-yield-if/main.html diff --git a/test/generator/samples/component-yield-multiple-in-each/Widget.html b/test/runtime/samples/component-yield-multiple-in-each/Widget.html similarity index 100% rename from test/generator/samples/component-yield-multiple-in-each/Widget.html rename to test/runtime/samples/component-yield-multiple-in-each/Widget.html diff --git a/test/generator/samples/component-yield-multiple-in-each/_config.js b/test/runtime/samples/component-yield-multiple-in-each/_config.js similarity index 100% rename from test/generator/samples/component-yield-multiple-in-each/_config.js rename to test/runtime/samples/component-yield-multiple-in-each/_config.js diff --git a/test/generator/samples/component-yield-multiple-in-each/main.html b/test/runtime/samples/component-yield-multiple-in-each/main.html similarity index 100% rename from test/generator/samples/component-yield-multiple-in-each/main.html rename to test/runtime/samples/component-yield-multiple-in-each/main.html diff --git a/test/generator/samples/component-yield-multiple-in-if/Widget.html b/test/runtime/samples/component-yield-multiple-in-if/Widget.html similarity index 100% rename from test/generator/samples/component-yield-multiple-in-if/Widget.html rename to test/runtime/samples/component-yield-multiple-in-if/Widget.html diff --git a/test/generator/samples/component-yield-multiple-in-if/_config.js b/test/runtime/samples/component-yield-multiple-in-if/_config.js similarity index 100% rename from test/generator/samples/component-yield-multiple-in-if/_config.js rename to test/runtime/samples/component-yield-multiple-in-if/_config.js diff --git a/test/generator/samples/component-yield-multiple-in-if/main.html b/test/runtime/samples/component-yield-multiple-in-if/main.html similarity index 100% rename from test/generator/samples/component-yield-multiple-in-if/main.html rename to test/runtime/samples/component-yield-multiple-in-if/main.html diff --git a/test/generator/samples/component-yield-parent/Widget.html b/test/runtime/samples/component-yield-parent/Widget.html similarity index 100% rename from test/generator/samples/component-yield-parent/Widget.html rename to test/runtime/samples/component-yield-parent/Widget.html diff --git a/test/generator/samples/component-yield-parent/_config.js b/test/runtime/samples/component-yield-parent/_config.js similarity index 100% rename from test/generator/samples/component-yield-parent/_config.js rename to test/runtime/samples/component-yield-parent/_config.js diff --git a/test/generator/samples/component-yield-parent/main.html b/test/runtime/samples/component-yield-parent/main.html similarity index 100% rename from test/generator/samples/component-yield-parent/main.html rename to test/runtime/samples/component-yield-parent/main.html diff --git a/test/generator/samples/component-yield/_config.js b/test/runtime/samples/component-yield/_config.js similarity index 100% rename from test/generator/samples/component-yield/_config.js rename to test/runtime/samples/component-yield/_config.js diff --git a/test/generator/samples/component-yield/main.html b/test/runtime/samples/component-yield/main.html similarity index 100% rename from test/generator/samples/component-yield/main.html rename to test/runtime/samples/component-yield/main.html diff --git a/test/generator/samples/component/Widget.html b/test/runtime/samples/component/Widget.html similarity index 100% rename from test/generator/samples/component/Widget.html rename to test/runtime/samples/component/Widget.html diff --git a/test/generator/samples/component/_config.js b/test/runtime/samples/component/_config.js similarity index 100% rename from test/generator/samples/component/_config.js rename to test/runtime/samples/component/_config.js diff --git a/test/generator/samples/component/main.html b/test/runtime/samples/component/main.html similarity index 100% rename from test/generator/samples/component/main.html rename to test/runtime/samples/component/main.html diff --git a/test/generator/samples/computed-function/_config.js b/test/runtime/samples/computed-function/_config.js similarity index 100% rename from test/generator/samples/computed-function/_config.js rename to test/runtime/samples/computed-function/_config.js diff --git a/test/generator/samples/computed-function/main.html b/test/runtime/samples/computed-function/main.html similarity index 100% rename from test/generator/samples/computed-function/main.html rename to test/runtime/samples/computed-function/main.html diff --git a/test/generator/samples/computed-values-default/_config.js b/test/runtime/samples/computed-values-default/_config.js similarity index 100% rename from test/generator/samples/computed-values-default/_config.js rename to test/runtime/samples/computed-values-default/_config.js diff --git a/test/generator/samples/computed-values-default/main.html b/test/runtime/samples/computed-values-default/main.html similarity index 100% rename from test/generator/samples/computed-values-default/main.html rename to test/runtime/samples/computed-values-default/main.html diff --git a/test/generator/samples/computed-values-function-dependency/_config.js b/test/runtime/samples/computed-values-function-dependency/_config.js similarity index 100% rename from test/generator/samples/computed-values-function-dependency/_config.js rename to test/runtime/samples/computed-values-function-dependency/_config.js diff --git a/test/generator/samples/computed-values-function-dependency/main.html b/test/runtime/samples/computed-values-function-dependency/main.html similarity index 100% rename from test/generator/samples/computed-values-function-dependency/main.html rename to test/runtime/samples/computed-values-function-dependency/main.html diff --git a/test/generator/samples/computed-values/_config.js b/test/runtime/samples/computed-values/_config.js similarity index 100% rename from test/generator/samples/computed-values/_config.js rename to test/runtime/samples/computed-values/_config.js diff --git a/test/generator/samples/computed-values/main.html b/test/runtime/samples/computed-values/main.html similarity index 100% rename from test/generator/samples/computed-values/main.html rename to test/runtime/samples/computed-values/main.html diff --git a/test/generator/samples/css-comments/_config.js b/test/runtime/samples/css-comments/_config.js similarity index 100% rename from test/generator/samples/css-comments/_config.js rename to test/runtime/samples/css-comments/_config.js diff --git a/test/generator/samples/css-comments/main.html b/test/runtime/samples/css-comments/main.html similarity index 100% rename from test/generator/samples/css-comments/main.html rename to test/runtime/samples/css-comments/main.html diff --git a/test/generator/samples/css-false/Widget.html b/test/runtime/samples/css-false/Widget.html similarity index 100% rename from test/generator/samples/css-false/Widget.html rename to test/runtime/samples/css-false/Widget.html diff --git a/test/generator/samples/css-false/_config.js b/test/runtime/samples/css-false/_config.js similarity index 100% rename from test/generator/samples/css-false/_config.js rename to test/runtime/samples/css-false/_config.js diff --git a/test/generator/samples/css-false/main.html b/test/runtime/samples/css-false/main.html similarity index 100% rename from test/generator/samples/css-false/main.html rename to test/runtime/samples/css-false/main.html diff --git a/test/generator/samples/css-space-in-attribute/Widget.html b/test/runtime/samples/css-space-in-attribute/Widget.html similarity index 100% rename from test/generator/samples/css-space-in-attribute/Widget.html rename to test/runtime/samples/css-space-in-attribute/Widget.html diff --git a/test/generator/samples/css-space-in-attribute/_config.js b/test/runtime/samples/css-space-in-attribute/_config.js similarity index 100% rename from test/generator/samples/css-space-in-attribute/_config.js rename to test/runtime/samples/css-space-in-attribute/_config.js diff --git a/test/generator/samples/css-space-in-attribute/main.html b/test/runtime/samples/css-space-in-attribute/main.html similarity index 100% rename from test/generator/samples/css-space-in-attribute/main.html rename to test/runtime/samples/css-space-in-attribute/main.html diff --git a/test/generator/samples/css/Widget.html b/test/runtime/samples/css/Widget.html similarity index 100% rename from test/generator/samples/css/Widget.html rename to test/runtime/samples/css/Widget.html diff --git a/test/generator/samples/css/_config.js b/test/runtime/samples/css/_config.js similarity index 100% rename from test/generator/samples/css/_config.js rename to test/runtime/samples/css/_config.js diff --git a/test/generator/samples/css/main.html b/test/runtime/samples/css/main.html similarity index 100% rename from test/generator/samples/css/main.html rename to test/runtime/samples/css/main.html diff --git a/test/generator/samples/custom-method/_config.js b/test/runtime/samples/custom-method/_config.js similarity index 100% rename from test/generator/samples/custom-method/_config.js rename to test/runtime/samples/custom-method/_config.js diff --git a/test/generator/samples/custom-method/main.html b/test/runtime/samples/custom-method/main.html similarity index 100% rename from test/generator/samples/custom-method/main.html rename to test/runtime/samples/custom-method/main.html diff --git a/test/generator/samples/deconflict-builtins/_config.js b/test/runtime/samples/deconflict-builtins/_config.js similarity index 100% rename from test/generator/samples/deconflict-builtins/_config.js rename to test/runtime/samples/deconflict-builtins/_config.js diff --git a/test/generator/samples/deconflict-builtins/get.js b/test/runtime/samples/deconflict-builtins/get.js similarity index 100% rename from test/generator/samples/deconflict-builtins/get.js rename to test/runtime/samples/deconflict-builtins/get.js diff --git a/test/generator/samples/deconflict-builtins/main.html b/test/runtime/samples/deconflict-builtins/main.html similarity index 100% rename from test/generator/samples/deconflict-builtins/main.html rename to test/runtime/samples/deconflict-builtins/main.html diff --git a/test/generator/samples/deconflict-contexts/_config.js b/test/runtime/samples/deconflict-contexts/_config.js similarity index 100% rename from test/generator/samples/deconflict-contexts/_config.js rename to test/runtime/samples/deconflict-contexts/_config.js diff --git a/test/generator/samples/deconflict-contexts/main.html b/test/runtime/samples/deconflict-contexts/main.html similarity index 100% rename from test/generator/samples/deconflict-contexts/main.html rename to test/runtime/samples/deconflict-contexts/main.html diff --git a/test/generator/samples/deconflict-non-helpers/_config.js b/test/runtime/samples/deconflict-non-helpers/_config.js similarity index 100% rename from test/generator/samples/deconflict-non-helpers/_config.js rename to test/runtime/samples/deconflict-non-helpers/_config.js diff --git a/test/generator/samples/deconflict-non-helpers/main.html b/test/runtime/samples/deconflict-non-helpers/main.html similarity index 100% rename from test/generator/samples/deconflict-non-helpers/main.html rename to test/runtime/samples/deconflict-non-helpers/main.html diff --git a/test/generator/samples/deconflict-non-helpers/module.js b/test/runtime/samples/deconflict-non-helpers/module.js similarity index 100% rename from test/generator/samples/deconflict-non-helpers/module.js rename to test/runtime/samples/deconflict-non-helpers/module.js diff --git a/test/generator/samples/deconflict-template-1/_config.js b/test/runtime/samples/deconflict-template-1/_config.js similarity index 100% rename from test/generator/samples/deconflict-template-1/_config.js rename to test/runtime/samples/deconflict-template-1/_config.js diff --git a/test/generator/samples/deconflict-template-1/main.html b/test/runtime/samples/deconflict-template-1/main.html similarity index 100% rename from test/generator/samples/deconflict-template-1/main.html rename to test/runtime/samples/deconflict-template-1/main.html diff --git a/test/generator/samples/deconflict-template-1/module.js b/test/runtime/samples/deconflict-template-1/module.js similarity index 100% rename from test/generator/samples/deconflict-template-1/module.js rename to test/runtime/samples/deconflict-template-1/module.js diff --git a/test/generator/samples/deconflict-template-2/_config.js b/test/runtime/samples/deconflict-template-2/_config.js similarity index 100% rename from test/generator/samples/deconflict-template-2/_config.js rename to test/runtime/samples/deconflict-template-2/_config.js diff --git a/test/generator/samples/deconflict-template-2/main.html b/test/runtime/samples/deconflict-template-2/main.html similarity index 100% rename from test/generator/samples/deconflict-template-2/main.html rename to test/runtime/samples/deconflict-template-2/main.html diff --git a/test/generator/samples/default-data-function/_config.js b/test/runtime/samples/default-data-function/_config.js similarity index 100% rename from test/generator/samples/default-data-function/_config.js rename to test/runtime/samples/default-data-function/_config.js diff --git a/test/generator/samples/default-data-function/main.html b/test/runtime/samples/default-data-function/main.html similarity index 100% rename from test/generator/samples/default-data-function/main.html rename to test/runtime/samples/default-data-function/main.html diff --git a/test/generator/samples/default-data-override/_config.js b/test/runtime/samples/default-data-override/_config.js similarity index 100% rename from test/generator/samples/default-data-override/_config.js rename to test/runtime/samples/default-data-override/_config.js diff --git a/test/generator/samples/default-data-override/main.html b/test/runtime/samples/default-data-override/main.html similarity index 100% rename from test/generator/samples/default-data-override/main.html rename to test/runtime/samples/default-data-override/main.html diff --git a/test/generator/samples/default-data/_config.js b/test/runtime/samples/default-data/_config.js similarity index 100% rename from test/generator/samples/default-data/_config.js rename to test/runtime/samples/default-data/_config.js diff --git a/test/generator/samples/default-data/main.html b/test/runtime/samples/default-data/main.html similarity index 100% rename from test/generator/samples/default-data/main.html rename to test/runtime/samples/default-data/main.html diff --git a/test/generator/samples/destructuring/_config.js b/test/runtime/samples/destructuring/_config.js similarity index 100% rename from test/generator/samples/destructuring/_config.js rename to test/runtime/samples/destructuring/_config.js diff --git a/test/generator/samples/destructuring/main.html b/test/runtime/samples/destructuring/main.html similarity index 100% rename from test/generator/samples/destructuring/main.html rename to test/runtime/samples/destructuring/main.html diff --git a/test/generator/samples/dev-warning-bad-observe-arguments/_config.js b/test/runtime/samples/dev-warning-bad-observe-arguments/_config.js similarity index 100% rename from test/generator/samples/dev-warning-bad-observe-arguments/_config.js rename to test/runtime/samples/dev-warning-bad-observe-arguments/_config.js diff --git a/test/generator/samples/dev-warning-bad-observe-arguments/main.html b/test/runtime/samples/dev-warning-bad-observe-arguments/main.html similarity index 100% rename from test/generator/samples/dev-warning-bad-observe-arguments/main.html rename to test/runtime/samples/dev-warning-bad-observe-arguments/main.html diff --git a/test/generator/samples/dev-warning-destroy-not-teardown/_config.js b/test/runtime/samples/dev-warning-destroy-not-teardown/_config.js similarity index 100% rename from test/generator/samples/dev-warning-destroy-not-teardown/_config.js rename to test/runtime/samples/dev-warning-destroy-not-teardown/_config.js diff --git a/test/generator/samples/dev-warning-destroy-not-teardown/main.html b/test/runtime/samples/dev-warning-destroy-not-teardown/main.html similarity index 100% rename from test/generator/samples/dev-warning-destroy-not-teardown/main.html rename to test/runtime/samples/dev-warning-destroy-not-teardown/main.html diff --git a/test/generator/samples/dev-warning-missing-data-binding/_config.js b/test/runtime/samples/dev-warning-missing-data-binding/_config.js similarity index 100% rename from test/generator/samples/dev-warning-missing-data-binding/_config.js rename to test/runtime/samples/dev-warning-missing-data-binding/_config.js diff --git a/test/generator/samples/dev-warning-missing-data-binding/main.html b/test/runtime/samples/dev-warning-missing-data-binding/main.html similarity index 100% rename from test/generator/samples/dev-warning-missing-data-binding/main.html rename to test/runtime/samples/dev-warning-missing-data-binding/main.html diff --git a/test/generator/samples/dev-warning-missing-data/_config.js b/test/runtime/samples/dev-warning-missing-data/_config.js similarity index 100% rename from test/generator/samples/dev-warning-missing-data/_config.js rename to test/runtime/samples/dev-warning-missing-data/_config.js diff --git a/test/generator/samples/dev-warning-missing-data/main.html b/test/runtime/samples/dev-warning-missing-data/main.html similarity index 100% rename from test/generator/samples/dev-warning-missing-data/main.html rename to test/runtime/samples/dev-warning-missing-data/main.html diff --git a/test/generator/samples/each-block-containing-if/_config.js b/test/runtime/samples/each-block-containing-if/_config.js similarity index 100% rename from test/generator/samples/each-block-containing-if/_config.js rename to test/runtime/samples/each-block-containing-if/_config.js diff --git a/test/generator/samples/each-block-containing-if/main.html b/test/runtime/samples/each-block-containing-if/main.html similarity index 100% rename from test/generator/samples/each-block-containing-if/main.html rename to test/runtime/samples/each-block-containing-if/main.html diff --git a/test/runtime/samples/each-block-else/_config.js b/test/runtime/samples/each-block-else/_config.js new file mode 100644 index 000000000000..35ba9637be1d --- /dev/null +++ b/test/runtime/samples/each-block-else/_config.js @@ -0,0 +1,37 @@ +export default { + data: { + animals: [ 'alpaca', 'baboon', 'capybara' ], + foo: 'something else' + }, + + html: ` + before + alpaca + baboon + capybara + after + `, + + test ( assert, component, target ) { + component.set({ animals: [] }); + assert.htmlEqual( target.innerHTML, ` + before + no animals, but rather something else + after + ` ); + + component.set({ foo: 'something other' }); + assert.htmlEqual( target.innerHTML, ` + before + no animals, but rather something other + after + ` ); + + component.set({ animals: ['wombat'] }); + assert.htmlEqual( target.innerHTML, ` + before + wombat + after + ` ); + } +}; diff --git a/test/generator/samples/each-block-else/main.html b/test/runtime/samples/each-block-else/main.html similarity index 100% rename from test/generator/samples/each-block-else/main.html rename to test/runtime/samples/each-block-else/main.html diff --git a/test/generator/samples/each-block-indexed/_config.js b/test/runtime/samples/each-block-indexed/_config.js similarity index 100% rename from test/generator/samples/each-block-indexed/_config.js rename to test/runtime/samples/each-block-indexed/_config.js diff --git a/test/generator/samples/each-block-indexed/main.html b/test/runtime/samples/each-block-indexed/main.html similarity index 100% rename from test/generator/samples/each-block-indexed/main.html rename to test/runtime/samples/each-block-indexed/main.html diff --git a/test/generator/samples/each-block-keyed/_config.js b/test/runtime/samples/each-block-keyed/_config.js similarity index 100% rename from test/generator/samples/each-block-keyed/_config.js rename to test/runtime/samples/each-block-keyed/_config.js diff --git a/test/generator/samples/each-block-keyed/main.html b/test/runtime/samples/each-block-keyed/main.html similarity index 100% rename from test/generator/samples/each-block-keyed/main.html rename to test/runtime/samples/each-block-keyed/main.html diff --git a/test/generator/samples/each-block-random-permute/_config.js b/test/runtime/samples/each-block-random-permute/_config.js similarity index 100% rename from test/generator/samples/each-block-random-permute/_config.js rename to test/runtime/samples/each-block-random-permute/_config.js diff --git a/test/generator/samples/each-block-random-permute/main.html b/test/runtime/samples/each-block-random-permute/main.html similarity index 100% rename from test/generator/samples/each-block-random-permute/main.html rename to test/runtime/samples/each-block-random-permute/main.html diff --git a/test/generator/samples/each-block-text-node/_config.js b/test/runtime/samples/each-block-text-node/_config.js similarity index 100% rename from test/generator/samples/each-block-text-node/_config.js rename to test/runtime/samples/each-block-text-node/_config.js diff --git a/test/generator/samples/each-block-text-node/main.html b/test/runtime/samples/each-block-text-node/main.html similarity index 100% rename from test/generator/samples/each-block-text-node/main.html rename to test/runtime/samples/each-block-text-node/main.html diff --git a/test/generator/samples/each-block/_config.js b/test/runtime/samples/each-block/_config.js similarity index 50% rename from test/generator/samples/each-block/_config.js rename to test/runtime/samples/each-block/_config.js index 655556bedfd9..73e3d0c6f461 100644 --- a/test/generator/samples/each-block/_config.js +++ b/test/runtime/samples/each-block/_config.js @@ -2,11 +2,23 @@ export default { data: { animals: [ 'alpaca', 'baboon', 'capybara' ] }, - html: 'alpacababooncapybara', + + html: ` + alpaca + baboon + capybara + `, + test ( assert, component, target ) { component.set({ animals: [ 'alpaca', 'baboon', 'caribou', 'dogfish' ] }); - assert.equal( target.innerHTML, 'alpacababooncariboudogfish' ); + assert.htmlEqual( target.innerHTML, ` + alpaca + baboon + caribou + dogfish + ` ); + component.set({ animals: [] }); - assert.equal( target.innerHTML, '' ); + assert.htmlEqual( target.innerHTML, '' ); } }; diff --git a/test/generator/samples/each-block/main.html b/test/runtime/samples/each-block/main.html similarity index 100% rename from test/generator/samples/each-block/main.html rename to test/runtime/samples/each-block/main.html diff --git a/test/generator/samples/each-blocks-expression/_config.js b/test/runtime/samples/each-blocks-expression/_config.js similarity index 100% rename from test/generator/samples/each-blocks-expression/_config.js rename to test/runtime/samples/each-blocks-expression/_config.js diff --git a/test/generator/samples/each-blocks-expression/main.html b/test/runtime/samples/each-blocks-expression/main.html similarity index 100% rename from test/generator/samples/each-blocks-expression/main.html rename to test/runtime/samples/each-blocks-expression/main.html diff --git a/test/generator/samples/each-blocks-nested-b/_config.js b/test/runtime/samples/each-blocks-nested-b/_config.js similarity index 100% rename from test/generator/samples/each-blocks-nested-b/_config.js rename to test/runtime/samples/each-blocks-nested-b/_config.js diff --git a/test/generator/samples/each-blocks-nested-b/main.html b/test/runtime/samples/each-blocks-nested-b/main.html similarity index 100% rename from test/generator/samples/each-blocks-nested-b/main.html rename to test/runtime/samples/each-blocks-nested-b/main.html diff --git a/test/generator/samples/each-blocks-nested/_config.js b/test/runtime/samples/each-blocks-nested/_config.js similarity index 100% rename from test/generator/samples/each-blocks-nested/_config.js rename to test/runtime/samples/each-blocks-nested/_config.js diff --git a/test/generator/samples/each-blocks-nested/main.html b/test/runtime/samples/each-blocks-nested/main.html similarity index 100% rename from test/generator/samples/each-blocks-nested/main.html rename to test/runtime/samples/each-blocks-nested/main.html diff --git a/test/generator/samples/event-handler-custom-context/_config.js b/test/runtime/samples/event-handler-custom-context/_config.js similarity index 100% rename from test/generator/samples/event-handler-custom-context/_config.js rename to test/runtime/samples/event-handler-custom-context/_config.js diff --git a/test/generator/samples/event-handler-custom-context/main.html b/test/runtime/samples/event-handler-custom-context/main.html similarity index 100% rename from test/generator/samples/event-handler-custom-context/main.html rename to test/runtime/samples/event-handler-custom-context/main.html diff --git a/test/generator/samples/event-handler-custom-node-context/_config.js b/test/runtime/samples/event-handler-custom-node-context/_config.js similarity index 100% rename from test/generator/samples/event-handler-custom-node-context/_config.js rename to test/runtime/samples/event-handler-custom-node-context/_config.js diff --git a/test/generator/samples/event-handler-custom-node-context/main.html b/test/runtime/samples/event-handler-custom-node-context/main.html similarity index 100% rename from test/generator/samples/event-handler-custom-node-context/main.html rename to test/runtime/samples/event-handler-custom-node-context/main.html diff --git a/test/generator/samples/event-handler-custom/_config.js b/test/runtime/samples/event-handler-custom/_config.js similarity index 100% rename from test/generator/samples/event-handler-custom/_config.js rename to test/runtime/samples/event-handler-custom/_config.js diff --git a/test/generator/samples/event-handler-custom/main.html b/test/runtime/samples/event-handler-custom/main.html similarity index 100% rename from test/generator/samples/event-handler-custom/main.html rename to test/runtime/samples/event-handler-custom/main.html diff --git a/test/generator/samples/event-handler-event-methods/_config.js b/test/runtime/samples/event-handler-event-methods/_config.js similarity index 100% rename from test/generator/samples/event-handler-event-methods/_config.js rename to test/runtime/samples/event-handler-event-methods/_config.js diff --git a/test/generator/samples/event-handler-event-methods/main.html b/test/runtime/samples/event-handler-event-methods/main.html similarity index 100% rename from test/generator/samples/event-handler-event-methods/main.html rename to test/runtime/samples/event-handler-event-methods/main.html diff --git a/test/generator/samples/event-handler-removal/_config.js b/test/runtime/samples/event-handler-removal/_config.js similarity index 100% rename from test/generator/samples/event-handler-removal/_config.js rename to test/runtime/samples/event-handler-removal/_config.js diff --git a/test/generator/samples/event-handler-removal/main.html b/test/runtime/samples/event-handler-removal/main.html similarity index 100% rename from test/generator/samples/event-handler-removal/main.html rename to test/runtime/samples/event-handler-removal/main.html diff --git a/test/generator/samples/event-handler-this-methods/_config.js b/test/runtime/samples/event-handler-this-methods/_config.js similarity index 100% rename from test/generator/samples/event-handler-this-methods/_config.js rename to test/runtime/samples/event-handler-this-methods/_config.js diff --git a/test/generator/samples/event-handler-this-methods/main.html b/test/runtime/samples/event-handler-this-methods/main.html similarity index 100% rename from test/generator/samples/event-handler-this-methods/main.html rename to test/runtime/samples/event-handler-this-methods/main.html diff --git a/test/generator/samples/event-handler/_config.js b/test/runtime/samples/event-handler/_config.js similarity index 100% rename from test/generator/samples/event-handler/_config.js rename to test/runtime/samples/event-handler/_config.js diff --git a/test/generator/samples/event-handler/main.html b/test/runtime/samples/event-handler/main.html similarity index 100% rename from test/generator/samples/event-handler/main.html rename to test/runtime/samples/event-handler/main.html diff --git a/test/generator/samples/events-custom/_config.js b/test/runtime/samples/events-custom/_config.js similarity index 100% rename from test/generator/samples/events-custom/_config.js rename to test/runtime/samples/events-custom/_config.js diff --git a/test/generator/samples/events-custom/main.html b/test/runtime/samples/events-custom/main.html similarity index 100% rename from test/generator/samples/events-custom/main.html rename to test/runtime/samples/events-custom/main.html diff --git a/test/generator/samples/events-lifecycle/_config.js b/test/runtime/samples/events-lifecycle/_config.js similarity index 100% rename from test/generator/samples/events-lifecycle/_config.js rename to test/runtime/samples/events-lifecycle/_config.js diff --git a/test/generator/samples/events-lifecycle/main.html b/test/runtime/samples/events-lifecycle/main.html similarity index 100% rename from test/generator/samples/events-lifecycle/main.html rename to test/runtime/samples/events-lifecycle/main.html diff --git a/test/generator/samples/function-in-expression/_config.js b/test/runtime/samples/function-in-expression/_config.js similarity index 100% rename from test/generator/samples/function-in-expression/_config.js rename to test/runtime/samples/function-in-expression/_config.js diff --git a/test/generator/samples/function-in-expression/main.html b/test/runtime/samples/function-in-expression/main.html similarity index 100% rename from test/generator/samples/function-in-expression/main.html rename to test/runtime/samples/function-in-expression/main.html diff --git a/test/generator/samples/get-state/_config.js b/test/runtime/samples/get-state/_config.js similarity index 100% rename from test/generator/samples/get-state/_config.js rename to test/runtime/samples/get-state/_config.js diff --git a/test/generator/samples/get-state/main.html b/test/runtime/samples/get-state/main.html similarity index 100% rename from test/generator/samples/get-state/main.html rename to test/runtime/samples/get-state/main.html diff --git a/test/generator/samples/globals-accessible-directly/_config.js b/test/runtime/samples/globals-accessible-directly/_config.js similarity index 100% rename from test/generator/samples/globals-accessible-directly/_config.js rename to test/runtime/samples/globals-accessible-directly/_config.js diff --git a/test/generator/samples/globals-accessible-directly/main.html b/test/runtime/samples/globals-accessible-directly/main.html similarity index 100% rename from test/generator/samples/globals-accessible-directly/main.html rename to test/runtime/samples/globals-accessible-directly/main.html diff --git a/test/generator/samples/globals-not-dereferenced/_config.js b/test/runtime/samples/globals-not-dereferenced/_config.js similarity index 100% rename from test/generator/samples/globals-not-dereferenced/_config.js rename to test/runtime/samples/globals-not-dereferenced/_config.js diff --git a/test/generator/samples/globals-not-dereferenced/main.html b/test/runtime/samples/globals-not-dereferenced/main.html similarity index 100% rename from test/generator/samples/globals-not-dereferenced/main.html rename to test/runtime/samples/globals-not-dereferenced/main.html diff --git a/test/generator/samples/globals-shadowed-by-data/_config.js b/test/runtime/samples/globals-shadowed-by-data/_config.js similarity index 100% rename from test/generator/samples/globals-shadowed-by-data/_config.js rename to test/runtime/samples/globals-shadowed-by-data/_config.js diff --git a/test/generator/samples/globals-shadowed-by-data/main.html b/test/runtime/samples/globals-shadowed-by-data/main.html similarity index 100% rename from test/generator/samples/globals-shadowed-by-data/main.html rename to test/runtime/samples/globals-shadowed-by-data/main.html diff --git a/test/generator/samples/globals-shadowed-by-helpers/_config.js b/test/runtime/samples/globals-shadowed-by-helpers/_config.js similarity index 100% rename from test/generator/samples/globals-shadowed-by-helpers/_config.js rename to test/runtime/samples/globals-shadowed-by-helpers/_config.js diff --git a/test/generator/samples/globals-shadowed-by-helpers/main.html b/test/runtime/samples/globals-shadowed-by-helpers/main.html similarity index 100% rename from test/generator/samples/globals-shadowed-by-helpers/main.html rename to test/runtime/samples/globals-shadowed-by-helpers/main.html diff --git a/test/generator/samples/hello-world/_config.js b/test/runtime/samples/hello-world/_config.js similarity index 100% rename from test/generator/samples/hello-world/_config.js rename to test/runtime/samples/hello-world/_config.js diff --git a/test/generator/samples/hello-world/main.html b/test/runtime/samples/hello-world/main.html similarity index 100% rename from test/generator/samples/hello-world/main.html rename to test/runtime/samples/hello-world/main.html diff --git a/test/generator/samples/helpers/_config.js b/test/runtime/samples/helpers/_config.js similarity index 100% rename from test/generator/samples/helpers/_config.js rename to test/runtime/samples/helpers/_config.js diff --git a/test/generator/samples/helpers/main.html b/test/runtime/samples/helpers/main.html similarity index 100% rename from test/generator/samples/helpers/main.html rename to test/runtime/samples/helpers/main.html diff --git a/test/generator/samples/if-block-else/_config.js b/test/runtime/samples/if-block-else/_config.js similarity index 100% rename from test/generator/samples/if-block-else/_config.js rename to test/runtime/samples/if-block-else/_config.js diff --git a/test/generator/samples/if-block-else/main.html b/test/runtime/samples/if-block-else/main.html similarity index 100% rename from test/generator/samples/if-block-else/main.html rename to test/runtime/samples/if-block-else/main.html diff --git a/test/generator/samples/if-block-elseif-text/_config.js b/test/runtime/samples/if-block-elseif-text/_config.js similarity index 100% rename from test/generator/samples/if-block-elseif-text/_config.js rename to test/runtime/samples/if-block-elseif-text/_config.js diff --git a/test/generator/samples/if-block-elseif-text/main.html b/test/runtime/samples/if-block-elseif-text/main.html similarity index 100% rename from test/generator/samples/if-block-elseif-text/main.html rename to test/runtime/samples/if-block-elseif-text/main.html diff --git a/test/generator/samples/if-block-elseif/_config.js b/test/runtime/samples/if-block-elseif/_config.js similarity index 100% rename from test/generator/samples/if-block-elseif/_config.js rename to test/runtime/samples/if-block-elseif/_config.js diff --git a/test/generator/samples/if-block-elseif/main.html b/test/runtime/samples/if-block-elseif/main.html similarity index 100% rename from test/generator/samples/if-block-elseif/main.html rename to test/runtime/samples/if-block-elseif/main.html diff --git a/test/generator/samples/if-block-expression/_config.js b/test/runtime/samples/if-block-expression/_config.js similarity index 100% rename from test/generator/samples/if-block-expression/_config.js rename to test/runtime/samples/if-block-expression/_config.js diff --git a/test/generator/samples/if-block-expression/main.html b/test/runtime/samples/if-block-expression/main.html similarity index 100% rename from test/generator/samples/if-block-expression/main.html rename to test/runtime/samples/if-block-expression/main.html diff --git a/test/generator/samples/if-block-widget/Widget.html b/test/runtime/samples/if-block-widget/Widget.html similarity index 100% rename from test/generator/samples/if-block-widget/Widget.html rename to test/runtime/samples/if-block-widget/Widget.html diff --git a/test/generator/samples/if-block-widget/_config.js b/test/runtime/samples/if-block-widget/_config.js similarity index 100% rename from test/generator/samples/if-block-widget/_config.js rename to test/runtime/samples/if-block-widget/_config.js diff --git a/test/generator/samples/if-block-widget/main.html b/test/runtime/samples/if-block-widget/main.html similarity index 100% rename from test/generator/samples/if-block-widget/main.html rename to test/runtime/samples/if-block-widget/main.html diff --git a/test/generator/samples/if-block/_config.js b/test/runtime/samples/if-block/_config.js similarity index 52% rename from test/generator/samples/if-block/_config.js rename to test/runtime/samples/if-block/_config.js index 4194fd29bcab..8f9f85ab68d6 100644 --- a/test/generator/samples/if-block/_config.js +++ b/test/runtime/samples/if-block/_config.js @@ -2,11 +2,13 @@ export default { data: { visible: true }, - html: 'i am visible', + + html: 'i am visible', + test ( assert, component, target ) { component.set({ visible: false }); - assert.equal( target.innerHTML, '' ); + assert.htmlEqual( target.innerHTML, '' ); component.set({ visible: true }); - assert.equal( target.innerHTML, 'i am visible' ); + assert.htmlEqual( target.innerHTML, 'i am visible' ); } }; diff --git a/test/generator/samples/if-block/main.html b/test/runtime/samples/if-block/main.html similarity index 100% rename from test/generator/samples/if-block/main.html rename to test/runtime/samples/if-block/main.html diff --git a/test/generator/samples/imported-renamed-components/ComponentOne.html b/test/runtime/samples/imported-renamed-components/ComponentOne.html similarity index 100% rename from test/generator/samples/imported-renamed-components/ComponentOne.html rename to test/runtime/samples/imported-renamed-components/ComponentOne.html diff --git a/test/generator/samples/imported-renamed-components/ComponentTwo.html b/test/runtime/samples/imported-renamed-components/ComponentTwo.html similarity index 100% rename from test/generator/samples/imported-renamed-components/ComponentTwo.html rename to test/runtime/samples/imported-renamed-components/ComponentTwo.html diff --git a/test/generator/samples/imported-renamed-components/_config.js b/test/runtime/samples/imported-renamed-components/_config.js similarity index 100% rename from test/generator/samples/imported-renamed-components/_config.js rename to test/runtime/samples/imported-renamed-components/_config.js diff --git a/test/generator/samples/imported-renamed-components/main.html b/test/runtime/samples/imported-renamed-components/main.html similarity index 100% rename from test/generator/samples/imported-renamed-components/main.html rename to test/runtime/samples/imported-renamed-components/main.html diff --git a/test/generator/samples/inline-expressions/_config.js b/test/runtime/samples/inline-expressions/_config.js similarity index 100% rename from test/generator/samples/inline-expressions/_config.js rename to test/runtime/samples/inline-expressions/_config.js diff --git a/test/generator/samples/inline-expressions/main.html b/test/runtime/samples/inline-expressions/main.html similarity index 100% rename from test/generator/samples/inline-expressions/main.html rename to test/runtime/samples/inline-expressions/main.html diff --git a/test/generator/samples/input-list/_config.js b/test/runtime/samples/input-list/_config.js similarity index 100% rename from test/generator/samples/input-list/_config.js rename to test/runtime/samples/input-list/_config.js diff --git a/test/generator/samples/input-list/main.html b/test/runtime/samples/input-list/main.html similarity index 100% rename from test/generator/samples/input-list/main.html rename to test/runtime/samples/input-list/main.html diff --git a/test/generator/samples/lifecycle-events/_config.js b/test/runtime/samples/lifecycle-events/_config.js similarity index 100% rename from test/generator/samples/lifecycle-events/_config.js rename to test/runtime/samples/lifecycle-events/_config.js diff --git a/test/generator/samples/lifecycle-events/main.html b/test/runtime/samples/lifecycle-events/main.html similarity index 100% rename from test/generator/samples/lifecycle-events/main.html rename to test/runtime/samples/lifecycle-events/main.html diff --git a/test/generator/samples/names-deconflicted-nested/_config.js b/test/runtime/samples/names-deconflicted-nested/_config.js similarity index 100% rename from test/generator/samples/names-deconflicted-nested/_config.js rename to test/runtime/samples/names-deconflicted-nested/_config.js diff --git a/test/generator/samples/names-deconflicted-nested/main.html b/test/runtime/samples/names-deconflicted-nested/main.html similarity index 100% rename from test/generator/samples/names-deconflicted-nested/main.html rename to test/runtime/samples/names-deconflicted-nested/main.html diff --git a/test/generator/samples/names-deconflicted/Widget.html b/test/runtime/samples/names-deconflicted/Widget.html similarity index 100% rename from test/generator/samples/names-deconflicted/Widget.html rename to test/runtime/samples/names-deconflicted/Widget.html diff --git a/test/generator/samples/names-deconflicted/_config.js b/test/runtime/samples/names-deconflicted/_config.js similarity index 100% rename from test/generator/samples/names-deconflicted/_config.js rename to test/runtime/samples/names-deconflicted/_config.js diff --git a/test/generator/samples/names-deconflicted/main.html b/test/runtime/samples/names-deconflicted/main.html similarity index 100% rename from test/generator/samples/names-deconflicted/main.html rename to test/runtime/samples/names-deconflicted/main.html diff --git a/test/generator/samples/nbsp/_config.js b/test/runtime/samples/nbsp/_config.js similarity index 100% rename from test/generator/samples/nbsp/_config.js rename to test/runtime/samples/nbsp/_config.js diff --git a/test/generator/samples/nbsp/main.html b/test/runtime/samples/nbsp/main.html similarity index 100% rename from test/generator/samples/nbsp/main.html rename to test/runtime/samples/nbsp/main.html diff --git a/test/generator/samples/observe-component-ignores-irrelevant-changes/Foo.html b/test/runtime/samples/observe-component-ignores-irrelevant-changes/Foo.html similarity index 100% rename from test/generator/samples/observe-component-ignores-irrelevant-changes/Foo.html rename to test/runtime/samples/observe-component-ignores-irrelevant-changes/Foo.html diff --git a/test/generator/samples/observe-component-ignores-irrelevant-changes/_config.js b/test/runtime/samples/observe-component-ignores-irrelevant-changes/_config.js similarity index 100% rename from test/generator/samples/observe-component-ignores-irrelevant-changes/_config.js rename to test/runtime/samples/observe-component-ignores-irrelevant-changes/_config.js diff --git a/test/generator/samples/observe-component-ignores-irrelevant-changes/main.html b/test/runtime/samples/observe-component-ignores-irrelevant-changes/main.html similarity index 100% rename from test/generator/samples/observe-component-ignores-irrelevant-changes/main.html rename to test/runtime/samples/observe-component-ignores-irrelevant-changes/main.html diff --git a/test/generator/samples/observe-prevents-loop/_config.js b/test/runtime/samples/observe-prevents-loop/_config.js similarity index 100% rename from test/generator/samples/observe-prevents-loop/_config.js rename to test/runtime/samples/observe-prevents-loop/_config.js diff --git a/test/generator/samples/observe-prevents-loop/main.html b/test/runtime/samples/observe-prevents-loop/main.html similarity index 100% rename from test/generator/samples/observe-prevents-loop/main.html rename to test/runtime/samples/observe-prevents-loop/main.html diff --git a/test/generator/samples/onrender-chain/Item.html b/test/runtime/samples/onrender-chain/Item.html similarity index 100% rename from test/generator/samples/onrender-chain/Item.html rename to test/runtime/samples/onrender-chain/Item.html diff --git a/test/generator/samples/onrender-chain/List.html b/test/runtime/samples/onrender-chain/List.html similarity index 100% rename from test/generator/samples/onrender-chain/List.html rename to test/runtime/samples/onrender-chain/List.html diff --git a/test/generator/samples/onrender-chain/_config.js b/test/runtime/samples/onrender-chain/_config.js similarity index 100% rename from test/generator/samples/onrender-chain/_config.js rename to test/runtime/samples/onrender-chain/_config.js diff --git a/test/generator/samples/onrender-chain/main.html b/test/runtime/samples/onrender-chain/main.html similarity index 100% rename from test/generator/samples/onrender-chain/main.html rename to test/runtime/samples/onrender-chain/main.html diff --git a/test/generator/samples/onrender-fires-when-ready-nested/ParentWidget.html b/test/runtime/samples/onrender-fires-when-ready-nested/ParentWidget.html similarity index 100% rename from test/generator/samples/onrender-fires-when-ready-nested/ParentWidget.html rename to test/runtime/samples/onrender-fires-when-ready-nested/ParentWidget.html diff --git a/test/generator/samples/onrender-fires-when-ready-nested/Widget.html b/test/runtime/samples/onrender-fires-when-ready-nested/Widget.html similarity index 100% rename from test/generator/samples/onrender-fires-when-ready-nested/Widget.html rename to test/runtime/samples/onrender-fires-when-ready-nested/Widget.html diff --git a/test/generator/samples/onrender-fires-when-ready-nested/_config.js b/test/runtime/samples/onrender-fires-when-ready-nested/_config.js similarity index 100% rename from test/generator/samples/onrender-fires-when-ready-nested/_config.js rename to test/runtime/samples/onrender-fires-when-ready-nested/_config.js diff --git a/test/generator/samples/onrender-fires-when-ready-nested/main.html b/test/runtime/samples/onrender-fires-when-ready-nested/main.html similarity index 100% rename from test/generator/samples/onrender-fires-when-ready-nested/main.html rename to test/runtime/samples/onrender-fires-when-ready-nested/main.html diff --git a/test/generator/samples/onrender-fires-when-ready/Widget.html b/test/runtime/samples/onrender-fires-when-ready/Widget.html similarity index 100% rename from test/generator/samples/onrender-fires-when-ready/Widget.html rename to test/runtime/samples/onrender-fires-when-ready/Widget.html diff --git a/test/generator/samples/onrender-fires-when-ready/_config.js b/test/runtime/samples/onrender-fires-when-ready/_config.js similarity index 100% rename from test/generator/samples/onrender-fires-when-ready/_config.js rename to test/runtime/samples/onrender-fires-when-ready/_config.js diff --git a/test/generator/samples/onrender-fires-when-ready/main.html b/test/runtime/samples/onrender-fires-when-ready/main.html similarity index 100% rename from test/generator/samples/onrender-fires-when-ready/main.html rename to test/runtime/samples/onrender-fires-when-ready/main.html diff --git a/test/generator/samples/pass-no-options/_config.js b/test/runtime/samples/pass-no-options/_config.js similarity index 75% rename from test/generator/samples/pass-no-options/_config.js rename to test/runtime/samples/pass-no-options/_config.js index 7a8e7a4fb628..9683944f21b8 100644 --- a/test/generator/samples/pass-no-options/_config.js +++ b/test/runtime/samples/pass-no-options/_config.js @@ -1,6 +1,7 @@ export default { html: 'Just some static HTML', - test: function ( assert, component, target, window ) { + + test ( assert, component, target, window ) { const newComp = new window.SvelteComponent(); assert.equal(newComp instanceof window.SvelteComponent, true); } diff --git a/test/generator/samples/pass-no-options/main.html b/test/runtime/samples/pass-no-options/main.html similarity index 100% rename from test/generator/samples/pass-no-options/main.html rename to test/runtime/samples/pass-no-options/main.html diff --git a/test/generator/samples/raw-mustaches-preserved/_config.js b/test/runtime/samples/raw-mustaches-preserved/_config.js similarity index 100% rename from test/generator/samples/raw-mustaches-preserved/_config.js rename to test/runtime/samples/raw-mustaches-preserved/_config.js diff --git a/test/generator/samples/raw-mustaches-preserved/main.html b/test/runtime/samples/raw-mustaches-preserved/main.html similarity index 100% rename from test/generator/samples/raw-mustaches-preserved/main.html rename to test/runtime/samples/raw-mustaches-preserved/main.html diff --git a/test/generator/samples/raw-mustaches/_config.js b/test/runtime/samples/raw-mustaches/_config.js similarity index 100% rename from test/generator/samples/raw-mustaches/_config.js rename to test/runtime/samples/raw-mustaches/_config.js diff --git a/test/generator/samples/raw-mustaches/main.html b/test/runtime/samples/raw-mustaches/main.html similarity index 100% rename from test/generator/samples/raw-mustaches/main.html rename to test/runtime/samples/raw-mustaches/main.html diff --git a/test/generator/samples/refs-unset/_config.js b/test/runtime/samples/refs-unset/_config.js similarity index 100% rename from test/generator/samples/refs-unset/_config.js rename to test/runtime/samples/refs-unset/_config.js diff --git a/test/generator/samples/refs-unset/main.html b/test/runtime/samples/refs-unset/main.html similarity index 100% rename from test/generator/samples/refs-unset/main.html rename to test/runtime/samples/refs-unset/main.html diff --git a/test/generator/samples/refs/_config.js b/test/runtime/samples/refs/_config.js similarity index 100% rename from test/generator/samples/refs/_config.js rename to test/runtime/samples/refs/_config.js diff --git a/test/generator/samples/refs/main.html b/test/runtime/samples/refs/main.html similarity index 100% rename from test/generator/samples/refs/main.html rename to test/runtime/samples/refs/main.html diff --git a/test/generator/samples/select-one-way-bind/_config.js b/test/runtime/samples/select-one-way-bind/_config.js similarity index 100% rename from test/generator/samples/select-one-way-bind/_config.js rename to test/runtime/samples/select-one-way-bind/_config.js diff --git a/test/generator/samples/select-one-way-bind/main.html b/test/runtime/samples/select-one-way-bind/main.html similarity index 100% rename from test/generator/samples/select-one-way-bind/main.html rename to test/runtime/samples/select-one-way-bind/main.html diff --git a/test/generator/samples/select/_config.js b/test/runtime/samples/select/_config.js similarity index 100% rename from test/generator/samples/select/_config.js rename to test/runtime/samples/select/_config.js diff --git a/test/generator/samples/select/main.html b/test/runtime/samples/select/main.html similarity index 100% rename from test/generator/samples/select/main.html rename to test/runtime/samples/select/main.html diff --git a/test/generator/samples/self-reference-tree/_config.js b/test/runtime/samples/self-reference-tree/_config.js similarity index 100% rename from test/generator/samples/self-reference-tree/_config.js rename to test/runtime/samples/self-reference-tree/_config.js diff --git a/test/generator/samples/self-reference-tree/main.html b/test/runtime/samples/self-reference-tree/main.html similarity index 100% rename from test/generator/samples/self-reference-tree/main.html rename to test/runtime/samples/self-reference-tree/main.html diff --git a/test/generator/samples/self-reference/_config.js b/test/runtime/samples/self-reference/_config.js similarity index 90% rename from test/generator/samples/self-reference/_config.js rename to test/runtime/samples/self-reference/_config.js index dabb46783384..ea6e33fb8841 100644 --- a/test/generator/samples/self-reference/_config.js +++ b/test/runtime/samples/self-reference/_config.js @@ -1,4 +1,6 @@ export default { + // solo: true, + data: { depth: 5 }, diff --git a/test/generator/samples/self-reference/main.html b/test/runtime/samples/self-reference/main.html similarity index 100% rename from test/generator/samples/self-reference/main.html rename to test/runtime/samples/self-reference/main.html diff --git a/test/generator/samples/set-in-observe-dedupes-renders/Widget.html b/test/runtime/samples/set-in-observe-dedupes-renders/Widget.html similarity index 100% rename from test/generator/samples/set-in-observe-dedupes-renders/Widget.html rename to test/runtime/samples/set-in-observe-dedupes-renders/Widget.html diff --git a/test/generator/samples/set-in-observe-dedupes-renders/_config.js b/test/runtime/samples/set-in-observe-dedupes-renders/_config.js similarity index 100% rename from test/generator/samples/set-in-observe-dedupes-renders/_config.js rename to test/runtime/samples/set-in-observe-dedupes-renders/_config.js diff --git a/test/generator/samples/set-in-observe-dedupes-renders/main.html b/test/runtime/samples/set-in-observe-dedupes-renders/main.html similarity index 100% rename from test/generator/samples/set-in-observe-dedupes-renders/main.html rename to test/runtime/samples/set-in-observe-dedupes-renders/main.html diff --git a/test/generator/samples/set-in-observe/_config.js b/test/runtime/samples/set-in-observe/_config.js similarity index 100% rename from test/generator/samples/set-in-observe/_config.js rename to test/runtime/samples/set-in-observe/_config.js diff --git a/test/generator/samples/set-in-observe/main.html b/test/runtime/samples/set-in-observe/main.html similarity index 100% rename from test/generator/samples/set-in-observe/main.html rename to test/runtime/samples/set-in-observe/main.html diff --git a/test/generator/samples/set-in-onrender/_config.js b/test/runtime/samples/set-in-onrender/_config.js similarity index 100% rename from test/generator/samples/set-in-onrender/_config.js rename to test/runtime/samples/set-in-onrender/_config.js diff --git a/test/generator/samples/set-in-onrender/main.html b/test/runtime/samples/set-in-onrender/main.html similarity index 100% rename from test/generator/samples/set-in-onrender/main.html rename to test/runtime/samples/set-in-onrender/main.html diff --git a/test/generator/samples/set-prevents-loop/Foo.html b/test/runtime/samples/set-prevents-loop/Foo.html similarity index 100% rename from test/generator/samples/set-prevents-loop/Foo.html rename to test/runtime/samples/set-prevents-loop/Foo.html diff --git a/test/generator/samples/set-prevents-loop/_config.js b/test/runtime/samples/set-prevents-loop/_config.js similarity index 100% rename from test/generator/samples/set-prevents-loop/_config.js rename to test/runtime/samples/set-prevents-loop/_config.js diff --git a/test/generator/samples/set-prevents-loop/main.html b/test/runtime/samples/set-prevents-loop/main.html similarity index 100% rename from test/generator/samples/set-prevents-loop/main.html rename to test/runtime/samples/set-prevents-loop/main.html diff --git a/test/generator/samples/single-static-element/_config.js b/test/runtime/samples/single-static-element/_config.js similarity index 100% rename from test/generator/samples/single-static-element/_config.js rename to test/runtime/samples/single-static-element/_config.js diff --git a/test/generator/samples/single-static-element/main.html b/test/runtime/samples/single-static-element/main.html similarity index 100% rename from test/generator/samples/single-static-element/main.html rename to test/runtime/samples/single-static-element/main.html diff --git a/test/generator/samples/single-text-node/_config.js b/test/runtime/samples/single-text-node/_config.js similarity index 100% rename from test/generator/samples/single-text-node/_config.js rename to test/runtime/samples/single-text-node/_config.js diff --git a/test/generator/samples/single-text-node/main.html b/test/runtime/samples/single-text-node/main.html similarity index 100% rename from test/generator/samples/single-text-node/main.html rename to test/runtime/samples/single-text-node/main.html diff --git a/test/generator/samples/svg-attributes/_config.js b/test/runtime/samples/svg-attributes/_config.js similarity index 100% rename from test/generator/samples/svg-attributes/_config.js rename to test/runtime/samples/svg-attributes/_config.js diff --git a/test/generator/samples/svg-attributes/main.html b/test/runtime/samples/svg-attributes/main.html similarity index 100% rename from test/generator/samples/svg-attributes/main.html rename to test/runtime/samples/svg-attributes/main.html diff --git a/test/generator/samples/svg-child-component-declared-namespace-shorthand/Rect.html b/test/runtime/samples/svg-child-component-declared-namespace-shorthand/Rect.html similarity index 100% rename from test/generator/samples/svg-child-component-declared-namespace-shorthand/Rect.html rename to test/runtime/samples/svg-child-component-declared-namespace-shorthand/Rect.html diff --git a/test/generator/samples/svg-child-component-declared-namespace-shorthand/_config.js b/test/runtime/samples/svg-child-component-declared-namespace-shorthand/_config.js similarity index 100% rename from test/generator/samples/svg-child-component-declared-namespace-shorthand/_config.js rename to test/runtime/samples/svg-child-component-declared-namespace-shorthand/_config.js diff --git a/test/generator/samples/svg-child-component-declared-namespace-shorthand/main.html b/test/runtime/samples/svg-child-component-declared-namespace-shorthand/main.html similarity index 100% rename from test/generator/samples/svg-child-component-declared-namespace-shorthand/main.html rename to test/runtime/samples/svg-child-component-declared-namespace-shorthand/main.html diff --git a/test/generator/samples/svg-child-component-declared-namespace/Rect.html b/test/runtime/samples/svg-child-component-declared-namespace/Rect.html similarity index 100% rename from test/generator/samples/svg-child-component-declared-namespace/Rect.html rename to test/runtime/samples/svg-child-component-declared-namespace/Rect.html diff --git a/test/generator/samples/svg-child-component-declared-namespace/_config.js b/test/runtime/samples/svg-child-component-declared-namespace/_config.js similarity index 100% rename from test/generator/samples/svg-child-component-declared-namespace/_config.js rename to test/runtime/samples/svg-child-component-declared-namespace/_config.js diff --git a/test/generator/samples/svg-child-component-declared-namespace/main.html b/test/runtime/samples/svg-child-component-declared-namespace/main.html similarity index 100% rename from test/generator/samples/svg-child-component-declared-namespace/main.html rename to test/runtime/samples/svg-child-component-declared-namespace/main.html diff --git a/test/generator/samples/svg-class/_config.js b/test/runtime/samples/svg-class/_config.js similarity index 100% rename from test/generator/samples/svg-class/_config.js rename to test/runtime/samples/svg-class/_config.js diff --git a/test/generator/samples/svg-class/main.html b/test/runtime/samples/svg-class/main.html similarity index 100% rename from test/generator/samples/svg-class/main.html rename to test/runtime/samples/svg-class/main.html diff --git a/test/generator/samples/svg-each-block-namespace/_config.js b/test/runtime/samples/svg-each-block-namespace/_config.js similarity index 100% rename from test/generator/samples/svg-each-block-namespace/_config.js rename to test/runtime/samples/svg-each-block-namespace/_config.js diff --git a/test/generator/samples/svg-each-block-namespace/main.html b/test/runtime/samples/svg-each-block-namespace/main.html similarity index 100% rename from test/generator/samples/svg-each-block-namespace/main.html rename to test/runtime/samples/svg-each-block-namespace/main.html diff --git a/test/generator/samples/svg-multiple/_config.js b/test/runtime/samples/svg-multiple/_config.js similarity index 100% rename from test/generator/samples/svg-multiple/_config.js rename to test/runtime/samples/svg-multiple/_config.js diff --git a/test/generator/samples/svg-multiple/main.html b/test/runtime/samples/svg-multiple/main.html similarity index 100% rename from test/generator/samples/svg-multiple/main.html rename to test/runtime/samples/svg-multiple/main.html diff --git a/test/generator/samples/svg-no-whitespace/_config.js b/test/runtime/samples/svg-no-whitespace/_config.js similarity index 100% rename from test/generator/samples/svg-no-whitespace/_config.js rename to test/runtime/samples/svg-no-whitespace/_config.js diff --git a/test/generator/samples/svg-no-whitespace/main.html b/test/runtime/samples/svg-no-whitespace/main.html similarity index 100% rename from test/generator/samples/svg-no-whitespace/main.html rename to test/runtime/samples/svg-no-whitespace/main.html diff --git a/test/generator/samples/svg-xlink/_config.js b/test/runtime/samples/svg-xlink/_config.js similarity index 100% rename from test/generator/samples/svg-xlink/_config.js rename to test/runtime/samples/svg-xlink/_config.js diff --git a/test/generator/samples/svg-xlink/main.html b/test/runtime/samples/svg-xlink/main.html similarity index 100% rename from test/generator/samples/svg-xlink/main.html rename to test/runtime/samples/svg-xlink/main.html diff --git a/test/generator/samples/svg-xmlns/_config.js b/test/runtime/samples/svg-xmlns/_config.js similarity index 100% rename from test/generator/samples/svg-xmlns/_config.js rename to test/runtime/samples/svg-xmlns/_config.js diff --git a/test/generator/samples/svg-xmlns/main.html b/test/runtime/samples/svg-xmlns/main.html similarity index 100% rename from test/generator/samples/svg-xmlns/main.html rename to test/runtime/samples/svg-xmlns/main.html diff --git a/test/generator/samples/svg/_config.js b/test/runtime/samples/svg/_config.js similarity index 100% rename from test/generator/samples/svg/_config.js rename to test/runtime/samples/svg/_config.js diff --git a/test/generator/samples/svg/main.html b/test/runtime/samples/svg/main.html similarity index 100% rename from test/generator/samples/svg/main.html rename to test/runtime/samples/svg/main.html diff --git a/test/generator/samples/window-binding-resize/_config.js b/test/runtime/samples/window-binding-resize/_config.js similarity index 100% rename from test/generator/samples/window-binding-resize/_config.js rename to test/runtime/samples/window-binding-resize/_config.js diff --git a/test/generator/samples/window-binding-resize/main.html b/test/runtime/samples/window-binding-resize/main.html similarity index 100% rename from test/generator/samples/window-binding-resize/main.html rename to test/runtime/samples/window-binding-resize/main.html diff --git a/test/generator/samples/window-event/_config.js b/test/runtime/samples/window-event/_config.js similarity index 100% rename from test/generator/samples/window-event/_config.js rename to test/runtime/samples/window-event/_config.js diff --git a/test/generator/samples/window-event/main.html b/test/runtime/samples/window-event/main.html similarity index 100% rename from test/generator/samples/window-event/main.html rename to test/runtime/samples/window-event/main.html diff --git a/test/server-side-rendering/index.js b/test/server-side-rendering/index.js index 8fa6f74e0a89..d9ac917e54c6 100644 --- a/test/server-side-rendering/index.js +++ b/test/server-side-rendering/index.js @@ -81,10 +81,10 @@ describe( 'ssr', () => { }); // duplicate client-side tests, as far as possible - fs.readdirSync( 'test/generator/samples' ).forEach( dir => { + fs.readdirSync( 'test/runtime/samples' ).forEach( dir => { if ( dir[0] === '.' ) return; - const config = loadConfig( `./generator/samples/${dir}/_config.js` ); + const config = loadConfig( `./runtime/samples/${dir}/_config.js` ); if ( config.solo && process.env.CI ) { throw new Error( 'Forgot to remove `solo: true` from test' ); @@ -96,7 +96,7 @@ describe( 'ssr', () => { let compiled; try { - const source = fs.readFileSync( `test/generator/samples/${dir}/main.html`, 'utf-8' ); + const source = fs.readFileSync( `test/runtime/samples/${dir}/main.html`, 'utf-8' ); compiled = svelte.compile( source, { generate: 'ssr' }); } catch ( err ) { if ( config.compileError ) { @@ -107,7 +107,7 @@ describe( 'ssr', () => { } } - const component = require( `../generator/samples/${dir}/main.html` ); + const component = require( `../runtime/samples/${dir}/main.html` ); let html; try {
alpaca
baboon
capybara
no animals, but rather something else
no animals, but rather something other
wombat
caribou
dogfish
i am visible