Skip to content

Commit 00440ee

Browse files
nochevmister-benEssk
authored
fix(track-button): properly remove event listeners on dispose to prevent leaks and runtime errors (#9101)
Co-authored-by: mister-ben <1676039+mister-ben@users.noreply.github.com> Co-authored-by: Essk <sarah@teaandbiscuits.net>
1 parent 69ea0e0 commit 00440ee

1 file changed

Lines changed: 47 additions & 12 deletions

File tree

src/js/control-bar/track-button.js

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,55 @@ class TrackButton extends MenuButton {
3636
return;
3737
}
3838

39-
const updateHandler = Fn.bind_(this, this.update);
40-
41-
tracks.addEventListener('removetrack', updateHandler);
42-
tracks.addEventListener('addtrack', updateHandler);
43-
tracks.addEventListener('labelchange', updateHandler);
44-
this.player_.on('ready', updateHandler);
45-
46-
this.player_.on('dispose', function() {
47-
tracks.removeEventListener('removetrack', updateHandler);
48-
tracks.removeEventListener('addtrack', updateHandler);
49-
tracks.removeEventListener('labelchange', updateHandler);
50-
});
39+
this.updateHandler_ = Fn.bind_(this, this.update);
40+
this.cleanupHandler_ = Fn.bind_(this, this.cleanupTrackListeners_);
41+
42+
tracks.addEventListener('removetrack', this.updateHandler_);
43+
tracks.addEventListener('addtrack', this.updateHandler_);
44+
tracks.addEventListener('labelchange', this.updateHandler_);
45+
46+
this.player_.on('ready', this.updateHandler_);
47+
this.player_.on('dispose', this.cleanupHandler_);
48+
}
49+
50+
/**
51+
* Remove all track list event listeners without triggering a full dispose.
52+
* Used as the player 'dispose' handler and called by dispose() before super.
53+
*
54+
* @private
55+
*/
56+
cleanupTrackListeners_() {
57+
if (!this.updateHandler_) {
58+
return;
59+
}
60+
61+
const tracks = this.options_.tracks;
62+
63+
if (tracks) {
64+
tracks.removeEventListener('removetrack', this.updateHandler_);
65+
tracks.removeEventListener('addtrack', this.updateHandler_);
66+
tracks.removeEventListener('labelchange', this.updateHandler_);
67+
}
68+
69+
if (this.player_) {
70+
this.player_.off('ready', this.updateHandler_);
71+
this.player_.off('dispose', this.cleanupHandler_);
72+
}
73+
74+
this.updateHandler_ = null;
75+
this.cleanupHandler_ = null;
5176
}
5277

78+
/**
79+
* Dispose of the Component and remove all event listeners.
80+
*
81+
* @override
82+
*/
83+
dispose() {
84+
this.cleanupTrackListeners_();
85+
86+
super.dispose();
87+
}
5388
}
5489

5590
Component.registerComponent('TrackButton', TrackButton);

0 commit comments

Comments
 (0)