Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cb0f32b

Browse files
committed
fix(core): handle GestureObservers the same as event listeners
1 parent 4a7e40d commit cb0f32b

File tree

3 files changed

+41
-25
lines changed

3 files changed

+41
-25
lines changed

packages/core/ui/core/view/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ export abstract class View extends ViewCommon {
587587
*/
588588
public focus(): boolean;
589589

590-
public getGestureObservers(type: GestureTypes): Array<GesturesObserver>;
590+
public getGestureObservers(type: GestureTypes): Array<GesturesObserver> | undefined;
591591

592592
/**
593593
* Removes listener(s) for the specified event name.

packages/core/ui/core/view/view-common.ts

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,14 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
278278
}
279279
}
280280

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+
282289
if (!this._gestureObservers[type]) {
283290
this._gestureObservers[type] = [];
284291
}
@@ -291,8 +298,10 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
291298
}
292299

293300
public addEventListener(arg: string | GestureTypes, callback: (data: EventData) => void, thisArg?: any) {
301+
thisArg = thisArg || undefined;
302+
294303
if (typeof arg === 'number') {
295-
this._observe(arg, callback as unknown as (data: GestureEventData) => void, thisArg);
304+
this._observe(arg, callback, thisArg);
296305
return;
297306
}
298307

@@ -305,16 +314,18 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
305314

306315
// If it's a gesture (and this Observable declares e.g. `static tapEvent`)
307316
if (gesture && !this._isEvent(normalizedName)) {
308-
this._observe(gesture, callback as unknown as (data: GestureEventData) => void, thisArg);
317+
this._observe(gesture, callback, thisArg);
309318
return;
310319
}
311320

312321
super.addEventListener(normalizedName, callback, thisArg);
313322
}
314323

315324
public removeEventListener(arg: string | GestureTypes, callback?: (data: EventData) => void, thisArg?: any) {
325+
thisArg = thisArg || undefined;
326+
316327
if (typeof arg === 'number') {
317-
this._disconnectGestureObservers(arg);
328+
this._disconnectGestureObservers(arg, callback, thisArg);
318329
return;
319330
}
320331

@@ -327,7 +338,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
327338

328339
// If it's a gesture (and this Observable declares e.g. `static tapEvent`)
329340
if (gesture && !this._isEvent(normalizedName)) {
330-
this._disconnectGestureObservers(gesture);
341+
this._disconnectGestureObservers(gesture, callback, thisArg);
331342
return;
332343
}
333344

@@ -489,14 +500,34 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
489500
return this.constructor && `${name}Event` in this.constructor;
490501
}
491502

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+
493506
const observers = this.getGestureObservers(type);
494507
if (!observers) {
495508
return;
496509
}
497510

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+
499524
observer.disconnect();
525+
observers.splice(i, 1);
526+
i--;
527+
}
528+
529+
if (!observers.length) {
530+
delete this._gestureObservers[type];
500531
}
501532
}
502533

packages/core/ui/gestures/gestures-common.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ export function fromString(type: string): GestureTypes {
354354
export abstract class GesturesObserverBase implements GesturesObserverDefinition {
355355
private _callback: (args: GestureEventData) => void;
356356
private _target: View;
357-
private _context: any;
357+
private _context?: any;
358358

359359
public type: GestureTypes;
360360

@@ -370,7 +370,7 @@ export abstract class GesturesObserverBase implements GesturesObserverDefinition
370370
return this._context;
371371
}
372372

373-
constructor(target: View, callback: (args: GestureEventData) => void, context: any) {
373+
constructor(target: View, callback: (args: GestureEventData) => void, context?: any) {
374374
this._target = target;
375375
this._callback = callback;
376376
this._context = context;
@@ -380,21 +380,6 @@ export abstract class GesturesObserverBase implements GesturesObserverDefinition
380380
public abstract observe(type: GestureTypes);
381381

382382
public disconnect() {
383-
// remove gesture observer from map
384-
if (this.target) {
385-
const list = this.target.getGestureObservers(this.type);
386-
if (list && list.length > 0) {
387-
for (let i = 0; i < list.length; i++) {
388-
if (list[i].callback === this.callback) {
389-
break;
390-
}
391-
}
392-
list.length = 0;
393-
394-
this.target._gestureObservers[this.type] = undefined;
395-
delete this.target._gestureObservers[this.type];
396-
}
397-
}
398383
this._target = null;
399384
this._callback = null;
400385
this._context = null;

0 commit comments

Comments
 (0)