svelte:component

pull/1367/head
Rich Harris 7 years ago
parent cd99eb6275
commit 577e28b8be

@ -14,10 +14,12 @@ import usesThisOrArguments from '../../validate/js/utils/usesThisOrArguments';
import mapChildren from './shared/mapChildren'; import mapChildren from './shared/mapChildren';
import Binding from './Binding'; import Binding from './Binding';
import EventHandler from './EventHandler'; import EventHandler from './EventHandler';
import Expression from './shared/Expression';
export default class Component extends Node { export default class Component extends Node {
type: 'Component'; type: 'Component';
name: string; name: string;
expression: Expression;
attributes: Attribute[]; attributes: Attribute[];
bindings: Binding[]; bindings: Binding[];
handlers: EventHandler[]; handlers: EventHandler[];
@ -31,6 +33,10 @@ export default class Component extends Node {
this.name = info.name; this.name = info.name;
this.expression = this.name === 'svelte:component'
? new Expression(compiler, this, scope, info.expression)
: null;
this.attributes = []; this.attributes = [];
this.bindings = []; this.bindings = [];
this.handlers = []; this.handlers = [];
@ -266,7 +272,7 @@ export default class Component extends Node {
if (isStoreProp) hasStoreBindings = true; if (isStoreProp) hasStoreBindings = true;
else hasLocalBindings = 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') { if (binding.value.node.type === 'MemberExpression') {
setFromChild = deindent` setFromChild = deindent`
${binding.value.snippet} = childState.${binding.name}; ${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 = [ const initialisers = [
'state = #component.get()', 'ctx = #component.get()',
hasLocalBindings && 'newState = {}', hasLocalBindings && 'newState = {}',
hasStoreBindings && 'newStoreState = {}', hasStoreBindings && 'newStoreState = {}',
].filter(Boolean).join(', '); ].filter(Boolean).join(', ');
@ -346,7 +352,7 @@ export default class Component extends Node {
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
var ${switch_value} = ${snippet}; var ${switch_value} = ${snippet};
function ${switch_props}(state) { function ${switch_props}(ctx) {
${(this.attributes.length || this.bindings.length) && deindent` ${(this.attributes.length || this.bindings.length) && deindent`
var ${name_initial_data} = ${attributeObject};`} var ${name_initial_data} = ${attributeObject};`}
${statements} ${statements}
@ -356,7 +362,7 @@ export default class Component extends Node {
} }
if (${switch_value}) { if (${switch_value}) {
var ${name} = new ${switch_value}(${switch_props}(state)); var ${name} = new ${switch_value}(${switch_props}(ctx));
${beforecreate} ${beforecreate}
} }
@ -394,13 +400,13 @@ export default class Component extends Node {
if (${name}) ${name}.destroy(); if (${name}) ${name}.destroy();
if (${switch_value}) { if (${switch_value}) {
${name} = new ${switch_value}(${switch_props}(state)); ${name} = new ${switch_value}(${switch_props}(ctx));
${name}._fragment.c(); ${name}._fragment.c();
${this.children.map(child => child.remount(name))} ${this.children.map(child => child.remount(name))}
${name}._mount(${updateMountNode}, ${anchor}); ${name}._mount(${updateMountNode}, ${anchor});
${eventHandlers.map(handler => deindent` ${this.handlers.map(handler => deindent`
${name}.on("${handler.name}", ${handler.var}); ${name}.on("${handler.name}", ${handler.var});
`)} `)}
@ -419,7 +425,7 @@ export default class Component extends Node {
else { else {
${updates} ${updates}
${name}._set(${name_changes}); ${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; let prop;
if (contextual) { if (contextual) {
obj = `state.${block.listNames.get(name)}`; obj = `ctx.${block.listNames.get(name)}`;
prop = `${block.indexNames.get(name)}`; prop = `${block.indexNames.get(name)}`;
} else if (binding.value.type === 'MemberExpression') { } else if (binding.value.type === 'MemberExpression') {
prop = `[✂${binding.value.property.start}-${binding.value.property.end}✂]`; prop = `[✂${binding.value.property.start}-${binding.value.property.end}✂]`;
if (!binding.value.computed) prop = `'${prop}'`; if (!binding.value.computed) prop = `'${prop}'`;
obj = `[✂${binding.value.object.start}-${binding.value.object.end}✂]`; obj = `[✂${binding.value.object.start}-${binding.value.object.end}✂]`;
} else { } else {
obj = 'state'; obj = 'ctx';
prop = `'${name}'`; prop = `'${name}'`;
} }
@ -546,7 +552,7 @@ function mungeEventHandler(compiler: DomGenerator, node: Node, handler: Node, bl
}); });
body = deindent` body = deindent`
${usesState && `const state = #component.get();`} ${usesState && `const ctx = #component.get();`}
[${handler.expression.start}-${handler.expression.end}]; [${handler.expression.start}-${handler.expression.end}];
`; `;
} else { } else {

@ -84,11 +84,10 @@ export default function visitComponent(
.join(', ')} }`; .join(', ')} }`;
const isDynamicComponent = node.name === 'svelte:component'; const isDynamicComponent = node.name === 'svelte:component';
if (isDynamicComponent) block.contextualise(node.expression);
const expression = ( const expression = (
node.name === 'svelte:self' ? generator.name : node.name === 'svelte:self' ? generator.name :
isDynamicComponent ? `((${node.metadata.snippet}) || __missingComponent)` : isDynamicComponent ? `((${node.expression.snippet}) || __missingComponent)` :
`%components-${node.name}` `%components-${node.name}`
); );

@ -113,7 +113,7 @@ export default function tag(parser: Parser) {
const type = metaTags.has(name) const type = metaTags.has(name)
? metaTags.get(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'; : name === 'slot' ? 'Slot' : 'Element';
const element: Node = { const element: Node = {

Loading…
Cancel
Save