diff --git a/src/compile/Component.ts b/src/compile/Component.ts index a237eb456a..258ecade2d 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -538,6 +538,7 @@ export default class Component { node.specifiers.forEach((specifier: Node) => { 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') { const { name } = flattenReference(node.left); - code.appendLeft(node.end, `; __make_dirty('${name}')`); + code.appendLeft(node.end, `; $$make_dirty('${name}')`); } }, diff --git a/src/compile/nodes/InlineComponent.ts b/src/compile/nodes/InlineComponent.ts index b55cd58726..ae019ad295 100644 --- a/src/compile/nodes/InlineComponent.ts +++ b/src/compile/nodes/InlineComponent.ts @@ -24,17 +24,6 @@ export default class InlineComponent extends Node { 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' ? new Expression(component, this, scope, info.expression) : null; diff --git a/src/compile/render-dom/Block.ts b/src/compile/render-dom/Block.ts index 4f6f91fb9c..e1eceac1e6 100644 --- a/src/compile/render-dom/Block.ts +++ b/src/compile/render-dom/Block.ts @@ -381,7 +381,7 @@ export default class Block { return deindent` ${this.comment && `// ${escape(this.comment)}`} - function ${this.name}(${this.key ? `${localKey}, ` : ''}ctx) { + function ${this.name}(#component, ${this.key ? `${localKey}, ` : ''}ctx) { ${this.getContents(localKey)} } `.replace(/(#+)(\w*)/g, (match: string, sigil: string, name: string) => { diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index 6bae52f4bf..88b16743e2 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -109,10 +109,10 @@ export default function dom( } else { builder.addBlock(deindent` 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};`)} - __set_inject_props(props => { + $$set_inject_props(props => { // TODO only do this for export let|var ${(component.exports.map(name => `if ('${name.as}' in props) ${name.as} = props.${name.as};` @@ -122,17 +122,17 @@ export default function dom( return () => ({ ${(component.declarations).join(', ')} }); } - __create_fragment(ctx) { + $$create_fragment(${component.alias('component')}, ctx) { ${block.getContents()} } ${component.exports.map(x => deindent` get ${x.as}() { - return this.__get_state().${x.name}; + return this.$$get_state().${x.name}; } set ${x.as}(value) { - this.__set('${x.name}', value); + this.$$set('${x.name}', value); @flush(); } `)} diff --git a/src/compile/render-dom/wrappers/EachBlock.ts b/src/compile/render-dom/wrappers/EachBlock.ts index c1de0aebd9..94e20f5d53 100644 --- a/src/compile/render-dom/wrappers/EachBlock.ts +++ b/src/compile/render-dom/wrappers/EachBlock.ts @@ -300,7 +300,7 @@ export default class EachBlockWrapper extends Wrapper { 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 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} = []; 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]) { ${iterations}[#i].p(changed, child_ctx); } else { - ${iterations}[#i] = ${create_each_block}(child_ctx); + ${iterations}[#i] = ${create_each_block}(#component, child_ctx); ${iterations}[#i].c(); } ${iterations}[#i].i(${updateMountNode}, ${anchor}); @@ -443,13 +443,13 @@ export default class EachBlockWrapper extends Wrapper { if (${iterations}[#i]) { ${iterations}[#i].p(changed, child_ctx); } else { - ${iterations}[#i] = ${create_each_block}(child_ctx); + ${iterations}[#i] = ${create_each_block}(#component, child_ctx); ${iterations}[#i].c(); ${iterations}[#i].m(${updateMountNode}, ${anchor}); } ` : deindent` - ${iterations}[#i] = ${create_each_block}(child_ctx); + ${iterations}[#i] = ${create_each_block}(#component, child_ctx); ${iterations}[#i].c(); ${iterations}[#i].${mountOrIntro}(${updateMountNode}, ${anchor}); `; diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index fc0a422241..c585e11169 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -84,8 +84,7 @@ export default class InlineComponentWrapper extends Wrapper { const name = this.var; const componentInitProperties = [ - `root: #component.root`, - `store: #component.store` + `root: #component.root` ]; if (this.fragment) { @@ -115,7 +114,7 @@ export default class InlineComponentWrapper extends Wrapper { ); 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)) { @@ -284,7 +283,6 @@ export default class InlineComponentWrapper extends Wrapper { _bind(changed, childState) { var ${initialisers}; ${builder} - ${hasStoreBindings && `#component.store.set(newStoreState);`} ${hasLocalBindings && `#component._set(newState);`} ${name_updating} = {}; } @@ -299,7 +297,7 @@ export default class InlineComponentWrapper extends Wrapper { this.node.handlers.forEach(handler => { 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? }); @@ -337,18 +335,18 @@ export default class InlineComponentWrapper extends Wrapper { `); block.builders.create.addLine( - `if (${name}) ${name}._fragment.c();` + `if (${name}) ${name}.$$fragment.c();` ); if (parentNodes) { block.builders.claim.addLine( - `if (${name}) ${name}._fragment.l(${parentNodes});` + `if (${name}) ${name}.$$fragment.l(${parentNodes});` ); } block.builders.mount.addBlock(deindent` 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};`} } `); @@ -369,10 +367,10 @@ export default class InlineComponentWrapper extends Wrapper { ? deindent` @groupOutros(); const old_component = ${name}; - old_component._fragment.o(() => { - old_component.destroy(); + old_component.$$fragment.o(() => { + old_component.$destroy(); });` - : `${name}.destroy();`} + : `${name}.$destroy();`} } if (${switch_value}) { @@ -385,10 +383,10 @@ export default class InlineComponentWrapper extends Wrapper { if (${binding.value.snippet} === void 0) changed.${binding.name} = 1;`)} ${name}._bind(changed, ${name}.get()); });`} - ${name}._fragment.c(); + ${name}.$$fragment.c(); ${this.fragment && this.fragment.nodes.map(child => child.remount(name))} - ${name}._mount(${updateMountNode}, ${anchor}); + ${name}.$$mount(${updateMountNode}, ${anchor}); ${this.node.handlers.map(handler => deindent` ${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 { const expression = this.node.name === 'svelte:self' ? component.name - : `%components-${this.node.name}`; + : `ctx.${this.node.name}`; block.builders.init.addBlock(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};`} `); - block.builders.create.addLine(`${name}._fragment.c();`); + block.builders.create.addLine(`${name}.$$fragment.c();`); if (parentNodes) { block.builders.claim.addLine( - `${name}._fragment.l(${parentNodes});` + `${name}.$$fragment.l(${parentNodes});` ); } block.builders.mount.addLine( - `${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});` + `${name}.$$mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});` ); if (updates.length) { @@ -460,20 +458,20 @@ export default class InlineComponentWrapper extends Wrapper { } 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;`} `); } if (component.options.nestedTransitions) { block.builders.outro.addLine( - `if (${name}) ${name}._fragment.o(#outrocallback);` + `if (${name}) ${name}.$$fragment.o(#outrocallback);` ); } } remount(name: string) { - return `${this.var}._mount(${name}._slotted.default, null);`; + return `${this.var}.$$mount(${name}._slotted.default, null);`; } } diff --git a/src/internal/SvelteComponent.js b/src/internal/SvelteComponent.js index a04094df02..5d17b64205 100644 --- a/src/internal/SvelteComponent.js +++ b/src/internal/SvelteComponent.js @@ -2,20 +2,22 @@ import { schedule_update, flush } from './scheduler'; export class SvelteComponent { constructor(options) { - this.__get_state = this.__init( - fn => this.__inject_props = fn, - fn => this.__inject_refs = fn, - key => this.__make_dirty(key) + this.$$get_state = this.$$init( + fn => this.$$inject_props = fn, + fn => this.$$inject_refs = fn, + key => this.$$make_dirty(key) ); - this.__dirty = null; + this.$$dirty = null; 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) { - this.__mount(options.target); + this.$$mount(options.target); flush(); } } @@ -25,34 +27,33 @@ export class SvelteComponent { } $destroy() { - this.__destroy(true); + this.$$destroy(true); } - __make_dirty(key) { - if (!this.__dirty) { + $$make_dirty(key) { + if (!this.$$dirty) { schedule_update(this); - this.__dirty = {}; + this.$$dirty = {}; } - this.__dirty[key] = true; + this.$$dirty[key] = true; } - __mount(target, anchor) { - this.__fragment = this.__create_fragment(this.__get_state()); - this.__fragment.c(); - this.__fragment.m(target, anchor); + $$mount(target, anchor) { + this.$$fragment.c(); + this.$$fragment.m(target, anchor); } - __set(key, value) { - this.__inject_props({ [key]: value }); - this.__make_dirty(key); + $$set(key, value) { + this.$$inject_props({ [key]: value }); + this.$$make_dirty(key); } - __update() { - this.__fragment.p(this.__dirty, this.__get_state()); - this.__dirty = null; + $$update() { + this.$$fragment.p(this.$$dirty, this.$$get_state()); + this.$$dirty = null; } - __destroy(detach) { - this.__fragment.d(detach); + $$destroy(detach) { + this.$$fragment.d(detach); } } \ No newline at end of file diff --git a/src/internal/scheduler.js b/src/internal/scheduler.js index c9e028c87f..7aa63c58e1 100644 --- a/src/internal/scheduler.js +++ b/src/internal/scheduler.js @@ -12,7 +12,7 @@ export function schedule_update(component) { export function flush() { while (dirty_components.length) { - dirty_components.pop().__update(); + dirty_components.pop().$$update(); } update_scheduled = false; diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index 3ba5f8950a..7fccb7d88f 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -388,9 +388,9 @@ function readAttribute(parser: Parser, uniqueNames: Set) { const end = parser.index; const colon_index = name.indexOf(':'); + const type = colon_index !== 1 && get_directive_type(name.slice(0, colon_index)); - if (colon_index !== -1) { - const type = get_directive_type(name.slice(0, colon_index)); + if (type) { name = name.slice(colon_index + 1); return { @@ -413,9 +413,12 @@ function readAttribute(parser: Parser, uniqueNames: Set) { function get_directive_type(name) { if (name === 'use') return 'Action'; - if (name === 'on') return 'EventHandler'; 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) { diff --git a/test/runtime/index.js b/test/runtime/index.js index 155c1888cb..d9403bc25d 100644 --- a/test/runtime/index.js +++ b/test/runtime/index.js @@ -181,7 +181,6 @@ describe.only("runtime", () => { internal, format: 'cjs', hydratable: hydrate, - store: !!compileOptions.store, skipIntroByDefault: compileOptions.skipIntroByDefault, nestedTransitions: compileOptions.nestedTransitions, dev: compileOptions.dev @@ -190,7 +189,15 @@ describe.only("runtime", () => { } }) .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(); }); diff --git a/test/runtime/samples/attribute-dynamic-reserved/_config.js b/test/runtime/samples/attribute-dynamic-reserved/_config.js deleted file mode 100644 index c3f5fe4a53..0000000000 --- a/test/runtime/samples/attribute-dynamic-reserved/_config.js +++ /dev/null @@ -1,20 +0,0 @@ -export default { - props: { - class: 'foo' - }, - - html: ` -
123 -
123 - `, - - test ( assert, component, target ) { - component.class = 'bar'; - assert.htmlEqual( target.innerHTML, ` -
123 -
123 - ` ); - - component.destroy(); - } -}; diff --git a/test/runtime/samples/attribute-dynamic-reserved/main.html b/test/runtime/samples/attribute-dynamic-reserved/main.html deleted file mode 100644 index 7d94f23eff..0000000000 --- a/test/runtime/samples/attribute-dynamic-reserved/main.html +++ /dev/null @@ -1,2 +0,0 @@ -
{123} -
{ 123 } \ No newline at end of file diff --git a/test/runtime/samples/set-mutated-data/_config.js b/test/runtime/samples/set-mutated-data/_config.js index 56e87d388f..e901490895 100644 --- a/test/runtime/samples/set-mutated-data/_config.js +++ b/test/runtime/samples/set-mutated-data/_config.js @@ -1,4 +1,4 @@ -const data = { foo: 0 }; +const props = { foo: 0 }; export default { props, @@ -6,8 +6,8 @@ export default { html: '0', test(assert, component, target) { - data.foo = 42; - component.set(data); + props.foo = 42; + component.set(props); assert.htmlEqual(target.innerHTML, '42'); }