diff --git a/src/generators/nodes/Component.ts b/src/generators/nodes/Component.ts index 1f9e65a73e..4fe64b5393 100644 --- a/src/generators/nodes/Component.ts +++ b/src/generators/nodes/Component.ts @@ -14,10 +14,12 @@ import usesThisOrArguments from '../../validate/js/utils/usesThisOrArguments'; import mapChildren from './shared/mapChildren'; import Binding from './Binding'; import EventHandler from './EventHandler'; +import Expression from './shared/Expression'; export default class Component extends Node { type: 'Component'; name: string; + expression: Expression; attributes: Attribute[]; bindings: Binding[]; handlers: EventHandler[]; @@ -31,6 +33,10 @@ export default class Component extends Node { this.name = info.name; + this.expression = this.name === 'svelte:component' + ? new Expression(compiler, this, scope, info.expression) + : null; + this.attributes = []; this.bindings = []; this.handlers = []; @@ -266,7 +272,7 @@ export default class Component extends Node { if (isStoreProp) hasStoreBindings = true; else hasLocalBindings = true; - return `${newState}.${prop} = state.${name};`; + return `${newState}.${prop} = ctx.${name};`; })} `; } @@ -282,7 +288,7 @@ export default class Component extends Node { if (binding.value.node.type === 'MemberExpression') { setFromChild = deindent` ${binding.value.snippet} = childState.${binding.name}; - ${newState}.${prop} = state.${key}; + ${newState}.${prop} = ctx.${key}; `; } @@ -312,7 +318,7 @@ export default class Component extends Node { }); const initialisers = [ - 'state = #component.get()', + 'ctx = #component.get()', hasLocalBindings && 'newState = {}', hasStoreBindings && 'newStoreState = {}', ].filter(Boolean).join(', '); @@ -346,7 +352,7 @@ export default class Component extends Node { block.builders.init.addBlock(deindent` var ${switch_value} = ${snippet}; - function ${switch_props}(state) { + function ${switch_props}(ctx) { ${(this.attributes.length || this.bindings.length) && deindent` var ${name_initial_data} = ${attributeObject};`} ${statements} @@ -356,7 +362,7 @@ export default class Component extends Node { } if (${switch_value}) { - var ${name} = new ${switch_value}(${switch_props}(state)); + var ${name} = new ${switch_value}(${switch_props}(ctx)); ${beforecreate} } @@ -394,13 +400,13 @@ export default class Component extends Node { if (${name}) ${name}.destroy(); if (${switch_value}) { - ${name} = new ${switch_value}(${switch_props}(state)); + ${name} = new ${switch_value}(${switch_props}(ctx)); ${name}._fragment.c(); ${this.children.map(child => child.remount(name))} ${name}._mount(${updateMountNode}, ${anchor}); - ${eventHandlers.map(handler => deindent` + ${this.handlers.map(handler => deindent` ${name}.on("${handler.name}", ${handler.var}); `)} @@ -419,7 +425,7 @@ export default class Component extends Node { else { ${updates} ${name}._set(${name_changes}); - ${bindings.length && `${name_updating} = {};`} + ${this.bindings.length && `${name_updating} = {};`} } `); } @@ -495,14 +501,14 @@ function mungeBinding(binding: Node, block: Block): Binding { let prop; if (contextual) { - obj = `state.${block.listNames.get(name)}`; + obj = `ctx.${block.listNames.get(name)}`; prop = `${block.indexNames.get(name)}`; } else if (binding.value.type === 'MemberExpression') { prop = `[✂${binding.value.property.start}-${binding.value.property.end}✂]`; if (!binding.value.computed) prop = `'${prop}'`; obj = `[✂${binding.value.object.start}-${binding.value.object.end}✂]`; } else { - obj = 'state'; + obj = 'ctx'; prop = `'${name}'`; } @@ -546,7 +552,7 @@ function mungeEventHandler(compiler: DomGenerator, node: Node, handler: Node, bl }); body = deindent` - ${usesState && `const state = #component.get();`} + ${usesState && `const ctx = #component.get();`} [✂${handler.expression.start}-${handler.expression.end}✂]; `; } else { diff --git a/src/generators/server-side-rendering/visitors/Component.ts b/src/generators/server-side-rendering/visitors/Component.ts index 8fc8f3b098..a020c81164 100644 --- a/src/generators/server-side-rendering/visitors/Component.ts +++ b/src/generators/server-side-rendering/visitors/Component.ts @@ -84,11 +84,10 @@ export default function visitComponent( .join(', ')} }`; const isDynamicComponent = node.name === 'svelte:component'; - if (isDynamicComponent) block.contextualise(node.expression); const expression = ( node.name === 'svelte:self' ? generator.name : - isDynamicComponent ? `((${node.metadata.snippet}) || __missingComponent)` : + isDynamicComponent ? `((${node.expression.snippet}) || __missingComponent)` : `%components-${node.name}` ); diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index c3f82be9d7..f4d3dd542e 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -113,7 +113,7 @@ export default function tag(parser: Parser) { const type = metaTags.has(name) ? metaTags.get(name) - : /[A-Z]/.test(name[0]) ? 'Component' + : (/[A-Z]/.test(name[0]) || name === 'svelte:self' || name === 'svelte:component') ? 'Component' : name === 'slot' ? 'Slot' : 'Element'; const element: Node = {