From 6a1d0ead408c425e72ef6c53df529c9a6a768675 Mon Sep 17 00:00:00 2001 From: Laszlo Korte Date: Wed, 30 Jul 2025 23:21:01 +0200 Subject: [PATCH] Fix double event processing (#16522) Firefox seems to garbage collect event objects during event propagation if no global reference to the event object is kept. That discards the __root marker set on the event object to early, leading to duplicate processing. --- .changeset/chilly-bananas-train.md | 5 +++++ .../svelte/src/internal/client/dom/elements/events.js | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 .changeset/chilly-bananas-train.md diff --git a/.changeset/chilly-bananas-train.md b/.changeset/chilly-bananas-train.md new file mode 100644 index 0000000000..2a977b3925 --- /dev/null +++ b/.changeset/chilly-bananas-train.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +Fix double event processing in firefox due to event object being garbage collected (#16522) diff --git a/packages/svelte/src/internal/client/dom/elements/events.js b/packages/svelte/src/internal/client/dom/elements/events.js index fa3bf0b021..7f676c4aff 100644 --- a/packages/svelte/src/internal/client/dom/elements/events.js +++ b/packages/svelte/src/internal/client/dom/elements/events.js @@ -141,6 +141,13 @@ export function delegate(events) { } } +// used to store the reference to the currently propagated event +// to prevent garbage collection between microtasks in Firefox +// If the event object is GCed to early, the expando __root property +// set on the event object is lost, causing the event delegation +// to process the event twice +let last_propagated_event = null; + /** * @this {EventTarget} * @param {Event} event @@ -153,6 +160,8 @@ export function handle_event_propagation(event) { var path = event.composedPath?.() || []; var current_target = /** @type {null | Element} */ (path[0] || event.target); + last_propagated_event = event; + // composedPath contains list of nodes the event has propagated through. // We check __root to skip all nodes below it in case this is a // parent of the __root node, which indicates that there's nested