diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index b9d1b834f2..da6659f7c7 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -93,7 +93,7 @@ export default function dom( const body = []; const not_equal = component.component_options.immutable ? `@not_equal` : `@safe_not_equal`; - let dev_props_check; + let dev_props_check; let inject_state; let capture_state; props.forEach(x => { const variable = component.var_lookup.get(x.name); @@ -150,6 +150,29 @@ export default function dom( }`)} `; } + + capture_state = (uses_props || writable_props.length > 0) ? deindent` + () => { + return { ${component.vars.filter(prop => prop.writable).map(prop => prop.name).join(", ")} }; + } + ` : deindent` + () => { + return {} + } + `; + + inject_state = (uses_props || writable_props.length > 0) ? deindent` + ${$$props} => { + ${uses_props && component.invalidate('$$props', `$$props = @assign(@assign({}, $$props), $$new_props)`)} + ${component.vars.filter(prop => prop.writable).map(prop => deindent` + if ('${prop.name}' in $$props) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.name}`)}; + `)} + } + ` : deindent` + ${$$props} => { + return + } + `; } // instrument assignments @@ -351,6 +374,10 @@ export default function dom( ${set && `$$self.$set = ${set};`} + ${capture_state && `$$self.$capture_state = ${capture_state};`} + + ${inject_state && `$$self.$inject_state = ${inject_state};`} + ${injected.length && `let ${injected.join(', ')};`} ${reactive_declarations.length > 0 && deindent` diff --git a/test/js/samples/capture-inject-dev-only/_config.js b/test/js/samples/capture-inject-dev-only/_config.js new file mode 100644 index 0000000000..1e0819f22e --- /dev/null +++ b/test/js/samples/capture-inject-dev-only/_config.js @@ -0,0 +1,5 @@ +export default { + options: { + dev: false + } +}; \ No newline at end of file diff --git a/test/js/samples/capture-inject-dev-only/expected.js b/test/js/samples/capture-inject-dev-only/expected.js new file mode 100644 index 0000000000..9e930bdf15 --- /dev/null +++ b/test/js/samples/capture-inject-dev-only/expected.js @@ -0,0 +1,79 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + append, + detach, + element, + init, + insert, + listen, + noop, + safe_not_equal, + set_data, + space, + text +} from "svelte/internal"; + +function create_fragment(ctx) { + var p, t0, t1, input, dispose; + + return { + c() { + p = element("p"); + t0 = text(ctx.foo); + t1 = space(); + input = element("input"); + dispose = listen(input, "input", ctx.input_input_handler); + }, + + m(target, anchor) { + insert(target, p, anchor); + append(p, t0); + insert(target, t1, anchor); + insert(target, input, anchor); + + input.value = ctx.foo; + }, + + p(changed, ctx) { + if (changed.foo) { + set_data(t0, ctx.foo); + } + + if (changed.foo && (input.value !== ctx.foo)) input.value = ctx.foo; + }, + + i: noop, + o: noop, + + d(detaching) { + if (detaching) { + detach(p); + detach(t1); + detach(input); + } + + dispose(); + } + }; +} + +function instance($$self, $$props, $$invalidate) { + let foo = "bar"; + + function input_input_handler() { + foo = this.value; + $$invalidate('foo', foo); + } + + return { foo, input_input_handler }; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, []); + } +} + +export default Component; \ No newline at end of file diff --git a/test/js/samples/capture-inject-dev-only/input.svelte b/test/js/samples/capture-inject-dev-only/input.svelte new file mode 100644 index 0000000000..b4f2088b49 --- /dev/null +++ b/test/js/samples/capture-inject-dev-only/input.svelte @@ -0,0 +1,5 @@ + +
{foo}
+ \ No newline at end of file diff --git a/test/js/samples/debug-empty/expected.js b/test/js/samples/debug-empty/expected.js index 6f07993590..ccf14a9e76 100644 --- a/test/js/samples/debug-empty/expected.js +++ b/test/js/samples/debug-empty/expected.js @@ -74,6 +74,14 @@ function instance($$self, $$props, $$invalidate) { if ('name' in $$props) $$invalidate('name', name = $$props.name); }; + $$self.$capture_state = () => { + return { name }; + }; + + $$self.$inject_state = $$props => { + if ('name' in $$props) $$invalidate('name', name = $$props.name); + }; + return { name }; } diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js index f613329fb6..dedc920508 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -164,6 +164,17 @@ function instance($$self, $$props, $$invalidate) { if ('baz' in $$props) $$invalidate('baz', baz = $$props.baz); }; + $$self.$capture_state = () => { + return { things, foo, bar, baz }; + }; + + $$self.$inject_state = $$props => { + if ('things' in $$props) $$invalidate('things', things = $$props.things); + if ('foo' in $$props) $$invalidate('foo', foo = $$props.foo); + if ('bar' in $$props) $$invalidate('bar', bar = $$props.bar); + if ('baz' in $$props) $$invalidate('baz', baz = $$props.baz); + }; + return { things, foo, bar, baz }; } diff --git a/test/js/samples/debug-foo/expected.js b/test/js/samples/debug-foo/expected.js index 0e12e3a6cb..4fd5869f36 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -162,6 +162,15 @@ function instance($$self, $$props, $$invalidate) { if ('foo' in $$props) $$invalidate('foo', foo = $$props.foo); }; + $$self.$capture_state = () => { + return { things, foo }; + }; + + $$self.$inject_state = $$props => { + if ('things' in $$props) $$invalidate('things', things = $$props.things); + if ('foo' in $$props) $$invalidate('foo', foo = $$props.foo); + }; + return { things, foo }; } diff --git a/test/js/samples/debug-hoisted/expected.js b/test/js/samples/debug-hoisted/expected.js index 51d8bf63a3..8a1f0ff9d4 100644 --- a/test/js/samples/debug-hoisted/expected.js +++ b/test/js/samples/debug-hoisted/expected.js @@ -43,6 +43,14 @@ let kobzol = 5; function instance($$self) { let obj = { x: 5 }; + $$self.$capture_state = () => { + return {} + }; + + $$self.$inject_state = $$props => { + return + }; + return { obj }; } diff --git a/test/js/samples/dev-warning-missing-data-computed/expected.js b/test/js/samples/dev-warning-missing-data-computed/expected.js index 90cd5b8baa..ce5a053ced 100644 --- a/test/js/samples/dev-warning-missing-data-computed/expected.js +++ b/test/js/samples/dev-warning-missing-data-computed/expected.js @@ -74,6 +74,15 @@ function instance($$self, $$props, $$invalidate) { if ('foo' in $$props) $$invalidate('foo', foo = $$props.foo); }; + $$self.$capture_state = () => { + return { foo, bar }; + }; + + $$self.$inject_state = $$props => { + if ('foo' in $$props) $$invalidate('foo', foo = $$props.foo); + if ('bar' in $$props) $$invalidate('bar', bar = $$props.bar); + }; + $$self.$$.update = ($$dirty = { foo: 1 }) => { if ($$dirty.foo) { $$invalidate('bar', bar = foo * 2); } };