@@ -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,8 +298,10 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
291
298
}
292
299
293
300
public addEventListener ( arg : string | GestureTypes , callback : ( data : EventData ) => void , thisArg ?: any ) {
301
+ thisArg = thisArg || undefined ;
302
+
294
303
if ( typeof arg === 'number' ) {
295
- this . _observe ( arg , callback as unknown as ( data : GestureEventData ) => void , thisArg ) ;
304
+ this . _observe ( arg , callback , thisArg ) ;
296
305
return ;
297
306
}
298
307
@@ -305,16 +314,18 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
305
314
306
315
// If it's a gesture (and this Observable declares e.g. `static tapEvent`)
307
316
if ( gesture && ! this . _isEvent ( normalizedName ) ) {
308
- this . _observe ( gesture , callback as unknown as ( data : GestureEventData ) => void , thisArg ) ;
317
+ this . _observe ( gesture , callback , thisArg ) ;
309
318
return ;
310
319
}
311
320
312
321
super . addEventListener ( normalizedName , callback , thisArg ) ;
313
322
}
314
323
315
324
public removeEventListener ( arg : string | GestureTypes , callback ?: ( data : EventData ) => void , thisArg ?: any ) {
325
+ thisArg = thisArg || undefined ;
326
+
316
327
if ( typeof arg === 'number' ) {
317
- this . _disconnectGestureObservers ( arg ) ;
328
+ this . _disconnectGestureObservers ( arg , callback , thisArg ) ;
318
329
return ;
319
330
}
320
331
@@ -327,7 +338,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
327
338
328
339
// If it's a gesture (and this Observable declares e.g. `static tapEvent`)
329
340
if ( gesture && ! this . _isEvent ( normalizedName ) ) {
330
- this . _disconnectGestureObservers ( gesture ) ;
341
+ this . _disconnectGestureObservers ( gesture , callback , thisArg ) ;
331
342
return ;
332
343
}
333
344
@@ -489,14 +500,34 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
489
500
return this . constructor && `${ name } Event` in this . constructor ;
490
501
}
491
502
492
- private _disconnectGestureObservers ( type : GestureTypes ) : void {
503
+ private _disconnectGestureObservers ( type : GestureTypes , callback ?: ( data : EventData ) => void , thisArg ?: any ) : void {
504
+ // Largely mirrors the implementation of Observable.innerRemoveEventListener().
505
+
493
506
const observers = this . getGestureObservers ( type ) ;
494
507
if ( ! observers ) {
495
508
return ;
496
509
}
497
510
498
- for ( const observer of observers ) {
511
+ for ( let i = 0 ; i < observers . length ; i ++ ) {
512
+ const observer = observers [ i ] ;
513
+
514
+ // If we have a `thisArg`, refine on both `callback` and `thisArg`.
515
+ if ( thisArg && ( observer . callback !== callback || observer . context !== thisArg ) ) {
516
+ continue ;
517
+ }
518
+
519
+ // If we don't have a `thisArg`, refine only on `callback`.
520
+ if ( callback && observer . callback !== callback ) {
521
+ continue ;
522
+ }
523
+
499
524
observer . disconnect ( ) ;
525
+ observers . splice ( i , 1 ) ;
526
+ i -- ;
527
+ }
528
+
529
+ if ( ! observers . length ) {
530
+ delete this . _gestureObservers [ type ] ;
500
531
}
501
532
}
502
533
0 commit comments