From 2e1a0aca39aa326939d88a17071db5e51c3ef355 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Fri, 7 Feb 2025 21:06:05 +0000 Subject: [PATCH] chore: unify bindings to use internal event system --- .changeset/mighty-icons-sin.md | 5 +++++ .../client/dom/elements/bindings/media.js | 5 +++-- .../client/dom/elements/bindings/shared.js | 13 ++++++----- .../client/dom/elements/bindings/universal.js | 5 +++-- .../client/dom/elements/bindings/window.js | 22 +++++++++---------- .../src/internal/client/dom/elements/misc.js | 4 +++- 6 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 .changeset/mighty-icons-sin.md diff --git a/.changeset/mighty-icons-sin.md b/.changeset/mighty-icons-sin.md new file mode 100644 index 0000000000..e117aec8f1 --- /dev/null +++ b/.changeset/mighty-icons-sin.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +chore: unify bindings to use internal event system diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/media.js b/packages/svelte/src/internal/client/dom/elements/bindings/media.js index 4893426d55..fbf34102f9 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/media.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/media.js @@ -1,6 +1,7 @@ import { hydrating } from '../../hydration.js'; import { render_effect, effect, teardown } from '../../../reactivity/effects.js'; import { listen } from './shared.js'; +import { on } from '../events.js'; /** @param {TimeRanges} ranges */ function time_ranges_to_array(ranges) { @@ -42,7 +43,7 @@ export function bind_current_time(media, get, set = get) { }; raf_id = requestAnimationFrame(callback); - media.addEventListener('timeupdate', callback); + var destroy = on(media, 'timeupdate', callback); render_effect(() => { var next_value = Number(get()); @@ -54,7 +55,7 @@ export function bind_current_time(media, get, set = get) { teardown(() => { cancelAnimationFrame(raf_id); - media.removeEventListener('timeupdate', callback); + destroy(); }); } diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/shared.js b/packages/svelte/src/internal/client/dom/elements/bindings/shared.js index aa083776a5..1f8ff703c0 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/shared.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/shared.js @@ -1,3 +1,4 @@ +import { run_all } from '../../../../shared/utils.js'; import { teardown } from '../../../reactivity/effects.js'; import { active_effect, @@ -5,6 +6,7 @@ import { set_active_effect, set_active_reaction } from '../../../runtime.js'; +import { on } from '../events.js'; import { add_form_reset_listener } from '../misc.js'; /** @@ -20,14 +22,15 @@ export function listen(target, events, handler, call_handler_immediately = true) handler(); } + /** @type {(() => void)[]} */ + var destroys = []; + for (var name of events) { - target.addEventListener(name, handler); + destroys.push(on(target, name, handler)); } teardown(() => { - for (var name of events) { - target.removeEventListener(name, handler); - } + run_all(destroys); }); } @@ -57,7 +60,7 @@ export function without_reactive_context(fn) { * @param {(is_reset?: true) => void} [on_reset] */ export function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) { - element.addEventListener(event, () => without_reactive_context(handler)); + on(element, event, () => handler()); // @ts-expect-error const prev = element.__on_r; if (prev) { diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/universal.js b/packages/svelte/src/internal/client/dom/elements/bindings/universal.js index 5b10abdc4c..fe3a459d2f 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/universal.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/universal.js @@ -1,4 +1,5 @@ import { render_effect, teardown } from '../../../reactivity/effects.js'; +import { on } from '../events.js'; import { listen } from './shared.js'; /** @@ -9,7 +10,7 @@ import { listen } from './shared.js'; * @returns {void} */ export function bind_content_editable(property, element, get, set = get) { - element.addEventListener('input', () => { + on(element, 'input', () => { // @ts-ignore set(element[property]); }); @@ -44,7 +45,7 @@ export function bind_property(property, event_name, element, set, get) { set(element[property]); }; - element.addEventListener(event_name, handler); + on(element, event_name, handler); if (get) { render_effect(() => { diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/window.js b/packages/svelte/src/internal/client/dom/elements/bindings/window.js index 2f7e44c5d9..b47910e97e 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/window.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/window.js @@ -1,5 +1,6 @@ import { effect, render_effect, teardown } from '../../../reactivity/effects.js'; -import { listen, without_reactive_context } from './shared.js'; +import { on } from '../events.js'; +import { listen } from './shared.js'; /** * @param {'x' | 'y'} type @@ -10,16 +11,15 @@ import { listen, without_reactive_context } from './shared.js'; export function bind_window_scroll(type, get, set = get) { var is_scrolling_x = type === 'x'; - var target_handler = () => - without_reactive_context(() => { - scrolling = true; - clearTimeout(timeout); - timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?) + var target_handler = () => { + scrolling = true; + 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, { + var destroy = on(window, 'scroll', target_handler, { passive: true }); @@ -53,7 +53,7 @@ export function bind_window_scroll(type, get, set = get) { effect(target_handler); teardown(() => { - removeEventListener('scroll', target_handler); + destroy(); }); } @@ -62,5 +62,5 @@ export function bind_window_scroll(type, get, set = get) { * @param {(size: number) => void} set */ export function bind_window_size(type, set) { - listen(window, ['resize'], () => without_reactive_context(() => set(window[type]))); + listen(window, ['resize'], () => set(window[type])); } diff --git a/packages/svelte/src/internal/client/dom/elements/misc.js b/packages/svelte/src/internal/client/dom/elements/misc.js index 61e513903f..2e730471b6 100644 --- a/packages/svelte/src/internal/client/dom/elements/misc.js +++ b/packages/svelte/src/internal/client/dom/elements/misc.js @@ -1,6 +1,7 @@ import { hydrating } from '../hydration.js'; import { clear_text_content, get_first_child } from '../operations.js'; import { queue_micro_task } from '../task.js'; +import { on } from './events.js'; /** * @param {HTMLElement} dom @@ -37,7 +38,8 @@ let listening_to_form_reset = false; export function add_form_reset_listener() { if (!listening_to_form_reset) { listening_to_form_reset = true; - document.addEventListener( + on( + document, 'reset', (evt) => { // Needs to happen one tick later or else the dom properties of the form