Skip to content

Commit

Permalink
only add event listeners when a block is first mounted (#4860)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed May 26, 2020
1 parent 24ef4e1 commit 3330c3f
Show file tree
Hide file tree
Showing 31 changed files with 305 additions and 132 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Add `a11y-no-onchange` warning ([#4788](https://github.com/sveltejs/svelte/pull/4788))
* Add `muted` binding for media elements ([#2998](https://github.com/sveltejs/svelte/issues/2998))
* Fix let-less `<slot>` with context overflow ([#4624](https://github.com/sveltejs/svelte/issues/4624))
* Fix `use:` actions being recreated when a keyed `{#each}` is reordered ([#4693](https://github.com/sveltejs/svelte/issues/4693))

## 3.22.3

Expand Down
21 changes: 14 additions & 7 deletions src/compiler/compile/render_dom/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ export default class Block {
${this.chunks.mount}
}`;
} else {
properties.mount = x`function #mount(#target, #anchor, #remount) {
properties.mount = x`function #mount(#target, #anchor) {
${this.chunks.mount}
}`;
}
Expand Down Expand Up @@ -452,6 +452,9 @@ export default class Block {

render_listeners(chunk: string = '') {
if (this.event_listeners.length > 0) {
this.add_variable({ type: 'Identifier', name: '#mounted' });
this.chunks.destroy.push(b`#mounted = false`);

const dispose: Identifier = {
type: 'Identifier',
name: `#dispose${chunk}`
Expand All @@ -462,8 +465,10 @@ export default class Block {
if (this.event_listeners.length === 1) {
this.chunks.mount.push(
b`
if (#remount) ${dispose}();
${dispose} = ${this.event_listeners[0]};
if (!#mounted) {
${dispose} = ${this.event_listeners[0]};
#mounted = true;
}
`
);

Expand All @@ -472,10 +477,12 @@ export default class Block {
);
} else {
this.chunks.mount.push(b`
if (#remount) @run_all(${dispose});
${dispose} = [
${this.event_listeners}
];
if (!#mounted) {
${dispose} = [
${this.event_listeners}
];
#mounted = true;
}
`);

this.chunks.destroy.push(
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/internal/keyed_each.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list

function insert(block) {
transition_in(block, 1);
block.m(node, next, lookup.has(block.key));
block.m(node, next);
lookup.set(block.key, block);
next = block.first;
n--;
Expand Down
11 changes: 8 additions & 3 deletions test/js/samples/action-custom-event-handler/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@ import {
function create_fragment(ctx) {
let button;
let foo_action;
let mounted;
let dispose;

return {
c() {
button = element("button");
button.textContent = "foo";
},
m(target, anchor, remount) {
m(target, anchor) {
insert(target, button, anchor);
if (remount) dispose();
dispose = action_destroyer(foo_action = foo.call(null, button, /*foo_function*/ ctx[1]));

if (!mounted) {
dispose = action_destroyer(foo_action = foo.call(null, button, /*foo_function*/ ctx[1]));
mounted = true;
}
},
p(ctx, [dirty]) {
if (foo_action && is_function(foo_action.update) && dirty & /*bar*/ 1) foo_action.update.call(null, /*foo_function*/ ctx[1]);
Expand All @@ -33,6 +37,7 @@ function create_fragment(ctx) {
o: noop,
d(detaching) {
if (detaching) detach(button);
mounted = false;
dispose();
}
};
Expand Down
11 changes: 8 additions & 3 deletions test/js/samples/action/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
function create_fragment(ctx) {
let a;
let link_action;
let mounted;
let dispose;

return {
Expand All @@ -22,16 +23,20 @@ function create_fragment(ctx) {
a.textContent = "Test";
attr(a, "href", "#");
},
m(target, anchor, remount) {
m(target, anchor) {
insert(target, a, anchor);
if (remount) dispose();
dispose = action_destroyer(link_action = link.call(null, a));

if (!mounted) {
dispose = action_destroyer(link_action = link.call(null, a));
mounted = true;
}
},
p: noop,
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(a);
mounted = false;
dispose();
}
};
Expand Down
18 changes: 11 additions & 7 deletions test/js/samples/bind-online/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,27 @@ import {
} from "svelte/internal";

function create_fragment(ctx) {
let mounted;
let dispose;
add_render_callback(/*onlinestatuschanged*/ ctx[1]);

return {
c: noop,
m(target, anchor, remount) {
if (remount) run_all(dispose);

dispose = [
listen(window, "online", /*onlinestatuschanged*/ ctx[1]),
listen(window, "offline", /*onlinestatuschanged*/ ctx[1])
];
m(target, anchor) {
if (!mounted) {
dispose = [
listen(window, "online", /*onlinestatuschanged*/ ctx[1]),
listen(window, "offline", /*onlinestatuschanged*/ ctx[1])
];

mounted = true;
}
},
p: noop,
i: noop,
o: noop,
d(detaching) {
mounted = false;
run_all(dispose);
}
};
Expand Down
11 changes: 8 additions & 3 deletions test/js/samples/bind-open/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {

function create_fragment(ctx) {
let details;
let mounted;
let dispose;

return {
Expand All @@ -21,11 +22,14 @@ function create_fragment(ctx) {
details.innerHTML = `<summary>summary</summary>content
`;
},
m(target, anchor, remount) {
m(target, anchor) {
insert(target, details, anchor);
details.open = /*open*/ ctx[0];
if (remount) dispose();
dispose = listen(details, "toggle", /*details_toggle_handler*/ ctx[1]);

if (!mounted) {
dispose = listen(details, "toggle", /*details_toggle_handler*/ ctx[1]);
mounted = true;
}
},
p(ctx, [dirty]) {
if (dirty & /*open*/ 1) {
Expand All @@ -36,6 +40,7 @@ function create_fragment(ctx) {
o: noop,
d(detaching) {
if (detaching) detach(details);
mounted = false;
dispose();
}
};
Expand Down
17 changes: 11 additions & 6 deletions test/js/samples/bindings-readonly-order/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function create_fragment(ctx) {
let input0;
let t;
let input1;
let mounted;
let dispose;

return {
Expand All @@ -27,16 +28,19 @@ function create_fragment(ctx) {
attr(input0, "type", "file");
attr(input1, "type", "file");
},
m(target, anchor, remount) {
m(target, anchor) {
insert(target, input0, anchor);
insert(target, t, anchor);
insert(target, input1, anchor);
if (remount) run_all(dispose);

dispose = [
listen(input0, "change", /*input0_change_handler*/ ctx[1]),
listen(input1, "change", /*input1_change_handler*/ ctx[2])
];
if (!mounted) {
dispose = [
listen(input0, "change", /*input0_change_handler*/ ctx[1]),
listen(input1, "change", /*input1_change_handler*/ ctx[2])
];

mounted = true;
}
},
p: noop,
i: noop,
Expand All @@ -45,6 +49,7 @@ function create_fragment(ctx) {
if (detaching) detach(input0);
if (detaching) detach(t);
if (detaching) detach(input1);
mounted = false;
run_all(dispose);
}
};
Expand Down
11 changes: 8 additions & 3 deletions test/js/samples/capture-inject-dev-only/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function create_fragment(ctx) {
let t0;
let t1;
let input;
let mounted;
let dispose;

return {
Expand All @@ -29,14 +30,17 @@ function create_fragment(ctx) {
t1 = space();
input = element("input");
},
m(target, anchor, remount) {
m(target, anchor) {
insert(target, p, anchor);
append(p, t0);
insert(target, t1, anchor);
insert(target, input, anchor);
set_input_value(input, /*foo*/ ctx[0]);
if (remount) dispose();
dispose = listen(input, "input", /*input_input_handler*/ ctx[1]);

if (!mounted) {
dispose = listen(input, "input", /*input_input_handler*/ ctx[1]);
mounted = true;
}
},
p(ctx, [dirty]) {
if (dirty & /*foo*/ 1) set_data(t0, /*foo*/ ctx[0]);
Expand All @@ -51,6 +55,7 @@ function create_fragment(ctx) {
if (detaching) detach(p);
if (detaching) detach(t1);
if (detaching) detach(input);
mounted = false;
dispose();
}
};
Expand Down
11 changes: 8 additions & 3 deletions test/js/samples/component-static-var/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function create_fragment(ctx) {
let t1;
let input;
let current;
let mounted;
let dispose;
const foo = new Foo({ props: { x: y } });
const bar = new Bar({ props: { x: /*z*/ ctx[0] } });
Expand All @@ -36,16 +37,19 @@ function create_fragment(ctx) {
t1 = space();
input = element("input");
},
m(target, anchor, remount) {
m(target, anchor) {
mount_component(foo, target, anchor);
insert(target, t0, anchor);
mount_component(bar, target, anchor);
insert(target, t1, anchor);
insert(target, input, anchor);
set_input_value(input, /*z*/ ctx[0]);
current = true;
if (remount) dispose();
dispose = listen(input, "input", /*input_input_handler*/ ctx[1]);

if (!mounted) {
dispose = listen(input, "input", /*input_input_handler*/ ctx[1]);
mounted = true;
}
},
p(ctx, [dirty]) {
const bar_changes = {};
Expand Down Expand Up @@ -73,6 +77,7 @@ function create_fragment(ctx) {
destroy_component(bar, detaching);
if (detaching) detach(t1);
if (detaching) detach(input);
mounted = false;
dispose();
}
};
Expand Down
11 changes: 8 additions & 3 deletions test/js/samples/component-store-reassign-invalidate/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function create_fragment(ctx) {
let t0;
let t1;
let button;
let mounted;
let dispose;

return {
Expand All @@ -32,13 +33,16 @@ function create_fragment(ctx) {
button = element("button");
button.textContent = "reset";
},
m(target, anchor, remount) {
m(target, anchor) {
insert(target, h1, anchor);
append(h1, t0);
insert(target, t1, anchor);
insert(target, button, anchor);
if (remount) dispose();
dispose = listen(button, "click", /*click_handler*/ ctx[2]);

if (!mounted) {
dispose = listen(button, "click", /*click_handler*/ ctx[2]);
mounted = true;
}
},
p(ctx, [dirty]) {
if (dirty & /*$foo*/ 2) set_data(t0, /*$foo*/ ctx[1]);
Expand All @@ -49,6 +53,7 @@ function create_fragment(ctx) {
if (detaching) detach(h1);
if (detaching) detach(t1);
if (detaching) detach(button);
mounted = false;
dispose();
}
};
Expand Down
11 changes: 8 additions & 3 deletions test/js/samples/dont-invalidate-this/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,27 @@ import {

function create_fragment(ctx) {
let input;
let mounted;
let dispose;

return {
c() {
input = element("input");
},
m(target, anchor, remount) {
m(target, anchor) {
insert(target, input, anchor);
if (remount) dispose();
dispose = listen(input, "input", make_uppercase);

if (!mounted) {
dispose = listen(input, "input", make_uppercase);
mounted = true;
}
},
p: noop,
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(input);
mounted = false;
dispose();
}
};
Expand Down

0 comments on commit 3330c3f

Please sign in to comment.