From 07932da5480ae6dcd68045c577e4dee232ecc18a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 19 Aug 2019 11:41:34 -0400 Subject: [PATCH 1/2] allow slots to have missing props in SSR - fixes #3322 --- src/compiler/compile/render_ssr/handlers/Slot.ts | 2 +- .../samples/component-slot-let-missing-prop/Bar.svelte | 5 +++++ .../samples/component-slot-let-missing-prop/Foo.svelte | 1 + .../samples/component-slot-let-missing-prop/_config.js | 5 +++++ .../component-slot-let-missing-prop/main.svelte | 10 ++++++++++ 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/component-slot-let-missing-prop/Bar.svelte create mode 100644 test/runtime/samples/component-slot-let-missing-prop/Foo.svelte create mode 100644 test/runtime/samples/component-slot-let-missing-prop/_config.js create mode 100644 test/runtime/samples/component-slot-let-missing-prop/main.svelte diff --git a/src/compiler/compile/render_ssr/handlers/Slot.ts b/src/compiler/compile/render_ssr/handlers/Slot.ts index 087519979b..ef0699ee80 100644 --- a/src/compiler/compile/render_ssr/handlers/Slot.ts +++ b/src/compiler/compile/render_ssr/handlers/Slot.ts @@ -8,7 +8,7 @@ export default function(node: Slot, renderer: Renderer, options: RenderOptions) const slot_data = get_slot_data(node.values, true); - const arg = slot_data.length > 0 ? `{ ${slot_data.join(', ')} }` : ''; + const arg = slot_data.length > 0 ? `{ ${slot_data.join(', ')} }` : '{}'; renderer.append(`\${$$slots${prop} ? $$slots${prop}(${arg}) : \``); diff --git a/test/runtime/samples/component-slot-let-missing-prop/Bar.svelte b/test/runtime/samples/component-slot-let-missing-prop/Bar.svelte new file mode 100644 index 0000000000..d3707c7d8b --- /dev/null +++ b/test/runtime/samples/component-slot-let-missing-prop/Bar.svelte @@ -0,0 +1,5 @@ + + +

{thing}

\ No newline at end of file diff --git a/test/runtime/samples/component-slot-let-missing-prop/Foo.svelte b/test/runtime/samples/component-slot-let-missing-prop/Foo.svelte new file mode 100644 index 0000000000..49aeb95a1d --- /dev/null +++ b/test/runtime/samples/component-slot-let-missing-prop/Foo.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-let-missing-prop/_config.js b/test/runtime/samples/component-slot-let-missing-prop/_config.js new file mode 100644 index 0000000000..b3bf13b01b --- /dev/null +++ b/test/runtime/samples/component-slot-let-missing-prop/_config.js @@ -0,0 +1,5 @@ +export default { + html: ` +

undefined

+ ` +}; diff --git a/test/runtime/samples/component-slot-let-missing-prop/main.svelte b/test/runtime/samples/component-slot-let-missing-prop/main.svelte new file mode 100644 index 0000000000..3ac3ba5363 --- /dev/null +++ b/test/runtime/samples/component-slot-let-missing-prop/main.svelte @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file From dcd927630e2844d15951aedebbe51bc6700e87c1 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 19 Aug 2019 12:58:12 -0400 Subject: [PATCH 2/2] dont set undefined input value - fixes #1233 --- .../render_dom/wrappers/Element/Binding.ts | 4 + src/runtime/internal/dom.ts | 6 ++ .../input-no-initial-value/expected.js | 87 +++++++++++++++++++ .../input-no-initial-value/input.svelte | 13 +++ test/js/samples/input-range/expected.js | 5 +- 5 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 test/js/samples/input-no-initial-value/expected.js create mode 100644 test/js/samples/input-no-initial-value/input.svelte diff --git a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts index 1ea65830ef..df46d759a5 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts @@ -208,6 +208,10 @@ function get_dom_updater( return `${element.var}.checked = ${condition};`; } + if (binding.node.name === 'value') { + return `@set_input_value(${element.var}, ${binding.snippet});` + } + return `${element.var}.${binding.node.name} = ${binding.snippet};`; } diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index a918c3193d..8b28a1f77a 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -169,6 +169,12 @@ export function set_data(text, data) { if (text.data !== data) text.data = data; } +export function set_input_value(input, value) { + if (value != null || input.value) { + input.value = value; + } +} + export function set_input_type(input, type) { try { input.type = type; diff --git a/test/js/samples/input-no-initial-value/expected.js b/test/js/samples/input-no-initial-value/expected.js new file mode 100644 index 0000000000..a651d72059 --- /dev/null +++ b/test/js/samples/input-no-initial-value/expected.js @@ -0,0 +1,87 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + append, + attr, + detach, + element, + init, + insert, + listen, + noop, + run_all, + safe_not_equal, + set_input_value, + space +} from "svelte/internal"; + +function create_fragment(ctx) { + var form, input, t, button, dispose; + + return { + c() { + form = element("form"); + input = element("input"); + t = space(); + button = element("button"); + button.textContent = "Store"; + attr(input, "type", "text"); + input.required = true; + + dispose = [ + listen(input, "input", ctx.input_input_handler), + listen(form, "submit", ctx.handleSubmit) + ]; + }, + + m(target, anchor) { + insert(target, form, anchor); + append(form, input); + + set_input_value(input, ctx.test); + + append(form, t); + append(form, button); + }, + + p(changed, ctx) { + if (changed.test && (input.value !== ctx.test)) set_input_value(input, ctx.test); + }, + + i: noop, + o: noop, + + d(detaching) { + if (detaching) { + detach(form); + } + + run_all(dispose); + } + }; +} + +function instance($$self, $$props, $$invalidate) { + let test = undefined; + + function handleSubmit(event) { + event.preventDefault(); + console.log('value', test); + } + + function input_input_handler() { + test = this.value; + $$invalidate('test', test); + } + + return { test, handleSubmit, 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/input-no-initial-value/input.svelte b/test/js/samples/input-no-initial-value/input.svelte new file mode 100644 index 0000000000..d60c0b196e --- /dev/null +++ b/test/js/samples/input-no-initial-value/input.svelte @@ -0,0 +1,13 @@ + + +
+ + +
\ No newline at end of file diff --git a/test/js/samples/input-range/expected.js b/test/js/samples/input-range/expected.js index 8331e73bad..04552d20cd 100644 --- a/test/js/samples/input-range/expected.js +++ b/test/js/samples/input-range/expected.js @@ -10,6 +10,7 @@ import { noop, run_all, safe_not_equal, + set_input_value, to_number } from "svelte/internal"; @@ -30,11 +31,11 @@ function create_fragment(ctx) { m(target, anchor) { insert(target, input, anchor); - input.value = ctx.value; + set_input_value(input, ctx.value); }, p(changed, ctx) { - if (changed.value) input.value = ctx.value; + if (changed.value) set_input_value(input, ctx.value); }, i: noop,