fix(core): clean up event handling in ViewCommon (#10534)

This commit is contained in:
Jamie Birch
2024-05-02 16:03:08 +09:00
committed by GitHub
parent 53e958e623
commit 4a7e40d129

View File

@ -123,7 +123,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
_setMinWidthNative: (value: CoreTypes.LengthType) => void; _setMinWidthNative: (value: CoreTypes.LengthType) => void;
_setMinHeightNative: (value: CoreTypes.LengthType) => void; _setMinHeightNative: (value: CoreTypes.LengthType) => void;
public _gestureObservers = {}; public readonly _gestureObservers = {} as Record<GestureTypes, Array<GesturesObserver>>;
_androidContentDescriptionUpdated?: boolean; _androidContentDescriptionUpdated?: boolean;
@ -177,7 +177,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
onLoaded() { onLoaded() {
if (!this.isLoaded) { if (!this.isLoaded) {
const hasTap = this.hasListeners('tap') || this.hasListeners('tapChange') || this.getGestureObservers(GestureTypes.tap); const hasTap = this.hasListeners('tap') || this.hasListeners('tapChange') || !!this.getGestureObservers(GestureTypes.tap);
const enableTapAnimations = TouchManager.enableGlobalTapAnimations && hasTap; const enableTapAnimations = TouchManager.enableGlobalTapAnimations && hasTap;
if (!this.ignoreTouchAnimation && (this.touchAnimation || enableTapAnimations)) { if (!this.ignoreTouchAnimation && (this.touchAnimation || enableTapAnimations)) {
TouchManager.addAnimations(this); TouchManager.addAnimations(this);
@ -286,62 +286,52 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
this._gestureObservers[type].push(gestureObserve(this, type, callback, thisArg)); this._gestureObservers[type].push(gestureObserve(this, type, callback, thisArg));
} }
public getGestureObservers(type: GestureTypes): Array<GesturesObserver> { public getGestureObservers(type: GestureTypes): Array<GesturesObserver> | undefined {
return this._gestureObservers[type]; return this._gestureObservers[type];
} }
public addEventListener(arg: string | GestureTypes, callback: (data: EventData) => void, thisArg?: any) { public addEventListener(arg: string | GestureTypes, callback: (data: EventData) => void, thisArg?: any) {
if (typeof arg === 'string') { if (typeof arg === 'number') {
arg = getEventOrGestureName(arg); this._observe(arg, callback as unknown as (data: GestureEventData) => void, thisArg);
return;
}
const gesture = gestureFromString(arg); // Normalize "ontap" -> "tap"
if (gesture && !this._isEvent(arg)) { const normalizedName = getEventOrGestureName(arg);
// Coerce "tap" -> GestureTypes.tap
// Coerce "loaded" -> undefined
const gesture: GestureTypes | undefined = gestureFromString(normalizedName);
// If it's a gesture (and this Observable declares e.g. `static tapEvent`)
if (gesture && !this._isEvent(normalizedName)) {
this._observe(gesture, callback as unknown as (data: GestureEventData) => void, thisArg); this._observe(gesture, callback as unknown as (data: GestureEventData) => void, thisArg);
} else { return;
const events = arg.split(',');
if (events.length > 0) {
for (let i = 0; i < events.length; i++) {
const evt = events[i].trim();
const gst = gestureFromString(evt);
if (gst && !this._isEvent(arg)) {
this._observe(gst, callback as unknown as (data: GestureEventData) => void, thisArg);
} else {
super.addEventListener(evt, callback, thisArg);
}
}
} else {
super.addEventListener(arg, callback, thisArg);
}
}
} else if (typeof arg === 'number') {
this._observe(<GestureTypes>arg, callback as unknown as (data: GestureEventData) => void, thisArg);
} }
super.addEventListener(normalizedName, callback, thisArg);
} }
public removeEventListener(arg: string | GestureTypes, callback?: (data: EventData) => void, thisArg?: any) { public removeEventListener(arg: string | GestureTypes, callback?: (data: EventData) => void, thisArg?: any) {
if (typeof arg === 'string') { if (typeof arg === 'number') {
const gesture = gestureFromString(arg); this._disconnectGestureObservers(arg);
if (gesture && !this._isEvent(arg)) { return;
}
// Normalize "ontap" -> "tap"
const normalizedName = getEventOrGestureName(arg);
// Coerce "tap" -> GestureTypes.tap
// Coerce "loaded" -> undefined
const gesture: GestureTypes | undefined = gestureFromString(normalizedName);
// If it's a gesture (and this Observable declares e.g. `static tapEvent`)
if (gesture && !this._isEvent(normalizedName)) {
this._disconnectGestureObservers(gesture); this._disconnectGestureObservers(gesture);
} else { return;
const events = arg.split(',');
if (events.length > 0) {
for (let i = 0; i < events.length; i++) {
const evt = events[i].trim();
const gst = gestureFromString(evt);
if (gst && !this._isEvent(arg)) {
this._disconnectGestureObservers(gst);
} else {
super.removeEventListener(evt, callback, thisArg);
}
}
} else {
super.removeEventListener(arg, callback, thisArg);
}
}
} else if (typeof arg === 'number') {
this._disconnectGestureObservers(<GestureTypes>arg);
} }
super.removeEventListener(normalizedName, callback, thisArg);
} }
public onBackPressed(): boolean { public onBackPressed(): boolean {
@ -501,10 +491,12 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
private _disconnectGestureObservers(type: GestureTypes): void { private _disconnectGestureObservers(type: GestureTypes): void {
const observers = this.getGestureObservers(type); const observers = this.getGestureObservers(type);
if (observers) { if (!observers) {
for (let i = 0; i < observers.length; i++) { return;
observers[i].disconnect();
} }
for (const observer of observers) {
observer.disconnect();
} }
} }