@@ -15,6 +15,7 @@ let $openModal: Modal|undefined = undefined;
1515let lastFocusElement : HTMLElement | undefined = undefined ;
1616
1717const TITLE_ID = 'boost-modal-title' ;
18+ const elementsWithModalListeners = new WeakSet ( ) ;
1819
1920function tryClose ( ) {
2021 if ( $openModal && $openModal . canClose ) $openModal . close ( ) ;
@@ -51,12 +52,12 @@ export class Modal extends CustomElementView {
5152 this . $video = this . $ ( 'video' ) as MediaView | undefined ;
5253
5354 const $buttons = $$ ( `[data-modal=${ this . id } ]` ) ;
54- for ( const $b of $buttons ) $b . on ( 'click' , ( ) => this . open ( ) ) ;
55+ for ( const $b of $buttons ) this . attachListener ( $b ) ;
5556
5657 // Look for new modals to open, after browser navigation.
5758 Router . on ( 'afterChange' , ( { $viewport} ) => {
5859 const $buttons = $viewport . $$ ( `[data-modal=${ this . id } ]` ) ;
59- for ( const $b of $buttons ) $b . on ( 'click' , ( ) => this . open ( ) ) ;
60+ for ( const $b of $buttons ) this . attachListener ( $b ) ;
6061 } ) ;
6162
6263 // Open modals that are shown on pageload
@@ -90,6 +91,26 @@ export class Modal extends CustomElementView {
9091 } ) ;
9192 }
9293
94+ /**
95+ * Attaches a click listener to an element with data-modal attribute, if there isn't one already.
96+ */
97+ attachListener ( $button : ElementView ) {
98+ if ( elementsWithModalListeners . has ( $button . _el ) ) return ;
99+
100+ $button . on ( 'click' , ( ) => this . open ( ) ) ;
101+ elementsWithModalListeners . add ( $button . _el ) ;
102+ }
103+
104+ /**
105+ * Removes the click listener from an element
106+ */
107+ removeListener ( $button : ElementView ) {
108+ if ( ! elementsWithModalListeners . has ( $button . _el ) ) return ;
109+
110+ $button . off ( 'click' ) ;
111+ elementsWithModalListeners . delete ( $button . _el ) ;
112+ }
113+
93114 open ( noAnimation = false ) {
94115 if ( this . isOpen ) return ;
95116
0 commit comments