mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
chore: remove critical circular dependencies (#8114)
* chore: remove critical circular dependencies * chore: fix tslint errors * chore: remove platform specific types from interfaces * chore: update unit tests polyfills * fix: incorrect null check * chore: update api.md file * test: improve test case * chore: apply comments * test: avoid page style leaks in tests
This commit is contained in:

committed by
Alexander Vakrilov

parent
5b647bd809
commit
0ffc790d82
@ -1,13 +1,29 @@
|
||||
// Require globals first so that snapshot takes __extends function.
|
||||
import "../globals";
|
||||
import { Observable, EventData } from "../data/observable";
|
||||
|
||||
// Types
|
||||
import { AndroidApplication, iOSApplication } from ".";
|
||||
import {
|
||||
CssChangedEventData, DiscardedErrorEventData,
|
||||
LoadAppCSSEventData, UnhandledErrorEventData
|
||||
} from "./application-interfaces";
|
||||
import { EventData } from "../data/observable/observable-interfaces";
|
||||
import { View } from "../ui/core/view";
|
||||
|
||||
// Requires
|
||||
import { Observable } from "../data/observable";
|
||||
import {
|
||||
trace as profilingTrace,
|
||||
time,
|
||||
uptime,
|
||||
level as profilingLevel,
|
||||
} from "../profiling";
|
||||
import * as bindableResources from "../ui/core/bindable/bindable-resources";
|
||||
import { CLASS_PREFIX, pushToRootViewCssClasses, removeFromRootViewCssClasses } from "../css/system-classes";
|
||||
import { DeviceOrientation, SystemAppearance } from "../ui/enums/enums";
|
||||
|
||||
export { Observable };
|
||||
export * from "./application-interfaces";
|
||||
|
||||
const events = new Observable();
|
||||
let launched = false;
|
||||
@ -30,22 +46,6 @@ export function hasLaunched(): boolean {
|
||||
return launched;
|
||||
}
|
||||
|
||||
export { Observable };
|
||||
|
||||
import {
|
||||
AndroidApplication,
|
||||
CssChangedEventData,
|
||||
DiscardedErrorEventData,
|
||||
iOSApplication,
|
||||
LoadAppCSSEventData,
|
||||
UnhandledErrorEventData
|
||||
} from "./application";
|
||||
|
||||
import { CLASS_PREFIX, pushToRootViewCssClasses, removeFromRootViewCssClasses } from "../css/system-classes";
|
||||
import { DeviceOrientation, SystemAppearance } from "../ui/enums/enums";
|
||||
|
||||
export { UnhandledErrorEventData, DiscardedErrorEventData, CssChangedEventData, LoadAppCSSEventData };
|
||||
|
||||
export const launchEvent = "launch";
|
||||
export const suspendEvent = "suspend";
|
||||
export const displayedEvent = "displayed";
|
||||
@ -70,18 +70,16 @@ const SYSTEM_APPEARANCE_CSS_CLASSES = [
|
||||
|
||||
let cssFile: string = "./app.css";
|
||||
|
||||
let resources: any = {};
|
||||
|
||||
export function getResources() {
|
||||
return resources;
|
||||
return bindableResources.get();
|
||||
}
|
||||
|
||||
export function setResources(res: any) {
|
||||
resources = res;
|
||||
bindableResources.set(res);
|
||||
}
|
||||
|
||||
export let android = undefined;
|
||||
export let ios = undefined;
|
||||
export let android: AndroidApplication = undefined;
|
||||
export let ios: iOSApplication = undefined;
|
||||
|
||||
export const on: typeof events.on = events.on.bind(events);
|
||||
export const off: typeof events.off = events.off.bind(events);
|
||||
@ -127,8 +125,7 @@ export function loadAppCss(): void {
|
||||
try {
|
||||
events.notify(<LoadAppCSSEventData>{ eventName: "loadAppCss", object: app, cssFile: getCssFileName() });
|
||||
} catch (e) {
|
||||
throw new Error(`The file ${getCssFileName()} couldn't be loaded! ` +
|
||||
`You may need to register it inside ./app/vendor.ts.`);
|
||||
throw new Error(`The app CSS file ${getCssFileName()} couldn't be loaded!`);
|
||||
}
|
||||
}
|
||||
|
||||
|
79
nativescript-core/application/application-interfaces.ts
Normal file
79
nativescript-core/application/application-interfaces.ts
Normal file
@ -0,0 +1,79 @@
|
||||
// Types
|
||||
import { EventData } from "../data/observable/observable-interfaces";
|
||||
import { View } from "../ui/core/view";
|
||||
|
||||
export interface ApplicationEventData extends EventData {
|
||||
ios?: any;
|
||||
android?: any;
|
||||
eventName: string;
|
||||
object: any;
|
||||
}
|
||||
|
||||
export interface LaunchEventData extends ApplicationEventData {
|
||||
root?: View;
|
||||
savedInstanceState?: any /* android.os.Bundle */;
|
||||
}
|
||||
|
||||
export interface OrientationChangedEventData extends ApplicationEventData {
|
||||
newValue: "portrait" | "landscape" | "unknown";
|
||||
}
|
||||
|
||||
export interface SystemAppearanceChangedEventData extends ApplicationEventData {
|
||||
newValue: "light" | "dark";
|
||||
}
|
||||
|
||||
export interface UnhandledErrorEventData extends ApplicationEventData {
|
||||
ios?: NativeScriptError;
|
||||
android?: NativeScriptError;
|
||||
error: NativeScriptError;
|
||||
}
|
||||
|
||||
export interface DiscardedErrorEventData extends ApplicationEventData {
|
||||
error: NativeScriptError;
|
||||
}
|
||||
|
||||
export interface CssChangedEventData extends EventData {
|
||||
cssFile?: string;
|
||||
cssText?: string;
|
||||
}
|
||||
|
||||
export interface AndroidActivityEventData {
|
||||
activity: any /* androidx.appcompat.app.AppCompatActivity */;
|
||||
eventName: string;
|
||||
object: any;
|
||||
}
|
||||
|
||||
export interface AndroidActivityBundleEventData extends AndroidActivityEventData {
|
||||
bundle: any /* android.os.Bundle */;
|
||||
}
|
||||
|
||||
export interface AndroidActivityRequestPermissionsEventData extends AndroidActivityEventData {
|
||||
requestCode: number;
|
||||
permissions: Array<string>;
|
||||
grantResults: Array<number>;
|
||||
}
|
||||
|
||||
export interface AndroidActivityResultEventData extends AndroidActivityEventData {
|
||||
requestCode: number;
|
||||
resultCode: number;
|
||||
intent: any /* android.content.Intent */;
|
||||
}
|
||||
|
||||
export interface AndroidActivityNewIntentEventData extends AndroidActivityEventData {
|
||||
intent: any /* android.content.Intent */;
|
||||
}
|
||||
|
||||
export interface AndroidActivityBackPressedEventData extends AndroidActivityEventData {
|
||||
cancel: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export interface RootViewControllerImpl {
|
||||
contentController: any;
|
||||
}
|
||||
|
||||
export interface LoadAppCSSEventData extends EventData {
|
||||
cssFile: string;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
// Definitions.
|
||||
// Types.
|
||||
import { AndroidApplication as AndroidApplicationDefinition } from ".";
|
||||
import {
|
||||
AndroidActivityBackPressedEventData,
|
||||
AndroidActivityBundleEventData,
|
||||
@ -6,26 +7,24 @@ import {
|
||||
AndroidActivityNewIntentEventData,
|
||||
AndroidActivityRequestPermissionsEventData,
|
||||
AndroidActivityResultEventData,
|
||||
AndroidApplication as AndroidApplicationDefinition,
|
||||
ApplicationEventData,
|
||||
CssChangedEventData,
|
||||
OrientationChangedEventData,
|
||||
SystemAppearanceChangedEventData
|
||||
} from ".";
|
||||
} from "./application-interfaces";
|
||||
import { View } from "../ui/core/view";
|
||||
import { NavigationEntry, AndroidActivityCallbacks } from "../ui/frame/frame-interfaces";
|
||||
|
||||
// Requires
|
||||
import {
|
||||
displayedEvent, hasListeners, livesync, lowMemoryEvent, notify, Observable, on,
|
||||
displayedEvent, hasListeners, livesync, lowMemoryEvent, notify, Observable,
|
||||
orientationChanged, orientationChangedEvent, setApplication, suspendEvent,
|
||||
systemAppearanceChanged, systemAppearanceChangedEvent
|
||||
} from "./application-common";
|
||||
|
||||
import { profile } from "../profiling";
|
||||
|
||||
// First reexport so that app module is initialized.
|
||||
export * from "./application-common";
|
||||
|
||||
// Types.
|
||||
import { NavigationEntry, View, AndroidActivityCallbacks } from "../ui/frame";
|
||||
import { profile } from "../profiling";
|
||||
|
||||
const ActivityCreated = "activityCreated";
|
||||
const ActivityDestroyed = "activityDestroyed";
|
||||
@ -149,6 +148,10 @@ export class AndroidApplication extends Observable implements AndroidApplication
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: Use an interface with the same name, so that the class above fulfills the 'implements' requirement
|
||||
// HACK: We use the 'implements' to verify the class above is the same as the one declared in the d.ts
|
||||
// HACK: We declare all these 'on' statements, so that they can appear in the API reference
|
||||
// HACK: Do we need this? Is it useful? There are static fields to the AndroidApplication class for the event names.
|
||||
export interface AndroidApplication {
|
||||
on(eventNames: string, callback: (data: AndroidActivityEventData) => void, thisArg?: any);
|
||||
on(event: "activityCreated", callback: (args: AndroidActivityBundleEventData) => void, thisArg?: any);
|
||||
@ -171,9 +174,8 @@ setApplication(androidApp);
|
||||
|
||||
let mainEntry: NavigationEntry;
|
||||
let started = false;
|
||||
const createRootFrame = { value: true };
|
||||
|
||||
export function _start(entry?: NavigationEntry | string) {
|
||||
export function run(entry?: NavigationEntry | string) {
|
||||
if (started) {
|
||||
throw new Error("Application is already started.");
|
||||
}
|
||||
@ -186,15 +188,6 @@ export function _start(entry?: NavigationEntry | string) {
|
||||
}
|
||||
}
|
||||
|
||||
export function _shouldCreateRootFrame(): boolean {
|
||||
return createRootFrame.value;
|
||||
}
|
||||
|
||||
export function run(entry?: NavigationEntry | string) {
|
||||
createRootFrame.value = false;
|
||||
_start(entry);
|
||||
}
|
||||
|
||||
export function addCss(cssText: string, attributeScoped?: boolean): void {
|
||||
notify(<CssChangedEventData>{ eventName: "cssChanged", object: androidApp, cssText: cssText });
|
||||
if (!attributeScoped) {
|
||||
@ -213,7 +206,6 @@ export function _resetRootView(entry?: NavigationEntry | string) {
|
||||
throw new Error("Cannot find android activity.");
|
||||
}
|
||||
|
||||
createRootFrame.value = false;
|
||||
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
|
||||
const callbacks: AndroidActivityCallbacks = activity[CALLBACKS];
|
||||
if (!callbacks) {
|
||||
|
11
nativescript-core/application/application.d.ts
vendored
11
nativescript-core/application/application.d.ts
vendored
@ -211,15 +211,6 @@ export function run(entry?: NavigationEntry | string);
|
||||
*/
|
||||
export function _resetRootView(entry?: NavigationEntry | string);
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export function _shouldCreateRootFrame(): boolean;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export function _start(entry?: NavigationEntry | string);
|
||||
|
||||
/**
|
||||
* A basic method signature to hook an event listener (shortcut alias to the addEventListener method).
|
||||
* @param eventNames - String corresponding to events (e.g. "onLaunch"). Optionally could be used more events separated by `,` (e.g. "onLaunch", "onSuspend").
|
||||
@ -610,7 +601,7 @@ export class AndroidApplication extends Observable {
|
||||
/**
|
||||
* The abstraction of an iOS-specific application object.
|
||||
*/
|
||||
export interface iOSApplication {
|
||||
export class iOSApplication {
|
||||
/* tslint:enable */
|
||||
/**
|
||||
* The root view controller for the application.
|
||||
|
@ -1,19 +1,22 @@
|
||||
// Types
|
||||
import { iOSApplication as iOSApplicationDefinition } from ".";
|
||||
import {
|
||||
ApplicationEventData,
|
||||
CssChangedEventData,
|
||||
iOSApplication as IOSApplicationDefinition,
|
||||
LaunchEventData,
|
||||
LoadAppCSSEventData,
|
||||
OrientationChangedEventData,
|
||||
SystemAppearanceChangedEventData
|
||||
} from ".";
|
||||
} from "./application-interfaces";
|
||||
import { View } from "../ui/core/view";
|
||||
import { NavigationEntry } from "../ui/frame/frame-interfaces";
|
||||
|
||||
// Require
|
||||
import {
|
||||
displayedEvent, exitEvent, getCssFileName, launchEvent, livesync, lowMemoryEvent, notify, on,
|
||||
orientationChanged, orientationChangedEvent, resumeEvent, setApplication, suspendEvent,
|
||||
systemAppearanceChanged, systemAppearanceChangedEvent
|
||||
} from "./application-common";
|
||||
|
||||
// First reexport so that app module is initialized.
|
||||
export * from "./application-common";
|
||||
|
||||
@ -24,9 +27,7 @@ import {
|
||||
getRootViewCssClasses,
|
||||
pushToRootViewCssClasses
|
||||
} from "../css/system-classes";
|
||||
|
||||
import { ios as iosView, View } from "../ui/core/view";
|
||||
import { Frame, NavigationEntry } from "../ui/frame";
|
||||
import { ios as iosViewHelper } from "../ui/core/view/view-helper";
|
||||
import { device } from "../platform/platform";
|
||||
import { profile } from "../profiling";
|
||||
import { ios } from "../utils/utils";
|
||||
@ -88,7 +89,9 @@ class CADisplayLinkTarget extends NSObject {
|
||||
};
|
||||
}
|
||||
|
||||
class IOSApplication implements IOSApplicationDefinition {
|
||||
/* tslint:disable */
|
||||
export class iOSApplication implements iOSApplicationDefinition {
|
||||
/* tslint:enable */
|
||||
private _backgroundColor = majorVersion <= 12 ? UIColor.whiteColor : UIColor.systemBackgroundColor;
|
||||
private _delegate: typeof UIApplicationDelegate;
|
||||
private _window: UIWindow;
|
||||
@ -293,13 +296,8 @@ class IOSApplication implements IOSApplicationDefinition {
|
||||
|
||||
this._rootView = rootView;
|
||||
|
||||
if (createRootFrame.value) {
|
||||
// Don't setup as styleScopeHost
|
||||
rootView._setupUI({});
|
||||
} else {
|
||||
// setup view as styleScopeHost
|
||||
rootView._setupAsRootView({});
|
||||
}
|
||||
// setup view as styleScopeHost
|
||||
rootView._setupAsRootView({});
|
||||
|
||||
setViewControllerView(rootView);
|
||||
|
||||
@ -312,7 +310,7 @@ class IOSApplication implements IOSApplicationDefinition {
|
||||
this._window.makeKeyAndVisible();
|
||||
}
|
||||
|
||||
rootView.on(iosView.traitCollectionColorAppearanceChangedEvent, () => {
|
||||
rootView.on(iosViewHelper.traitCollectionColorAppearanceChangedEvent, () => {
|
||||
const userInterfaceStyle = controller.traitCollection.userInterfaceStyle;
|
||||
const newSystemAppearance = getSystemAppearanceValue(userInterfaceStyle);
|
||||
|
||||
@ -331,8 +329,9 @@ class IOSApplication implements IOSApplicationDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
const iosApp = new IOSApplication();
|
||||
|
||||
/* tslint:disable */
|
||||
const iosApp = new iOSApplication();
|
||||
/* tslint:enable */
|
||||
export { iosApp as ios };
|
||||
setApplication(iosApp);
|
||||
|
||||
@ -350,12 +349,7 @@ function createRootView(v?: View) {
|
||||
if (!mainEntry) {
|
||||
throw new Error("Main entry is missing. App cannot be started. Verify app bootstrap.");
|
||||
} else {
|
||||
if (createRootFrame.value) {
|
||||
const frame = rootView = new Frame();
|
||||
frame.navigate(mainEntry);
|
||||
} else {
|
||||
rootView = Builder.createViewFromEntry(mainEntry);
|
||||
}
|
||||
rootView = Builder.createViewFromEntry(mainEntry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,10 +366,8 @@ export function getRootView() {
|
||||
return iosApp.rootView;
|
||||
}
|
||||
|
||||
// NOTE: for backwards compatibility. Remove for 4.0.0.
|
||||
const createRootFrame = { value: true };
|
||||
let started: boolean = false;
|
||||
export function _start(entry?: string | NavigationEntry) {
|
||||
export function run(entry?: string | NavigationEntry) {
|
||||
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
|
||||
started = true;
|
||||
|
||||
@ -404,7 +396,7 @@ export function _start(entry?: string | NavigationEntry) {
|
||||
// Mind root view CSS classes in future work
|
||||
// on embedding NativeScript applications
|
||||
setRootViewSystemAppearanceCssClass(rootView);
|
||||
rootView.on(iosView.traitCollectionColorAppearanceChangedEvent, () => {
|
||||
rootView.on(iosViewHelper.traitCollectionColorAppearanceChangedEvent, () => {
|
||||
const userInterfaceStyle = controller.traitCollection.userInterfaceStyle;
|
||||
const newSystemAppearance = getSystemAppearanceValue(userInterfaceStyle);
|
||||
|
||||
@ -426,11 +418,6 @@ export function _start(entry?: string | NavigationEntry) {
|
||||
}
|
||||
}
|
||||
|
||||
export function run(entry?: string | NavigationEntry) {
|
||||
createRootFrame.value = false;
|
||||
_start(entry);
|
||||
}
|
||||
|
||||
export function addCss(cssText: string, attributeScoped?: boolean): void {
|
||||
notify(<CssChangedEventData>{ eventName: "cssChanged", object: <any>iosApp, cssText: cssText });
|
||||
if (!attributeScoped) {
|
||||
@ -442,7 +429,6 @@ export function addCss(cssText: string, attributeScoped?: boolean): void {
|
||||
}
|
||||
|
||||
export function _resetRootView(entry?: NavigationEntry | string) {
|
||||
createRootFrame.value = false;
|
||||
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
|
||||
iosApp.setWindowContent();
|
||||
}
|
||||
@ -467,7 +453,7 @@ function getViewController(rootView: View): UIViewController {
|
||||
if (!(viewController instanceof UIViewController)) {
|
||||
// We set UILayoutViewController dynamically to the root view if it doesn't have a view controller
|
||||
// At the moment the root view doesn't have its native view created. We set it in the setViewControllerView func
|
||||
viewController = iosView.UILayoutViewController.initWithOwner(new WeakRef(rootView)) as UIViewController;
|
||||
viewController = iosViewHelper.UILayoutViewController.initWithOwner(new WeakRef(rootView)) as UIViewController;
|
||||
rootView.viewController = viewController;
|
||||
}
|
||||
|
||||
@ -482,7 +468,7 @@ function setViewControllerView(view: View): void {
|
||||
throw new Error("Root should be either UIViewController or UIView");
|
||||
}
|
||||
|
||||
if (viewController instanceof iosView.UILayoutViewController) {
|
||||
if (viewController instanceof iosViewHelper.UILayoutViewController) {
|
||||
viewController.view.addSubview(nativeView);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user