From 99fecab33e3f00c315ee0e321b8f0dcd9730459f Mon Sep 17 00:00:00 2001 From: Axelen123 Date: Thu, 27 Jun 2019 11:45:40 +0200 Subject: [PATCH 1/6] Add hooks for HMR support (sveltejs#2377) --- src/compiler/compile/render_dom/index.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 9fdaa0cbaa..f1cc3b1443 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -94,7 +94,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); @@ -151,6 +151,21 @@ export default function dom( }`)} `; } + + capture_state = (uses_props || writable_props.length > 0) ? deindent` + () => { + return { ${component.vars.map(prop => prop.name).join(", ")} }; + } + ` : null; + + inject_state = (uses_props || writable_props.length > 0) ? deindent` + ${$$props} => { + ${uses_props && component.invalidate('$$props', `$$props = @assign(@assign({}, $$props), $$new_props)`)} + ${component.vars.map(prop => deindent` + if ('${prop.name}' in $$props) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.name}`)}; + `)} + } + ` : null; } // instrument assignments @@ -430,6 +445,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` From 82fec43c32128525b76efeba73e2a56d2a000368 Mon Sep 17 00:00:00 2001 From: Axelen123 Date: Thu, 27 Jun 2019 11:59:35 +0200 Subject: [PATCH 2/6] Update tests --- test/js/samples/debug-empty/expected.js | 8 ++++++++ test/js/samples/debug-foo-bar-baz-things/expected.js | 11 +++++++++++ test/js/samples/debug-foo/expected.js | 9 +++++++++ .../dev-warning-missing-data-computed/expected.js | 9 +++++++++ 4 files changed, 37 insertions(+) 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 eea35d5ba7..fbcd8e1409 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -163,6 +163,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 5b931d9464..ec48213811 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -161,6 +161,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/dev-warning-missing-data-computed/expected.js b/test/js/samples/dev-warning-missing-data-computed/expected.js index 5c4b2ece1b..60f71bf9c4 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); } }; From c0a366b995843fe9f3483007c08a315fcbbd1507 Mon Sep 17 00:00:00 2001 From: Axelen123 Date: Thu, 27 Jun 2019 12:52:03 +0200 Subject: [PATCH 3/6] Add test for capture_state and inject_state --- .../capture-inject-dev-only/_config.js | 5 ++ .../capture-inject-dev-only/expected.js | 79 +++++++++++++++++++ .../capture-inject-dev-only/input.svelte | 5 ++ 3 files changed, 89 insertions(+) create mode 100644 test/js/samples/capture-inject-dev-only/_config.js create mode 100644 test/js/samples/capture-inject-dev-only/expected.js create mode 100644 test/js/samples/capture-inject-dev-only/input.svelte 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 From 508f2e7e349ab2d8f46313509a6fd882054b8503 Mon Sep 17 00:00:00 2001 From: Axelen123 Date: Thu, 27 Jun 2019 13:31:49 +0200 Subject: [PATCH 4/6] Only capture and inject writable props --- src/compiler/compile/render_dom/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index f1cc3b1443..4274d233eb 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -154,14 +154,14 @@ export default function dom( capture_state = (uses_props || writable_props.length > 0) ? deindent` () => { - return { ${component.vars.map(prop => prop.name).join(", ")} }; + return { ${component.vars.filter(prop => prop.writable).map(prop => prop.name).join(", ")} }; } ` : null; inject_state = (uses_props || writable_props.length > 0) ? deindent` ${$$props} => { ${uses_props && component.invalidate('$$props', `$$props = @assign(@assign({}, $$props), $$new_props)`)} - ${component.vars.map(prop => deindent` + ${component.vars.filter(prop => prop.writable).map(prop => deindent` if ('${prop.name}' in $$props) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.name}`)}; `)} } From bdb8237cf85e5dc23c01423c81a1f44e159ab309 Mon Sep 17 00:00:00 2001 From: Axelen123 Date: Fri, 28 Jun 2019 18:31:04 +0200 Subject: [PATCH 5/6] Make inject_state and capture_state always available --- src/compiler/compile/render_dom/index.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 4274d233eb..fe4c43c5fe 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -156,7 +156,11 @@ export default function dom( () => { return { ${component.vars.filter(prop => prop.writable).map(prop => prop.name).join(", ")} }; } - ` : null; + ` : deindent` + () => { + return {} + } + `; inject_state = (uses_props || writable_props.length > 0) ? deindent` ${$$props} => { @@ -165,7 +169,11 @@ export default function dom( if ('${prop.name}' in $$props) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.name}`)}; `)} } - ` : null; + ` : deindent` + ${$$props} => { + return + } + `; } // instrument assignments From 8f6e6859f7f33fa68764dca13be9ef096304df4e Mon Sep 17 00:00:00 2001 From: Axelen123 Date: Fri, 28 Jun 2019 18:40:10 +0200 Subject: [PATCH 6/6] Update tests --- test/js/samples/debug-hoisted/expected.js | 8 ++++++++ 1 file changed, 8 insertions(+) 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 }; }