From d34b1be9be4c94e8b072953491d1c45b3ba3f334 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 22 Apr 2025 11:46:58 +0200 Subject: [PATCH] fix: ensure more bindings run without active context Continuation of #14194, fixes #15742 --- .changeset/strange-rocks-beam.md | 5 ++++ .../client/dom/elements/bindings/shared.js | 11 +++++++-- .../client/dom/elements/bindings/window.js | 2 +- .../effect-tracking-binding-set/_config.js | 2 +- .../effect-tracking-binding-set/main.svelte | 23 +++++++++++-------- 5 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 .changeset/strange-rocks-beam.md diff --git a/.changeset/strange-rocks-beam.md b/.changeset/strange-rocks-beam.md new file mode 100644 index 000000000000..9895a6aa6b98 --- /dev/null +++ b/.changeset/strange-rocks-beam.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure more bindings run without active context 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 aa083776a5bc..cf683104f057 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/shared.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/shared.js @@ -12,10 +12,14 @@ import { add_form_reset_listener } from '../misc.js'; * then listens to the given events until the render effect context is destroyed * @param {EventTarget} target * @param {Array} events - * @param {(event?: Event) => void} handler + * @param {(event?: Event) => void} event_handler * @param {any} call_handler_immediately */ -export function listen(target, events, handler, call_handler_immediately = true) { +export function listen(target, events, event_handler, call_handler_immediately = true) { + // Just like user-defined events, our internal events shouldn't have any reactive context + /** @type {typeof event_handler} */ + const handler = (e) => without_reactive_context(() => event_handler(e)); + if (call_handler_immediately) { handler(); } @@ -32,6 +36,9 @@ export function listen(target, events, handler, call_handler_immediately = true) } /** + * Runs a function without a reactive context. + * This is important for events which should "start fresh" and not inherit + * context that accidentally happens to be active at the time of the event. * @template T * @param {() => T} fn */ 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 2f7e44c5d988..4b8116107760 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/window.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/window.js @@ -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/tests/runtime-runes/samples/effect-tracking-binding-set/_config.js b/packages/svelte/tests/runtime-runes/samples/effect-tracking-binding-set/_config.js index aebbfec832f6..64965e79ec5b 100644 --- a/packages/svelte/tests/runtime-runes/samples/effect-tracking-binding-set/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/effect-tracking-binding-set/_config.js @@ -2,6 +2,6 @@ import { test } from '../../test'; export default test({ test({ assert, logs }) { - assert.deepEqual(logs, [false]); + assert.deepEqual(logs, ['bind:activeElement false', 'bind:value false']); } }); diff --git a/packages/svelte/tests/runtime-runes/samples/effect-tracking-binding-set/main.svelte b/packages/svelte/tests/runtime-runes/samples/effect-tracking-binding-set/main.svelte index f21ecfdce6cb..fd9f12c08e0b 100644 --- a/packages/svelte/tests/runtime-runes/samples/effect-tracking-binding-set/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/effect-tracking-binding-set/main.svelte @@ -1,24 +1,29 @@ - + + pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy