From 0a3b7c0e5387552f537396a2e5ba3bff43bba0a0 Mon Sep 17 00:00:00 2001 From: tanhauhau Date: Sat, 11 Dec 2021 14:11:27 +0800 Subject: [PATCH] binding member expression should only invalidate the object, not the member property --- .../render_dom/wrappers/Element/Binding.ts | 15 +++++++++++++++ .../render_dom/wrappers/Element/index.ts | 2 +- .../render_dom/wrappers/shared/bind_this.ts | 2 +- .../_config.js | 18 ++++++++++++++++++ .../main.svelte | 9 +++++++++ .../samples/binding-this-each-key/_config.js | 10 ++++++++++ .../samples/binding-this-each-key/main.svelte | 13 +++++++++++++ .../_config.js | 8 ++++++++ .../main.svelte | 9 +++++++++ 9 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 test/runtime/samples/binding-input-member-expression-update/_config.js create mode 100644 test/runtime/samples/binding-input-member-expression-update/main.svelte create mode 100644 test/runtime/samples/binding-this-each-key/_config.js create mode 100644 test/runtime/samples/binding-this-each-key/main.svelte create mode 100644 test/runtime/samples/binding-this-member-expression-update/_config.js create mode 100644 test/runtime/samples/binding-this-member-expression-update/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts index 7c8a339d00..d3a40128c4 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts @@ -70,6 +70,21 @@ export default class BindingWrapper { return dependencies; } + get_update_dependencies() { + const object = get_object(this.node.expression.node).name; + const dependencies = new Set(); + dependencies.add(object); + + + const indirect_dependencies = this.parent.renderer.component.indirect_dependencies.get(object); + if (indirect_dependencies) { + indirect_dependencies.forEach(indirect_dependency => { + dependencies.add(indirect_dependency); + }); + } + return dependencies; + } + is_readonly_media_attribute() { return this.node.is_readonly_media_attribute(); } diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 9ec36b12d7..583274044b 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -466,7 +466,7 @@ export default class ElementWrapper extends Wrapper { binding_group.bindings.forEach(binding => { // TODO this is a mess - add_to_set(dependencies, binding.get_dependencies()); + add_to_set(dependencies, binding.get_update_dependencies()); add_to_set(contextual_dependencies, binding.handler.contextual_dependencies); binding.render(block, lock); diff --git a/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts b/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts index 1b8c4f9db8..af440b6341 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts @@ -12,7 +12,7 @@ export default function bind_this(component: Component, block: Block, binding: B const callee = block.renderer.reference(fn.name); const { contextual_dependencies, mutation } = binding.handler; - const dependencies = binding.get_dependencies(); + const dependencies = binding.get_update_dependencies(); const body = b` ${mutation} diff --git a/test/runtime/samples/binding-input-member-expression-update/_config.js b/test/runtime/samples/binding-input-member-expression-update/_config.js new file mode 100644 index 0000000000..c0dfc3bbe8 --- /dev/null +++ b/test/runtime/samples/binding-input-member-expression-update/_config.js @@ -0,0 +1,18 @@ +// binding member expression shouldn't invalidate the property name +export default { + async test({ assert, component, target, window }) { + const input = target.querySelector('input'); + assert.deepEqual(component.logs.length, 1); + assert.equal(input.value, 'abc'); + + input.value = 'hij'; + await input.dispatchEvent(new window.Event('input')); + + assert.deepEqual(component.values.a, 'hij'); + assert.deepEqual(component.logs.length, 1); + + component.paths = ['b']; + assert.deepEqual(component.logs.length, 2); + assert.equal(input.value, 'def'); + } +}; diff --git a/test/runtime/samples/binding-input-member-expression-update/main.svelte b/test/runtime/samples/binding-input-member-expression-update/main.svelte new file mode 100644 index 0000000000..5c841379ca --- /dev/null +++ b/test/runtime/samples/binding-input-member-expression-update/main.svelte @@ -0,0 +1,9 @@ + + + diff --git a/test/runtime/samples/binding-this-each-key/_config.js b/test/runtime/samples/binding-this-each-key/_config.js new file mode 100644 index 0000000000..332e14fda8 --- /dev/null +++ b/test/runtime/samples/binding-this-each-key/_config.js @@ -0,0 +1,10 @@ +export default { + html: '
content
content
content
', + + test({ assert, target, component }) { + const divs = target.querySelectorAll('div'); + assert.equal(component.refs[0], divs[0]); + assert.equal(component.refs[1], divs[1]); + assert.equal(component.refs[2], divs[2]); + } +}; diff --git a/test/runtime/samples/binding-this-each-key/main.svelte b/test/runtime/samples/binding-this-each-key/main.svelte new file mode 100644 index 0000000000..7ff076568a --- /dev/null +++ b/test/runtime/samples/binding-this-each-key/main.svelte @@ -0,0 +1,13 @@ + + +{#each list as { id }, index (id)} +
+ content +
+{/each} \ No newline at end of file diff --git a/test/runtime/samples/binding-this-member-expression-update/_config.js b/test/runtime/samples/binding-this-member-expression-update/_config.js new file mode 100644 index 0000000000..782d44311c --- /dev/null +++ b/test/runtime/samples/binding-this-member-expression-update/_config.js @@ -0,0 +1,8 @@ +// binding member expression shouldn't invalidate the property name +export default { + test({ assert, component, target }) { + const div = target.querySelector('div'); + assert.equal(div, component.container.a); + assert.deepEqual(component.logs.length, 1); + } +}; diff --git a/test/runtime/samples/binding-this-member-expression-update/main.svelte b/test/runtime/samples/binding-this-member-expression-update/main.svelte new file mode 100644 index 0000000000..a4f8948afe --- /dev/null +++ b/test/runtime/samples/binding-this-member-expression-update/main.svelte @@ -0,0 +1,9 @@ + + +