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:
Hristo Hristov
2017-11-10 15:47:02 +02:00
committed by GitHub
parent 729b068e7b
commit 43fbabb5e9
19 changed files with 227 additions and 236 deletions

View File

@ -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"
}
}

View File

@ -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";
@ -54,7 +56,11 @@ export function setApplication(instance: iOSApplication | AndroidApplication): v
}
export function livesync() {
events.notify(<EventData>{ eventName: "livesync", object: app });
events.notify(<EventData>{ eventName: "livesync", object: app });
const liveSyncCore = global.__onLiveSyncCore;
if (liveSyncCore) {
liveSyncCore();
}
}
export function setCssFileName(cssFileName: string) {
@ -76,4 +82,4 @@ export function addCss(cssText: string): void {
global.__onUncaughtError = function (error: NativeScriptError) {
events.notify(<UnhandledErrorEventData>{ eventName: uncaughtErrorEvent, object: app, android: error, ios: error, error: error });
}
}

View File

@ -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());

View File

@ -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;
}
@ -250,32 +235,18 @@ export class FileSystemAccess {
public getTempFolderPath(): string {
return this.getKnownPath(NSSearchPathDirectory.CachesDirectory);
}
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;
public getCurrentAppPath(): string {
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);
}
}
}

View File

@ -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());
@ -49,4 +49,4 @@ export function getFile(arg: any, destinationFilePath?: string): Promise<any> {
}
}, e => reject(e));
});
}
}

View File

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

View File

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

View File

@ -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];

View File

@ -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);
}
}

View File

@ -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,
@ -807,4 +808,4 @@ export const isEnabledProperty = new Property<ViewCommon, boolean>({
isEnabledProperty.register(ViewCommon);
export const isUserInteractionEnabledProperty = new Property<ViewCommon, boolean>({ name: "isUserInteractionEnabled", defaultValue: true, valueConverter: booleanConverter });
isUserInteractionEnabledProperty.register(ViewCommon);
isUserInteractionEnabledProperty.register(ViewCommon);

View File

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

View File

@ -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 {
@ -626,4 +602,4 @@ export function goBack(): boolean {
export function stack(): Array<FrameBase> {
return frameStack;
}
}

View File

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

View File

@ -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
@ -730,4 +751,4 @@ class iOSFrame implements iOSFrameDefinition {
public set navBarVisibility(value: "auto" | "never" | "always") {
this._navBarVisibility = value;
}
}
}

View File

@ -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 {
@ -1038,4 +1037,4 @@ export const visibilityProperty = new CssProperty<Style, Visibility>({
target.view.isCollapsed = (newValue === Visibility.COLLAPSE);
}
});
visibilityProperty.register(Style);
visibilityProperty.register(Style);

View File

@ -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 {
@ -662,4 +662,4 @@ class InlineSelector implements SelectorCore {
public dynamic: boolean = false;
public ruleset: RuleSet;
public match(node: Node): boolean { return true; }
}
}

View File

@ -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);
}
@ -160,4 +150,4 @@ export function hasDuplicates(arr: Array<any>): boolean {
export function eliminateDuplicates(arr: Array<any>): Array<any> {
return Array.from(new Set(arr));
}
}

View File

@ -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;
}
/**

View File

@ -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) {
@ -135,4 +157,4 @@ class UIDocumentInteractionControllerDelegateImpl extends NSObject implements UI
}
}
mainScreenScale = ios.getter(UIScreen, UIScreen.mainScreen).scale;
mainScreenScale = ios.getter(UIScreen, UIScreen.mainScreen).scale;