Skip to content

Commit 94a2bca

Browse files
7nikdummdidumm
andauthored
fix: cleanup event handlers on media elements (#16005)
Co-authored-by: 7nik <kifiranet@gmail.com> Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
1 parent fbb6444 commit 94a2bca

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

.changeset/thin-dolls-cover.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: cleanup event handlers on media elements

packages/svelte/src/internal/client/dom/elements/events.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,15 @@ export function event(event_name, dom, handler, capture, passive) {
112112
var options = { capture, passive };
113113
var target_handler = create_event(event_name, dom, handler, options);
114114

115-
// @ts-ignore
116-
if (dom === document.body || dom === window || dom === document) {
115+
if (
116+
dom === document.body ||
117+
// @ts-ignore
118+
dom === window ||
119+
// @ts-ignore
120+
dom === document ||
121+
// Firefox has quirky behavior, it can happen that we still get "canplay" events when the element is already removed
122+
dom instanceof HTMLMediaElement
123+
) {
117124
teardown(() => {
118125
dom.removeEventListener(event_name, target_handler, options);
119126
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
import { expect, vi } from 'vitest';
4+
5+
const handler = vi.fn();
6+
7+
export default test({
8+
props: {
9+
handler
10+
},
11+
async test({ target }) {
12+
const button = target.querySelector('button');
13+
const video = target.querySelector('video');
14+
15+
button?.click();
16+
flushSync();
17+
video?.dispatchEvent(new Event('someevent'));
18+
expect(handler).not.toHaveBeenCalled();
19+
}
20+
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
const { handler } = $props();
3+
let show = $state(true);
4+
</script>
5+
6+
<button onclick={() => show = false}>show/hide</button>
7+
{#if show}
8+
<video onsomeevent={handler}></video>
9+
{/if}

0 commit comments

Comments
 (0)