diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index b50f1d1bd1..b496000291 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -198,7 +198,11 @@ export default class InlineComponentWrapper extends Wrapper { const value = attr.expression.render(block); initial_props.push(value); - changes.push(condition ? `${condition} && ${value}` : value); + let value_object = value + if (attr.expression.node.type !== 'ObjectExpression') { + value_object = `@get_spread_object(${value})`; + } + changes.push(condition ? `${condition} && ${value_object}` : value_object); } else { const obj = `{ ${quote_name_if_necessary(name)}: ${attr.get_value(block)} }`; initial_props.push(obj); diff --git a/src/runtime/internal/spread.ts b/src/runtime/internal/spread.ts index 0075c947cd..203b0b11e9 100644 --- a/src/runtime/internal/spread.ts +++ b/src/runtime/internal/spread.ts @@ -35,3 +35,7 @@ export function get_spread_update(levels, updates) { return update; } + +export function get_spread_object(spread_props) { + return typeof spread_props === 'object' && spread_props !== null ? spread_props : {}; +} \ No newline at end of file diff --git a/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/Widget.svelte b/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/Widget.svelte new file mode 100644 index 0000000000..3433ffc243 --- /dev/null +++ b/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/Widget.svelte @@ -0,0 +1,11 @@ + + +
foo: {foo}
+baz: {baz}
+qux: {qux}
+corge: {corge}
diff --git a/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/_config.js b/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/_config.js new file mode 100644 index 0000000000..c5e23a023c --- /dev/null +++ b/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/_config.js @@ -0,0 +1,53 @@ +export default { + props: { + props: { + foo: 'lol', + baz: 40 + 2, + } + }, + + html: ` +foo: lol
+baz: 42
+qux: named
+corge: b
+ `, + + test({ assert, component, target }) { + const html = ` +foo: undefined
+baz: undefined
+qux: named
+corge: b
+ `; + + // test undefined + component.props = undefined; + assert.htmlEqual(target.innerHTML, html); + + // set object props + component.props = this.props.props; + assert.htmlEqual(target.innerHTML, this.html); + + // test null + component.props = null; + assert.htmlEqual(target.innerHTML, html); + + // set object props + component.props = this.props.props; + assert.htmlEqual(target.innerHTML, this.html); + + // test boolean + component.props = true; + assert.htmlEqual(target.innerHTML, html); + + // set object props + component.props = this.props.props; + assert.htmlEqual(target.innerHTML, this.html); + + // test number + component.props = 123; + assert.htmlEqual(target.innerHTML, html); + + } +}; diff --git a/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/main.svelte b/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/main.svelte new file mode 100644 index 0000000000..5f9f9cbff0 --- /dev/null +++ b/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/main.svelte @@ -0,0 +1,13 @@ + + +foo: {foo}
+baz: {baz}
+qux: {qux}
diff --git a/test/runtime/samples/spread-component-dynamic-non-object/_config.js b/test/runtime/samples/spread-component-dynamic-non-object/_config.js new file mode 100644 index 0000000000..094f2fbb9b --- /dev/null +++ b/test/runtime/samples/spread-component-dynamic-non-object/_config.js @@ -0,0 +1,51 @@ +export default { + props: { + props: { + foo: 'lol', + baz: 40 + 2, + } + }, + + html: ` +foo: lol
+baz: 42
+qux: named
+ `, + + test({ assert, component, target }) { + const html = ` +foo: undefined
+baz: undefined
+qux: named
+ `; + + // test undefined + component.props = undefined; + assert.htmlEqual(target.innerHTML, html); + + // set object props + component.props = this.props.props; + assert.htmlEqual(target.innerHTML, this.html); + + // test null + component.props = null; + assert.htmlEqual(target.innerHTML, html); + + // set object props + component.props = this.props.props; + assert.htmlEqual(target.innerHTML, this.html); + + // test boolean + component.props = true; + assert.htmlEqual(target.innerHTML, html); + + // set object props + component.props = this.props.props; + assert.htmlEqual(target.innerHTML, this.html); + + // test number + component.props = 123; + assert.htmlEqual(target.innerHTML, html); + + } +}; diff --git a/test/runtime/samples/spread-component-dynamic-non-object/main.svelte b/test/runtime/samples/spread-component-dynamic-non-object/main.svelte new file mode 100644 index 0000000000..3ca281903e --- /dev/null +++ b/test/runtime/samples/spread-component-dynamic-non-object/main.svelte @@ -0,0 +1,9 @@ + + +i: {i}
+foo: {foo}
+qux: {qux}
diff --git a/test/runtime/samples/spread-component-side-effects/_config.js b/test/runtime/samples/spread-component-side-effects/_config.js new file mode 100644 index 0000000000..35c4fb7474 --- /dev/null +++ b/test/runtime/samples/spread-component-side-effects/_config.js @@ -0,0 +1,19 @@ +export default { + props: {}, + + html: ` +i: 1
+foo: foo
+qux: named
+ `, + + test({ assert, component, target }) { + component.foo = 'lol'; + + assert.htmlEqual(target.innerHTML, ` +i: 2
+foo: lol
+qux: named
+ `); + } +}; diff --git a/test/runtime/samples/spread-component-side-effects/main.svelte b/test/runtime/samples/spread-component-side-effects/main.svelte new file mode 100644 index 0000000000..8c2dcfd2c3 --- /dev/null +++ b/test/runtime/samples/spread-component-side-effects/main.svelte @@ -0,0 +1,16 @@ + + +