diff --git a/src/compiler/compile/nodes/EventHandler.ts b/src/compiler/compile/nodes/EventHandler.ts index 688f7e85ce..a1adfd345b 100644 --- a/src/compiler/compile/nodes/EventHandler.ts +++ b/src/compiler/compile/nodes/EventHandler.ts @@ -63,7 +63,7 @@ export default class EventHandler extends Node { // TODO move this? it is specific to render-dom render(block: Block) { - if (this.expression) return this.expression.render(block); + if (this.expression) this.expression.manipulate(block); // this.component.add_reference(this.handler_name); return `ctx.${this.handler_name}`; diff --git a/src/compiler/compile/nodes/shared/Expression.ts b/src/compiler/compile/nodes/shared/Expression.ts index 50ff97ef93..ea133e322e 100644 --- a/src/compiler/compile/nodes/shared/Expression.ts +++ b/src/compiler/compile/nodes/shared/Expression.ts @@ -1,7 +1,6 @@ import Component from '../../Component'; import { walk } from 'estree-walker'; import is_reference from 'is-reference'; -// import { b } from 'code-red'; import flatten_reference from '../../utils/flatten_reference'; import { create_scopes, Scope, extract_names } from '../../utils/scope'; import { Node } from '../../../interfaces'; @@ -12,7 +11,8 @@ import get_object from '../../utils/get_object'; import Block from '../../render_dom/Block'; import { INode } from '../interfaces'; import is_dynamic from '../../render_dom/wrappers/shared/is_dynamic'; -// import { invalidate } from '../../utils/invalidate'; +import { x } from 'code-red'; +import { invalidate } from '../../utils/invalidate'; const binary_operators: Record = { '**': 15, @@ -82,8 +82,6 @@ export default class Expression { declarations: Node[] = []; uses_context = false; - rendered: string; - // todo: owner type constructor(component: Component, owner: Owner, template_scope: TemplateScope, info, lazy?: boolean) { // TODO revert to direct property access in prod? @@ -224,193 +222,191 @@ export default class Expression { } // TODO move this into a render-dom wrapper? - render(_block?: Block) { - // TODO - - // if (this.rendered) return this.rendered; - - // const { - // component, - // declarations, - // scope_map: map, - // template_scope, - // owner, - // is_synthetic - // } = this; - // let scope = this.scope; - - // let function_expression; - - // let dependencies: Set; - // let contextual_dependencies: Set; - - // // rewrite code as appropriate - // walk(this.node, { - // enter(node: any, parent: any, key: string) { - // // don't manipulate shorthand props twice - // if (key === 'value' && parent.shorthand) return; - - // if (map.has(node)) { - // scope = map.get(node); - // } - - // if (is_reference(node, parent)) { - // const { name, nodes } = flatten_reference(node); - - // if (scope.has(name)) return; - // if (globals.has(name) && !component.var_lookup.has(name)) return; - - // if (function_expression) { - // if (template_scope.names.has(name)) { - // contextual_dependencies.add(name); - - // template_scope.dependencies_for_name.get(name).forEach(dependency => { - // dependencies.add(dependency); - // }); - // } else { - // dependencies.add(name); - // component.add_reference(name); // TODO is this redundant/misplaced? - // } - // } else if (!is_synthetic && is_contextual(component, template_scope, name)) { - // code.prependRight(node.start, key === 'key' && parent.shorthand - // ? `${name}: ctx.` - // : 'ctx.'); - // } - - // if (node.type === 'MemberExpression') { - // nodes.forEach(node => { - // code.addSourcemapLocation(node.start); - // code.addSourcemapLocation(node.end); - // }); - // } - - // this.skip(); - // } - - // if (!function_expression) { - // if (node.type === 'AssignmentExpression') { - // // TODO should this be a warning/error? `

{foo = 1}

` - // } - - // if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') { - // function_expression = node; - // dependencies = new Set(); - // contextual_dependencies = new Set(); - // } - // } - // }, - - // leave(node: Node, parent: Node) { - // if (map.has(node)) scope = scope.parent; - - // if (node === function_expression) { - // const id = component.get_unique_name( - // sanitize(get_function_name(node, owner)) - // ); - - // const args = contextual_dependencies.size > 0 - // ? [`{ ${Array.from(contextual_dependencies).join(', ')} }`] - // : []; - - // let original_params; - - // if (node.params.length > 0) { - // original_params = code.slice(node.params[0].start, node.params[node.params.length - 1].end); - // args.push(original_params); - // } - - // const body = code.slice(node.body.start, node.body.end).trim(); - - // const fn = node.type === 'FunctionExpression' - // ? b`${node.async ? 'async ' : ''}function${node.generator ? '*' : ''} ${id}(${args.join(', ')}) ${body}` - // : b`const ${id} = ${node.async ? 'async ' : ''}(${args.join(', ')}) => ${body};`; - - // if (dependencies.size === 0 && contextual_dependencies.size === 0) { - // // we can hoist this out of the component completely - // component.fully_hoisted.push(fn); - // code.overwrite(node.start, node.end, id.name); - - // component.add_var({ - // name: id.name, - // internal: true, - // hoistable: true, - // referenced: true - // }); - // } - - // else if (contextual_dependencies.size === 0) { - // // function can be hoisted inside the component init - // component.partly_hoisted.push(fn); - // code.overwrite(node.start, node.end, `ctx.${id}`); - - // component.add_var({ - // name: id.name, - // internal: true, - // referenced: true - // }); - // } - - // else { - // // we need a combo block/init recipe - // component.partly_hoisted.push(fn); - // code.overwrite(node.start, node.end, id.name); - - // component.add_var({ - // name: id.name, - // internal: true, - // referenced: true - // }); - - // declarations.push(b` - // function ${id}(${original_params ? '...args' : ''}) { - // return ctx.${id}(ctx${original_params ? ', ...args' : ''}); - // } - // `); - // } - - // if (parent && parent.method) { - // code.prependRight(node.start, ': '); - // } - - // function_expression = null; - // dependencies = null; - // contextual_dependencies = null; - // } - - // if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { - // const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; - - // // normally (`a = 1`, `b.c = 2`), there'll be a single name - // // (a or b). In destructuring cases (`[d, e] = [e, d]`) there - // // may be more, in which case we need to tack the extra ones - // // onto the initial function call - // const names = new Set(extract_names(assignee)); - - // const traced: Set = new Set(); - // names.forEach(name => { - // const dependencies = template_scope.dependencies_for_name.get(name); - // if (dependencies) { - // dependencies.forEach(name => traced.add(name)); - // } else { - // traced.add(name); - // } - // }); - - // invalidate(component, scope, code, node, traced); - // } - // } - // }); - - // if (declarations.length > 0) { - // block.maintain_context = true; - // declarations.forEach(declaration => { - // block.chunks.init.push(declaration); - // }); - // } - - throw new Error(`bad`); - - return this.rendered = `[✂${this.node.start}-${this.node.end}✂]`; + manipulate(block?: Block) { + const { + component, + declarations, + scope_map: map, + template_scope, + is_synthetic + } = this; + let scope = this.scope; + + let function_expression; + + let dependencies: Set; + let contextual_dependencies: Set; + + // TODO this feels a lil messy + let return_value = this.node; + + walk(this.node, { + enter(node: any, parent: any, key: string, index: number) { + // don't manipulate shorthand props twice + if (key === 'value' && parent.shorthand) return; + + if (map.has(node)) { + scope = map.get(node); + } + + if (is_reference(node, parent)) { + const { name } = flatten_reference(node); + + if (scope.has(name)) return; + if (globals.has(name) && !component.var_lookup.has(name)) return; + + if (function_expression) { + if (template_scope.names.has(name)) { + contextual_dependencies.add(name); + + template_scope.dependencies_for_name.get(name).forEach(dependency => { + dependencies.add(dependency); + }); + } else { + dependencies.add(name); + component.add_reference(name); // TODO is this redundant/misplaced? + } + } else if (!is_synthetic && is_contextual(component, template_scope, name)) { + const replaced = x`ctx.${node}`; + + if (parent) { + if (index !== null) { + // TODO can this happen? + parent[key][index] = replaced; + } else { + parent[key] = replaced; + } + } else { + return_value = replaced; + } + } + + this.skip(); + } + + if (!function_expression) { + if (node.type === 'AssignmentExpression') { + // TODO should this be a warning/error? `

{foo = 1}

` + } + + if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') { + function_expression = node; + dependencies = new Set(); + contextual_dependencies = new Set(); + } + } + }, + + leave(node: Node, _parent: Node) { + if (map.has(node)) scope = scope.parent; + + if (node === function_expression) { + // const id = component.get_unique_name( + // sanitize(get_function_name(node, owner)) + // ); + + // const args = contextual_dependencies.size > 0 + // ? [`{ ${Array.from(contextual_dependencies).join(', ')} }`] + // : []; + + // let original_params; + + // if (node.params.length > 0) { + // original_params = code.slice(node.params[0].start, node.params[node.params.length - 1].end); + // args.push(original_params); + // } + + // const body = code.slice(node.body.start, node.body.end).trim(); + + // const fn = node.type === 'FunctionExpression' + // ? b`${node.async ? 'async ' : ''}function${node.generator ? '*' : ''} ${id}(${args.join(', ')}) ${body}` + // : b`const ${id} = ${node.async ? 'async ' : ''}(${args.join(', ')}) => ${body};`; + + // if (dependencies.size === 0 && contextual_dependencies.size === 0) { + // // we can hoist this out of the component completely + // component.fully_hoisted.push(fn); + + // // code.overwrite(node.start, node.end, id.name); + + // component.add_var({ + // name: id.name, + // internal: true, + // hoistable: true, + // referenced: true + // }); + // } + + // else if (contextual_dependencies.size === 0) { + // // function can be hoisted inside the component init + // component.partly_hoisted.push(fn); + // code.overwrite(node.start, node.end, `ctx.${id}`); + + // component.add_var({ + // name: id.name, + // internal: true, + // referenced: true + // }); + // } + + // else { + // // we need a combo block/init recipe + // component.partly_hoisted.push(fn); + // code.overwrite(node.start, node.end, id.name); + + // component.add_var({ + // name: id.name, + // internal: true, + // referenced: true + // }); + + // declarations.push(b` + // function ${id}(${original_params ? '...args' : ''}) { + // return ctx.${id}(ctx${original_params ? ', ...args' : ''}); + // } + // `); + // } + + // if (parent && parent.method) { + // code.prependRight(node.start, ': '); + // } + + function_expression = null; + dependencies = null; + contextual_dependencies = null; + } + + if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') { + const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument; + + // normally (`a = 1`, `b.c = 2`), there'll be a single name + // (a or b). In destructuring cases (`[d, e] = [e, d]`) there + // may be more, in which case we need to tack the extra ones + // onto the initial function call + const names = new Set(extract_names(assignee)); + + const traced: Set = new Set(); + names.forEach(name => { + const dependencies = template_scope.dependencies_for_name.get(name); + if (dependencies) { + dependencies.forEach(name => traced.add(name)); + } else { + traced.add(name); + } + }); + + invalidate(component, scope, node, traced); + } + } + }); + + if (declarations.length > 0) { + block.maintain_context = true; + declarations.forEach(declaration => { + block.chunks.init.push(declaration); + }); + } + + return return_value; } } @@ -426,17 +422,17 @@ export default class Expression { // return 'func'; // } -// function is_contextual(component: Component, scope: TemplateScope, name: string) { -// if (name === '$$props') return true; +function is_contextual(component: Component, scope: TemplateScope, name: string) { + if (name === '$$props') return true; -// // if it's a name below root scope, it's contextual -// if (!scope.is_top_level(name)) return true; + // if it's a name below root scope, it's contextual + if (!scope.is_top_level(name)) return true; -// const variable = component.var_lookup.get(name); + const variable = component.var_lookup.get(name); -// // hoistables, module declarations, and imports are non-contextual -// if (!variable || variable.hoistable) return false; + // hoistables, module declarations, and imports are non-contextual + if (!variable || variable.hoistable) return false; -// // assume contextual -// return true; -// } + // assume contextual + return true; +} diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index d765dbc7d5..31469be6eb 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -77,12 +77,12 @@ export default function dom( const set = (uses_props || writable_props.length > 0 || component.slots.size > 0) ? x` ${$$props} => { - ${uses_props && component.invalidate('$$props', `$$props = @assign(@assign({}, $$props), $$new_props)`)} + ${uses_props && component.invalidate('$$props', b`$$props = @assign(@assign({}, $$props), $$new_props)`)} ${writable_props.map(prop => - `if ('${prop.export_name}' in ${$$props}) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.export_name}`)};` + b`if ('${prop.export_name}' in ${$$props}) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.export_name}`)};` )} ${component.slots.size > 0 && - `if ('$$scope' in ${$$props}) ${component.invalidate('$$scope', `$$scope = ${$$props}.$$scope`)};`} + b`if ('$$scope' in ${$$props}) ${component.invalidate('$$scope', `$$scope = ${$$props}.$$scope`)};`} } ` : null; @@ -370,7 +370,7 @@ export default function dom( ${component.partly_hoisted.length > 0 && component.partly_hoisted.join('\n\n')} - ${set && `$$self.$set = ${set};`} + ${set && b`$$self.$set = ${set};`} ${capture_state && `$$self.$capture_state = ${capture_state};`} diff --git a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts index 979bb553ce..9eceea691d 100644 --- a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts @@ -127,7 +127,7 @@ export default class AwaitBlockWrapper extends Wrapper { const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); const update_mount_node = this.get_update_mount_node(anchor); - const snippet = this.node.expression.render(block); + const snippet = this.node.expression.manipulate(block); const info = block.get_unique_name(`info`); const promise = block.get_unique_name(`promise`); diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index c29f935132..7387ab27b0 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -111,7 +111,7 @@ export default class EachBlockWrapper extends Wrapper { while (renderer.component.source[c] !== 'e') c += 1; // renderer.component.code.overwrite(c, c + 4, 'length'); - const each_block_value = renderer.component.get_unique_name(`${this.var}_value`); + const each_block_value = renderer.component.get_unique_name(`${this.var.name}_value`); const iterations = block.get_unique_name(`${this.var}_blocks`); this.vars = { @@ -190,7 +190,7 @@ export default class EachBlockWrapper extends Wrapper { if (this.node.has_binding) this.context_props.push(`child_ctx.${this.vars.each_block_value} = list;`); if (this.node.has_binding || this.node.index) this.context_props.push(`child_ctx.${this.index_name} = i;`); - const snippet = this.node.expression.render(block); + const snippet = this.node.expression.manipulate(block); block.chunks.init.push(b`let ${this.vars.each_block_value} = ${snippet};`); diff --git a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts index 457e84f152..76da9f0de9 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts @@ -78,7 +78,7 @@ export default class AttributeWrapper { // DRY it out if that's possible without introducing crazy indirection if (this.node.chunks.length === 1) { // single {tag} — may be a non-string - value = (this.node.chunks[0] as Expression).render(block); + value = (this.node.chunks[0] as Expression).manipulate(block); } else { // '{foo} {bar}' — treat as string concatenation const prefix = this.node.chunks[0].type === 'Text' ? '' : `"" + `; @@ -207,10 +207,7 @@ export default class AttributeWrapper { return stringify(chunk.data); } - const rendered = chunk.render(); - return chunk.get_precedence() <= 13 - ? `(${rendered})` - : rendered; + return chunk.manipulate(); }); } @@ -223,7 +220,7 @@ export default class AttributeWrapper { return `="${value.map(chunk => { return chunk.type === 'Text' ? chunk.data.replace(/"/g, '\\"') - : `\${${chunk.render()}}`; + : `\${${chunk.manipulate()}}`; }).join('')}"`; } } diff --git a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts index 3ea94364b0..c644608c88 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts @@ -64,7 +64,7 @@ export default class BindingWrapper { // view to model this.handler = get_event_handler(this, parent.renderer, block, this.object, contextless_snippet); - this.snippet = this.node.expression.render(block); + this.snippet = this.node.expression.manipulate(block); this.is_readonly = this.node.is_readonly; diff --git a/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts b/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts index c7135ce267..1bf8a341d4 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts @@ -35,10 +35,10 @@ export default class StyleAttributeWrapper extends AttributeWrapper { if (chunk.type === 'Text') { return stringify(chunk.data); } else { - const snippet = chunk.render(); + const snippet = chunk.manipulate(); add_to_set(prop_dependencies, chunk.dynamic_dependencies()); - return chunk.get_precedence() <= 13 ? `(${snippet})` : snippet; + return snippet; } }) .join(' + '); diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index f9ff501255..01f034242e 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -601,7 +601,7 @@ export default class ElementWrapper extends Wrapper { : null; if (attr.is_spread) { - const snippet = attr.expression.render(block); + const snippet = attr.expression.manipulate(block); initial_props.push(snippet); @@ -654,7 +654,7 @@ export default class ElementWrapper extends Wrapper { // bidirectional transition const name = block.get_unique_name(`${this.var}_transition`); const snippet = intro.expression - ? intro.expression.render(block) + ? intro.expression.manipulate(block) : '{}'; block.add_variable(name); @@ -700,7 +700,7 @@ export default class ElementWrapper extends Wrapper { if (intro) { block.add_variable(intro_name); const snippet = intro.expression - ? intro.expression.render(block) + ? intro.expression.manipulate(block) : '{}'; const fn = component.qualify(intro.name); @@ -742,7 +742,7 @@ export default class ElementWrapper extends Wrapper { if (outro) { block.add_variable(outro_name); const snippet = outro.expression - ? outro.expression.render(block) + ? outro.expression.manipulate(block) : '{}'; const fn = component.qualify(outro.name); @@ -796,7 +796,7 @@ export default class ElementWrapper extends Wrapper { ${outro && `@add_transform(${this.var}, ${rect});`} `); - const params = this.node.animation.expression ? this.node.animation.expression.render(block) : '{}'; + const params = this.node.animation.expression ? this.node.animation.expression.manipulate(block) : '{}'; const name = component.qualify(this.node.animation.name); @@ -816,7 +816,7 @@ export default class ElementWrapper extends Wrapper { let snippet; let dependencies; if (expression) { - snippet = expression.render(block); + snippet = expression.manipulate(block); dependencies = expression.dependencies; } else { snippet = `${quote_prop_if_necessary(name)}`; diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 1c0a8106c3..791cd9399e 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -200,7 +200,7 @@ export default class InlineComponentWrapper extends Wrapper { : null; if (attr.is_spread) { - const value = attr.expression.render(block); + const value = attr.expression.manipulate(block); initial_props.push(value); let value_object = value; @@ -271,7 +271,7 @@ export default class InlineComponentWrapper extends Wrapper { const updating = block.get_unique_name(`updating_${binding.name}`); block.add_variable(updating); - const snippet = binding.expression.render(block); + const snippet = binding.expression.manipulate(block); statements.push(b` if (${snippet} !== void 0) { @@ -346,7 +346,7 @@ export default class InlineComponentWrapper extends Wrapper { const switch_value = block.get_unique_name('switch_value'); const switch_props = block.get_unique_name('switch_props'); - const snippet = this.node.expression.render(block); + const snippet = this.node.expression.manipulate(block); block.chunks.init.push(b` var ${switch_value} = ${snippet}; diff --git a/src/compiler/compile/render_dom/wrappers/Title.ts b/src/compiler/compile/render_dom/wrappers/Title.ts index 0ccd85b872..1954294c2a 100644 --- a/src/compiler/compile/render_dom/wrappers/Title.ts +++ b/src/compiler/compile/render_dom/wrappers/Title.ts @@ -35,7 +35,7 @@ export default class TitleWrapper extends Wrapper { // single {tag} — may be a non-string // @ts-ignore todo: check this const { expression } = this.node.children[0]; - value = expression.render(block); + value = expression.manipulate(block); add_to_set(all_dependencies, expression.dependencies); } else { // '{foo} {bar}' — treat as string concatenation @@ -47,7 +47,7 @@ export default class TitleWrapper extends Wrapper { return stringify(chunk.data); } else { // @ts-ignore todo: check this - const snippet = chunk.expression.render(block); + const snippet = chunk.expression.manipulate(block); // @ts-ignore todo: check this chunk.expression.dependencies.forEach(d => { all_dependencies.add(d); diff --git a/src/compiler/compile/render_dom/wrappers/shared/Tag.ts b/src/compiler/compile/render_dom/wrappers/shared/Tag.ts index 6ee900f2e9..08e0fc1c35 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/Tag.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/Tag.ts @@ -21,9 +21,9 @@ export default class Tag extends Wrapper { update: ((value: Node) => Node) ) { const dependencies = this.node.expression.dynamic_dependencies(); - const snippet = this.node.expression.node; + const snippet = this.node.expression.manipulate(block); - const value = this.node.should_cache && block.get_unique_name(`${this.var}_value`); + const value = this.node.should_cache && block.get_unique_name(`${this.var.name}_value`); const content = this.node.should_cache ? value : snippet; if (this.node.should_cache) block.add_variable(value, snippet); // TODO may need to coerce snippet to string diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts b/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts index 485ae9b9fd..6b7e2a039a 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts @@ -15,7 +15,7 @@ export default function add_actions( let dependencies; if (expression) { - snippet = expression.render(block); + snippet = expression.manipulate(block); dependencies = expression.dynamic_dependencies(); } diff --git a/test/runtime/samples/_/_config.js b/test/runtime/samples/_/_config.js index e7538c4ecf..9ea1f81777 100644 --- a/test/runtime/samples/_/_config.js +++ b/test/runtime/samples/_/_config.js @@ -1,6 +1,3 @@ export default { - solo: 1, - show: 1, - - html: '

Hello world!

' + html: '

1 + 2 = 3

' }; \ No newline at end of file diff --git a/test/runtime/samples/_/main.svelte b/test/runtime/samples/_/main.svelte index 41e3ddf043..19ec9ea8ce 100644 --- a/test/runtime/samples/_/main.svelte +++ b/test/runtime/samples/_/main.svelte @@ -1,5 +1,6 @@ -

Hello {name}!

\ No newline at end of file +

{a} + {b} = {a + b}

\ No newline at end of file