Skip to content

Commit 7eb4cb9

Browse files
authored
chore: ensure binding events are without context (#14194)
* chore: ensure binding events are without context * doh
1 parent 5ce1159 commit 7eb4cb9

File tree

4 files changed

+37
-20
lines changed

4 files changed

+37
-20
lines changed

packages/svelte/src/internal/client/dom/elements/bindings/input.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { DEV } from 'esm-env';
22
import { render_effect, teardown } from '../../../reactivity/effects.js';
3-
import { listen_to_event_and_reset_event } from './shared.js';
3+
import { listen_to_event_and_reset_event, without_reactive_context } from './shared.js';
44
import * as e from '../../../errors.js';
55
import { is } from '../../../proxy.js';
66
import { queue_micro_task } from '../../task.js';

packages/svelte/src/internal/client/dom/elements/bindings/shared.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
import { teardown } from '../../../reactivity/effects.js';
2+
import {
3+
active_effect,
4+
active_reaction,
5+
set_active_effect,
6+
set_active_reaction
7+
} from '../../../runtime.js';
28
import { add_form_reset_listener } from '../misc.js';
39

410
/**
@@ -25,6 +31,23 @@ export function listen(target, events, handler, call_handler_immediately = true)
2531
});
2632
}
2733

34+
/**
35+
* @template T
36+
* @param {() => T} fn
37+
*/
38+
export function without_reactive_context(fn) {
39+
var previous_reaction = active_reaction;
40+
var previous_effect = active_effect;
41+
set_active_reaction(null);
42+
set_active_effect(null);
43+
try {
44+
return fn();
45+
} finally {
46+
set_active_reaction(previous_reaction);
47+
set_active_effect(previous_effect);
48+
}
49+
}
50+
2851
/**
2952
* Listen to the given event, and then instantiate a global form reset listener if not already done,
3053
* to notify all bindings when the form is reset
@@ -34,7 +57,7 @@ export function listen(target, events, handler, call_handler_immediately = true)
3457
* @param {() => void} [on_reset]
3558
*/
3659
export function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) {
37-
element.addEventListener(event, handler);
60+
element.addEventListener(event, () => without_reactive_context(handler));
3861
// @ts-expect-error
3962
const prev = element.__on_r;
4063
if (prev) {

packages/svelte/src/internal/client/dom/elements/bindings/window.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { effect, render_effect, teardown } from '../../../reactivity/effects.js';
2-
import { listen } from './shared.js';
2+
import { listen, without_reactive_context } from './shared.js';
33

44
/**
55
* @param {'x' | 'y'} type
@@ -10,13 +10,14 @@ import { listen } from './shared.js';
1010
export function bind_window_scroll(type, get, set = get) {
1111
var is_scrolling_x = type === 'x';
1212

13-
var target_handler = () => {
14-
scrolling = true;
15-
clearTimeout(timeout);
16-
timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?)
13+
var target_handler = () =>
14+
without_reactive_context(() => {
15+
scrolling = true;
16+
clearTimeout(timeout);
17+
timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?)
1718

18-
set(window[is_scrolling_x ? 'scrollX' : 'scrollY']);
19-
};
19+
set(window[is_scrolling_x ? 'scrollX' : 'scrollY']);
20+
});
2021

2122
addEventListener('scroll', target_handler, {
2223
passive: true
@@ -61,5 +62,5 @@ export function bind_window_scroll(type, get, set = get) {
6162
* @param {(size: number) => void} set
6263
*/
6364
export function bind_window_size(type, set) {
64-
listen(window, ['resize'], () => set(window[type]));
65+
listen(window, ['resize'], () => without_reactive_context(() => set(window[type])));
6566
}

packages/svelte/src/internal/client/dom/elements/events.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
set_active_effect,
1212
set_active_reaction
1313
} from '../../runtime.js';
14+
import { without_reactive_context } from './bindings/shared.js';
1415

1516
/** @type {Set<string>} */
1617
export const all_registered_events = new Set();
@@ -61,17 +62,9 @@ export function create_event(event_name, dom, handler, options) {
6162
handle_event_propagation.call(dom, event);
6263
}
6364
if (!event.cancelBubble) {
64-
var previous_reaction = active_reaction;
65-
var previous_effect = active_effect;
66-
67-
set_active_reaction(null);
68-
set_active_effect(null);
69-
try {
65+
return without_reactive_context(() => {
7066
return handler.call(this, event);
71-
} finally {
72-
set_active_reaction(previous_reaction);
73-
set_active_effect(previous_effect);
74-
}
67+
});
7568
}
7669
}
7770

0 commit comments

Comments
 (0)