Skip to content

Commit

Permalink
add updating guard to binding callback (#5126)
Browse files Browse the repository at this point in the history
  • Loading branch information
tanhauhau authored Jul 17, 2020
1 parent 5b80874 commit ec0f79c
Show file tree
Hide file tree
Showing 45 changed files with 144 additions and 48 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

* 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))
* Fix reactivity when passing `$$props` to a `<slot>` ([#3364](https://github.com/sveltejs/svelte/issues/3364))
* Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118))

Expand Down
3 changes: 1 addition & 2 deletions src/compiler/compile/render_dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ export default function dom(
const set = (uses_props || uses_rest || writable_props.length > 0 || component.slots.size > 0)
? x`
${$$props} => {
${(uses_props || uses_rest) && b`if (@is_empty(${$$props})) return;`}
${uses_props && renderer.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`)}
${uses_rest && !uses_props && x`$$props = @assign(@assign({}, $$props), @exclude_internal_props($$new_props))`}
${uses_rest && renderer.invalidate('$$restProps', x`$$restProps = ${compute_rest}`)}
Expand Down Expand Up @@ -421,7 +420,7 @@ export default function dom(
${component.partly_hoisted}
${set && b`$$self.$set = ${set};`}
${set && b`$$self.$$set = ${set};`}
${capture_state && b`$$self.$capture_state = ${capture_state};`}
Expand Down
26 changes: 19 additions & 7 deletions src/runtime/internal/Component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler';
import { current_component, set_current_component } from './lifecycle';
import { blank_object, is_function, run, run_all, noop } from './utils';
import { blank_object, is_empty, is_function, run, run_all, noop } from './utils';
import { children, detach } from './dom';
import { transition_in } from './transitions';

Expand Down Expand Up @@ -33,6 +33,7 @@ interface T$$ {
context: Map<any, any>;
on_mount: any[];
on_destroy: any[];
skip_bound: boolean;
}

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

// everything else
callbacks: blank_object(),
dirty
dirty,
skip_bound: false
};

let ready = false;
Expand All @@ -129,7 +131,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
? instance(component, prop_values, (i, ret, ...rest) => {
const value = rest.length ? rest[0] : ret;
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
if ($$.bound[i]) $$.bound[i](value);
if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value);
if (ready) make_dirty(component, i);
}
return ret;
Expand Down Expand Up @@ -166,6 +168,7 @@ export let SvelteElement;
if (typeof HTMLElement === 'function') {
SvelteElement = class extends HTMLElement {
$$: T$$;
$$set?: ($$props: any) => void;
constructor() {
super();
this.attachShadow({ mode: 'open' });
Expand Down Expand Up @@ -199,14 +202,19 @@ if (typeof HTMLElement === 'function') {
};
}

$set() {
// overridden by instance, if it has props
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
};
}

export class SvelteComponent {
$$: T$$;
$$set?: ($$props: any) => void;

$destroy() {
destroy_component(this, 1);
Expand All @@ -223,7 +231,11 @@ export class SvelteComponent {
};
}

$set() {
// overridden by instance, if it has props
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
}
2 changes: 1 addition & 1 deletion test/js/samples/action-custom-event-handler/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function instance($$self, $$props, $$invalidate) {
let { bar } = $$props;
const foo_function = () => handleFoo(bar);

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("bar" in $$props) $$invalidate(0, bar = $$props.bar);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/bind-open/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, open);
}

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("open" in $$props) $$invalidate(0, open = $$props.open);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/bind-width-height/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(1, h);
}

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("w" in $$props) $$invalidate(0, w = $$props.w);
if ("h" in $$props) $$invalidate(1, h = $$props.h);
};
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/bindings-readonly-order/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, files);
}

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("files" in $$props) $$invalidate(0, files = $$props.files);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/capture-inject-state/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("prop" in $$props) $$subscribe_prop($$invalidate(0, prop = $$props.prop));
if ("alias" in $$props) $$invalidate(1, realName = $$props.alias);
};
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/collapses-text-around-comments/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { foo = 42 } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/computed-collapsed-if/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function instance($$self, $$props, $$invalidate) {
return x * 3;
}

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("x" in $$props) $$invalidate(0, x = $$props.x);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/data-attribute/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { bar } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("bar" in $$props) $$invalidate(0, bar = $$props.bar);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/debug-empty/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("name" in $$props) $$invalidate(0, name = $$props.name);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/debug-foo-bar-baz-things/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
if ("foo" in $$props) $$invalidate(1, foo = $$props.foo);
if ("bar" in $$props) $$invalidate(2, bar = $$props.bar);
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/debug-foo/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
if ("foo" in $$props) $$invalidate(1, foo = $$props.foo);
};
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/deconflict-builtins/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { createElement } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("createElement" in $$props) $$invalidate(0, createElement = $$props.createElement);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/deconflict-globals/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function instance($$self, $$props, $$invalidate) {
alert(JSON.stringify(data()));
});

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function instance($$self, $$props, $$invalidate) {
let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/each-block-array-literal/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function instance($$self, $$props, $$invalidate) {
let { d } = $$props;
let { e } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("a" in $$props) $$invalidate(0, a = $$props.a);
if ("b" in $$props) $$invalidate(1, b = $$props.b);
if ("c" in $$props) $$invalidate(2, c = $$props.c);
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/each-block-changed-check/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function instance($$self, $$props, $$invalidate) {
let { time } = $$props;
let { foo } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("comments" in $$props) $$invalidate(0, comments = $$props.comments);
if ("elapsed" in $$props) $$invalidate(1, elapsed = $$props.elapsed);
if ("time" in $$props) $$invalidate(2, time = $$props.time);
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/each-block-keyed-animated/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ function foo(node, animation, params) {
function instance($$self, $$props, $$invalidate) {
let { things } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/each-block-keyed/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { things } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/if-block-no-update/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { foo } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/if-block-simple/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { foo } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function instance($$self, $$props, $$invalidate) {
let { x } = $$props;
let { y } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("color" in $$props) $$invalidate(0, color = $$props.color);
if ("x" in $$props) $$invalidate(1, x = $$props.x);
if ("y" in $$props) $$invalidate(2, y = $$props.y);
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/inline-style-optimized-url/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { data } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("data" in $$props) $$invalidate(0, data = $$props.data);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/inline-style-optimized/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { color } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("color" in $$props) $$invalidate(0, color = $$props.color);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/inline-style-unoptimized/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function instance($$self, $$props, $$invalidate) {
let { key } = $$props;
let { value } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("style" in $$props) $$invalidate(0, style = $$props.style);
if ("key" in $$props) $$invalidate(1, key = $$props.key);
if ("value" in $$props) $$invalidate(2, value = $$props.value);
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/input-files/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, files);
}

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("files" in $$props) $$invalidate(0, files = $$props.files);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/input-range/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, value);
}

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("value" in $$props) $$invalidate(0, value = $$props.value);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/input-without-blowback-guard/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(0, foo);
}

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};

Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/media-bindings/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ function instance($$self, $$props, $$invalidate) {
$$invalidate(10, ended);
}

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("buffered" in $$props) $$invalidate(0, buffered = $$props.buffered);
if ("seekable" in $$props) $$invalidate(1, seekable = $$props.seekable);
if ("played" in $$props) $$invalidate(2, played = $$props.played);
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/optional-chaining/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ function instance($$self, $$props, $$invalidate) {
let { f } = $$props;
let Component;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("a" in $$props) $$invalidate(0, a = $$props.a);
if ("b" in $$props) $$invalidate(1, b = $$props.b);
if ("c" in $$props) $$invalidate(2, c = $$props.c);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function instance($$self, $$props, $$invalidate) {
let a;
let b;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("x" in $$props) $$invalidate(0, x = $$props.x);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function instance($$self, $$props, $$invalidate) {
let { a = 1 } = $$props;
let { b = 2 } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("a" in $$props) $$invalidate(0, a = $$props.a);
if ("b" in $$props) $$invalidate(1, b = $$props.b);
};
Expand Down
2 changes: 1 addition & 1 deletion test/js/samples/select-dynamic-value/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { current } = $$props;

$$self.$set = $$props => {
$$self.$$set = $$props => {
if ("current" in $$props) $$invalidate(0, current = $$props.current);
};

Expand Down
Loading

0 comments on commit ec0f79c

Please sign in to comment.