chore: ensure binding events are without context (#14194)

* chore: ensure binding events are without context

* doh
pull/14184/head
Dominic Gannaway 1 week ago committed by GitHub
parent 5ce1159ec3
commit 7eb4cb91d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,6 +1,6 @@
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { render_effect, teardown } from '../../../reactivity/effects.js'; import { render_effect, teardown } from '../../../reactivity/effects.js';
import { listen_to_event_and_reset_event } from './shared.js'; import { listen_to_event_and_reset_event, without_reactive_context } from './shared.js';
import * as e from '../../../errors.js'; import * as e from '../../../errors.js';
import { is } from '../../../proxy.js'; import { is } from '../../../proxy.js';
import { queue_micro_task } from '../../task.js'; import { queue_micro_task } from '../../task.js';

@ -1,4 +1,10 @@
import { teardown } from '../../../reactivity/effects.js'; import { teardown } from '../../../reactivity/effects.js';
import {
active_effect,
active_reaction,
set_active_effect,
set_active_reaction
} from '../../../runtime.js';
import { add_form_reset_listener } from '../misc.js'; import { add_form_reset_listener } from '../misc.js';
/** /**
@ -25,6 +31,23 @@ export function listen(target, events, handler, call_handler_immediately = true)
}); });
} }
/**
* @template T
* @param {() => T} fn
*/
export function without_reactive_context(fn) {
var previous_reaction = active_reaction;
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
return fn();
} finally {
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
}
/** /**
* Listen to the given event, and then instantiate a global form reset listener if not already done, * Listen to the given event, and then instantiate a global form reset listener if not already done,
* to notify all bindings when the form is reset * to notify all bindings when the form is reset
@ -34,7 +57,7 @@ export function listen(target, events, handler, call_handler_immediately = true)
* @param {() => void} [on_reset] * @param {() => void} [on_reset]
*/ */
export function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) { export function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) {
element.addEventListener(event, handler); element.addEventListener(event, () => without_reactive_context(handler));
// @ts-expect-error // @ts-expect-error
const prev = element.__on_r; const prev = element.__on_r;
if (prev) { if (prev) {

@ -1,5 +1,5 @@
import { effect, render_effect, teardown } from '../../../reactivity/effects.js'; import { effect, render_effect, teardown } from '../../../reactivity/effects.js';
import { listen } from './shared.js'; import { listen, without_reactive_context } from './shared.js';
/** /**
* @param {'x' | 'y'} type * @param {'x' | 'y'} type
@ -10,13 +10,14 @@ import { listen } from './shared.js';
export function bind_window_scroll(type, get, set = get) { export function bind_window_scroll(type, get, set = get) {
var is_scrolling_x = type === 'x'; var is_scrolling_x = type === 'x';
var target_handler = () => { var target_handler = () =>
scrolling = true; without_reactive_context(() => {
clearTimeout(timeout); scrolling = true;
timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?) clearTimeout(timeout);
timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?)
set(window[is_scrolling_x ? 'scrollX' : 'scrollY']); set(window[is_scrolling_x ? 'scrollX' : 'scrollY']);
}; });
addEventListener('scroll', target_handler, { addEventListener('scroll', target_handler, {
passive: true passive: true
@ -61,5 +62,5 @@ export function bind_window_scroll(type, get, set = get) {
* @param {(size: number) => void} set * @param {(size: number) => void} set
*/ */
export function bind_window_size(type, set) { export function bind_window_size(type, set) {
listen(window, ['resize'], () => set(window[type])); listen(window, ['resize'], () => without_reactive_context(() => set(window[type])));
} }

@ -11,6 +11,7 @@ import {
set_active_effect, set_active_effect,
set_active_reaction set_active_reaction
} from '../../runtime.js'; } from '../../runtime.js';
import { without_reactive_context } from './bindings/shared.js';
/** @type {Set<string>} */ /** @type {Set<string>} */
export const all_registered_events = new Set(); export const all_registered_events = new Set();
@ -61,17 +62,9 @@ export function create_event(event_name, dom, handler, options) {
handle_event_propagation.call(dom, event); handle_event_propagation.call(dom, event);
} }
if (!event.cancelBubble) { if (!event.cancelBubble) {
var previous_reaction = active_reaction; return without_reactive_context(() => {
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
return handler.call(this, event); return handler.call(this, event);
} finally { });
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
} }
} }

Loading…
Cancel
Save