pull/1864/head
Rich Harris 7 years ago
parent 80f7446685
commit d1a8241107

@ -538,6 +538,7 @@ export default class Component {
node.specifiers.forEach((specifier: Node) => { node.specifiers.forEach((specifier: Node) => {
this.userVars.add(specifier.local.name); this.userVars.add(specifier.local.name);
this.declarations.push(specifier.local.name); // TODO we don't really want this, but it's convenient for now
}); });
} }
}); });
@ -550,7 +551,7 @@ export default class Component {
if (node.type === 'AssignmentExpression') { if (node.type === 'AssignmentExpression') {
const { name } = flattenReference(node.left); const { name } = flattenReference(node.left);
code.appendLeft(node.end, `; __make_dirty('${name}')`); code.appendLeft(node.end, `; $$make_dirty('${name}')`);
} }
}, },

@ -24,17 +24,6 @@ export default class InlineComponent extends Node {
this.name = info.name; this.name = info.name;
if (this.name !== 'svelte:self' && this.name !== 'svelte:component') {
if (!component.components.has(this.name)) {
component.error(this, {
code: `missing-component`,
message: `${this.name} component is not defined`
});
}
component.used.components.add(this.name);
}
this.expression = this.name === 'svelte:component' this.expression = this.name === 'svelte:component'
? new Expression(component, this, scope, info.expression) ? new Expression(component, this, scope, info.expression)
: null; : null;

@ -381,7 +381,7 @@ export default class Block {
return deindent` return deindent`
${this.comment && `// ${escape(this.comment)}`} ${this.comment && `// ${escape(this.comment)}`}
function ${this.name}(${this.key ? `${localKey}, ` : ''}ctx) { function ${this.name}(#component, ${this.key ? `${localKey}, ` : ''}ctx) {
${this.getContents(localKey)} ${this.getContents(localKey)}
} }
`.replace(/(#+)(\w*)/g, (match: string, sigil: string, name: string) => { `.replace(/(#+)(\w*)/g, (match: string, sigil: string, name: string) => {

@ -109,10 +109,10 @@ export default function dom(
} else { } else {
builder.addBlock(deindent` builder.addBlock(deindent`
class ${name} extends @SvelteComponent { class ${name} extends @SvelteComponent {
__init(__set_inject_props, __set_inject_refs, __make_dirty) { $$init($$set_inject_props, $$set_inject_refs, $$make_dirty) {
${component.javascript || component.exports.map(x => `let ${x.name};`)} ${component.javascript || component.exports.map(x => `let ${x.name};`)}
__set_inject_props(props => { $$set_inject_props(props => {
// TODO only do this for export let|var // TODO only do this for export let|var
${(component.exports.map(name => ${(component.exports.map(name =>
`if ('${name.as}' in props) ${name.as} = props.${name.as};` `if ('${name.as}' in props) ${name.as} = props.${name.as};`
@ -122,17 +122,17 @@ export default function dom(
return () => ({ ${(component.declarations).join(', ')} }); return () => ({ ${(component.declarations).join(', ')} });
} }
__create_fragment(ctx) { $$create_fragment(${component.alias('component')}, ctx) {
${block.getContents()} ${block.getContents()}
} }
${component.exports.map(x => deindent` ${component.exports.map(x => deindent`
get ${x.as}() { get ${x.as}() {
return this.__get_state().${x.name}; return this.$$get_state().${x.name};
} }
set ${x.as}(value) { set ${x.as}(value) {
this.__set('${x.name}', value); this.$$set('${x.name}', value);
@flush(); @flush();
} }
`)} `)}

@ -300,7 +300,7 @@ export default class EachBlockWrapper extends Wrapper {
for (var #i = 0; #i < ${this.vars.each_block_value}.${length}; #i += 1) { for (var #i = 0; #i < ${this.vars.each_block_value}.${length}; #i += 1) {
let child_ctx = ${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i); let child_ctx = ${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i);
let key = ${get_key}(child_ctx); let key = ${get_key}(child_ctx);
${blocks}[#i] = ${lookup}[key] = ${create_each_block}(key, child_ctx); ${blocks}[#i] = ${lookup}[key] = ${create_each_block}(#component, key, child_ctx);
} }
`); `);
@ -371,7 +371,7 @@ export default class EachBlockWrapper extends Wrapper {
var ${iterations} = []; var ${iterations} = [];
for (var #i = 0; #i < ${this.vars.each_block_value}.${length}; #i += 1) { for (var #i = 0; #i < ${this.vars.each_block_value}.${length}; #i += 1) {
${iterations}[#i] = ${create_each_block}(${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i)); ${iterations}[#i] = ${create_each_block}(#component, ${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i));
} }
`); `);
@ -434,7 +434,7 @@ export default class EachBlockWrapper extends Wrapper {
if (${iterations}[#i]) { if (${iterations}[#i]) {
${iterations}[#i].p(changed, child_ctx); ${iterations}[#i].p(changed, child_ctx);
} else { } else {
${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i] = ${create_each_block}(#component, child_ctx);
${iterations}[#i].c(); ${iterations}[#i].c();
} }
${iterations}[#i].i(${updateMountNode}, ${anchor}); ${iterations}[#i].i(${updateMountNode}, ${anchor});
@ -443,13 +443,13 @@ export default class EachBlockWrapper extends Wrapper {
if (${iterations}[#i]) { if (${iterations}[#i]) {
${iterations}[#i].p(changed, child_ctx); ${iterations}[#i].p(changed, child_ctx);
} else { } else {
${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i] = ${create_each_block}(#component, child_ctx);
${iterations}[#i].c(); ${iterations}[#i].c();
${iterations}[#i].m(${updateMountNode}, ${anchor}); ${iterations}[#i].m(${updateMountNode}, ${anchor});
} }
` `
: deindent` : deindent`
${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i] = ${create_each_block}(#component, child_ctx);
${iterations}[#i].c(); ${iterations}[#i].c();
${iterations}[#i].${mountOrIntro}(${updateMountNode}, ${anchor}); ${iterations}[#i].${mountOrIntro}(${updateMountNode}, ${anchor});
`; `;

@ -84,8 +84,7 @@ export default class InlineComponentWrapper extends Wrapper {
const name = this.var; const name = this.var;
const componentInitProperties = [ const componentInitProperties = [
`root: #component.root`, `root: #component.root`
`store: #component.store`
]; ];
if (this.fragment) { if (this.fragment) {
@ -115,7 +114,7 @@ export default class InlineComponentWrapper extends Wrapper {
); );
if (this.node.attributes.length || this.node.bindings.length) { if (this.node.attributes.length || this.node.bindings.length) {
componentInitProperties.push(`data: ${name_initial_data}`); componentInitProperties.push(`props: ${name_initial_data}`);
} }
if (!usesSpread && (this.node.attributes.filter(a => a.isDynamic).length || this.node.bindings.length)) { if (!usesSpread && (this.node.attributes.filter(a => a.isDynamic).length || this.node.bindings.length)) {
@ -284,7 +283,6 @@ export default class InlineComponentWrapper extends Wrapper {
_bind(changed, childState) { _bind(changed, childState) {
var ${initialisers}; var ${initialisers};
${builder} ${builder}
${hasStoreBindings && `#component.store.set(newStoreState);`}
${hasLocalBindings && `#component._set(newState);`} ${hasLocalBindings && `#component._set(newState);`}
${name_updating} = {}; ${name_updating} = {};
} }
@ -299,7 +297,7 @@ export default class InlineComponentWrapper extends Wrapper {
this.node.handlers.forEach(handler => { this.node.handlers.forEach(handler => {
handler.var = block.getUniqueName(`${this.var}_${handler.name}`); // TODO this is hacky handler.var = block.getUniqueName(`${this.var}_${handler.name}`); // TODO this is hacky
handler.render(component, block, this.var, false); // TODO hoist when possible // handler.render(component, block, this.var, false); // TODO hoist when possible
if (handler.usesContext) block.maintainContext = true; // TODO is there a better place to put this? if (handler.usesContext) block.maintainContext = true; // TODO is there a better place to put this?
}); });
@ -337,18 +335,18 @@ export default class InlineComponentWrapper extends Wrapper {
`); `);
block.builders.create.addLine( block.builders.create.addLine(
`if (${name}) ${name}._fragment.c();` `if (${name}) ${name}.$$fragment.c();`
); );
if (parentNodes) { if (parentNodes) {
block.builders.claim.addLine( block.builders.claim.addLine(
`if (${name}) ${name}._fragment.l(${parentNodes});` `if (${name}) ${name}.$$fragment.l(${parentNodes});`
); );
} }
block.builders.mount.addBlock(deindent` block.builders.mount.addBlock(deindent`
if (${name}) { if (${name}) {
${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'}); ${name}.$$mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});
${this.node.ref && `#component.refs.${this.node.ref.name} = ${name};`} ${this.node.ref && `#component.refs.${this.node.ref.name} = ${name};`}
} }
`); `);
@ -369,10 +367,10 @@ export default class InlineComponentWrapper extends Wrapper {
? deindent` ? deindent`
@groupOutros(); @groupOutros();
const old_component = ${name}; const old_component = ${name};
old_component._fragment.o(() => { old_component.$$fragment.o(() => {
old_component.destroy(); old_component.$destroy();
});` });`
: `${name}.destroy();`} : `${name}.$destroy();`}
} }
if (${switch_value}) { if (${switch_value}) {
@ -385,10 +383,10 @@ export default class InlineComponentWrapper extends Wrapper {
if (${binding.value.snippet} === void 0) changed.${binding.name} = 1;`)} if (${binding.value.snippet} === void 0) changed.${binding.name} = 1;`)}
${name}._bind(changed, ${name}.get()); ${name}._bind(changed, ${name}.get());
});`} });`}
${name}._fragment.c(); ${name}.$$fragment.c();
${this.fragment && this.fragment.nodes.map(child => child.remount(name))} ${this.fragment && this.fragment.nodes.map(child => child.remount(name))}
${name}._mount(${updateMountNode}, ${anchor}); ${name}.$$mount(${updateMountNode}, ${anchor});
${this.node.handlers.map(handler => deindent` ${this.node.handlers.map(handler => deindent`
${name}.on("${handler.name}", ${handler.var}); ${name}.on("${handler.name}", ${handler.var});
@ -414,11 +412,11 @@ export default class InlineComponentWrapper extends Wrapper {
`); `);
} }
block.builders.destroy.addLine(`if (${name}) ${name}.destroy(${parentNode ? '' : 'detach'});`); block.builders.destroy.addLine(`if (${name}) ${name}.$destroy(${parentNode ? '' : 'detach'});`);
} else { } else {
const expression = this.node.name === 'svelte:self' const expression = this.node.name === 'svelte:self'
? component.name ? component.name
: `%components-${this.node.name}`; : `ctx.${this.node.name}`;
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
${(this.node.attributes.length || this.node.bindings.length) && deindent` ${(this.node.attributes.length || this.node.bindings.length) && deindent`
@ -439,16 +437,16 @@ export default class InlineComponentWrapper extends Wrapper {
${this.node.ref && `#component.refs.${this.node.ref.name} = ${name};`} ${this.node.ref && `#component.refs.${this.node.ref.name} = ${name};`}
`); `);
block.builders.create.addLine(`${name}._fragment.c();`); block.builders.create.addLine(`${name}.$$fragment.c();`);
if (parentNodes) { if (parentNodes) {
block.builders.claim.addLine( block.builders.claim.addLine(
`${name}._fragment.l(${parentNodes});` `${name}.$$fragment.l(${parentNodes});`
); );
} }
block.builders.mount.addLine( block.builders.mount.addLine(
`${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});` `${name}.$$mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});`
); );
if (updates.length) { if (updates.length) {
@ -460,20 +458,20 @@ export default class InlineComponentWrapper extends Wrapper {
} }
block.builders.destroy.addLine(deindent` block.builders.destroy.addLine(deindent`
${name}.destroy(${parentNode ? '' : 'detach'}); ${name}.$destroy(${parentNode ? '' : 'detach'});
${this.node.ref && `if (#component.refs.${this.node.ref.name} === ${name}) #component.refs.${this.node.ref.name} = null;`} ${this.node.ref && `if (#component.refs.${this.node.ref.name} === ${name}) #component.refs.${this.node.ref.name} = null;`}
`); `);
} }
if (component.options.nestedTransitions) { if (component.options.nestedTransitions) {
block.builders.outro.addLine( block.builders.outro.addLine(
`if (${name}) ${name}._fragment.o(#outrocallback);` `if (${name}) ${name}.$$fragment.o(#outrocallback);`
); );
} }
} }
remount(name: string) { remount(name: string) {
return `${this.var}._mount(${name}._slotted.default, null);`; return `${this.var}.$$mount(${name}._slotted.default, null);`;
} }
} }

@ -2,20 +2,22 @@ import { schedule_update, flush } from './scheduler';
export class SvelteComponent { export class SvelteComponent {
constructor(options) { constructor(options) {
this.__get_state = this.__init( this.$$get_state = this.$$init(
fn => this.__inject_props = fn, fn => this.$$inject_props = fn,
fn => this.__inject_refs = fn, fn => this.$$inject_refs = fn,
key => this.__make_dirty(key) key => this.$$make_dirty(key)
); );
this.__dirty = null; this.$$dirty = null;
if (options.props) { if (options.props) {
this.__inject_props(options.props); this.$$inject_props(options.props);
} }
this.$$fragment = this.$$create_fragment(this, this.$$get_state());
if (options.target) { if (options.target) {
this.__mount(options.target); this.$$mount(options.target);
flush(); flush();
} }
} }
@ -25,34 +27,33 @@ export class SvelteComponent {
} }
$destroy() { $destroy() {
this.__destroy(true); this.$$destroy(true);
} }
__make_dirty(key) { $$make_dirty(key) {
if (!this.__dirty) { if (!this.$$dirty) {
schedule_update(this); schedule_update(this);
this.__dirty = {}; this.$$dirty = {};
} }
this.__dirty[key] = true; this.$$dirty[key] = true;
} }
__mount(target, anchor) { $$mount(target, anchor) {
this.__fragment = this.__create_fragment(this.__get_state()); this.$$fragment.c();
this.__fragment.c(); this.$$fragment.m(target, anchor);
this.__fragment.m(target, anchor);
} }
__set(key, value) { $$set(key, value) {
this.__inject_props({ [key]: value }); this.$$inject_props({ [key]: value });
this.__make_dirty(key); this.$$make_dirty(key);
} }
__update() { $$update() {
this.__fragment.p(this.__dirty, this.__get_state()); this.$$fragment.p(this.$$dirty, this.$$get_state());
this.__dirty = null; this.$$dirty = null;
} }
__destroy(detach) { $$destroy(detach) {
this.__fragment.d(detach); this.$$fragment.d(detach);
} }
} }

@ -12,7 +12,7 @@ export function schedule_update(component) {
export function flush() { export function flush() {
while (dirty_components.length) { while (dirty_components.length) {
dirty_components.pop().__update(); dirty_components.pop().$$update();
} }
update_scheduled = false; update_scheduled = false;

@ -388,9 +388,9 @@ function readAttribute(parser: Parser, uniqueNames: Set<string>) {
const end = parser.index; const end = parser.index;
const colon_index = name.indexOf(':'); const colon_index = name.indexOf(':');
const type = colon_index !== 1 && get_directive_type(name.slice(0, colon_index));
if (colon_index !== -1) { if (type) {
const type = get_directive_type(name.slice(0, colon_index));
name = name.slice(colon_index + 1); name = name.slice(colon_index + 1);
return { return {
@ -413,9 +413,12 @@ function readAttribute(parser: Parser, uniqueNames: Set<string>) {
function get_directive_type(name) { function get_directive_type(name) {
if (name === 'use') return 'Action'; if (name === 'use') return 'Action';
if (name === 'on') return 'EventHandler';
if (name === 'animate') return 'Animation'; if (name === 'animate') return 'Animation';
throw new Error(`TODO directive ${name}`); if (name === 'bind') return 'Binding';
if (name === 'class') return 'Class';
if (name === 'on') return 'EventHandler';
if (name === 'ref') return 'Ref';
if (name === 'in' || name === 'out' || name === 'transition') return 'Transition';
} }
function readAttributeValue(parser: Parser) { function readAttributeValue(parser: Parser) {

@ -181,7 +181,6 @@ describe.only("runtime", () => {
internal, internal,
format: 'cjs', format: 'cjs',
hydratable: hydrate, hydratable: hydrate,
store: !!compileOptions.store,
skipIntroByDefault: compileOptions.skipIntroByDefault, skipIntroByDefault: compileOptions.skipIntroByDefault,
nestedTransitions: compileOptions.nestedTransitions, nestedTransitions: compileOptions.nestedTransitions,
dev: compileOptions.dev dev: compileOptions.dev
@ -190,7 +189,15 @@ describe.only("runtime", () => {
} }
}) })
.then(() => { .then(() => {
if (config.show) showOutput(cwd, { internal, format: 'cjs', hydratable: hydrate, store: !!compileOptions.store, skipIntroByDefault: compileOptions.skipIntroByDefault, nestedTransitions: compileOptions.nestedTransitions }, compile); if (config.show) {
showOutput(cwd, {
internal,
format: 'cjs',
hydratable: hydrate,
skipIntroByDefault: compileOptions.skipIntroByDefault,
nestedTransitions: compileOptions.nestedTransitions
}, compile);
}
flush(); flush();
}); });

@ -1,20 +0,0 @@
export default {
props: {
class: 'foo'
},
html: `
<div class="foo"></div>123
<div class="foo"></div>123
`,
test ( assert, component, target ) {
component.class = 'bar';
assert.htmlEqual( target.innerHTML, `
<div class="bar"></div>123
<div class="bar"></div>123
` );
component.destroy();
}
};

@ -1,2 +0,0 @@
<div class='{class}'></div>{123}
<div class='{ class }'></div>{ 123 }

@ -1,4 +1,4 @@
const data = { foo: 0 }; const props = { foo: 0 };
export default { export default {
props, props,
@ -6,8 +6,8 @@ export default {
html: '0', html: '0',
test(assert, component, target) { test(assert, component, target) {
data.foo = 42; props.foo = 42;
component.set(data); component.set(props);
assert.htmlEqual(target.innerHTML, '42'); assert.htmlEqual(target.innerHTML, '42');
} }

Loading…
Cancel
Save