Skip to content

Commit 485fb61

Browse files
authored
fix(core): Observable event types consistency (#10181)
1 parent a7f1305 commit 485fb61

File tree

39 files changed

+380
-435
lines changed

39 files changed

+380
-435
lines changed
Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,75 @@
1-
21
import { Observable } from '../data/observable';
32

43
// Known Limitation
54
// Use `any` because the type of `AbortSignal` in `lib.dom.d.ts` is wrong and
65
// to make assignable our `AbortSignal` into that.
76
// https://github.com/Microsoft/TSJS-lib-generator/pull/623
87
type Events = {
9-
abort: any // Event & Type<"abort">
10-
}
8+
abort: any; // Event & Type<"abort">
9+
};
1110
type EventAttributes = {
12-
onabort: any // Event & Type<"abort">
13-
}
11+
onabort: any; // Event & Type<"abort">
12+
};
1413

1514
/**
1615
* The signal class.
1716
* @see https://dom.spec.whatwg.org/#abortsignal
1817
*/
1918
export default class AbortSignal extends Observable {
20-
/**
21-
* AbortSignal cannot be constructed directly.
22-
*/
23-
public constructor() {
24-
super()
25-
}
19+
/**
20+
* AbortSignal cannot be constructed directly.
21+
*/
22+
public constructor() {
23+
super();
24+
}
2625

27-
/**
28-
* Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise.
29-
*/
30-
public get aborted(): boolean {
31-
const aborted = abortedFlags.get(this)
32-
if (typeof aborted !== "boolean") {
33-
throw new TypeError(
34-
`Expected 'this' to be an 'AbortSignal' object, but got ${
35-
this === null ? "null" : typeof this
36-
}`,
37-
)
38-
}
39-
return aborted
40-
}
26+
/**
27+
* Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise.
28+
*/
29+
public get aborted(): boolean {
30+
const aborted = abortedFlags.get(this);
31+
if (typeof aborted !== 'boolean') {
32+
throw new TypeError(`Expected 'this' to be an 'AbortSignal' object, but got ${this === null ? 'null' : typeof this}`);
33+
}
34+
return aborted;
35+
}
4136
}
4237

4338
/**
4439
* Create an AbortSignal object.
4540
*/
4641
export function createAbortSignal(): AbortSignal {
47-
const signal = new AbortSignal();
48-
abortedFlags.set(signal, false)
49-
return signal
42+
const signal = new AbortSignal();
43+
abortedFlags.set(signal, false);
44+
return signal;
5045
}
5146

5247
/**
5348
* Abort a given signal.
5449
*/
5550
export function abortSignal(signal: AbortSignal): void {
56-
if (abortedFlags.get(signal) !== false) {
57-
return
58-
}
51+
if (abortedFlags.get(signal) !== false) {
52+
return;
53+
}
5954

60-
abortedFlags.set(signal, true)
61-
signal.notify({ eventName: "abort", type: "abort" })
55+
abortedFlags.set(signal, true);
56+
signal.notify({ eventName: 'abort', type: 'abort' });
6257
}
6358

6459
/**
6560
* Aborted flag for each instances.
6661
*/
67-
const abortedFlags = new WeakMap<AbortSignal, boolean>()
62+
const abortedFlags = new WeakMap<AbortSignal, boolean>();
6863

6964
// Properties should be enumerable.
7065
Object.defineProperties(AbortSignal.prototype, {
71-
aborted: { enumerable: true },
72-
})
66+
aborted: { enumerable: true },
67+
});
7368

7469
// `toString()` should return `"[object AbortSignal]"`
75-
if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") {
76-
Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, {
77-
configurable: true,
78-
value: "AbortSignal",
79-
})
80-
}
70+
if (typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol') {
71+
Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, {
72+
configurable: true,
73+
value: 'AbortSignal',
74+
});
75+
}

packages/core/accessibility/accessibility-common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const accessibilityPerformEscapeEvent = 'accessibilityPerformEscape';
1919
* @param {boolean} receivedFocus
2020
* @param {boolean} lostFocus
2121
*/
22-
export function notifyAccessibilityFocusState(view: Partial<View>, receivedFocus: boolean, lostFocus: boolean): void {
22+
export function notifyAccessibilityFocusState(view: View, receivedFocus: boolean, lostFocus: boolean): void {
2323
if (!receivedFocus && !lostFocus) {
2424
return;
2525
}

packages/core/accessibility/font-scale.android.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { ApplicationEventData } from '../application';
12
import * as Application from '../application';
23
import { FontScaleCategory, getClosestValidFontScale } from './font-scale-common';
34
export * from './font-scale-common';
@@ -12,7 +13,7 @@ function fontScaleChanged(origFontScale: number) {
1213
eventName: Application.fontScaleChangedEvent,
1314
object: Application,
1415
newValue: currentFontScale,
15-
});
16+
} as ApplicationEventData);
1617
}
1718
}
1819

packages/core/accessibility/index.android.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export * from './font-scale';
1313

1414
let clickableRolesMap = new Set<string>();
1515

16-
let lastFocusedView: WeakRef<Partial<View>>;
17-
function accessibilityEventHelper(view: Partial<View>, eventType: number) {
16+
let lastFocusedView: WeakRef<View>;
17+
function accessibilityEventHelper(view: View, eventType: number) {
1818
const eventName = accessibilityEventTypeMap.get(eventType);
1919
if (!isAccessibilityServiceEnabled()) {
2020
if (Trace.isEnabled()) {
@@ -103,7 +103,7 @@ function accessibilityEventHelper(view: Partial<View>, eventType: number) {
103103

104104
let TNSAccessibilityDelegate: android.view.View.androidviewViewAccessibilityDelegate;
105105

106-
const androidViewToTNSView = new WeakMap<android.view.View, WeakRef<Partial<View>>>();
106+
const androidViewToTNSView = new WeakMap<android.view.View, WeakRef<View>>();
107107

108108
let accessibilityEventMap: Map<AndroidAccessibilityEvent, number>;
109109
let accessibilityEventTypeMap: Map<number, string>;
@@ -438,11 +438,11 @@ export function isAccessibilityServiceEnabled(): boolean {
438438
return accessibilityServiceEnabled;
439439
}
440440

441-
export function setupAccessibleView(view: Partial<View>): void {
441+
export function setupAccessibleView(view: View): void {
442442
updateAccessibilityProperties(view);
443443
}
444444

445-
export function updateAccessibilityProperties(view: Partial<View>): void {
445+
export function updateAccessibilityProperties(view: View): void {
446446
if (!view.nativeViewProtected) {
447447
return;
448448
}
@@ -538,7 +538,7 @@ export function updateContentDescription(view: View, forceUpdate?: boolean): str
538538
return applyContentDescription(view, forceUpdate);
539539
}
540540

541-
function setAccessibilityDelegate(view: Partial<View>): void {
541+
function setAccessibilityDelegate(view: View): void {
542542
if (!view.nativeViewProtected) {
543543
return;
544544
}
@@ -564,7 +564,7 @@ function setAccessibilityDelegate(view: Partial<View>): void {
564564
androidView.setAccessibilityDelegate(TNSAccessibilityDelegate);
565565
}
566566

567-
function applyContentDescription(view: Partial<View>, forceUpdate?: boolean) {
567+
function applyContentDescription(view: View, forceUpdate?: boolean) {
568568
let androidView = view.nativeViewProtected as android.view.View;
569569
if (!androidView || (androidView instanceof android.widget.TextView && !view._androidContentDescriptionUpdated)) {
570570
return null;

packages/core/accessibility/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export * from './font-scale';
99
/**
1010
* Initialize accessibility for View. This should be called on loaded-event.
1111
*/
12-
export function setupAccessibleView(view: Partial<View>): void;
12+
export function setupAccessibleView(view: View): void;
1313

1414
/**
1515
* Update accessibility properties on nativeView

packages/core/application/application-common.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import '../globals';
33

44
// Types
5+
import type * as IApplication from '.';
56
import { AndroidApplication, iOSApplication } from '.';
67
import { CssChangedEventData, DiscardedErrorEventData, LoadAppCSSEventData, UnhandledErrorEventData } from './application-interfaces';
7-
import { EventData } from '../data/observable';
88
import { View } from '../ui/core/view';
99

1010
// Requires
@@ -50,10 +50,10 @@ export function setResources(res: any) {
5050
export const android: AndroidApplication = undefined;
5151
export const ios: iOSApplication = undefined;
5252

53-
export const on = global.NativeScriptGlobals.events.on.bind(global.NativeScriptGlobals.events);
54-
export const off = global.NativeScriptGlobals.events.off.bind(global.NativeScriptGlobals.events);
55-
export const notify = global.NativeScriptGlobals.events.notify.bind(global.NativeScriptGlobals.events);
56-
export const hasListeners = global.NativeScriptGlobals.events.hasListeners.bind(global.NativeScriptGlobals.events);
53+
export const on = global.NativeScriptGlobals.events.on.bind(global.NativeScriptGlobals.events) as typeof IApplication.on;
54+
export const off = global.NativeScriptGlobals.events.off.bind(global.NativeScriptGlobals.events) as typeof IApplication.off;
55+
export const notify = global.NativeScriptGlobals.events.notify.bind(global.NativeScriptGlobals.events) as typeof IApplication.notify;
56+
export const hasListeners = global.NativeScriptGlobals.events.hasListeners.bind(global.NativeScriptGlobals.events) as typeof IApplication.hasListeners;
5757

5858
let app: iOSApplication | AndroidApplication;
5959
export function setApplication(instance: iOSApplication | AndroidApplication): void {
@@ -63,7 +63,7 @@ export function setApplication(instance: iOSApplication | AndroidApplication): v
6363
}
6464

6565
export function livesync(rootView: View, context?: ModuleContext) {
66-
global.NativeScriptGlobals.events.notify(<EventData>{ eventName: 'livesync', object: app });
66+
notify({ eventName: 'livesync', object: app });
6767
const liveSyncCore = global.__onLiveSyncCore;
6868
let reapplyAppStyles = false;
6969

@@ -85,7 +85,7 @@ export function livesync(rootView: View, context?: ModuleContext) {
8585

8686
export function setCssFileName(cssFileName: string) {
8787
cssFile = cssFileName;
88-
global.NativeScriptGlobals.events.notify(<CssChangedEventData>{
88+
notify(<CssChangedEventData>{
8989
eventName: 'cssChanged',
9090
object: app,
9191
cssFile: cssFileName,
@@ -98,7 +98,7 @@ export function getCssFileName(): string {
9898

9999
export function loadAppCss(): void {
100100
try {
101-
global.NativeScriptGlobals.events.notify(<LoadAppCSSEventData>{
101+
notify(<LoadAppCSSEventData>{
102102
eventName: 'loadAppCss',
103103
object: app,
104104
cssFile: getCssFileName(),
@@ -181,7 +181,7 @@ export function setSuspended(value: boolean): void {
181181
}
182182

183183
global.__onUncaughtError = function (error: NativeScriptError) {
184-
global.NativeScriptGlobals.events.notify(<UnhandledErrorEventData>{
184+
notify(<UnhandledErrorEventData>{
185185
eventName: uncaughtErrorEvent,
186186
object: app,
187187
android: error,
@@ -191,7 +191,7 @@ global.__onUncaughtError = function (error: NativeScriptError) {
191191
};
192192

193193
global.__onDiscardedError = function (error: NativeScriptError) {
194-
global.NativeScriptGlobals.events.notify(<DiscardedErrorEventData>{
194+
notify(<DiscardedErrorEventData>{
195195
eventName: discardedErrorEvent,
196196
object: app,
197197
error: error,

packages/core/application/application-interfaces.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,45 @@ export interface NativeScriptError extends Error {
1313
}
1414

1515
export interface ApplicationEventData extends EventData {
16+
/**
17+
* UIApplication or undefined, unless otherwise specified. Prefer explicit
18+
* properties where possible.
19+
*/
1620
ios?: any;
21+
/**
22+
* androidx.appcompat.app.AppCompatActivity or undefined, unless otherwise
23+
* specified. Prefer explicit properties where possible.
24+
*/
1725
android?: any;
18-
eventName: string;
26+
/**
27+
* Careful with this messy type. A significant refactor is needed to make it
28+
* strictly extend EventData['object'], which is an Observable. It's used in
29+
* various ways:
30+
* - By font-scale: the Application module, typeof import('.')
31+
* - Within index.android.ts: AndroidApplication
32+
* - Within index.ios.ts: iOSApplication
33+
*/
1934
object: any;
2035
}
2136

2237
export interface LaunchEventData extends ApplicationEventData {
38+
/**
39+
* The value stored into didFinishLaunchingWithOptions notification's
40+
* userInfo under 'UIApplicationLaunchOptionsLocalNotificationKey';
41+
* otherwise, null.
42+
*/
43+
ios: unknown;
2344
root?: View | null;
2445
savedInstanceState?: any /* android.os.Bundle */;
2546
}
2647

2748
export interface OrientationChangedEventData extends ApplicationEventData {
49+
android: any /* globalAndroid.app.Application */;
2850
newValue: 'portrait' | 'landscape' | 'unknown';
2951
}
3052

3153
export interface SystemAppearanceChangedEventData extends ApplicationEventData {
54+
android: any /* globalAndroid.app.Application */;
3255
newValue: 'light' | 'dark';
3356
}
3457

@@ -42,15 +65,14 @@ export interface DiscardedErrorEventData extends ApplicationEventData {
4265
error: NativeScriptError;
4366
}
4467

45-
export interface CssChangedEventData extends EventData {
68+
export interface CssChangedEventData extends ApplicationEventData {
4669
cssFile?: string;
4770
cssText?: string;
4871
}
4972

50-
export interface AndroidActivityEventData {
73+
export interface AndroidActivityEventData extends ApplicationEventData {
5174
activity: any /* androidx.appcompat.app.AppCompatActivity */;
52-
eventName: string;
53-
object: any;
75+
object: any /* AndroidApplication */;
5476
}
5577

5678
export interface AndroidActivityBundleEventData extends AndroidActivityEventData {
@@ -84,6 +106,6 @@ export interface RootViewControllerImpl {
84106
contentController: any;
85107
}
86108

87-
export interface LoadAppCSSEventData extends EventData {
109+
export interface LoadAppCSSEventData extends ApplicationEventData {
88110
cssFile: string;
89111
}

packages/core/application/index.android.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { AndroidActivityBackPressedEventData, AndroidActivityBundleEventData, An
44

55
// TODO: explain why we need to this or remov it
66
// Use requires to ensure order of imports is maintained
7-
const appCommon = require('./application-common');
7+
const appCommon = require('./application-common') as typeof import('./application-common');
88

99
// First reexport so that app module is initialized.
1010
export * from './application-common';
@@ -163,18 +163,18 @@ export class AndroidApplication extends Observable implements AndroidApplication
163163
// HACK: We declare all these 'on' statements, so that they can appear in the API reference
164164
// HACK: Do we need this? Is it useful? There are static fields to the AndroidApplication class for the event names.
165165
export interface AndroidApplication {
166-
on(eventNames: string, callback: (data: AndroidActivityEventData) => void, thisArg?: any);
167-
on(event: 'activityCreated', callback: (args: AndroidActivityBundleEventData) => void, thisArg?: any);
168-
on(event: 'activityDestroyed', callback: (args: AndroidActivityEventData) => void, thisArg?: any);
169-
on(event: 'activityStarted', callback: (args: AndroidActivityEventData) => void, thisArg?: any);
170-
on(event: 'activityPaused', callback: (args: AndroidActivityEventData) => void, thisArg?: any);
171-
on(event: 'activityResumed', callback: (args: AndroidActivityEventData) => void, thisArg?: any);
172-
on(event: 'activityStopped', callback: (args: AndroidActivityEventData) => void, thisArg?: any);
173-
on(event: 'saveActivityState', callback: (args: AndroidActivityBundleEventData) => void, thisArg?: any);
174-
on(event: 'activityResult', callback: (args: AndroidActivityResultEventData) => void, thisArg?: any);
175-
on(event: 'activityBackPressed', callback: (args: AndroidActivityBackPressedEventData) => void, thisArg?: any);
176-
on(event: 'activityNewIntent', callback: (args: AndroidActivityNewIntentEventData) => void, thisArg?: any);
177-
on(event: 'activityRequestPermissions', callback: (args: AndroidActivityRequestPermissionsEventData) => void, thisArg?: any);
166+
on(eventNames: string, callback: (data: AndroidActivityEventData) => void, thisArg?: any): void;
167+
on(event: 'activityCreated', callback: (args: AndroidActivityBundleEventData) => void, thisArg?: any): void;
168+
on(event: 'activityDestroyed', callback: (args: AndroidActivityEventData) => void, thisArg?: any): void;
169+
on(event: 'activityStarted', callback: (args: AndroidActivityEventData) => void, thisArg?: any): void;
170+
on(event: 'activityPaused', callback: (args: AndroidActivityEventData) => void, thisArg?: any): void;
171+
on(event: 'activityResumed', callback: (args: AndroidActivityEventData) => void, thisArg?: any): void;
172+
on(event: 'activityStopped', callback: (args: AndroidActivityEventData) => void, thisArg?: any): void;
173+
on(event: 'saveActivityState', callback: (args: AndroidActivityBundleEventData) => void, thisArg?: any): void;
174+
on(event: 'activityResult', callback: (args: AndroidActivityResultEventData) => void, thisArg?: any): void;
175+
on(event: 'activityBackPressed', callback: (args: AndroidActivityBackPressedEventData) => void, thisArg?: any): void;
176+
on(event: 'activityNewIntent', callback: (args: AndroidActivityNewIntentEventData) => void, thisArg?: any): void;
177+
on(event: 'activityRequestPermissions', callback: (args: AndroidActivityRequestPermissionsEventData) => void, thisArg?: any): void;
178178
}
179179

180180
let androidApp: AndroidApplication;

0 commit comments

Comments
 (0)