Merge remote-tracking branch 'origin/master' into merge-release-in-master

This commit is contained in:
vakrilov
2019-12-03 15:51:59 +02:00
118 changed files with 3073 additions and 1813 deletions

View File

@ -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, pushToSystemCssClasses, removeSystemCssClass } 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,18 +125,17 @@ 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!`);
}
}
function applyCssClass(rootView: View, cssClass: string) {
pushToRootViewCssClasses(cssClass);
function addCssClass(rootView: View, cssClass: string) {
pushToSystemCssClasses(cssClass);
rootView.cssClasses.add(cssClass);
}
function removeCssClass(rootView: View, cssClass: string) {
removeFromRootViewCssClasses(cssClass);
removeSystemCssClass(cssClass);
rootView.cssClasses.delete(cssClass);
}
@ -150,18 +147,27 @@ function increaseStyleScopeApplicationCssSelectorVersion(rootView: View) {
}
}
function applyCssClass(rootView: View, cssClasses: string[], newCssClass: string) {
if (!rootView.cssClasses.has(newCssClass)) {
cssClasses.forEach(cssClass => removeCssClass(rootView, cssClass));
addCssClass(rootView, newCssClass);
increaseStyleScopeApplicationCssSelectorVersion(rootView);
rootView._onCssStateChange();
}
}
export function orientationChanged(rootView: View, newOrientation: "portrait" | "landscape" | "unknown"): void {
if (!rootView) {
return;
}
const newOrientationCssClass = `${CLASS_PREFIX}${newOrientation}`;
if (!rootView.cssClasses.has(newOrientationCssClass)) {
ORIENTATION_CSS_CLASSES.forEach(cssClass => removeCssClass(rootView, cssClass));
applyCssClass(rootView, newOrientationCssClass);
increaseStyleScopeApplicationCssSelectorVersion(rootView);
rootView._onCssStateChange();
}
applyCssClass(rootView, ORIENTATION_CSS_CLASSES, newOrientationCssClass);
const rootModalViews = <Array<View>>rootView._getRootModalViews();
rootModalViews.forEach(rootModalView => {
applyCssClass(rootModalView, ORIENTATION_CSS_CLASSES, newOrientationCssClass);
});
}
export function systemAppearanceChanged(rootView: View, newSystemAppearance: "dark" | "light"): void {
@ -170,12 +176,12 @@ export function systemAppearanceChanged(rootView: View, newSystemAppearance: "da
}
const newSystemAppearanceCssClass = `${CLASS_PREFIX}${newSystemAppearance}`;
if (!rootView.cssClasses.has(newSystemAppearanceCssClass)) {
SYSTEM_APPEARANCE_CSS_CLASSES.forEach(cssClass => removeCssClass(rootView, cssClass));
applyCssClass(rootView, newSystemAppearanceCssClass);
increaseStyleScopeApplicationCssSelectorVersion(rootView);
rootView._onCssStateChange();
}
applyCssClass(rootView, SYSTEM_APPEARANCE_CSS_CLASSES, newSystemAppearanceCssClass);
const rootModalViews = <Array<View>>rootView._getRootModalViews();
rootModalViews.forEach(rootModalView => {
applyCssClass(rootModalView, SYSTEM_APPEARANCE_CSS_CLASSES, newSystemAppearanceCssClass);
});
}
global.__onUncaughtError = function (error: NativeScriptError) {

View 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;
}

View File

@ -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) {

View File

@ -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.

View File

@ -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";
@ -21,12 +24,11 @@ export * from "./application-common";
import { Builder } from "../ui/builder";
import {
CLASS_PREFIX,
getRootViewCssClasses,
pushToRootViewCssClasses
getSystemCssClasses,
pushToSystemCssClasses,
ROOT_VIEW_CSS_CLASS
} 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 +90,9 @@ class CADisplayLinkTarget extends NSObject {
};
}
class IOSApplication implements IOSApplicationDefinition {
/* tslint:disable */
export class iOSApplication implements iOSApplicationDefinition {
/* tslint:enable */
private _backgroundColor = (majorVersion <= 12 || !UIColor.systemBackgroundColor) ? UIColor.whiteColor : UIColor.systemBackgroundColor;
private _delegate: typeof UIApplicationDelegate;
private _window: UIWindow;
@ -292,26 +296,21 @@ 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);
const haveController = this._window.rootViewController !== null;
this._window.rootViewController = controller;
setRootViewSystemAppearanceCssClass(rootView);
setRootViewsSystemAppearanceCssClass(rootView);
if (!haveController) {
this._window.makeKeyAndVisible();
}
rootView.on(iosView.traitCollectionColorAppearanceChangedEvent, () => {
rootView.on(iosViewHelper.traitCollectionColorAppearanceChangedEvent, () => {
const userInterfaceStyle = controller.traitCollection.userInterfaceStyle;
const newSystemAppearance = getSystemAppearanceValue(userInterfaceStyle);
@ -330,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);
@ -349,16 +349,11 @@ 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);
}
}
setRootViewCssClasses(rootView);
setRootViewsCssClasses(rootView);
return rootView;
}
@ -371,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;
@ -402,8 +395,8 @@ export function _start(entry?: string | NavigationEntry) {
// Mind root view CSS classes in future work
// on embedding NativeScript applications
setRootViewSystemAppearanceCssClass(rootView);
rootView.on(iosView.traitCollectionColorAppearanceChangedEvent, () => {
setRootViewsSystemAppearanceCssClass(rootView);
rootView.on(iosViewHelper.traitCollectionColorAppearanceChangedEvent, () => {
const userInterfaceStyle = controller.traitCollection.userInterfaceStyle;
const newSystemAppearance = getSystemAppearanceValue(userInterfaceStyle);
@ -425,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) {
@ -441,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();
}
@ -466,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;
}
@ -481,25 +468,27 @@ 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);
}
}
function setRootViewCssClasses(rootView: View): void {
function setRootViewsCssClasses(rootView: View): void {
const deviceType = device.deviceType.toLowerCase();
pushToRootViewCssClasses(`${CLASS_PREFIX}${IOS_PLATFORM}`);
pushToRootViewCssClasses(`${CLASS_PREFIX}${deviceType}`);
pushToRootViewCssClasses(`${CLASS_PREFIX}${iosApp.orientation}`);
const rootViewCssClasses = getRootViewCssClasses();
pushToSystemCssClasses(`${CLASS_PREFIX}${IOS_PLATFORM}`);
pushToSystemCssClasses(`${CLASS_PREFIX}${deviceType}`);
pushToSystemCssClasses(`${CLASS_PREFIX}${iosApp.orientation}`);
rootView.cssClasses.add(ROOT_VIEW_CSS_CLASS);
const rootViewCssClasses = getSystemCssClasses();
rootViewCssClasses.forEach(c => rootView.cssClasses.add(c));
}
function setRootViewSystemAppearanceCssClass(rootView: View): void {
function setRootViewsSystemAppearanceCssClass(rootView: View): void {
if (majorVersion >= 13) {
const systemAppearanceCssClass = `${CLASS_PREFIX}${iosApp.systemAppearance}`;
pushToRootViewCssClasses(systemAppearanceCssClass);
pushToSystemCssClasses(systemAppearanceCssClass);
rootView.cssClasses.add(systemAppearanceCssClass);
}
}