From 01676aac4698b4fb590aa37ea8bbb952f5282d93 Mon Sep 17 00:00:00 2001 From: Bryan Terce Date: Sun, 23 Jun 2019 05:26:00 -0700 Subject: [PATCH] Fix dynamic `bind:this` on components (#2333) --- .../render-dom/wrappers/InlineComponent/index.ts | 6 ++++-- src/compiler/compile/utils/flatten_reference.ts | 14 ++++++++------ .../binding-this-component-computed-key/Foo.svelte | 1 + .../binding-this-component-computed-key/_config.js | 8 ++++++++ .../main.svelte | 9 +++++++++ .../Foo.svelte | 1 + .../_config.js | 12 ++++++++++++ .../main.svelte | 11 +++++++++++ .../binding-this-component-each-block/Foo.svelte | 1 + .../binding-this-component-each-block/_config.js | 12 ++++++++++++ .../binding-this-component-each-block/main.svelte | 11 +++++++++++ 11 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 test/runtime/samples/binding-this-component-computed-key/Foo.svelte create mode 100644 test/runtime/samples/binding-this-component-computed-key/_config.js create mode 100644 test/runtime/samples/binding-this-component-computed-key/main.svelte create mode 100644 test/runtime/samples/binding-this-component-each-block-value/Foo.svelte create mode 100644 test/runtime/samples/binding-this-component-each-block-value/_config.js create mode 100644 test/runtime/samples/binding-this-component-each-block-value/main.svelte create mode 100644 test/runtime/samples/binding-this-component-each-block/Foo.svelte create mode 100644 test/runtime/samples/binding-this-component-each-block/_config.js create mode 100644 test/runtime/samples/binding-this-component-each-block/main.svelte diff --git a/src/compiler/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render-dom/wrappers/InlineComponent/index.ts index 8d5c751add..46b3df4c31 100644 --- a/src/compiler/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render-dom/wrappers/InlineComponent/index.ts @@ -276,15 +276,17 @@ export default class InlineComponentWrapper extends Wrapper { lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end).trim(); } + const contextual_dependencies = [...binding.expression.contextual_dependencies]; + component.partly_hoisted.push(deindent` - function ${fn}($$component) { + function ${fn}(${['$$component', ...contextual_dependencies].join(', ')}) { ${lhs} = $$component; ${object && component.invalidate(object)} } `); block.builders.destroy.add_line(`ctx.${fn}(null);`); - return `@add_binding_callback(() => ctx.${fn}(${this.var}));`; + return `@add_binding_callback(() => ctx.${fn}(${[this.var, ...contextual_dependencies.map(name => `ctx.${name}`)].join(', ')}));`; } const name = component.get_unique_name(`${this.var}_${binding.name}_binding`); diff --git a/src/compiler/compile/utils/flatten_reference.ts b/src/compiler/compile/utils/flatten_reference.ts index e7d66d01ca..460cd2f1e9 100644 --- a/src/compiler/compile/utils/flatten_reference.ts +++ b/src/compiler/compile/utils/flatten_reference.ts @@ -7,10 +7,11 @@ export default function flatten_reference(node: Node) { const prop_end = node.end; while (node.type === 'MemberExpression') { - if (node.computed) return null; - nodes.unshift(node.property); - parts.unshift(node.property.name); + + if (!node.computed) { + parts.unshift(node.property.name); + } node = node.object; } @@ -20,10 +21,11 @@ export default function flatten_reference(node: Node) { ? node.name : node.type === 'ThisExpression' ? 'this' : null; - if (!name) return null; - - parts.unshift(name); nodes.unshift(node); + if (!node.computed) { + parts.unshift(name); + } + return { name, nodes, parts, keypath: `${name}[✂${prop_start}-${prop_end}✂]` }; } diff --git a/test/runtime/samples/binding-this-component-computed-key/Foo.svelte b/test/runtime/samples/binding-this-component-computed-key/Foo.svelte new file mode 100644 index 0000000000..066a48b65e --- /dev/null +++ b/test/runtime/samples/binding-this-component-computed-key/Foo.svelte @@ -0,0 +1 @@ +
foo
\ No newline at end of file diff --git a/test/runtime/samples/binding-this-component-computed-key/_config.js b/test/runtime/samples/binding-this-component-computed-key/_config.js new file mode 100644 index 0000000000..415d2e641c --- /dev/null +++ b/test/runtime/samples/binding-this-component-computed-key/_config.js @@ -0,0 +1,8 @@ +export default { + skip_if_ssr: true, + + html: ` +
foo
+
has foo: true
+ ` +}; diff --git a/test/runtime/samples/binding-this-component-computed-key/main.svelte b/test/runtime/samples/binding-this-component-computed-key/main.svelte new file mode 100644 index 0000000000..af450ea1fe --- /dev/null +++ b/test/runtime/samples/binding-this-component-computed-key/main.svelte @@ -0,0 +1,9 @@ + + + +
+ has foo: {!!foo.computed} +
diff --git a/test/runtime/samples/binding-this-component-each-block-value/Foo.svelte b/test/runtime/samples/binding-this-component-each-block-value/Foo.svelte new file mode 100644 index 0000000000..066a48b65e --- /dev/null +++ b/test/runtime/samples/binding-this-component-each-block-value/Foo.svelte @@ -0,0 +1 @@ +
foo
\ No newline at end of file diff --git a/test/runtime/samples/binding-this-component-each-block-value/_config.js b/test/runtime/samples/binding-this-component-each-block-value/_config.js new file mode 100644 index 0000000000..2b5df8c595 --- /dev/null +++ b/test/runtime/samples/binding-this-component-each-block-value/_config.js @@ -0,0 +1,12 @@ +export default { + skip_if_ssr: true, + + html: ` +
foo
+
first has foo: true
+
foo
+
second has foo: true
+
foo
+
third has foo: true
+ ` +}; diff --git a/test/runtime/samples/binding-this-component-each-block-value/main.svelte b/test/runtime/samples/binding-this-component-each-block-value/main.svelte new file mode 100644 index 0000000000..5093eecd3f --- /dev/null +++ b/test/runtime/samples/binding-this-component-each-block-value/main.svelte @@ -0,0 +1,11 @@ + + +{#each ["first", "second", "third"] as value} + +
+ {value} has foo: {!!foo[value]} +
+{/each} diff --git a/test/runtime/samples/binding-this-component-each-block/Foo.svelte b/test/runtime/samples/binding-this-component-each-block/Foo.svelte new file mode 100644 index 0000000000..066a48b65e --- /dev/null +++ b/test/runtime/samples/binding-this-component-each-block/Foo.svelte @@ -0,0 +1 @@ +
foo
\ No newline at end of file diff --git a/test/runtime/samples/binding-this-component-each-block/_config.js b/test/runtime/samples/binding-this-component-each-block/_config.js new file mode 100644 index 0000000000..358c5b5afc --- /dev/null +++ b/test/runtime/samples/binding-this-component-each-block/_config.js @@ -0,0 +1,12 @@ +export default { + skip_if_ssr: true, + + html: ` +
foo
+
0 has foo: true
+
foo
+
1 has foo: true
+
foo
+
2 has foo: true
+ ` +}; diff --git a/test/runtime/samples/binding-this-component-each-block/main.svelte b/test/runtime/samples/binding-this-component-each-block/main.svelte new file mode 100644 index 0000000000..49d1d76172 --- /dev/null +++ b/test/runtime/samples/binding-this-component-each-block/main.svelte @@ -0,0 +1,11 @@ + + +{#each Array(3) as _, i} + +
+ {i} has foo: {!!foo[i]} +
+{/each}