Skip to content

Commit c3da9e4

Browse files
tanhauhauTruffula
authored andcommitted
add updating guard to binding callback (sveltejs#5126)
1 parent 179d9ff commit c3da9e4

File tree

45 files changed

+144
-48
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+144
-48
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
* Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144))
56
* Fix reactivity when passing `$$props` to a `<slot>` ([#3364](https://github.com/sveltejs/svelte/issues/3364))
67
* Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118))
78

src/compiler/compile/render_dom/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ export default function dom(
8686
const set = (uses_props || uses_rest || writable_props.length > 0 || component.slots.size > 0)
8787
? x`
8888
${$$props} => {
89-
${(uses_props || uses_rest) && b`if (@is_empty(${$$props})) return;`}
9089
${uses_props && renderer.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`)}
9190
${uses_rest && !uses_props && x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`}
9291
${uses_rest && renderer.invalidate('$$restProps', x`$$restProps = ${compute_rest}`)}
@@ -421,7 +420,7 @@ export default function dom(
421420
422421
${component.partly_hoisted}
423422
424-
${set && b`$$self.$set = ${set};`}
423+
${set && b`$$self.$$set = ${set};`}
425424
426425
${capture_state && b`$$self.$capture_state = ${capture_state};`}
427426

src/runtime/internal/Component.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler';
22
import { current_component, set_current_component } from './lifecycle';
3-
import { blank_object, is_function, run, run_all, noop } from './utils';
3+
import { blank_object, is_empty, is_function, run, run_all, noop } from './utils';
44
import { children, detach } from './dom';
55
import { transition_in } from './transitions';
66

@@ -33,6 +33,7 @@ interface T$$ {
3333
context: Map<any, any>;
3434
on_mount: any[];
3535
on_destroy: any[];
36+
skip_bound: boolean;
3637
}
3738

3839
export function bind(component, name, callback) {
@@ -120,7 +121,8 @@ export function init(component, options, instance, create_fragment, not_equal, p
120121

121122
// everything else
122123
callbacks: blank_object(),
123-
dirty
124+
dirty,
125+
skip_bound: false
124126
};
125127

126128
let ready = false;
@@ -129,7 +131,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
129131
? instance(component, prop_values, (i, ret, ...rest) => {
130132
const value = rest.length ? rest[0] : ret;
131133
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
132-
if ($$.bound[i]) $$.bound[i](value);
134+
if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value);
133135
if (ready) make_dirty(component, i);
134136
}
135137
return ret;
@@ -166,6 +168,7 @@ export let SvelteElement;
166168
if (typeof HTMLElement === 'function') {
167169
SvelteElement = class extends HTMLElement {
168170
$$: T$$;
171+
$$set?: ($$props: any) => void;
169172
constructor() {
170173
super();
171174
this.attachShadow({ mode: 'open' });
@@ -199,14 +202,19 @@ if (typeof HTMLElement === 'function') {
199202
};
200203
}
201204

202-
$set() {
203-
// overridden by instance, if it has props
205+
$set($$props) {
206+
if (this.$$set && !is_empty($$props)) {
207+
this.$$.skip_bound = true;
208+
this.$$set($$props);
209+
this.$$.skip_bound = false;
210+
}
204211
}
205212
};
206213
}
207214

208215
export class SvelteComponent {
209216
$$: T$$;
217+
$$set?: ($$props: any) => void;
210218

211219
$destroy() {
212220
destroy_component(this, 1);
@@ -223,7 +231,11 @@ export class SvelteComponent {
223231
};
224232
}
225233

226-
$set() {
227-
// overridden by instance, if it has props
234+
$set($$props) {
235+
if (this.$$set && !is_empty($$props)) {
236+
this.$$.skip_bound = true;
237+
this.$$set($$props);
238+
this.$$.skip_bound = false;
239+
}
228240
}
229241
}

test/js/samples/action-custom-event-handler/expected.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function instance($$self, $$props, $$invalidate) {
5555
let { bar } = $$props;
5656
const foo_function = () => handleFoo(bar);
5757

58-
$$self.$set = $$props => {
58+
$$self.$$set = $$props => {
5959
if ("bar" in $$props) $$invalidate(0, bar = $$props.bar);
6060
};
6161

test/js/samples/bind-open/expected.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function instance($$self, $$props, $$invalidate) {
5252
$$invalidate(0, open);
5353
}
5454

55-
$$self.$set = $$props => {
55+
$$self.$$set = $$props => {
5656
if ("open" in $$props) $$invalidate(0, open = $$props.open);
5757
};
5858

test/js/samples/bind-width-height/expected.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function instance($$self, $$props, $$invalidate) {
4646
$$invalidate(1, h);
4747
}
4848

49-
$$self.$set = $$props => {
49+
$$self.$$set = $$props => {
5050
if ("w" in $$props) $$invalidate(0, w = $$props.w);
5151
if ("h" in $$props) $$invalidate(1, h = $$props.h);
5252
};

test/js/samples/bindings-readonly-order/expected.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function instance($$self, $$props, $$invalidate) {
6868
$$invalidate(0, files);
6969
}
7070

71-
$$self.$set = $$props => {
71+
$$self.$$set = $$props => {
7272
if ("files" in $$props) $$invalidate(0, files = $$props.files);
7373
};
7474

test/js/samples/capture-inject-state/expected.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ function instance($$self, $$props, $$invalidate) {
118118
let { $$slots = {}, $$scope } = $$props;
119119
validate_slots("Component", $$slots, []);
120120

121-
$$self.$set = $$props => {
121+
$$self.$$set = $$props => {
122122
if ("prop" in $$props) $$subscribe_prop($$invalidate(0, prop = $$props.prop));
123123
if ("alias" in $$props) $$invalidate(1, realName = $$props.alias);
124124
};

test/js/samples/collapses-text-around-comments/expected.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ function create_fragment(ctx) {
4848
function instance($$self, $$props, $$invalidate) {
4949
let { foo = 42 } = $$props;
5050

51-
$$self.$set = $$props => {
51+
$$self.$$set = $$props => {
5252
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
5353
};
5454

test/js/samples/computed-collapsed-if/expected.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function instance($$self, $$props, $$invalidate) {
1212
return x * 3;
1313
}
1414

15-
$$self.$set = $$props => {
15+
$$self.$$set = $$props => {
1616
if ("x" in $$props) $$invalidate(0, x = $$props.x);
1717
};
1818

0 commit comments

Comments
 (0)