@@ -278,7 +278,14 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
278
278
}
279
279
}
280
280
281
- _observe ( type : GestureTypes , callback : ( args : GestureEventData ) => void , thisArg ?: any ) : void {
281
+ protected _observe ( type : GestureTypes , callback : ( args : GestureEventData ) => void , thisArg ?: any ) : void {
282
+ thisArg = thisArg || undefined ;
283
+
284
+ if ( this . _gestureObservers [ type ] ?. find ( ( observer ) => observer . callback === callback && observer . context === thisArg ) ) {
285
+ // Already added.
286
+ return ;
287
+ }
288
+
282
289
if ( ! this . _gestureObservers [ type ] ) {
283
290
this . _gestureObservers [ type ] = [ ] ;
284
291
}
@@ -291,6 +298,8 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
291
298
}
292
299
293
300
public addEventListener ( eventNames : string , callback : ( data : EventData ) => void , thisArg ?: any ) {
301
+ thisArg = thisArg || undefined ;
302
+
294
303
// Normalize "ontap" -> "tap"
295
304
const normalizedName = getEventOrGestureName ( eventNames ) ;
296
305
@@ -300,14 +309,16 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
300
309
301
310
// If it's a gesture (and this Observable declares e.g. `static tapEvent`)
302
311
if ( gesture && ! this . _isEvent ( normalizedName ) ) {
303
- this . _observe ( gesture , callback as unknown as ( data : GestureEventData ) => void , thisArg ) ;
312
+ this . _observe ( gesture , callback , thisArg ) ;
304
313
return ;
305
314
}
306
315
307
316
super . addEventListener ( normalizedName , callback , thisArg ) ;
308
317
}
309
318
310
319
public removeEventListener ( eventNames : string , callback ?: ( data : EventData ) => void , thisArg ?: any ) {
320
+ thisArg = thisArg || undefined ;
321
+
311
322
// Normalize "ontap" -> "tap"
312
323
const normalizedName = getEventOrGestureName ( eventNames ) ;
313
324
@@ -317,7 +328,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
317
328
318
329
// If it's a gesture (and this Observable declares e.g. `static tapEvent`)
319
330
if ( gesture && ! this . _isEvent ( normalizedName ) ) {
320
- this . _disconnectGestureObservers ( gesture ) ;
331
+ this . _disconnectGestureObservers ( gesture , callback , thisArg ) ;
321
332
return ;
322
333
}
323
334
@@ -479,14 +490,34 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
479
490
return this . constructor && `${ name } Event` in this . constructor ;
480
491
}
481
492
482
- private _disconnectGestureObservers ( type : GestureTypes ) : void {
493
+ private _disconnectGestureObservers ( type : GestureTypes , callback ?: ( data : EventData ) => void , thisArg ?: any ) : void {
494
+ // Largely mirrors the implementation of Observable.innerRemoveEventListener().
495
+
483
496
const observers = this . getGestureObservers ( type ) ;
484
497
if ( ! observers ) {
485
498
return ;
486
499
}
487
500
488
- for ( const observer of observers ) {
501
+ for ( let i = 0 ; i < observers . length ; i ++ ) {
502
+ const observer = observers [ i ] ;
503
+
504
+ // If we have a `thisArg`, refine on both `callback` and `thisArg`.
505
+ if ( thisArg && ( observer . callback !== callback || observer . context !== thisArg ) ) {
506
+ continue ;
507
+ }
508
+
509
+ // If we don't have a `thisArg`, refine only on `callback`.
510
+ if ( callback && observer . callback !== callback ) {
511
+ continue ;
512
+ }
513
+
489
514
observer . disconnect ( ) ;
515
+ observers . splice ( i , 1 ) ;
516
+ i -- ;
517
+ }
518
+
519
+ if ( ! observers . length ) {
520
+ delete this . _gestureObservers [ type ] ;
490
521
}
491
522
}
492
523
0 commit comments