chore: cleanup android refs

This commit is contained in:
Nathan Walker
2025-07-15 12:01:45 -07:00
parent 7bc57216c0
commit 2fb70c1f10
27 changed files with 283 additions and 332 deletions

View File

@ -84,7 +84,7 @@ export class SafeAreaTests extends testModule.UITest<any> {
}
private layout_insets_top_action_bar_hidden_test(layout: view.View) {
const keyWindow = Utils.ios.getWindow();
const keyWindow = Utils.getWindow<UIWindow>();
// const statusBarHeight = round(dipToDp(app.statusBarFrame.size.height));
// use window inset instead of status bar frame as that's unreliable on iOS 16+
const topInset = Math.round(dipToDp(keyWindow ? keyWindow.safeAreaInsets.top : UIApplication.sharedApplication.keyWindow.safeAreaInsets.top));

1
apps/ui/.gitignore vendored
View File

@ -1 +1,2 @@
!webpack.config.js
hooks

View File

@ -4,7 +4,7 @@ import { getNativeApp } from '../application/helpers-common';
let sharedPreferences: android.content.SharedPreferences;
function ensureSharedPreferences() {
if (!sharedPreferences) {
sharedPreferences = (getNativeApp() as android.app.Application).getApplicationContext().getSharedPreferences('prefs.db', 0);
sharedPreferences = getNativeApp<android.app.Application>().getApplicationContext().getSharedPreferences('prefs.db', 0);
}
}

View File

@ -1,7 +1,5 @@
import { profile } from '../profiling';
import type { View } from '../ui/core/view';
import { isEmbedded } from '../ui/embedding';
import { GestureTypes } from '../ui/gestures';
import { AndroidActivityCallbacks, NavigationEntry } from '../ui/frame/frame-common';
import { SDK_VERSION } from '../utils/constants';
import { android as androidUtils } from '../utils';
@ -9,7 +7,6 @@ import { ApplicationCommon } from './application-common';
import type { AndroidActivityBundleEventData, AndroidActivityEventData, ApplicationEventData } from './application-interfaces';
import { Observable } from '../data/observable';
import { Trace } from '../trace';
import * as Utils from '../utils';
import {
CommonA11YServiceEnabledObservable,
SharedA11YObservable,
@ -44,21 +41,7 @@ import {
setA11yEnabled,
} from '../accessibility/accessibility-common';
import { androidGetForegroundActivity, androidGetStartActivity, androidPendingReceiverRegistrations, androidRegisterBroadcastReceiver, androidRegisteredReceivers, androidSetForegroundActivity, androidSetStartActivity, androidUnregisterBroadcastReceiver, applyContentDescription } from './helpers';
import { getImageFetcher, getRootView, initImageCache, setA11yUpdatePropertiesCallback, setApplicationPropertiesCallback, setAppMainEntry, setNativeApp, setRootView, setToggleApplicationEventListenersCallback } from './helpers-common';
declare namespace com {
namespace tns {
class NativeScriptApplication extends android.app.Application {
static getInstance(): NativeScriptApplication;
}
namespace embedding {
class ApplicationHolder {
static getInstance(): android.app.Application;
}
}
}
}
import { getImageFetcher, getNativeApp, getRootView, initImageCache, setA11yUpdatePropertiesCallback, setApplicationPropertiesCallback, setAppMainEntry, setNativeApp, setRootView, setToggleApplicationEventListenersCallback } from './helpers-common';
declare class NativeScriptLifecycleCallbacks extends android.app.Application.ActivityLifecycleCallbacks {}
@ -366,27 +349,7 @@ export class AndroidApplication extends ApplicationCommon {
return nativeApp;
}
// Try getting it from module - check whether application.android.init has been explicitly called
// check whether the com.tns.NativeScriptApplication type exists
if (com.tns.NativeScriptApplication) {
nativeApp = com.tns.NativeScriptApplication.getInstance();
}
if (!nativeApp && isEmbedded()) {
nativeApp = com.tns.embedding.ApplicationHolder.getInstance();
}
// the getInstance might return null if com.tns.NativeScriptApplication exists but is not the starting app type
if (!nativeApp) {
// TODO: Should we handle the case when a custom application type is provided and the user has not explicitly initialized the application module?
const clazz = java.lang.Class.forName('android.app.ActivityThread');
if (clazz) {
const method = clazz.getMethod('currentApplication', null);
if (method) {
nativeApp = method.invoke(null, null);
}
}
}
nativeApp = getNativeApp<android.app.Application>();
// we cannot work without having the app instance
if (!nativeApp) {
@ -621,7 +584,7 @@ function applyFontScaleToRootViews(): void {
}
export function getAndroidAccessibilityManager(): android.view.accessibility.AccessibilityManager | null {
const context = Utils.ad.getApplicationContext() as android.content.Context;
const context = getNativeApp<android.app.Application>().getApplicationContext() as android.content.Context;
if (!context) {
return null;
}
@ -860,13 +823,13 @@ function accessibilityEventHelper(view: View, eventType: number) {
*/
if (SDK_VERSION >= 26) {
// Find all tap gestures and trigger them.
for (const tapGesture of view.getGestureObservers(GestureTypes.tap) ?? []) {
for (const tapGesture of view.getGestureObservers(1) ?? []) {
tapGesture.callback({
android: view.android,
eventName: 'tap',
ios: null,
object: view,
type: GestureTypes.tap,
type: 1,
view: view,
});
}

View File

@ -1,16 +1,73 @@
/**
* Do not import other files here to avoid circular dependencies.
* Used to define helper functions and variables that are shared between Android and iOS
* without introducing platform-specific code directly.
* Used to define helper functions and variables that are shared between Android and iOS.
* This file can declare cross platform types and use bundler platform checks.
* For example, use `__ANDROID__` or `__APPLE__` to check the platform.
*/
let nativeApp: UIApplication | android.app.Application;
/**
* Application type. UIApplication on iOS or android.app.Application on Android.
*/
type NativeApp = UIApplication | android.app.Application;
let nativeApp: NativeApp;
declare namespace com {
namespace tns {
class NativeScriptApplication extends android.app.Application {
static getInstance(): NativeScriptApplication;
}
namespace embedding {
class ApplicationHolder {
static getInstance(): android.app.Application;
}
}
}
}
function isEmbedded(): boolean {
if (__APPLE__) {
return !!NativeScriptEmbedder.sharedInstance().delegate;
} else {
// @ts-ignore
// Check if the Bootstrap class exists and has the isEmbeddedNativeScript property
// This is a way to determine if the app is embedded in a host project.
return org.nativescript?.Bootstrap?.isEmbeddedNativeScript;
}
}
/**
* Get the current application instance.
* @returns current application instance, UIApplication on iOS or android.app.Application on Android.
*/
export function getNativeApp() {
return nativeApp;
export function getNativeApp<T extends NativeApp>(): T {
if (__ANDROID__) {
if (!nativeApp) {
// Try getting it from module - check whether application.android.init has been explicitly called
// check whether the com.tns.NativeScriptApplication type exists
if (com.tns.NativeScriptApplication) {
nativeApp = com.tns.NativeScriptApplication.getInstance();
}
if (!nativeApp && isEmbedded()) {
nativeApp = com.tns.embedding.ApplicationHolder.getInstance();
}
// the getInstance might return null if com.tns.NativeScriptApplication exists but is not the starting app type
if (!nativeApp) {
// TODO: Should we handle the case when a custom application type is provided and the user has not explicitly initialized the application module?
const clazz = java.lang.Class.forName('android.app.ActivityThread');
if (clazz) {
const method = clazz.getMethod('currentApplication', null);
if (method) {
nativeApp = method.invoke(null, null);
}
}
}
}
}
return nativeApp! as T;
}
/**
@ -20,7 +77,7 @@ export function getNativeApp() {
* @param app The native application instance to set.
* This should be called once during application startup to set the native app instance.
*/
export function setNativeApp(app: UIApplication | android.app.Application) {
export function setNativeApp(app: NativeApp) {
nativeApp = app;
}
@ -96,7 +153,6 @@ export function updateA11yPropertiesCallback(view: any /* View */) {
/**
* Internal Android app helpers
*/
// Circular dependency avoidance for image fetching on android
let _imageFetcher: org.nativescript.widgets.image.Fetcher;
export function getImageFetcher(): org.nativescript.widgets.image.Fetcher {
return _imageFetcher;

View File

@ -23,7 +23,7 @@ export function androidSetStartActivity(activity: androidx.appcompat.app.AppComp
}
function getApplicationContext(): android.content.Context {
return (getNativeApp() as android.app.Application).getApplicationContext();
return getNativeApp<android.app.Application>().getApplicationContext();
}
export const androidRegisteredReceivers: { [key: string]: android.content.BroadcastReceiver } = {};

View File

@ -19,7 +19,7 @@ const vpn = 'vpn';
// Get Connection Type
function getConnectivityManager(): android.net.ConnectivityManager {
return (getNativeApp() as android.app.Application).getApplicationContext().getSystemService(android.content.Context.CONNECTIVITY_SERVICE);
return getNativeApp<android.app.Application>().getApplicationContext().getSystemService(android.content.Context.CONNECTIVITY_SERVICE);
}
function getActiveNetworkInfo(): android.net.NetworkInfo {

View File

@ -225,7 +225,7 @@ export class NetworkDomainDebugger implements inspectorCommands.NetworkDomain.Ne
* Loads a resource in the context of a frame on the inspected page without cross origin checks.
*/
loadResource(params: inspectorCommands.NetworkDomain.LoadResourceMethodArguments): { content: string; mimeType: string; status: number } {
const appPath = (getNativeApp() as android.app.Application).getApplicationContext().getFilesDir().getCanonicalPath() + '/app';
const appPath = getNativeApp<android.app.Application>().getApplicationContext().getFilesDir().getCanonicalPath() + '/app';
const pathUrl = params.url.replace('file://', appPath);
const file = new java.io.File(pathUrl);
const is = file.exists() ? new java.io.FileInputStream(file) : undefined;

View File

@ -1,12 +1,12 @@
import * as textModule from '../text';
import { android as androidUtils } from '../utils';
import { getNativeApp } from '../application/helpers-common';
import { getFileExtension } from '../utils/utils-shared';
import { SDK_VERSION } from '../utils/constants';
import type { IFileSystemAccess } from './file-system-access';
function getOrSetHelper(path: string): org.nativescript.widgets.FileHelper {
return org.nativescript.widgets.FileHelper.fromString(androidUtils.getApplicationContext(), path);
return org.nativescript.widgets.FileHelper.fromString(getNativeApp<android.app.Application>().getApplicationContext(), path);
}
function isContentUri(path: string): boolean {
@ -213,30 +213,30 @@ export class FileSystemAccess implements IFileSystemAccess {
}
public getDocumentsFolderPath(): string {
const dir = androidUtils.getApplicationContext().getFilesDir();
const dir = getNativeApp<android.app.Application>().getApplicationContext().getFilesDir();
return dir.getAbsolutePath();
}
public getExternalDocumentsFolderPath(): string {
const dirs = androidUtils.getApplicationContext().getExternalFilesDirs(null);
const dirs = getNativeApp<android.app.Application>().getApplicationContext().getExternalFilesDirs(null);
let dir;
if (dirs && dirs.length > 1) {
dir = dirs[dirs.length - 1];
}
if (!dir) {
dir = androidUtils.getApplicationContext().getExternalFilesDir(null);
dir = getNativeApp<android.app.Application>().getApplicationContext().getExternalFilesDir(null);
}
return dir.getAbsolutePath();
}
public getLogicalRootPath(): string {
const dir = androidUtils.getApplicationContext().getFilesDir();
const dir = getNativeApp<android.app.Application>().getApplicationContext().getFilesDir();
return dir.getCanonicalPath();
}
public getTempFolderPath(): string {
const dir = androidUtils.getApplicationContext().getCacheDir();
const dir = getNativeApp<android.app.Application>().getApplicationContext().getCacheDir();
return dir.getAbsolutePath();
}
@ -249,7 +249,7 @@ export class FileSystemAccess implements IFileSystemAccess {
public copySync(src: string, dest: string, onError?: (error: any) => any) {
try {
return org.nativescript.widgets.Async.File.copySync(src, dest, androidUtils.getApplicationContext());
return org.nativescript.widgets.Async.File.copySync(src, dest, getNativeApp<android.app.Application>().getApplicationContext());
} catch (error) {
if (onError) {
onError(error);
@ -273,7 +273,7 @@ export class FileSystemAccess implements IFileSystemAccess {
reject(err);
},
}),
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
);
} catch (ex) {
reject(ex);
@ -917,7 +917,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
}
fileExists(path: string): boolean {
if (isContentUri(path)) {
return org.nativescript.widgets.FileHelper.exists(androidUtils.getApplicationContext(), path);
return org.nativescript.widgets.FileHelper.exists(getNativeApp<android.app.Application>().getApplicationContext(), path);
}
return super.fileExists(path);
}
@ -930,7 +930,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
deleteFile(path: string, onError?: (error: any) => any) {
if (isContentUri(path)) {
try {
getOrSetHelper(path).delete(androidUtils.getApplicationContext());
getOrSetHelper(path).delete(getNativeApp<android.app.Application>().getApplicationContext());
} catch (e) {
onError?.(e);
}
@ -959,7 +959,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
getOrSetHelper(path).renameSync(androidUtils.getApplicationContext(), newPath, callback);
getOrSetHelper(path).renameSync(getNativeApp<android.app.Application>().getApplicationContext(), newPath, callback);
} else {
super.rename(path, newPath, onError);
}
@ -968,7 +968,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
public renameAsync(path: string, newPath: string): Promise<any> {
return new Promise<void>((resolve, reject) => {
getOrSetHelper(path).renameSync(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
newPath,
new org.nativescript.widgets.FileHelper.Callback({
onSuccess(result) {
@ -1001,7 +1001,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise<void>((resolve, reject) => {
getOrSetHelper(path).appendBuffer(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
FileSystemAccess.getBuffer(content),
new org.nativescript.widgets.FileHelper.Callback({
onSuccess(result) {
@ -1028,7 +1028,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
getOrSetHelper(path).appendSync(androidUtils.getApplicationContext(), FileSystemAccess.getBuffer(content), callback);
getOrSetHelper(path).appendSync(getNativeApp<android.app.Application>().getApplicationContext(), FileSystemAccess.getBuffer(content), callback);
} else {
super.appendSync(path, content, onError);
}
@ -1040,7 +1040,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise<void>((resolve, reject) => {
getOrSetHelper(path).append(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
content,
new org.nativescript.widgets.FileHelper.Callback({
onSuccess(result) {
@ -1067,7 +1067,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
getOrSetHelper(path).appendSync(androidUtils.getApplicationContext(), content, callback);
getOrSetHelper(path).appendSync(getNativeApp<android.app.Application>().getApplicationContext(), content, callback);
} else {
super.appendSync(path, content, onError);
}
@ -1079,7 +1079,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise<void>((resolve, reject) => {
getOrSetHelper(path).appendText(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
content,
encoding ?? null,
new org.nativescript.widgets.FileHelper.Callback({
@ -1107,7 +1107,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
getOrSetHelper(path).appendTextSync(androidUtils.getApplicationContext(), content, encoding ?? null, callback);
getOrSetHelper(path).appendTextSync(getNativeApp<android.app.Application>().getApplicationContext(), content, encoding ?? null, callback);
} else {
super.appendTextSync(path, content, onError);
}
@ -1119,7 +1119,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise((resolve, reject) => {
getOrSetHelper(path).readText(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
encoding ?? null,
new org.nativescript.widgets.FileHelper.Callback({
onSuccess(result) {
@ -1145,7 +1145,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
return getOrSetHelper(path).readTextSync(androidUtils.getApplicationContext(), encoding ?? null, callback);
return getOrSetHelper(path).readTextSync(getNativeApp<android.app.Application>().getApplicationContext(), encoding ?? null, callback);
} else {
return super.readTextSync(path, onError, encoding);
}
@ -1157,7 +1157,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise((resolve, reject) => {
getOrSetHelper(path).readBuffer(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
new org.nativescript.widgets.FileHelper.Callback({
onSuccess(result) {
resolve(result);
@ -1183,7 +1183,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
const ret = getOrSetHelper(path).readBufferSync(androidUtils.getApplicationContext(), callback);
const ret = getOrSetHelper(path).readBufferSync(getNativeApp<android.app.Application>().getApplicationContext(), callback);
if (ret) {
return null;
}
@ -1198,7 +1198,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise((resolve, reject) => {
getOrSetHelper(path).read(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
new org.nativescript.widgets.FileHelper.Callback({
onSuccess(result) {
resolve(result);
@ -1224,7 +1224,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
return getOrSetHelper(path).readSync(androidUtils.getApplicationContext(), callback);
return getOrSetHelper(path).readSync(getNativeApp<android.app.Application>().getApplicationContext(), callback);
}
return super.readSync(path, onError);
}
@ -1235,7 +1235,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise<void>((resolve, reject) => {
getOrSetHelper(path).writeText(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
content,
encoding ?? null,
new org.nativescript.widgets.FileHelper.Callback({
@ -1263,7 +1263,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
getOrSetHelper(path).writeTextSync(androidUtils.getApplicationContext(), content, encoding ?? null, callback);
getOrSetHelper(path).writeTextSync(getNativeApp<android.app.Application>().getApplicationContext(), content, encoding ?? null, callback);
} else {
super.writeTextSync(path, content, onError);
}
@ -1275,7 +1275,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise<void>((resolve, reject) => {
getOrSetHelper(path).writeBuffer(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
FileSystemAccess.getBuffer(content),
new org.nativescript.widgets.FileHelper.Callback({
onSuccess(result) {
@ -1302,7 +1302,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
getOrSetHelper(path).writeSync(androidUtils.getApplicationContext(), FileSystemAccess.getBuffer(content), callback);
getOrSetHelper(path).writeSync(getNativeApp<android.app.Application>().getApplicationContext(), FileSystemAccess.getBuffer(content), callback);
} else {
super.writeSync(path, content, onError);
}
@ -1314,7 +1314,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
if (isContentUri(path)) {
return new Promise<void>((resolve, reject) => {
getOrSetHelper(path).write(
androidUtils.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
content,
new org.nativescript.widgets.FileHelper.Callback({
onSuccess(result) {
@ -1341,7 +1341,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
},
});
}
getOrSetHelper(path).writeSync(androidUtils.getApplicationContext(), content, callback);
getOrSetHelper(path).writeSync(getNativeApp<android.app.Application>().getApplicationContext(), content, callback);
} else {
super.writeSync(path, content, onError);
}

View File

@ -270,7 +270,7 @@ class Android {
throw new Error(`createFile is available on Android only!`);
}
const context = (getNativeApp() as android.app.Application).getApplicationContext() as android.content.Context;
const context = getNativeApp<android.app.Application>().getApplicationContext() as android.content.Context;
const meta = new android.content.ContentValues();
meta.put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, options.name);
@ -323,7 +323,7 @@ export class File extends FileSystemEntity {
// falls back to creating a temp file without a known extension.
if (!fileInfo) {
const tempFile = `${knownFolders.temp().path}/${java.util.UUID.randomUUID().toString()}`;
org.nativescript.widgets.Async.File.copySync(path, tempFile, (getNativeApp() as android.app.Application).getApplicationContext());
org.nativescript.widgets.Async.File.copySync(path, tempFile, getNativeApp<android.app.Application>().getApplicationContext());
path = tempFile;
} else {
const ext = fileInfo.extension;

View File

@ -1,7 +1,7 @@
import { ImageAssetBase, getRequestedImageSize } from './image-asset-common';
import { path as fsPath, knownFolders } from '../file-system';
import { ad } from '../utils';
import { Screen } from '../platform';
import { Screen } from '../platform/screen';
import { getNativeApp } from '../application/helpers-common';
export * from './image-asset-common';
export class ImageAsset extends ImageAssetBase {
@ -27,7 +27,7 @@ export class ImageAsset extends ImageAssetBase {
public getImageAsync(callback: (image, error) => void) {
org.nativescript.widgets.Utils.loadImageAsync(
ad.getApplicationContext(),
getNativeApp<android.app.Application>().getApplicationContext(),
this.android,
JSON.stringify(this.options || {}),
Screen.mainScreen.widthPixels,
@ -39,7 +39,7 @@ export class ImageAsset extends ImageAssetBase {
onError(ex) {
callback(null, ex);
},
})
}),
);
}
}

View File

@ -80,7 +80,7 @@ function initializeMenuItemClickListener(): void {
}
MenuItemClickListener = MenuItemClickListenerImpl;
appResources = (getNativeApp() as android.app.Application).getApplicationContext().getResources();
appResources = getNativeApp<android.app.Application>().getApplicationContext().getResources();
}
export class ActionItem extends ActionItemBase {
@ -310,7 +310,7 @@ export class ActionBar extends ActionBarBase {
if (title !== undefined) {
this.nativeViewProtected.setTitle(title);
} else {
const appContext = (getNativeApp() as android.app.Application).getApplicationContext();
const appContext = getNativeApp<android.app.Application>().getApplicationContext();
const appInfo = appContext.getApplicationInfo();
const appLabel = appContext.getPackageManager().getApplicationLabel(appInfo);
if (appLabel) {
@ -547,7 +547,7 @@ function getDrawableOrResourceId(icon: string, resources: android.content.res.Re
let result = null;
if (icon.indexOf(RESOURCE_PREFIX) === 0) {
const resourceId: number = resources.getIdentifier(icon.substr(RESOURCE_PREFIX.length), 'drawable', (getNativeApp() as android.app.Application).getApplicationContext().getPackageName());
const resourceId: number = resources.getIdentifier(icon.substring(RESOURCE_PREFIX.length), 'drawable', getNativeApp<android.app.Application>().getApplicationContext().getPackageName());
if (resourceId > 0) {
result = resourceId;
}

View File

@ -8,6 +8,9 @@ import { profile } from '../../../profiling';
import { unsetValue, PropertyOptions, CoerciblePropertyOptions, CssPropertyOptions, ShorthandPropertyOptions, CssAnimationPropertyOptions, isCssWideKeyword, isCssUnsetValue, isResetValue } from './property-shared';
import { calc } from '@csstools/css-calc';
// Backwards compatibility
export { unsetValue } from './property-shared';
const cssPropertyNames: string[] = [];
const symbolPropertyMap = {};
const cssSymbolPropertyMap = {};

View File

@ -4,7 +4,7 @@ import { isAccessibilityServiceEnabled } from '../../../application';
import { updateA11yPropertiesCallback } from '../../../application/helpers-common';
import { ShowModalOptions, hiddenProperty } from '../view-base';
import { Trace } from '../../../trace';
import { layout, ios as iosUtils, SDK_VERSION } from '../../../utils';
import { layout, ios as iosUtils, SDK_VERSION, getWindow } from '../../../utils';
import { IOSHelper } from './view-helper';
import { ios as iosBackground, Background } from '../../styling/background';
import { perspectiveProperty, visibilityProperty, opacityProperty, rotateProperty, rotateXProperty, rotateYProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty, zIndexProperty, backgroundInternalProperty } from '../../styling/style-properties';
@ -1082,7 +1082,7 @@ export class CustomLayoutView extends ContainerView {
nativeViewProtected: UIView;
createNativeView() {
const window = iosUtils.getWindow();
const window = getWindow<UIWindow>();
return UIView.alloc().initWithFrame(window ? window.screen.bounds : UIScreen.mainScreen.bounds);
}

View File

@ -3,7 +3,8 @@
*/
import { DialogOptions, ConfirmOptions, PromptOptions, PromptResult, LoginOptions, LoginResult, ActionOptions } from './dialogs-common';
import { getLabelColor, getButtonColors, isDialogOptions, inputType, capitalizationType, DialogStrings, parseLoginOptions } from './dialogs-common';
import { ad } from '../../utils/native-helper';
import { android as androidUtils } from '../../utils/native-helper';
import { getNativeApp } from '../../application/helpers-common';
export * from './dialogs-common';
@ -12,7 +13,7 @@ function isString(value): value is string {
}
function createAlertDialog(options?: DialogOptions): android.app.AlertDialog.Builder {
const alert = new android.app.AlertDialog.Builder(ad.getCurrentActivity(), options.theme ? options.theme : -1);
const alert = new android.app.AlertDialog.Builder(androidUtils.getCurrentActivity(), options.theme ? options.theme : -1);
alert.setTitle(options && isString(options.title) ? options.title : '');
alert.setMessage(options && isString(options.message) ? options.message : '');
if (options && options.cancelable === false) {
@ -202,7 +203,7 @@ export function prompt(...args): Promise<PromptResult> {
try {
const alert = createAlertDialog(options);
const input = new android.widget.EditText(ad.getCurrentActivity());
const input = new android.widget.EditText(androidUtils.getCurrentActivity());
if (options) {
if (options.inputType === inputType.password) {
@ -259,19 +260,19 @@ export function login(...args: any[]): Promise<LoginResult> {
try {
const alert = createAlertDialog(options);
const userNameInput = new android.widget.EditText(ad.getApplicationContext());
const userNameInput = new android.widget.EditText(getNativeApp<android.app.Application>().getApplicationContext());
userNameInput.setHint(options.userNameHint ? options.userNameHint : '');
userNameInput.setText(options.userName ? options.userName : '');
const passwordInput = new android.widget.EditText(ad.getApplicationContext());
const passwordInput = new android.widget.EditText(getNativeApp<android.app.Application>().getApplicationContext());
passwordInput.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD);
passwordInput.setTypeface(android.graphics.Typeface.DEFAULT);
passwordInput.setHint(options.passwordHint ? options.passwordHint : '');
passwordInput.setText(options.password ? options.password : '');
const layout = new android.widget.LinearLayout(ad.getApplicationContext());
const layout = new android.widget.LinearLayout(getNativeApp<android.app.Application>().getApplicationContext());
layout.setOrientation(1);
layout.addView(userNameInput);
layout.addView(passwordInput);
@ -322,7 +323,7 @@ export function action(...args): Promise<string> {
return new Promise<string>((resolve, reject) => {
try {
const alert = new android.app.AlertDialog.Builder(ad.getCurrentActivity(), options.theme ? options.theme : -1);
const alert = new android.app.AlertDialog.Builder(androidUtils.getCurrentActivity(), options.theme ? options.theme : -1);
const message = options && isString(options.message) ? options.message : '';
const title = options && isString(options.title) ? options.title : '';
if (options && options.cancelable === false) {

View File

@ -1,4 +1,4 @@
import type { View } from '../../ui/core/view';
import type { View } from '../core/view';
declare namespace org {
namespace nativescript {

View File

@ -1,4 +1,4 @@
import type { View } from '../../ui/core/view';
import type { View } from '../core/view';
/**
* Whether the app is embedded into a host project or standalone project

View File

@ -207,7 +207,7 @@ export class FragmentCallbacksImplementation implements AndroidFragmentCallbacks
if (hasRemovingParent) {
const nativeFrameView = this.frame.nativeViewProtected;
if (nativeFrameView) {
const bitmapDrawable = new android.graphics.drawable.BitmapDrawable((getNativeApp() as android.app.Application).getApplicationContext().getResources(), this.backgroundBitmap);
const bitmapDrawable = new android.graphics.drawable.BitmapDrawable(getNativeApp<android.app.Application>().getApplicationContext().getResources(), this.backgroundBitmap);
this.frame._originalBackground = this.frame.backgroundColor || new Color('White');
nativeFrameView.setBackgroundDrawable(bitmapDrawable);
this.backgroundBitmap = null;

View File

@ -2,7 +2,7 @@ import { View } from '../core/view';
import { LinearGradient } from './linear-gradient';
import { ClipPathFunction } from './clip-path-function';
import { isDataURI, isFileOrResourcePath, RESOURCE_PREFIX, FILE_PREFIX } from '../../utils';
import { CSSValue, parse } from '../../css-value';
import { CSSValue, parse } from '../../css-value/reworkcss-value';
import { path, knownFolders } from '../../file-system';
export * from './background-common';

View File

@ -1,9 +1,9 @@
import { Font as FontBase, parseFontFamily, genericFontFamilies, FontWeight, FontVariationSettings, FONTS_BASE_PATH } from './font-common';
import { FontStyleType, FontWeightType, FontVariationSettingsType } from './font-interfaces';
import { getNativeApp } from '../../application/helpers-common';
import { Trace } from '../../trace';
import { SDK_VERSION } from '../../utils/constants';
import * as fs from '../../file-system';
import { ad } from '../../utils';
export * from './font-common';
@ -60,7 +60,7 @@ function computeFontCacheKey(fontFamily: string, font: Font) {
function loadFontFromFile(fontFamily: string, font: Font): android.graphics.Typeface {
const cacheKey = SDK_VERSION >= 26 ? computeFontCacheKey(fontFamily, font) : fontFamily;
appAssets = appAssets || (ad.getApplicationContext() as android.content.Context).getAssets();
appAssets = appAssets || getNativeApp<android.app.Application>().getApplicationContext().getAssets();
if (!appAssets) {
return null;
}

View File

@ -284,7 +284,7 @@ function initializeNativeClasses() {
}
PagerAdapter = FragmentPagerAdapter;
appResources = (getNativeApp() as android.app.Application).getApplicationContext().getResources();
appResources = getNativeApp<android.app.Application>().getApplicationContext().getResources();
}
function createTabItemSpec(item: TabViewItem): org.nativescript.widgets.TabItemSpec {

View File

@ -1,15 +1,15 @@
import type { View } from '../core/view';
import { ViewBase } from '../core/view-base';
import { BackstackEntry } from '../frame';
import type { ViewBase } from '../core/view-base';
import type { BackstackEntry } from '../frame';
import { isNumber } from '../../utils/types';
import { Transition } from '.';
import { getRectFromProps, SharedTransition, SharedTransitionAnimationType, SharedTransitionEventData } from './shared-transition';
import { ImageSource } from '../../image-source';
import { ContentView } from '../content-view';
import { GridLayout } from '../layouts/grid-layout';
import { Screen } from '../../platform';
import { Screen } from '../../platform/screen';
import { ExpandedEntry } from '../frame/fragment.transitions.android';
import { android as AndroidUtils } from '../../utils/native-helper';
import { android as androidUtils } from '../../utils/native-helper';
// import { Image } from '../image';
@NativeClass
@ -289,10 +289,10 @@ function loadViewInBackground(view: View) {
hiddenHost.content = hostView;
hiddenHost.visibility = 'collapse';
hostView.addChild(view);
hiddenHost._setupAsRootView(AndroidUtils.getApplicationContext());
hiddenHost._setupAsRootView(androidUtils.getApplicationContext());
hiddenHost.callLoaded();
AndroidUtils.getCurrentActivity().addContentView(hiddenHost.android, new android.view.ViewGroup.LayoutParams(0, 0));
androidUtils.getCurrentActivity().addContentView(hiddenHost.android, new android.view.ViewGroup.LayoutParams(0, 0));
return {
hiddenHost,

View File

@ -16,7 +16,7 @@ function getCurrentAppPath(): string {
return appPath;
} else {
const dir = (getNativeApp() as android.app.Application).getApplicationContext().getFilesDir();
const dir = getNativeApp<android.app.Application>().getApplicationContext().getFilesDir();
return `${dir.getCanonicalPath()}/app`;
}

View File

@ -1,7 +1,7 @@
import { Trace } from '../trace';
import { getFileExtension } from './utils-shared';
import { SDK_VERSION } from './constants';
import { android as AndroidUtils } from './native-helper';
import { android as androidUtils } from './native-helper';
import { topmost } from '../ui/frame/frame-stack';
import { debounce, throttle } from './shared';
@ -61,7 +61,7 @@ export function releaseNativeObject(object: java.lang.Object) {
}
export function openUrl(location: string): boolean {
const context = AndroidUtils.getApplicationContext();
const context = androidUtils.getApplicationContext();
try {
const intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(location.trim()));
intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
@ -79,7 +79,7 @@ export function openUrl(location: string): boolean {
export function openUrlAsync(location: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
const context = AndroidUtils.getApplicationContext();
const context = androidUtils.getApplicationContext();
const intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(location.trim()));
intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
@ -140,7 +140,7 @@ function getMimeTypeNameFromExtension(filePath: string): string {
* @returns {boolean} whether opening the file succeeded or not
*/
export function openFile(filePath: string, title: string = 'Open File...'): boolean {
const context = AndroidUtils.getApplicationContext();
const context = androidUtils.getApplicationContext();
try {
// Ensure external storage is available
if (!isExternalStorageAvailable()) {
@ -222,13 +222,13 @@ Please ensure you have your manifest correctly configured with the FileProvider.
}
export function dismissSoftInput(nativeView?: any): void {
AndroidUtils.dismissSoftInput(nativeView);
androidUtils.dismissSoftInput(nativeView);
}
export function dismissKeyboard() {
dismissSoftInput();
const modalDialog = (topmost()?._modalParent ?? (topmost()?.modal as any))?._dialogFragment?.getDialog();
const view = modalDialog ?? AndroidUtils.getCurrentActivity();
const view = modalDialog ?? androidUtils.getCurrentActivity();
if (view) {
const focus = view.getCurrentFocus();
@ -240,7 +240,7 @@ export function dismissKeyboard() {
export function copyToClipboard(value: string) {
try {
const clipboard = AndroidUtils.getApplicationContext().getSystemService(android.content.Context.CLIPBOARD_SERVICE);
const clipboard = androidUtils.getApplicationContext().getSystemService(android.content.Context.CLIPBOARD_SERVICE);
const clip = android.content.ClipData.newPlainText('Clipboard value', value);
clipboard.setPrimaryClip(clip);
} catch (err) {

View File

@ -1,5 +1,5 @@
import * as layoutCommon from './layout-helper-common';
import { android as AndroidUtils } from '../native-helper';
import { android as androidUtils } from '../native-helper';
// export * from './layout-helper-common';
@ -38,7 +38,7 @@ export namespace layout {
export function makeMeasureSpec(size: number, mode: number): number {
if (sdkVersion === undefined) {
// check whether the old layout is needed
sdkVersion = AndroidUtils.getApplicationContext().getApplicationInfo().targetSdkVersion;
sdkVersion = androidUtils.getApplicationContext().getApplicationInfo().targetSdkVersion;
useOldMeasureSpec = sdkVersion <= 17;
}
@ -51,7 +51,7 @@ export namespace layout {
export function getDisplayDensity(): number {
if (density === undefined) {
density = AndroidUtils.getResources().getDisplayMetrics().density;
density = androidUtils.getResources().getDisplayMetrics().density;
}
return density;

View File

@ -1,10 +1,14 @@
import { platformCheck } from './platform-check';
// importing this helper as a separate file avoids "android" symbol clash with the global android object
import { resources, getApplication, getCurrentActivity, getApplicationContext, getWindow, getResources, getPackageName, getInputMethodManager, showSoftInput, dismissSoftInput } from './native-helper-for-android';
import { resources, collections, getWindow, getApplication, getCurrentActivity, getApplicationContext, getResources, getPackageName, getInputMethodManager, showSoftInput, dismissSoftInput } from './native-helper-for-android';
export { dataSerialize, dataDeserialize } from './native-helper-for-android';
export { getWindow } from './native-helper-for-android';
export const android = {
resources,
collections,
getApplication,
getCurrentActivity,
getApplicationContext,

View File

@ -14,211 +14,42 @@ export function dataDeserialize(nativeData?: any): any;
*/
export function isRealDevice(): boolean;
export function getWindow(): UIWindow | android.view.Window;
// /**
// * Module with android specific utilities.
// */
// declare namespace AndroidUtils {
// /**
// * Gets the native Android application instance.
// */
// export function getApplication(): any; /* android.app.Application */
// /**
// * Get the current native Android activity.
// */
// export function getCurrentActivity(): any; /* android.app.Activity */
// /**
// * Gets the native Android application resources.
// */
// export function getResources(): any; /* android.content.res.Resources */
// /**
// * Gets the Android application context.
// */
// export function getApplicationContext(): any; /* android.content.Context */
// /**
// * Gets the native Android input method manager.
// */
// export function getInputMethodManager(): any; /* android.view.inputmethod.InputMethodManager */
// /**
// * Hides the soft input method, usually a soft keyboard.
// */
// export function dismissSoftInput(nativeView?: any /* android.view.View */): void;
// /**
// * Shows the soft input method, usually a soft keyboard.
// */
// export function showSoftInput(nativeView: any /* android.view.View */): void;
// /**
// * Utility module dealing with some android collections.
// */
// namespace collections {
// /**
// * Converts string array into a String [hash set](http://developer.android.com/reference/java/util/HashSet.html).
// * @param str - An array of strings to convert.
// */
// export function stringArrayToStringSet(str: string[]): any;
// /**
// * Converts string hash set into array of strings.
// * @param stringSet - A string hash set to convert.
// */
// export function stringSetToStringArray(stringSet: any): string[];
// }
// /**
// * Utility module related to android resources.
// */
// export namespace resources {
// /**
// * Gets the drawable id from a given name.
// * @param name - Name of the resource.
// */
// export function getDrawableId(name);
// /**
// * Gets the string id from a given name.
// * @param name - Name of the resource.
// */
// export function getStringId(name);
// /**
// * Gets the id from a given name.
// * @param name - Name of the resource.
// */
// export function getId(name: string): number;
// /**
// * Gets the id from a given name with optional type.
// * This sets an explicit package name.
// * https://developer.android.com/reference/android/content/res/Resources#getIdentifier(java.lang.String,%20java.lang.String,%20java.lang.String)
// * @param name - Name of the resource.
// * @param type - (Optional) type
// */
// export function getResource(name: string, type?: string): number;
// }
// }
// /**
// * Module with ios specific utilities.
// */
// declare namespace iOSUtils {
// // Common properties between UILabel, UITextView and UITextField
// export interface TextUIView {
// font: any;
// textAlignment: number;
// textColor: any;
// text: string;
// attributedText: any;
// lineBreakMode: number;
// numberOfLines: number;
// }
// /**
// * Utility module dealing with some iOS collections.
// */
// export namespace collections {
// /**
// * Converts JavaScript array to [NSArray](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/).
// * @param str - JavaScript string array to convert.
// */
// export function jsArrayToNSArray<T>(str: T[]): NSArray<T>;
// /**
// * Converts NSArray to JavaScript array.
// * @param a - NSArray to convert.
// */
// export function nsArrayToJSArray<T>(a: NSArray<T>): T[];
// }
// /**
// * Get the root UIViewController of the app
// */
// export function getRootViewController(): any; /* UIViewController */
// /**
// * Get the UIWindow of the app
// */
// export function getWindow(): any; /* UIWindow */
// /**
// * Set the window background color of base view of the app.
// * Often this is shown when opening a modal as the view underneath scales down revealing the window color.
// * @param value color (hex, rgb, rgba, etc.)
// */
// export function setWindowBackgroundColor(value: string): void;
// /**
// * Data serialize and deserialize helpers
// */
// export function dataSerialize(data?: any): any;
// export function dataDeserialize(nativeData?: any): any;
// /**
// * @deprecated use application.orientation instead
// *
// * Gets an information about if current mode is Landscape.
// */
// export function isLandscape(): boolean;
// /**
// * Gets the iOS device major version (for 8.1 will return 8).
// */
// export const MajorVersion: number;
// /**
// * Opens file with associated application.
// * @param filePath The file path.
// */
// export function openFile(filePath: string): boolean;
// /**
// * Gets the currently visible(topmost) UIViewController.
// * @param rootViewController The root UIViewController instance to start searching from (normally window.rootViewController).
// * Returns the visible UIViewController.
// */
// export function getVisibleViewController(rootViewController: any /* UIViewController*/): any; /* UIViewController*/
// /**
// * Checks whether the application is running on real device and not on simulator.
// */
// export function isRealDevice(): boolean;
// /**
// * Debug utility to insert CGRect values into logging output.
// * Note: when printing a CGRect directly it will print blank so this helps show the values.
// * @param rect CGRect
// */
// export function printCGRect(rect: CGRect): void;
// /**
// * Take a snapshot of a View on screen.
// * @param view view to snapshot
// * @param scale screen scale
// */
// export function snapshotView(view: UIView, scale: number): UIImage;
// /**
// * Copy layer properties from one view to another.
// * @param view a view to copy layer properties to
// * @param toView a view to copy later properties from
// * @param (optional) custom properties to copy between both views
// */
// export function copyLayerProperties(view: UIView, toView: UIView, customProperties?: { view?: Array<string> /* Array<keyof UIView> */; layer?: Array<string> /* Array<keyof CALayer> */ }): void;
// }
type NativeWindow = android.view.Window | UIWindow;
/**
* Get the UIWindow or android.view.Window of the app
*/
export function getWindow<T extends NativeWindow>(): T;
/**
* Utilities related to Android.
*/
export const android: {
/**
* Utilities related to Android resources.
*/
resources: {
/**
* Gets the drawable id from a given name.
* @param name - Name of the resource.
*/
getDrawableId: (name) => number;
/**
* Gets the string id from a given name.
* @param name - Name of the resource.
*/
getStringId: (name) => number;
/**
* Gets the id from a given name.
* @param name - Name of the resource.
*/
getId: (name: string) => number;
/**
* Gets the id from a given name with optional type.
* This sets an explicit package name.
* https://developer.android.com/reference/android/content/res/Resources#getIdentifier(java.lang.String,%20java.lang.String,%20java.lang.String)
* @param name - Name of the resource.
* @param type - (Optional) type
*/
getResource: (name: string, type?: string) => number;
/**
* Gets a color from the current theme.
@ -227,14 +58,54 @@ export const android: {
*/
getPaletteColor: (name: string, context: android.content.Context) => number;
};
getApplication: () => android.app.Application;
getCurrentActivity: () => androidx.appcompat.app.AppCompatActivity | android.app.Activity | null;
getApplicationContext: () => android.content.Context;
/**
* Utilities related to Android collections.
*/
collections: {
/**
* Converts string array into a String [hash set](http://developer.android.com/reference/java/util/HashSet.html).
* @param str - An array of strings to convert.
*/
stringArrayToStringSet(str: string[]): java.util.HashSet<string>;
/**
* Converts string hash set into array of strings.
* @param stringSet - A string hash set to convert.
*/
stringSetToStringArray(stringSet: any): string[];
};
/**
* @deprecated Use `Utils.getWindow<android.view.Window>()` instead.
* @returns application window.
*/
getWindow: () => android.view.Window;
/**
* Gets the native Android application instance.
*/
getApplication: () => android.app.Application;
/**
* Get the current native Android activity.
*/
getCurrentActivity: () => androidx.appcompat.app.AppCompatActivity | android.app.Activity | null;
/**
* Gets the Android application context.
*/
getApplicationContext: () => android.content.Context;
/**
* Gets the native Android application resources.
*/
getResources: () => android.content.res.Resources;
getPackageName: () => string;
/**
* Gets the native Android input method manager.
*/
getInputMethodManager: () => android.view.inputmethod.InputMethodManager;
/**
* Shows the soft input method, usually a soft keyboard.
*/
showSoftInput: (nativeView: android.view.View) => void;
/**
* Hides the soft input method, usually a soft keyboard.
*/
dismissSoftInput: (nativeView?: android.view.View) => void;
};
@ -243,26 +114,67 @@ export const android: {
*/
export const ad = android;
/**
* Utilities related to iOS.
*/
export const ios: {
/**
* Utilities related to iOS collections.
*/
collections: {
/**
* Converts JavaScript array to [NSArray](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/).
* @param str - JavaScript string array to convert.
*/
jsArrayToNSArray<T>(str: T[]): NSArray<T>;
/**
* Converts NSArray to JavaScript array.
* @param a - NSArray to convert.
*/
nsArrayToJSArray<T>(a: NSArray<T>): Array<T>;
};
/**
* Create a UIDocumentInteractionControllerDelegate implementation for use with UIDocumentInteractionController
*/
createUIDocumentInteractionControllerDelegate: () => NSObject;
/**
* @deprecated Use `Utils.getWindow<UIWindow>()` instead.
* @returns application window.
*/
getWindow: () => UIWindow;
/**
* Gets the root folder for the current application. This Folder is private for the application and not accessible from Users/External apps.
* iOS - this folder is read-only and contains the app and all its resources.
*/
getCurrentAppPath: () => string;
/**
* Get the root UIViewController of the app
*/
getRootViewController: () => UIViewController;
/**
* Gets the currently visible(topmost) UIViewController.
* @param rootViewController The root UIViewController instance to start searching from (normally window.rootViewController).
* Returns the visible UIViewController.
*/
getVisibleViewController: (rootViewController: UIViewController) => UIViewController;
getWindow: () => UIWindow;
getMainScreen: () => UIScreen;
/**
* Set the window background color of base view of the app.
* Often this is the view shown behind opening a modal, eg: a modal scales down revealing the window color.
* @param value color (hex, rgb, rgba, etc.)
*/
setWindowBackgroundColor: (value: string) => void;
/**
* @deprecated use Application.orientation instead
*
* Gets an information about if current mode is Landscape.
*/
isLandscape: () => boolean;
/**
* Take a snapshot of a View on screen.
* @param view view to snapshot
* @param scale screen scale
*/
snapshotView: (view: UIView, scale: number) => UIImage;
/**
* Applies a rotation transform over X,Y and Z axis
@ -272,7 +184,18 @@ export const ios: {
* @param z Rotation over Z axis in degrees
*/
applyRotateTransform: (transform: CATransform3D, x: number, y: number, z: number) => CATransform3D;
/**
* Debug utility to insert CGRect values into logging output.
* Note: when printing a CGRect directly it will print blank so this helps show the values.
* @param rect CGRect
*/
printCGRect: (rect: CGRect) => void;
/**
* Copy layer properties from one view to another.
* @param view a view to copy layer properties to
* @param toView a view to copy later properties from
* @param (optional) custom properties to copy between both views
*/
copyLayerProperties: (view: UIView, toView: UIView, customProperties?: { view?: Array<keyof UIView>; layer?: Array<keyof CALayer> }) => void;
/**
* Animate views with a configurable spring effect