Skip to content

Commit

Permalink
fix: prevent window listeners from triggering events twice (sveltejs#…
Browse files Browse the repository at this point in the history
…10611)

fixes sveltejs#10271
The prior fix in sveltejs#10307 wasn't quite right, because JSDom has a difference between window and event.composedPath which sounds like a bug, and a workaround in that PR made it so the test did pass when the bug still occurred. That's also why there isn't a test here, because we can't properly test this using JSDom.
  • Loading branch information
xxkl1 committed Feb 23, 2024
1 parent 45e3857 commit fc6666b
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/fresh-impalas-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte": patch
---

fix: prevent window listeners from triggering events twice
15 changes: 9 additions & 6 deletions packages/svelte/src/internal/client/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,7 @@ export function delegate(events) {
* @returns {void}
*/
function handle_event_propagation(handler_element, event) {
const owner_document = handler_element.ownerDocument;
const event_name = event.type;
const path = event.composedPath?.() || [];
let current_target = /** @type {null | Element} */ (path[0] || event.target);
Expand All @@ -1420,12 +1421,15 @@ function handle_event_propagation(handler_element, event) {
const handled_at = event.__root;
if (handled_at) {
const at_idx = path.indexOf(handled_at);
if (at_idx !== -1 && handler_element === document) {
// This is the fallback document listener but the event was already handled
// -> ignore, but set handle_at to document so that we're resetting the event
if (
at_idx !== -1 &&
(handler_element === document || handler_element === /** @type {any} */ (window))
) {
// This is the fallback document listener or a window listener, but the event was already handled
// -> ignore, but set handle_at to document/window so that we're resetting the event
// chain in case someone manually dispatches the same event object again.
// @ts-expect-error
event.__root = document;
event.__root = handler_element;
return;
}
// We're deliberately not skipping if the index is higher, because
Expand All @@ -1451,8 +1455,7 @@ function handle_event_propagation(handler_element, event) {
define_property(event, 'currentTarget', {
configurable: true,
get() {
// TODO: ensure correct document?
return current_target || document;
return current_target || owner_document;
}
});

Expand Down

0 comments on commit fc6666b

Please sign in to comment.