mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
Fixed most module cyclic references. There is one left for ios and android: (#4978)
- http -> http-request -> image-source that can't be fixed easily and will be removed once we delete image-source module because it is obsolete anyway. There is one more for android: - frame -> fragment that could be removed if we use global object. Updated madge bersion
This commit is contained in:
@ -27,7 +27,7 @@
|
||||
"grunt-ts": "6.0.0-beta.11",
|
||||
"grunt-typedoc": "0.2.4",
|
||||
"http-server": "^0.9.0",
|
||||
"madge": "^2.0.0",
|
||||
"madge": "^2.2.0",
|
||||
"markdown-snippet-injector": "0.2.2",
|
||||
"mocha": "^3.5.0",
|
||||
"mocha-typescript": "^1.1.9",
|
||||
@ -80,6 +80,8 @@
|
||||
"test-tsc-es2016": "npm run tsc -- -p tsconfig.public.es2016.json",
|
||||
"tslint": "tslint --config build/tslint.json 'tns-core-modules/**/*.ts' 'tests/**/*.ts' 'apps/**/*.ts' -e '**/node_modules/**' -e '**/platforms/**'",
|
||||
"madge-ios": "tsc --skipLibCheck && tns prepare ios --path tests && madge --circular tests/platforms/ios/tests/app/tns_modules/tns-core-modules",
|
||||
"madge-android": "tsc --skipLibCheck && tns prepare android --path tests && madge --circular tests/platforms/android/src/main/assets/app/tns_modules/tns-core-modules"
|
||||
"madge-ios-image": "tsc --skipLibCheck && tns prepare ios --path tests && madge --image graph-tests-ios.svg tests/platforms/ios/tests/app/tns_modules/tns-core-modules",
|
||||
"madge-android": "tsc --skipLibCheck && tns prepare android --path tests && madge --circular tests/platforms/android/src/main/assets/app/tns_modules/tns-core-modules",
|
||||
"madge-android-image": "tsc --skipLibCheck && tns prepare android --path tests && madge --image graph-tests-android.svg tests/platforms/android/src/main/assets/app/tns_modules/tns-core-modules"
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ export { Observable };
|
||||
|
||||
import { UnhandledErrorEventData, iOSApplication, AndroidApplication, CssChangedEventData, LoadAppCSSEventData } from ".";
|
||||
|
||||
export { UnhandledErrorEventData, CssChangedEventData, LoadAppCSSEventData };
|
||||
|
||||
export const launchEvent = "launch";
|
||||
export const suspendEvent = "suspend";
|
||||
export const displayedEvent = "displayed";
|
||||
@ -55,6 +57,10 @@ export function setApplication(instance: iOSApplication | AndroidApplication): v
|
||||
|
||||
export function livesync() {
|
||||
events.notify(<EventData>{ eventName: "livesync", object: app });
|
||||
const liveSyncCore = global.__onLiveSyncCore;
|
||||
if (liveSyncCore) {
|
||||
liveSyncCore();
|
||||
}
|
||||
}
|
||||
|
||||
export function setCssFileName(cssFileName: string) {
|
||||
|
@ -2,7 +2,7 @@ import { PlatformContext, FileNameResolver as FileNameResolverDefinition } from
|
||||
import { screen, device } from "../../platform";
|
||||
import { path as fsPath, Folder, File } from "../file-system";
|
||||
import * as trace from "../../trace";
|
||||
import * as appModule from "../../application";
|
||||
import * as appCommonModule from "../../application/application-common";
|
||||
|
||||
const MIN_WH: string = "minWH";
|
||||
const MIN_W: string = "minW";
|
||||
@ -234,5 +234,5 @@ export function resolveFileName(path: string, ext: string): string {
|
||||
return resolverInstance.resolveFileName(path, ext);
|
||||
}
|
||||
|
||||
appModule.on("cssChanged", args => resolverInstance = undefined);
|
||||
appModule.on("livesync", args => resolverInstance && resolverInstance.clearCache());
|
||||
appCommonModule.on("cssChanged", args => resolverInstance = undefined);
|
||||
appCommonModule.on("livesync", args => resolverInstance && resolverInstance.clearCache());
|
@ -1,15 +1,13 @@
|
||||
import * as textModule from "../text";
|
||||
import * as utilsModule from "../utils/utils";
|
||||
|
||||
import * as utils from "../utils/utils";
|
||||
import { encoding as textEncoding } from "../text";
|
||||
import { ios } from "../utils/utils";
|
||||
|
||||
// TODO: Implement all the APIs receiving callback using async blocks
|
||||
// TODO: Check whether we need try/catch blocks for the iOS implementation
|
||||
export class FileSystemAccess {
|
||||
|
||||
public getLastModified(path: string): Date {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
var attributes = fileManager.attributesOfItemAtPathError(path);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const attributes = fileManager.attributesOfItemAtPathError(path);
|
||||
|
||||
if (attributes) {
|
||||
return attributes.objectForKey("NSFileModificationDate");
|
||||
@ -20,18 +18,17 @@ export class FileSystemAccess {
|
||||
|
||||
public getParent(path: string, onError?: (error: any) => any): { path: string; name: string } {
|
||||
try {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
var nsString = NSString.stringWithString(path);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const nsString = NSString.stringWithString(path);
|
||||
|
||||
var parentPath = nsString.stringByDeletingLastPathComponent;
|
||||
var name = fileManager.displayNameAtPath(parentPath);
|
||||
const parentPath = nsString.stringByDeletingLastPathComponent;
|
||||
const name = fileManager.displayNameAtPath(parentPath);
|
||||
|
||||
return {
|
||||
path: parentPath.toString(),
|
||||
name: name
|
||||
};
|
||||
}
|
||||
catch (exception) {
|
||||
} catch (exception) {
|
||||
if (onError) {
|
||||
onError(exception);
|
||||
}
|
||||
@ -42,13 +39,13 @@ export class FileSystemAccess {
|
||||
|
||||
public getFile(path: string, onError?: (error: any) => any): { path: string; name: string; extension: string } {
|
||||
try {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
var exists = fileManager.fileExistsAtPath(path);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const exists = fileManager.fileExistsAtPath(path);
|
||||
|
||||
if (!exists) {
|
||||
var parentPath = this.getParent(path, onError).path;
|
||||
if (!fileManager.createDirectoryAtPathWithIntermediateDirectoriesAttributesError(parentPath, true, null) ||
|
||||
!fileManager.createFileAtPathContentsAttributes(path, null, null)) {
|
||||
const parentPath = this.getParent(path, onError).path;
|
||||
if (!fileManager.createDirectoryAtPathWithIntermediateDirectoriesAttributesError(parentPath, true, null)
|
||||
|| !fileManager.createFileAtPathContentsAttributes(path, null, null)) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to create file at path '" + path + "'"));
|
||||
}
|
||||
@ -56,15 +53,14 @@ export class FileSystemAccess {
|
||||
}
|
||||
}
|
||||
|
||||
var fileName = fileManager.displayNameAtPath(path);
|
||||
const fileName = fileManager.displayNameAtPath(path);
|
||||
|
||||
return {
|
||||
path: path,
|
||||
name: fileName,
|
||||
extension: this.getFileExtension(path)
|
||||
};
|
||||
}
|
||||
catch (exception) {
|
||||
} catch (exception) {
|
||||
if (onError) {
|
||||
onError(exception);
|
||||
}
|
||||
@ -75,8 +71,8 @@ export class FileSystemAccess {
|
||||
|
||||
public getFolder(path: string, onError?: (error: any) => any): { path: string; name: string } {
|
||||
try {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
var exists = this.folderExists(path);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const exists = this.folderExists(path);
|
||||
|
||||
if (!exists) {
|
||||
try {
|
||||
@ -91,14 +87,13 @@ export class FileSystemAccess {
|
||||
}
|
||||
}
|
||||
|
||||
var dirName = fileManager.displayNameAtPath(path);
|
||||
const dirName = fileManager.displayNameAtPath(path);
|
||||
|
||||
return {
|
||||
path: path,
|
||||
name: dirName
|
||||
};
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to create folder at path '" + path + "'"));
|
||||
}
|
||||
@ -107,29 +102,27 @@ export class FileSystemAccess {
|
||||
}
|
||||
}
|
||||
|
||||
public getExistingFolder(path: string, onError?: (error: any) => any): { path: string; name: string } {
|
||||
public getExistingFolder(path: string, onError?: (error: any) => any): { path: string; name: string } {
|
||||
try {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
var exists = this.folderExists(path);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const exists = this.folderExists(path);
|
||||
|
||||
if (exists) {
|
||||
var dirName = fileManager.displayNameAtPath(path);
|
||||
|
||||
const dirName = fileManager.displayNameAtPath(path);
|
||||
return {
|
||||
path: path,
|
||||
name: dirName
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to get folder at path '" + path + "'"));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public eachEntity(path: string, onEntity: (file: { path: string; name: string; extension: string }) => any, onError?: (error: any) => any) {
|
||||
if (!onEntity) {
|
||||
@ -140,15 +133,15 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
public getEntities(path: string, onError?: (error: any) => any): Array<{ path: string; name: string; extension: string }> {
|
||||
var fileInfos = new Array<{ path: string; name: string; extension: string }>();
|
||||
const fileInfos = new Array<{ path: string; name: string; extension: string }>();
|
||||
|
||||
var onEntity = function (entity: { path: string; name: string; extension: string }): boolean {
|
||||
const onEntity = function (entity: { path: string; name: string; extension: string }): boolean {
|
||||
fileInfos.push(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
var errorOccurred;
|
||||
var localError = function (error: any) {
|
||||
let errorOccurred;
|
||||
const localError = function (error: any) {
|
||||
if (onError) {
|
||||
onError(error);
|
||||
}
|
||||
@ -166,31 +159,25 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
public fileExists(path: string): boolean {
|
||||
var result = this.exists(path);
|
||||
const result = this.exists(path);
|
||||
return result.exists;
|
||||
}
|
||||
|
||||
public folderExists(path: string): boolean {
|
||||
var result = this.exists(path);
|
||||
const result = this.exists(path);
|
||||
return result.exists && result.isDirectory;
|
||||
}
|
||||
|
||||
private exists(path: string): { exists: boolean, isDirectory: boolean } {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
var isDirectory = new interop.Reference(interop.types.bool, false);
|
||||
var exists = fileManager.fileExistsAtPathIsDirectory(path, isDirectory);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const isDirectory = new interop.Reference(interop.types.bool, false);
|
||||
const exists = fileManager.fileExistsAtPathIsDirectory(path, isDirectory);
|
||||
|
||||
return { exists: exists, isDirectory: isDirectory.value };
|
||||
}
|
||||
|
||||
public concatPath(left: string, right: string): string {
|
||||
var utils: typeof utilsModule = require("utils/utils");
|
||||
|
||||
// TODO: This probably is not efficient, we may try concatenation with the "/" character
|
||||
var nsArray = utils.ios.collections.jsArrayToNSArray([left, right]);
|
||||
var nsString = NSString.pathWithComponents(nsArray);
|
||||
|
||||
return nsString.toString();
|
||||
return NSString.pathWithComponents(<any>[left, right]).toString();
|
||||
}
|
||||
|
||||
public deleteFile(path: string, onError?: (error: any) => any) {
|
||||
@ -202,15 +189,14 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
public emptyFolder(path: string, onError?: (error: any) => any) {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
var entities = this.getEntities(path, onError);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const entities = this.getEntities(path, onError);
|
||||
|
||||
if (!entities) {
|
||||
return;
|
||||
}
|
||||
|
||||
var i;
|
||||
for (i = 0; i < entities.length; i++) {
|
||||
for (let i = 0; i < entities.length; i++) {
|
||||
try {
|
||||
fileManager.removeItemAtPathError(entities[i].path);
|
||||
}
|
||||
@ -225,12 +211,11 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
public rename(path: string, newPath: string, onError?: (error: any) => any) {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
|
||||
try {
|
||||
fileManager.moveItemAtPathToPathError(path, newPath);
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to rename '" + path + "' to '" + newPath + "': " + ex));
|
||||
}
|
||||
@ -238,8 +223,8 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
public getLogicalRootPath(): string {
|
||||
let mainBundlePath = utils.ios.getter(NSBundle, NSBundle.mainBundle).bundlePath;
|
||||
let resolvedPath = NSString.stringWithString(mainBundlePath).stringByResolvingSymlinksInPath;
|
||||
const mainBundlePath = ios.getter(NSBundle, NSBundle.mainBundle).bundlePath;
|
||||
const resolvedPath = NSString.stringWithString(mainBundlePath).stringByResolvingSymlinksInPath;
|
||||
return resolvedPath;
|
||||
}
|
||||
|
||||
@ -252,30 +237,16 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
public getCurrentAppPath(): string {
|
||||
const currentDir = __dirname;
|
||||
const tnsModulesIndex = currentDir.indexOf("/tns_modules");
|
||||
|
||||
// Module not hosted in ~/tns_modules when bundled. Use current dir.
|
||||
let appPath = currentDir;
|
||||
if (tnsModulesIndex !== -1) {
|
||||
// Strip part after tns_modules to obtain app root
|
||||
appPath = currentDir.substring(0, tnsModulesIndex);
|
||||
}
|
||||
|
||||
return appPath;
|
||||
return ios.getCurrentAppPath();
|
||||
}
|
||||
|
||||
public readText(path: string, onError?: (error: any) => any, encoding?: any) {
|
||||
var actualEncoding = encoding;
|
||||
if (!actualEncoding) {
|
||||
actualEncoding = textModule.encoding.UTF_8;
|
||||
}
|
||||
const actualEncoding = encoding || textEncoding.UTF_8;
|
||||
|
||||
try {
|
||||
var nsString = NSString.stringWithContentsOfFileEncodingError(path, actualEncoding);
|
||||
const nsString = NSString.stringWithContentsOfFileEncodingError(path, actualEncoding);
|
||||
return nsString.toString();
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to read file at path '" + path + "': " + ex));
|
||||
}
|
||||
@ -285,8 +256,7 @@ export class FileSystemAccess {
|
||||
public read(path: string, onError?: (error: any) => any): NSData {
|
||||
try {
|
||||
return NSData.dataWithContentsOfFile(path);
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to read file at path '" + path + "': " + ex));
|
||||
}
|
||||
@ -294,18 +264,14 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
public writeText(path: string, content: string, onError?: (error: any) => any, encoding?: any) {
|
||||
var nsString = NSString.stringWithString(content);
|
||||
const nsString = NSString.stringWithString(content);
|
||||
|
||||
var actualEncoding = encoding;
|
||||
if (!actualEncoding) {
|
||||
actualEncoding = textModule.encoding.UTF_8;
|
||||
}
|
||||
const actualEncoding = encoding || textEncoding.UTF_8;
|
||||
|
||||
// TODO: verify the useAuxiliaryFile parameter should be false
|
||||
try {
|
||||
nsString.writeToFileAtomicallyEncodingError(path, false, actualEncoding);
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to write to file '" + path + "': " + ex));
|
||||
}
|
||||
@ -315,8 +281,7 @@ export class FileSystemAccess {
|
||||
public write(path: string, content: NSData, onError?: (error: any) => any) {
|
||||
try {
|
||||
content.writeToFileAtomically(path, true);
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to write to file '" + path + "': " + ex));
|
||||
}
|
||||
@ -324,10 +289,10 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
private getKnownPath(folderType: number): string {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
var paths = fileManager.URLsForDirectoryInDomains(folderType, NSSearchPathDomainMask.UserDomainMask);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const paths = fileManager.URLsForDirectoryInDomains(folderType, NSSearchPathDomainMask.UserDomainMask);
|
||||
|
||||
var url = paths.objectAtIndex(0);
|
||||
const url = paths.objectAtIndex(0);
|
||||
return url.path;
|
||||
}
|
||||
|
||||
@ -335,15 +300,15 @@ export class FileSystemAccess {
|
||||
// Make it in a separate file / module so it can be reused from both implementations.
|
||||
private getFileExtension(path: string): string {
|
||||
// TODO [For Panata]: The definitions currently specify "any" as a return value of this method
|
||||
//var nsString = Foundation.NSString.stringWithString(path);
|
||||
//var extension = nsString.pathExtension();
|
||||
//const nsString = Foundation.NSString.stringWithString(path);
|
||||
//const extension = nsString.pathExtension();
|
||||
|
||||
//if (extension && extension.length > 0) {
|
||||
// extension = extension.concat(".", extension);
|
||||
//}
|
||||
|
||||
//return extension;
|
||||
var dotIndex = path.lastIndexOf(".");
|
||||
const dotIndex = path.lastIndexOf(".");
|
||||
if (dotIndex && dotIndex >= 0 && dotIndex < path.length) {
|
||||
return path.substring(dotIndex);
|
||||
}
|
||||
@ -352,11 +317,10 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
private deleteEntity(path: string, onError?: (error: any) => any) {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
try {
|
||||
fileManager.removeItemAtPathError(path);
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to delete file at path '" + path + "': " + ex));
|
||||
}
|
||||
@ -365,11 +329,11 @@ export class FileSystemAccess {
|
||||
|
||||
private enumEntities(path: string, callback: (entity: { path: string; name: string; extension: string }) => boolean, onError?: (error) => any) {
|
||||
try {
|
||||
var fileManager = utils.ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
const fileManager = ios.getter(NSFileManager, NSFileManager.defaultManager);
|
||||
let files: NSArray<string>;
|
||||
try {
|
||||
var files = fileManager.contentsOfDirectoryAtPathError(path);
|
||||
}
|
||||
catch (ex) {
|
||||
files = fileManager.contentsOfDirectoryAtPathError(path);
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(new Error("Failed to enum files for folder '" + path + "': " + ex));
|
||||
}
|
||||
@ -377,31 +341,26 @@ export class FileSystemAccess {
|
||||
return;
|
||||
}
|
||||
|
||||
var file;
|
||||
var i;
|
||||
var info;
|
||||
var retVal;
|
||||
for (let i = 0; i < files.count; i++) {
|
||||
const file = files.objectAtIndex(i);
|
||||
|
||||
for (i = 0; i < files.count; i++) {
|
||||
file = files.objectAtIndex(i);
|
||||
|
||||
info = {
|
||||
const info = {
|
||||
path: this.concatPath(path, file),
|
||||
name: file
|
||||
name: file,
|
||||
extension: ''
|
||||
};
|
||||
|
||||
if (!this.folderExists(this.joinPath(path, file))) {
|
||||
info.extension = this.getFileExtension(info.path);
|
||||
}
|
||||
|
||||
retVal = callback(info);
|
||||
const retVal = callback(info);
|
||||
if (retVal === false) {
|
||||
// the callback returned false meaning we should stop the iteration
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
} catch (ex) {
|
||||
if (onError) {
|
||||
onError(ex);
|
||||
}
|
||||
@ -413,30 +372,18 @@ export class FileSystemAccess {
|
||||
}
|
||||
|
||||
public normalizePath(path: string): string {
|
||||
var nsString: NSString = NSString.stringWithString(path);
|
||||
var normalized = nsString.stringByStandardizingPath;
|
||||
const nsString: NSString = NSString.stringWithString(path);
|
||||
const normalized = nsString.stringByStandardizingPath;
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
public joinPath(left: string, right: string): string {
|
||||
var nsString: NSString = NSString.stringWithString(left);
|
||||
const nsString: NSString = NSString.stringWithString(left);
|
||||
return nsString.stringByAppendingPathComponent(right);
|
||||
}
|
||||
|
||||
public joinPaths(paths: string[]): string {
|
||||
if (!paths || paths.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
var nsArray = NSMutableArray.alloc<string>().initWithCapacity(paths.length);
|
||||
|
||||
var i;
|
||||
for (i = 0; i < paths.length; i++) {
|
||||
nsArray.addObject(paths[i]);
|
||||
}
|
||||
|
||||
var nsString = NSString.stringWithString(NSString.pathWithComponents(nsArray));
|
||||
return nsString.stringByStandardizingPath;
|
||||
return ios.joinPaths(...paths);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import * as image from "../image-source";
|
||||
import { ImageSource } from "../image-source";
|
||||
import * as httpRequest from "./http-request";
|
||||
|
||||
global.moduleMerge(httpRequest, exports);
|
||||
@ -31,7 +31,7 @@ export function getJSON<T>(arg: any): Promise<T> {
|
||||
});
|
||||
}
|
||||
|
||||
export function getImage(arg: any): Promise<image.ImageSource> {
|
||||
export function getImage(arg: any): Promise<ImageSource> {
|
||||
return httpRequest
|
||||
.request(typeof arg === "string" ? { url: arg, method: "GET" } : arg)
|
||||
.then(responce => responce.content.toImage());
|
||||
|
@ -148,6 +148,7 @@ export function fromBase64(source: string): ImageSource;
|
||||
export function fromNativeSource(source: any): ImageSource;
|
||||
|
||||
/**
|
||||
* Deprecated. Use http.getImage(url: string) instead.
|
||||
* Downloads the image from the provided Url and creates a new ImageSource instance from it.
|
||||
* @param url The link to the remote image object. This operation will download and decode the image.
|
||||
*/
|
||||
|
1
tns-core-modules/module.d.ts
vendored
1
tns-core-modules/module.d.ts
vendored
@ -38,6 +38,7 @@ declare namespace NodeJS {
|
||||
__inspector?: any;
|
||||
__extends: any;
|
||||
__onLiveSync: () => void;
|
||||
__onLiveSyncCore: () => void;
|
||||
__onUncaughtError: (error: NativeScriptError) => void;
|
||||
TNS_WEBPACK?: boolean;
|
||||
__requireOverride?: (name: string, dir: string) => any;
|
||||
|
@ -9,7 +9,7 @@ import { escapeRegexSymbols } from "../../../utils/utils";
|
||||
import { isEnabled as traceEnabled, write as traceWrite, categories as traceCategories, notifyEvent as traceNotifyEvent, isCategorySet, messageType as traceMessageType } from "../../../trace";
|
||||
import * as types from "../../../utils/types";
|
||||
|
||||
import * as application from "../../../application";
|
||||
import * as applicationCommon from "../../../application/application-common";
|
||||
import * as polymerExpressions from "../../../js-libs/polymer-expressions";
|
||||
|
||||
export {
|
||||
@ -357,7 +357,7 @@ export class Binding {
|
||||
let context = this.source && this.source.get && this.source.get() || global;
|
||||
let model = {};
|
||||
let addedProps = [];
|
||||
const resources = application.getResources();
|
||||
const resources = applicationCommon.getResources();
|
||||
for (let prop in resources) {
|
||||
if (resources.hasOwnProperty(prop) && !context.hasOwnProperty(prop)) {
|
||||
context[prop] = resources[prop];
|
||||
|
@ -6,13 +6,12 @@ import { Order, FlexGrow, FlexShrink, FlexWrapBefore, AlignSelf } from "../../la
|
||||
import { KeyframeAnimation } from "../../animation/keyframe-animation";
|
||||
|
||||
// Types.
|
||||
import { Source } from "../../../utils/debug";
|
||||
import { Property, CssProperty, CssAnimationProperty, InheritedProperty, Style, clearInheritedProperties, propagateInheritableProperties, propagateInheritableCssProperties, resetCSSProperties, initNativeView, resetNativeView } from "../properties";
|
||||
import { Source } from "../../../utils/debug";
|
||||
import { Binding, BindingOptions, Observable, WrappedValue, PropertyChangeData, traceEnabled, traceWrite, traceCategories, traceNotifyEvent } from "../bindable";
|
||||
import { isIOS, isAndroid } from "../../../platform";
|
||||
import { layout } from "../../../utils/utils";
|
||||
import { Length, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty } from "../../styling/style-properties";
|
||||
import { DOMNode } from "../../../debugger/dom-node";
|
||||
|
||||
// TODO: Remove this import!
|
||||
import * as types from "../../../utils/types";
|
||||
@ -27,6 +26,16 @@ export * from "../properties";
|
||||
|
||||
import * as ssm from "../../styling/style-scope";
|
||||
|
||||
// import { DOMNode } from "../../../debugger/dom-node";
|
||||
import * as dnm from "../../../debugger/dom-node";
|
||||
let domNodeModule: typeof dnm;
|
||||
|
||||
function ensuredomNodeModule(): void {
|
||||
if (!domNodeModule) {
|
||||
domNodeModule = require("../../../debugger/dom-node");
|
||||
}
|
||||
}
|
||||
|
||||
let styleScopeModule: typeof ssm;
|
||||
function ensureStyleScopeModule() {
|
||||
if (!styleScopeModule) {
|
||||
@ -142,7 +151,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
private _visualState: string;
|
||||
private __nativeView: any;
|
||||
// private _disableNativeViewRecycling: boolean;
|
||||
public domNode: DOMNode;
|
||||
public domNode: dnm.DOMNode;
|
||||
|
||||
public recycleNativeView: "always" | "never" | "auto";
|
||||
public bindingContext: any;
|
||||
@ -271,7 +280,8 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
|
||||
public ensureDomNode() {
|
||||
if (!this.domNode) {
|
||||
this.domNode = new DOMNode(this);
|
||||
ensuredomNodeModule();
|
||||
this.domNode = new domNodeModule.DOMNode(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
// Definitions.
|
||||
import { View as ViewDefinition, Point, Size, Color, dip } from ".";
|
||||
import { HorizontalAlignment, VerticalAlignment, Visibility, Length, PercentLength } from "../../styling/style-properties";
|
||||
|
||||
import {
|
||||
ViewBase, Property, booleanConverter, EventData, layout,
|
||||
getEventOrGestureName, traceEnabled, traceWrite, traceCategories
|
||||
} from "../view-base";
|
||||
|
||||
import { HorizontalAlignment, VerticalAlignment, Visibility, Length, PercentLength } from "../../styling/style-properties";
|
||||
|
||||
import {
|
||||
observe as gestureObserve,
|
||||
GesturesObserver,
|
||||
|
@ -1,11 +1,12 @@
|
||||
// Definitions.
|
||||
import { Point, View as ViewDefinition, dip } from ".";
|
||||
|
||||
import { ios, Background } from "../../styling/background";
|
||||
import {
|
||||
ViewCommon, layout, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty,
|
||||
traceEnabled, traceWrite, traceCategories
|
||||
} from "./view-common";
|
||||
|
||||
import { ios, Background } from "../../styling/background";
|
||||
import {
|
||||
Visibility,
|
||||
visibilityProperty, opacityProperty,
|
||||
|
@ -7,34 +7,10 @@ import { View, CustomLayoutView, isIOS, isAndroid, traceEnabled, traceWrite, tra
|
||||
import { resolveFileName } from "../../file-system/file-name-resolver";
|
||||
import { knownFolders, path } from "../../file-system";
|
||||
import { parse, loadPage } from "../builder";
|
||||
import * as application from "../../application";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export { application };
|
||||
|
||||
export * from "../core/view";
|
||||
|
||||
function onLivesync(args: EventData): void {
|
||||
// give time to allow fileNameResolver & css to reload.
|
||||
setTimeout(() => {
|
||||
let g = <any>global;
|
||||
// Close the error page if available and remove the reference from global context.
|
||||
if (g.errorPage) {
|
||||
g.errorPage.closeModal();
|
||||
g.errorPage = undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
g.__onLiveSyncCore();
|
||||
} catch (ex) {
|
||||
// Show the error as modal page, save reference to the page in global context.
|
||||
g.errorPage = parse(`<Page><ScrollView><Label text="${ex}" textWrap="true" style="color: red;" /></ScrollView></Page>`);
|
||||
g.errorPage.showModal();
|
||||
}
|
||||
});
|
||||
}
|
||||
application.on("livesync", onLivesync);
|
||||
|
||||
let frameStack: Array<FrameBase> = [];
|
||||
|
||||
function buildEntryFromArgs(arg: any): NavigationEntry {
|
||||
|
@ -6,7 +6,8 @@ import {
|
||||
import { Page } from "../page";
|
||||
|
||||
// Types.
|
||||
import { FrameBase, application, NavigationContext, stack, goBack, View, Observable, traceEnabled, traceWrite, traceCategories } from "./frame-common";
|
||||
import * as application from "../../application";
|
||||
import { FrameBase, NavigationContext, stack, goBack, View, Observable, traceEnabled, traceWrite, traceCategories } from "./frame-common";
|
||||
import { DIALOG_FRAGMENT_TAG } from "../page/constants";
|
||||
import {
|
||||
_setAndroidFragmentTransitions, _onFragmentCreateAnimator,
|
||||
|
@ -4,7 +4,7 @@ import { Page } from "../page";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
//Types.
|
||||
import { FrameBase, View, application, layout, traceEnabled, traceWrite, traceCategories, isCategorySet } from "./frame-common";
|
||||
import { FrameBase, View, topmost, layout, traceEnabled, traceWrite, traceCategories, isCategorySet } from "./frame-common";
|
||||
import { _createIOSAnimatedTransitioning } from "./fragment.transitions";
|
||||
// HACK: Webpack. Use a fully-qualified import to allow resolve.extensions(.ios.js) to
|
||||
// kick in. `../utils` doesn't seem to trigger the webpack extensions mechanism.
|
||||
@ -20,6 +20,39 @@ const DELEGATE = "_delegate";
|
||||
|
||||
let navDepth = -1;
|
||||
|
||||
class NotificationObserver2 extends NSObject {
|
||||
private _onReceiveCallback: (notification: NSNotification) => void;
|
||||
|
||||
public static initWithCallback(onReceiveCallback: (notification: NSNotification) => void): NotificationObserver2 {
|
||||
const observer = <NotificationObserver2>super.new();
|
||||
observer._onReceiveCallback = onReceiveCallback;
|
||||
return observer;
|
||||
}
|
||||
|
||||
public onReceive(notification: NSNotification): void {
|
||||
this._onReceiveCallback(notification);
|
||||
}
|
||||
|
||||
public static ObjCExposedMethods = {
|
||||
"onReceive": { returns: interop.types.void, params: [NSNotification] }
|
||||
};
|
||||
}
|
||||
|
||||
const observer = NotificationObserver2.initWithCallback(handleNotification);
|
||||
const notificationCenter = utils.ios.getter(NSNotificationCenter, NSNotificationCenter.defaultCenter);
|
||||
notificationCenter.addObserverSelectorNameObject(observer, "onReceive", UIApplicationDidChangeStatusBarFrameNotification, null);
|
||||
|
||||
function handleNotification(notification: NSNotification): void {
|
||||
// When there is a 40px high "in-call" status bar, nobody moves the navigationBar top from 20 to 40 and it remains underneath the status bar.
|
||||
const frame = topmost() as Frame;
|
||||
if (frame) {
|
||||
frame._handleHigherInCallStatusBarIfNeeded();
|
||||
if (frame.currentPage) {
|
||||
frame.currentPage.requestLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Frame extends FrameBase {
|
||||
private _ios: iOSFrame;
|
||||
private _paramToNavigate: any;
|
||||
@ -37,18 +70,6 @@ export class Frame extends FrameBase {
|
||||
super();
|
||||
this._ios = new iOSFrame(this);
|
||||
this.nativeViewProtected = this._ios.controller.view;
|
||||
|
||||
// When there is a 40px high "in-call" status bar, nobody moves the navigationBar top from 20 to 40 and it remains underneath the status bar.
|
||||
let frameRef = new WeakRef(this);
|
||||
application.ios.addNotificationObserver(UIApplicationDidChangeStatusBarFrameNotification, (notification: NSNotification) => {
|
||||
let frame = frameRef.get();
|
||||
if (frame) {
|
||||
frame._handleHigherInCallStatusBarIfNeeded();
|
||||
if (frame.currentPage) {
|
||||
frame.currentPage.requestLayout();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@profile
|
||||
|
@ -1,4 +1,8 @@
|
||||
// Types
|
||||
import { unsetValue, Style,
|
||||
CssProperty, CssAnimationProperty,
|
||||
ShorthandProperty, InheritedCssProperty,
|
||||
makeValidator, makeParser } from "../core/properties";
|
||||
import {
|
||||
Transformation,
|
||||
TransformationValue,
|
||||
@ -9,15 +13,10 @@ import { dip, px, percent } from "../core/view";
|
||||
|
||||
import { Color } from "../../color";
|
||||
import { Font, parseFont, FontStyle, FontWeight } from "../../ui/styling/font";
|
||||
import { layout } from "../../utils/utils";
|
||||
import { layout, hasDuplicates } from "../../utils/utils";
|
||||
import { Background } from "../../ui/styling/background";
|
||||
import { isIOS } from "../../platform";
|
||||
|
||||
import { Style } from "./style";
|
||||
|
||||
import { unsetValue, CssProperty, CssAnimationProperty, ShorthandProperty, InheritedCssProperty, makeValidator, makeParser } from "../core/properties";
|
||||
|
||||
import { hasDuplicates } from "../../utils/utils";
|
||||
import { radiansToDegrees } from "../../utils/number-utils";
|
||||
|
||||
import {
|
||||
|
@ -28,7 +28,7 @@ import {
|
||||
messageType as traceMessageType,
|
||||
} from "../../trace";
|
||||
import { File, knownFolders, path } from "../../file-system";
|
||||
import * as application from "../../application";
|
||||
import * as applicationCommon from "../../application/application-common";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
import * as kam from "../animation/keyframe-animation";
|
||||
@ -216,7 +216,7 @@ class CSSSource {
|
||||
}
|
||||
}
|
||||
|
||||
const onCssChanged = profile('"style-scope".onCssChanged', (args: application.CssChangedEventData) => {
|
||||
const onCssChanged = profile('"style-scope".onCssChanged', (args: applicationCommon.CssChangedEventData) => {
|
||||
if (args.cssText) {
|
||||
const parsed = CSSSource.fromSource(args.cssText, applicationKeyframes, args.cssFile).selectors;
|
||||
if (parsed) {
|
||||
@ -228,8 +228,8 @@ const onCssChanged = profile('"style-scope".onCssChanged', (args: application.Cs
|
||||
}
|
||||
});
|
||||
|
||||
function onLiveSync(args: application.CssChangedEventData): void {
|
||||
loadCss(application.getCssFileName());
|
||||
function onLiveSync(args: applicationCommon.CssChangedEventData): void {
|
||||
loadCss(applicationCommon.getCssFileName());
|
||||
}
|
||||
|
||||
const loadCss = profile(`"style-scope".loadCss`, (cssFile: string) => {
|
||||
@ -244,18 +244,18 @@ const loadCss = profile(`"style-scope".loadCss`, (cssFile: string) => {
|
||||
}
|
||||
});
|
||||
|
||||
application.on("cssChanged", onCssChanged);
|
||||
application.on("livesync", onLiveSync);
|
||||
applicationCommon.on("cssChanged", onCssChanged);
|
||||
applicationCommon.on("livesync", onLiveSync);
|
||||
|
||||
export const loadAppCSS = profile('"style-scope".loadAppCSS', (args: application.LoadAppCSSEventData) => {
|
||||
export const loadAppCSS = profile('"style-scope".loadAppCSS', (args: applicationCommon.LoadAppCSSEventData) => {
|
||||
loadCss(args.cssFile);
|
||||
application.off("loadAppCss", loadAppCSS);
|
||||
applicationCommon.off("loadAppCss", loadAppCSS);
|
||||
});
|
||||
|
||||
if (application.hasLaunched()) {
|
||||
loadAppCSS({ eventName: "loadAppCss", object: <any>application, cssFile: application.getCssFileName() });
|
||||
if (applicationCommon.hasLaunched()) {
|
||||
loadAppCSS({ eventName: "loadAppCss", object: <any>applicationCommon, cssFile: applicationCommon.getCssFileName() });
|
||||
} else {
|
||||
application.on("loadAppCss", loadAppCSS);
|
||||
applicationCommon.on("loadAppCss", loadAppCSS);
|
||||
}
|
||||
|
||||
export class CssState {
|
||||
|
@ -31,7 +31,6 @@ export function convertString(value: any): any {
|
||||
}
|
||||
|
||||
export module layout {
|
||||
|
||||
const MODE_SHIFT = 30;
|
||||
const MODE_MASK = 0x3 << MODE_SHIFT;
|
||||
|
||||
@ -48,11 +47,8 @@ export module layout {
|
||||
switch (mode) {
|
||||
case layout.EXACTLY:
|
||||
return "Exact";
|
||||
|
||||
case layout.AT_MOST:
|
||||
|
||||
return "AtMost";
|
||||
|
||||
default:
|
||||
return "Unspecified";
|
||||
}
|
||||
@ -67,23 +63,17 @@ export module layout {
|
||||
}
|
||||
|
||||
export function measureSpecToString(measureSpec: number): string {
|
||||
let mode = getMeasureSpecMode(measureSpec);
|
||||
let size = getMeasureSpecSize(measureSpec);
|
||||
const mode = getMeasureSpecMode(measureSpec);
|
||||
const size = getMeasureSpecSize(measureSpec);
|
||||
|
||||
let text = "MeasureSpec: ";
|
||||
|
||||
if (mode === UNSPECIFIED) {
|
||||
text += "UNSPECIFIED ";
|
||||
}
|
||||
else if (mode === EXACTLY) {
|
||||
} else if (mode === EXACTLY) {
|
||||
text += "EXACTLY ";
|
||||
}
|
||||
else if (mode === AT_MOST) {
|
||||
} else if (mode === AT_MOST) {
|
||||
text += "AT_MOST ";
|
||||
}
|
||||
else {
|
||||
text += mode + " ";
|
||||
}
|
||||
|
||||
text += size;
|
||||
return text;
|
||||
@ -126,9 +116,9 @@ export function mergeSort(arr, compareFunc) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
let middle = arr.length / 2;
|
||||
let left = arr.slice(0, middle);
|
||||
let right = arr.slice(middle, arr.length);
|
||||
const middle = arr.length / 2;
|
||||
const left = arr.slice(0, middle);
|
||||
const right = arr.slice(middle, arr.length);
|
||||
|
||||
return merge(mergeSort(left, compareFunc), mergeSort(right, compareFunc), compareFunc);
|
||||
}
|
||||
|
15
tns-core-modules/utils/utils.d.ts
vendored
15
tns-core-modules/utils/utils.d.ts
vendored
@ -233,7 +233,20 @@ export module ios {
|
||||
* Opens file with associated application.
|
||||
* @param filePath The file path.
|
||||
*/
|
||||
export function openFile(filePath: string): boolean
|
||||
export function openFile(filePath: string): boolean;
|
||||
|
||||
/**
|
||||
* Joins an array of file paths.
|
||||
* @param paths An array of paths.
|
||||
* Returns the joined path.
|
||||
*/
|
||||
export function joinPaths(...paths: string[]): string;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
export function getCurrentAppPath(): string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,9 +72,9 @@ export module ios {
|
||||
}
|
||||
|
||||
export function isLandscape(): boolean {
|
||||
var device = getter(UIDevice, UIDevice.currentDevice);
|
||||
var statusBarOrientation = getter(UIApplication, UIApplication.sharedApplication).statusBarOrientation;
|
||||
var isStatusBarOrientationLandscape = isOrientationLandscape(statusBarOrientation);
|
||||
const device = getter(UIDevice, UIDevice.currentDevice);
|
||||
const statusBarOrientation = getter(UIApplication, UIApplication.sharedApplication).statusBarOrientation;
|
||||
const isStatusBarOrientationLandscape = isOrientationLandscape(statusBarOrientation);
|
||||
return isOrientationLandscape(device.orientation) || isStatusBarOrientationLandscape;
|
||||
}
|
||||
|
||||
@ -82,10 +82,10 @@ export module ios {
|
||||
|
||||
export function openFile(filePath: string): boolean {
|
||||
try {
|
||||
var fs: typeof fsModule = require("file-system");
|
||||
var path = filePath.replace("~", fs.knownFolders.currentApp().path)
|
||||
const appPath = getCurrentAppPath();
|
||||
const path = filePath.replace("~", appPath)
|
||||
|
||||
var controller = UIDocumentInteractionController.interactionControllerWithURL(NSURL.fileURLWithPath(path));
|
||||
const controller = UIDocumentInteractionController.interactionControllerWithURL(NSURL.fileURLWithPath(path));
|
||||
controller.delegate = new UIDocumentInteractionControllerDelegateImpl();
|
||||
return controller.presentPreviewAnimated(true);
|
||||
}
|
||||
@ -94,6 +94,28 @@ export module ios {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getCurrentAppPath(): string {
|
||||
const currentDir = __dirname;
|
||||
const tnsModulesIndex = currentDir.indexOf("/tns_modules");
|
||||
|
||||
// Module not hosted in ~/tns_modules when bundled. Use current dir.
|
||||
let appPath = currentDir;
|
||||
if (tnsModulesIndex !== -1) {
|
||||
// Strip part after tns_modules to obtain app root
|
||||
appPath = currentDir.substring(0, tnsModulesIndex);
|
||||
}
|
||||
|
||||
return appPath;
|
||||
}
|
||||
|
||||
export function joinPaths(...paths: string[]): string {
|
||||
if (!paths || paths.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return NSString.stringWithString(NSString.pathWithComponents(<any>paths)).stringByStandardizingPath;
|
||||
}
|
||||
}
|
||||
|
||||
export function GC() {
|
||||
@ -118,8 +140,8 @@ class UIDocumentInteractionControllerDelegateImpl extends NSObject implements UI
|
||||
public static ObjCProtocols = [UIDocumentInteractionControllerDelegate];
|
||||
|
||||
public getViewController(): UIViewController {
|
||||
var frame = require("ui/frame");
|
||||
return frame.topmost().currentPage.ios;
|
||||
const app = ios.getter(UIApplication, UIApplication.sharedApplication);
|
||||
return app.keyWindow.rootViewController;
|
||||
}
|
||||
|
||||
public documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController) {
|
||||
|
Reference in New Issue
Block a user