@@ -101,6 +101,8 @@ class ModeWidget {
101101 this . widgetWindow . clear ( ) ;
102102 this . widgetWindow . show ( ) ;
103103
104+ this . _timeouts = [ ] ;
105+
104106 // The mode table (holds a pie menu and a label)
105107 this . modeTableDiv = document . createElement ( "div" ) ;
106108 this . modeTableDiv . style . display = "inline" ;
@@ -113,6 +115,10 @@ class ModeWidget {
113115 this . widgetWindow . getWidgetBody ( ) . append ( this . modeTableDiv ) ;
114116
115117 this . widgetWindow . onclose = ( ) => {
118+ if ( this . _timeouts ) {
119+ this . _timeouts . forEach ( id => clearTimeout ( id ) ) ;
120+ this . _timeouts = [ ] ;
121+ }
116122 this . _playing = false ;
117123 this . hideMsgs ( ) ;
118124 this . widgetWindow . destroy ( ) ;
@@ -194,7 +200,22 @@ class ModeWidget {
194200
195201 //.TRANS: A circle of notes represents the musical mode.
196202 activity . textMsg ( _ ( "Click in the circle to select notes for the mode." ) , 3000 ) ;
197- setTimeout ( ( ) => this . widgetWindow . sendToCenter ( ) , 0 ) ;
203+ this . _setTimeout ( ( ) => this . widgetWindow . sendToCenter ( ) , 0 ) ;
204+ }
205+
206+ /**
207+ * @private
208+ * @param {Function } fn - function to execute
209+ * @param {number } delay - delay in milliseconds
210+ * @returns {number } timeout ID
211+ */
212+ _setTimeout ( fn , delay ) {
213+ const id = setTimeout ( ( ) => {
214+ this . _timeouts = this . _timeouts . filter ( t => t !== id ) ;
215+ fn ( ) ;
216+ } , delay ) ;
217+ this . _timeouts . push ( id ) ;
218+ return id ;
198219 }
199220
200221 /**
@@ -258,7 +279,7 @@ class ModeWidget {
258279 svg . style . pointerEvents = "none" ;
259280 svg . setAttribute ( "height" , `${ 400 * scale } px` ) ;
260281 svg . setAttribute ( "width" , `${ 400 * scale } px` ) ;
261- setTimeout ( ( ) => {
282+ this . _setTimeout ( ( ) => {
262283 svg . style . pointerEvents = "auto" ;
263284 } , 100 ) ;
264285 }
@@ -427,7 +448,7 @@ class ModeWidget {
427448 }
428449 this . _locked = false ;
429450 } else {
430- setTimeout ( ( ) => {
451+ this . _setTimeout ( ( ) => {
431452 this . __invertOnePair ( i + 1 ) ;
432453 } , ModeWidget . ROTATESPEED ) ;
433454 }
@@ -480,7 +501,7 @@ class ModeWidget {
480501 }
481502
482503 if ( i === 0 ) {
483- setTimeout ( ( ) => {
504+ this . _setTimeout ( ( ) => {
484505 if ( this . _selectedNotes [ 0 ] ) {
485506 // We are done.
486507 this . _saveState ( ) ;
@@ -499,7 +520,7 @@ class ModeWidget {
499520 }
500521 } , ModeWidget . ROTATESPEED ) ;
501522 } else {
502- setTimeout ( ( ) => {
523+ this . _setTimeout ( ( ) => {
503524 this . __rotateRightOneCell ( ( i + 1 ) % 12 ) ;
504525 } , ModeWidget . ROTATESPEED ) ;
505526 }
@@ -541,7 +562,7 @@ class ModeWidget {
541562 }
542563
543564 if ( i === 0 ) {
544- setTimeout ( ( ) => {
565+ this . _setTimeout ( ( ) => {
545566 if ( this . _selectedNotes [ 0 ] ) {
546567 // We are done.
547568 this . _saveState ( ) ;
@@ -560,7 +581,7 @@ class ModeWidget {
560581 }
561582 } , ModeWidget . ROTATESPEED ) ;
562583 } else {
563- setTimeout ( ( ) => {
584+ this . _setTimeout ( ( ) => {
564585 this . __rotateLeftOneCell ( i - 1 ) ;
565586 } , ModeWidget . ROTATESPEED ) ;
566587 }
@@ -647,7 +668,7 @@ class ModeWidget {
647668 const currentKey = keySignatureToMode ( this . turtles . ithTurtle ( 0 ) . singer . keySignature ) [ 0 ] ;
648669 if ( currentKey === "C" ) {
649670 if ( i > this . _notesToPlay . length - 1 ) {
650- setTimeout ( ( ) => {
671+ this . _setTimeout ( ( ) => {
651672 // Did we just play the last note?
652673 this . _playing = false ;
653674 const note_key = this . _pianoKeys ? this . _pianoKeys [ 0 ] : null ;
@@ -669,7 +690,7 @@ class ModeWidget {
669690 return ;
670691 }
671692
672- setTimeout ( ( ) => {
693+ this . _setTimeout ( ( ) => {
673694 if ( this . _lastNotePlayed !== null ) {
674695 this . _playWheel . navItems [ this . _lastNotePlayed % 12 ] . navItem . hide ( ) ;
675696 const note_key = this . _pianoKeys
@@ -707,13 +728,13 @@ class ModeWidget {
707728 this . __playNextNote ( i + 1 ) ;
708729 } else {
709730 this . _locked = false ;
710- setTimeout ( ( ) => this . _resetNotes ( ) , ModeWidget . RESET_NOTES_DELAY ) ;
731+ this . _setTimeout ( ( ) => this . _resetNotes ( ) , ModeWidget . RESET_NOTES_DELAY ) ;
711732 return ;
712733 }
713734 } , 1000 * time ) ;
714735 } else {
715736 if ( i > this . _notesToPlay . length - 1 ) {
716- setTimeout ( ( ) => {
737+ this . _setTimeout ( ( ) => {
717738 // Did we just play the last note?
718739 this . _playing = false ;
719740 this . _playButton . innerHTML = ` <img
@@ -731,7 +752,7 @@ class ModeWidget {
731752 return ;
732753 }
733754
734- setTimeout ( ( ) => {
755+ this . _setTimeout ( ( ) => {
735756 if ( this . _lastNotePlayed !== null ) {
736757 this . _playWheel . navItems [ this . _lastNotePlayed % 12 ] . navItem . hide ( ) ;
737758 }
@@ -754,7 +775,7 @@ class ModeWidget {
754775 this . __playNextNote ( i + 1 ) ;
755776 } else {
756777 this . _locked = false ;
757- setTimeout ( ( ) => this . _resetNotes ( ) , ModeWidget . RESET_NOTES_DELAY ) ;
778+ this . _setTimeout ( ( ) => this . _resetNotes ( ) , ModeWidget . RESET_NOTES_DELAY ) ;
758779 return ;
759780 }
760781 } , 1000 * time ) ;
@@ -1075,7 +1096,7 @@ class ModeWidget {
10751096
10761097 // Create a new stack for the chunk.
10771098 // console.debug(newStack);
1078- setTimeout ( ( ) => {
1099+ this . _setTimeout ( ( ) => {
10791100 this . blocks . loadNewBlocks ( newStack ) ;
10801101 } , 2000 ) ;
10811102 }
0 commit comments