start work on refs and lifecycle

pull/1864/head
Rich Harris 7 years ago
parent 6a752a5675
commit 9f586a9aed

@ -0,0 +1,3 @@
import { onprops, onmount, onupdate, ondestroy } from './internal.js';
export { onprops, onmount, onupdate, ondestroy };

30
package-lock.json generated

@ -553,7 +553,7 @@
},
"camelcase-keys": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"dev": true,
"requires": {
@ -918,7 +918,7 @@
"dependencies": {
"domelementtype": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
"dev": true
}
@ -926,7 +926,7 @@
},
"domelementtype": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
"resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
"integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
"dev": true
},
@ -1423,7 +1423,7 @@
},
"fast-deep-equal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
"dev": true
},
@ -2422,7 +2422,7 @@
},
"is-builtin-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
"dev": true,
"requires": {
@ -2795,7 +2795,7 @@
},
"load-json-file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"dev": true,
"requires": {
@ -2895,7 +2895,7 @@
},
"meow": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"dev": true,
"requires": {
@ -2913,7 +2913,7 @@
"dependencies": {
"load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true,
"requires": {
@ -3092,7 +3092,7 @@
},
"multiline": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/multiline/-/multiline-1.0.2.tgz",
"resolved": "http://registry.npmjs.org/multiline/-/multiline-1.0.2.tgz",
"integrity": "sha1-abHyX/B00oKJBPJE3dBrfZbvbJM=",
"dev": true,
"requires": {
@ -5473,7 +5473,7 @@
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
@ -5962,7 +5962,7 @@
},
"rollup-plugin-typescript": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/rollup-plugin-typescript/-/rollup-plugin-typescript-0.8.1.tgz",
"resolved": "http://registry.npmjs.org/rollup-plugin-typescript/-/rollup-plugin-typescript-0.8.1.tgz",
"integrity": "sha1-L/fuzCHPa7K0P8J+W2iJUs5xkko=",
"dev": true,
"requires": {
@ -5981,7 +5981,7 @@
},
"rollup-pluginutils": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
"resolved": "http://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
"integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=",
"dev": true,
"requires": {
@ -6156,7 +6156,7 @@
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
@ -6462,7 +6462,7 @@
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
@ -6484,7 +6484,7 @@
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"dev": true,
"requires": {

@ -2,7 +2,7 @@
"name": "svelte",
"version": "2.15.1",
"description": "The magical disappearing UI framework",
"main": "compiler/svelte.js",
"main": "index.js",
"bin": {
"svelte": "svelte"
},
@ -10,10 +10,8 @@
"cli",
"compiler/*.js",
"ssr/*.js",
"shared.js",
"store.js",
"store.umd.js",
"store.d.ts",
"index.js",
"internal.js",
"svelte",
"README.md"
],

@ -107,19 +107,26 @@ export default function dom(
customElements.define("${component.tag}", ${name});
`);
} else {
const refs = Array.from(component.refs);
builder.addBlock(deindent`
class ${name} extends @SvelteComponent {
$$init($$set_inject_props, $$set_inject_refs, $$make_dirty) {
$$init($$make_dirty) {
${component.javascript || component.exports.map(x => `let ${x.name};`)}
$$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};`
))}
});
return () => ({ ${(component.declarations).join(', ')} });
return [
() => ({ ${(component.declarations).join(', ')} }),
props => {
// TODO only do this for export let|var
${(component.exports.map(name =>
`if ('${name.as}' in props) ${name.as} = props.${name.as};`
))}
},
refs => {
// TODO only if we have some refs
${refs.map(name => `${name} = refs.${name};`)}
}
];
}
$$create_fragment(${component.alias('component')}, ctx) {
@ -128,7 +135,7 @@ export default function dom(
${component.exports.map(x => deindent`
get ${x.as}() {
return this.$$get_state().${x.name};
return this.$$.get_state().${x.name};
}
set ${x.as}(value) {

@ -688,7 +688,7 @@ export default class ElementWrapper extends Wrapper {
}
addRef(block: Block) {
const ref = `#component.refs.${this.node.ref.name}`;
const ref = `#component.$$refs.${this.node.ref.name}`;
block.builders.mount.addLine(
`${ref} = ${this.var};`

@ -347,7 +347,7 @@ export default class InlineComponentWrapper extends Wrapper {
block.builders.mount.addBlock(deindent`
if (${name}) {
${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};`}
}
`);
@ -392,12 +392,12 @@ export default class InlineComponentWrapper extends Wrapper {
${name}.on("${handler.name}", ${handler.var});
`)}
${this.node.ref && `#component.refs.${this.node.ref.name} = ${name};`}
${this.node.ref && `#component.$$refs.${this.node.ref.name} = ${name};`}
} else {
${name} = null;
${this.node.ref && deindent`
if (#component.refs.${this.node.ref.name} === ${name}) {
#component.refs.${this.node.ref.name} = null;
if (#component.$$refs.${this.node.ref.name} === ${name}) {
#component.$$refs.${this.node.ref.name} = null;
}`}
}
}
@ -434,7 +434,7 @@ 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();`);
@ -459,7 +459,7 @@ export default class InlineComponentWrapper extends Wrapper {
block.builders.destroy.addLine(deindent`
${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;`}
`);
}

@ -1,21 +1,31 @@
import { schedule_update, flush } from './scheduler';
import { schedule_update, flush } from './scheduler.js';
import { set_current_component } from './lifecycle.js'
import { run_all } from '../shared/utils.js';
export class SvelteComponent {
constructor(options) {
this.$$get_state = this.$$init(
fn => this.$$inject_props = fn,
fn => this.$$inject_refs = fn,
this.$$onprops = [];
this.$$onmount = [];
this.$$onupdate = [];
this.$$ondestroy = [];
set_current_component(this);
const [get_state, inject_props, inject_refs] = this.$$init(
key => this.$$make_dirty(key)
);
this.$$ = { get_state, inject_props, inject_refs };
this.$$refs = {};
this.$$dirty = null;
this.$$bindingGroups = []; // TODO find a way to not have this here?
if (options.props) {
this.$$inject_props(options.props);
this.$$.inject_props(options.props);
}
this.$$fragment = this.$$create_fragment(this, this.$$get_state());
this.$$fragment = this.$$create_fragment(this, this.$$.get_state());
if (options.target) {
this.$$mount(options.target);
@ -42,19 +52,31 @@ export class SvelteComponent {
$$mount(target, anchor) {
this.$$fragment.c();
this.$$fragment.m(target, anchor);
this.$$.inject_refs(this.$$refs);
const ondestroy = this.$$onmount.map(fn => fn()).filter(Boolean);
this.$$ondestroy.push(...ondestroy);
this.$$onmount = null;
}
$$set(key, value) {
this.$$inject_props({ [key]: value });
this.$$.inject_props({ [key]: value });
run_all(this.$$onprops);
this.$$make_dirty(key);
}
$$update() {
this.$$fragment.p(this.$$dirty, this.$$get_state());
this.$$fragment.p(this.$$dirty, this.$$.get_state());
this.$$.inject_refs(this.$$refs);
run_all(this.$$onupdate);
this.$$dirty = null;
}
$$destroy(detach) {
this.$$fragment.d(detach);
run_all(this.$$ondestroy);
// TODO null out other refs
this.$$ondestroy = null;
}
}

@ -1,5 +1,6 @@
import { assign, isPromise } from './utils.js';
import { groupOutros } from './transitions.js';
import { flush } from '../internal/scheduler.js';
export function handlePromise(promise, info) {
var token = info.token = {};
@ -30,7 +31,10 @@ export function handlePromise(promise, info) {
block.c();
block[block.i ? 'i' : 'm'](info.mount(), info.anchor);
info.component.root.set({}); // flush any handlers that were created
// TODO is some of this redundant?
info.component.$$.inject_refs(info.component.$$refs);
run_all(info.component.$$onupdate);
flush();
}
info.block = block;

@ -2,6 +2,7 @@ export * from './animations.js';
export * from './await-block.js';
export * from './dom.js';
export * from './keyed-each.js';
export * from './lifecycle.js';
export * from './scheduler.js';
export * from './spread.js';
export * from './ssr.js';

@ -0,0 +1,21 @@
let current_component;
export function set_current_component(component) {
current_component = component;
}
export function onprops(fn) {
current_component.$$onprops.push(fn);
}
export function onmount(fn) {
current_component.$$onmount.push(fn);
}
export function onupdate(fn) {
current_component.$$onupdate.push(fn);
}
export function ondestroy(fn) {
current_component.$$ondestroy.push(fn);
}

@ -35,4 +35,9 @@ export function exclude(src, prop) {
export function run(fn) {
fn();
}
export function run_all(fns) {
let i = fns.length;
while (i--) fns[i]();
}
Loading…
Cancel
Save