definitions fixed

This commit is contained in:
Erjan Gavalji
2015-03-03 10:34:40 +02:00
parent a03ce4ca1d
commit cc829e0152
705 changed files with 321431 additions and 148812 deletions

View File

@@ -1,31 +1,14 @@
To initialize the module put the following code in the main entry point file (app.js):
```js
var appModule = require("application");
appModule.init([native app instance]);
Use the frame in the following way:
### To navigate to the starting page of the application
```javascript
// put this in the bootstrap.js
var app = require("application");
var frameModule = require("ui/frame");
app.onLaunch = function(context) {
var frame = new frameModule.Frame();
frame.navigate("testPage");
}
```
iOS example:
```js
var app = require("application");
var MyViewController = UIKit.UIViewController.extends({
viewDidLoad: function() {
this.title = "Home";
var bm = require("ui/button");
var button = new bm.Button();
button.text = "test";
button.ios.frame = Foundation.CGRectMake(100, 100, 100, 40);
button.on("click", function(arg){
require("ui/dialogs").alert("Some message");
});
button.addToParent(this.view);
}
});
app.onLaunch = function(){
return new MyViewController();
}
app.init();
```

View File

@@ -1,6 +1,15 @@
require("globals");
import definition = require("application");
import cssParser = require("js-libs/reworkcss");
import fs = require("file-system");
import fileSystemAccess = require("file-system/file-system-access");
import styleScope = require("ui/styling/style-scope");
export var onLaunch: () => any = undefined;
export var cssFile: string = "app/app.css"
export var onUncaughtError: (error: definition.NativeScriptError) => void = undefined;
export var onLaunch: (context: any) => any = undefined;
export var onSuspend: () => any = undefined;
@@ -12,4 +21,17 @@ export var onLowMemory: () => any = undefined;
export var android = undefined;
export var ios = undefined;
export var ios = undefined;
export function loadCss() {
if (definition.cssFile) {
var cssFileName = fs.path.join(fs.knownFolders.currentApp().path, definition.cssFile);
var applicationCss;
if (fs.File.exists(cssFileName)) {
// Read the CSS file.
new fileSystemAccess.FileSystemAccess().readText(cssFileName, r => { applicationCss = r; });
var applicationCssSyntaxTree = cssParser.parse(applicationCss, undefined);
definition.cssSelectorsCache = styleScope.StyleScope.createSelectorsFromSyntaxTree(applicationCssSyntaxTree);
}
}
}

View File

@@ -1,6 +1,7 @@
import appModule = require("application/application-common");
import dts = require("application");
import frame = require("ui/frame");
import types = require("utils/types");
// merge the exports of the application_common file with the exports of this file
declare var exports;
@@ -8,6 +9,8 @@ require("utils/module-merge").merge(appModule, exports);
var callbacks = android.app.Application.ActivityLifecycleCallbacks;
export var mainModule: string;
// We are using the exports object for the common events since we merge the appModule with this module's exports, which is what users will receive when require("application") is called;
// TODO: This is kind of hacky and is "pure JS in TypeScript"
@@ -93,18 +96,17 @@ var initEvents = function () {
return lifecycleCallbacks;
}
var initialized;
export var init = function (nativeApp: android.app.Application) {
if (initialized) {
return;
app.init({
getActivity: function (intent: android.content.Intent) {
return exports.android.getActivity(intent);
},
onCreate: function () {
var androidApp = new AndroidApplication(this);
exports.android = androidApp;
androidApp.init();
}
var app = new AndroidApplication(nativeApp);
exports.android = app;
app.init();
initialized = true;
}
});
class AndroidApplication implements dts.AndroidApplication {
public nativeApp: android.app.Application;
@@ -113,6 +115,7 @@ class AndroidApplication implements dts.AndroidApplication {
public foregroundActivity: android.app.Activity;
public startActivity: android.app.Activity;
public packageName: string;
public hasActionBar: boolean;
// public getActivity: (intent: android.content.Intent) => any;
public onActivityCreated: (activity: android.app.Activity, bundle: android.os.Bundle) => void;
@@ -123,21 +126,81 @@ class AndroidApplication implements dts.AndroidApplication {
public onActivityStopped: (activity: android.app.Activity) => void;
public onSaveActivityState: (activity: android.app.Activity, bundle: android.os.Bundle) => void;
public onActivityResult: (requestCode: number, resultCode: number, data: android.content.Intent) => void;
private _eventsToken: any;
//private _initialized: boolean;
constructor(nativeApp: any) {
this.nativeApp = nativeApp;
this.packageName = nativeApp.getPackageName();
this.context = nativeApp.getApplicationContext();
}
public getActivity(intent: android.content.Intent): any {
var currentPage = rootFrame.currentPage;
if (!currentPage) {
throw new Error("Root frame not navigated to a page.");
//private setupUI() {
// // TODO: We probably don't need this flag if onCreate is going to be called once.
// if (!this._initialized) {
// this._initialized = true;
// if (mainModule && mainModule !== "") {
// var mainPage = require(mainModule).Page;
// if (mainPage instanceof page.Page) {
// this._rootView.addView(<android.view.View>mainPage.android);
// // TODO: We need to show ActionBar if there are any toolBar items
// // or if navigation page - showNavigationBar is true
// var showActionBar = false;
// if (mainPage instanceof page.TabbedPage) {
// showActionBar = true;
// this.startActivity.getActionBar().NavigationMode = android.app.ActionBar.NAVIGATION_MODE_TABS;
// }
// else if (mainPage instanceof page.NavigationPage) {
// showActionBar = (<page.NavigationPage>mainPage).showActionBar;
// this.startActivity.getActionBar().NavigationMode = android.app.ActionBar.NAVIGATION_MODE_STANDARD;
// }
// if (showActionBar) {
// this.startActivity.getActionBar().show();
// }
// else {
// this.startActivity.getActionBar().hide();
// }
// }
// else {
// // TODO: Throw exception when/if we remove Page/Frame support.
// }
// }
// }
//}
public getActivity(intent: android.content.Intent): Object {
if (intent && intent.Action === android.content.Intent.ACTION_MAIN) {
// application's main activity
if (exports.onLaunch) {
exports.onLaunch(intent);
}
/* In the onLaunch event we expect the following setup, which ensures a root frame:
* var frame = require("ui/frame");
* var rootFrame = new frame.Frame();
* rootFrame.navigate({ pageModuleName: "mainPage" });
*/
}
return currentPage.android.getActivityExtends();
var topFrame = frame.topmost();
if (!topFrame) {
// try to navigate to the mainModule (if specified)
if (mainModule) {
topFrame = new frame.Frame();
topFrame.navigate(mainModule);
} else {
// TODO: Throw an exception?
throw new Error("A Frame must be used to navigate to a Page.");
}
}
return topFrame.android.onActivityRequested(intent);
}
public init() {
@@ -147,5 +210,20 @@ class AndroidApplication implements dts.AndroidApplication {
}
}
// The root frame of the application
export var rootFrame = new frame.Frame();
global.__onUncaughtError = function (error: Error) {
if (!types.isFunction(exports.onUncaughtError)) {
return;
}
var nsError = {
message: error.message,
name: error.name,
nativeError: (<any>error).nativeException
}
exports.onUncaughtError(nsError);
}
exports.start = function () {
dts.loadCss();
}

View File

@@ -1,142 +1,192 @@

/**
* Contains the application abstraction with all related methods.
*/
declare module "application" {
import frame = require("ui/frame");
export var rootFrame: frame.Frame;
import cssSelector = require("ui/styling/css-selector");
/**
* An extended JavaScript Error which will have the nativeError property initialized in case the error is caused by executing platform-specific code.
*/
export interface NativeScriptError extends Error {
/**
* Represents the native error object.
*/
nativeError: any;
}
/**
* The main page path (without the file extension) for the application starting from the application root.
* For example if you have page called "main.js" in a folder called "subFolder" and your root folder is "app" you can specify mainModule like this:
* var application = require("application");
* application.mainModule = "app/subFolder/main";
* application.start();
*/
export var mainModule: string;
/**
* The application level css file name (starting from the application root). Used to set css across all pages.
* Css will be applied for every page and page css will be applied after.
*/
export var cssFile: string;
/**
* Cached css selectors created from the content of the css file.
*/
export var cssSelectorsCache: Array<cssSelector.CssSelector>;
/**
* Loads css file and parses to a css syntax tree.
*/
export function loadCss(): void;
/**
* Call this method to start the application. Important: All code after this method call will not be executed!
*/
export function start();
/**
* The main entry point event. This method is expected to use the root frame to navigate to the main application page.
*/
export function onLaunch(): void;
export function onLaunch(context: any): void;
/**
* A callback to be used when an uncaught error occurs while the application is running.
* The application will be shut down after this method returns.
* Loading new UI at this point is erroneous and may lead to unpredictable results.
* The method is intended to be used for crash reports and/or application restart.
*/
export function onUncaughtError(error: NativeScriptError): void;
/**
* This method will be called when the Application is suspended.
*/
export function onSuspend();
/**
/**
* This method will be called when the Application is resumed after it has been suspended.
*/
export function onResume();
/**
/**
* This method will be called when the Application is about to exit.
*/
export function onExit();
/**
/**
* This method will be called when there is low memory on the target device.
*/
export function onLowMemory();
/**
/**
* This is the Android-specific application object instance.
* Encapsulates methods and properties specific to the Android platform.
* Will be undefined when TargetOS is iOS.
*/
export var android: AndroidApplication;
/**
/**
* This is the iOS-specific application object instance.
* Encapsulates methods and properties specific to the iOS platform.
* Will be undefined when TargetOS is Android.
*/
export var ios: iOSApplication;
/**
* Entry point for the module. Initializes the Application singleton and hooks application lifecycle events.
* @param nativeApp The instance of the platform Application object - e.g. android.app.Application
*/
export function init(nativeApp: any);
/**
/**
* The abstraction of an Android-specific application object.
*/
interface AndroidApplication {
/**
* The android.app.Application object instance provided to the init of the module.
export interface AndroidApplication {
/**
* The [android Application](http://developer.android.com/reference/android/app/Application.html) object instance provided to the init of the module.
*/
nativeApp: android.app.Application;
/**
* The application android.content.Context object instance.
/**
* The application's [android Context](http://developer.android.com/reference/android/content/Context.html) object instance.
*/
context: android.content.Context;
/**
* The currently active (loaded) android.app.Activity. This property is automatically updated upon Activity events.
/**
* The currently active (loaded) [android Activity](http://developer.android.com/reference/android/app/Activity.html). This property is automatically updated upon Activity events.
*/
foregroundActivity: android.app.Activity;
/**
/**
* The currently active (loaded) Context. This is typically the top-level Activity that is just created.
*/
currentContext: android.content.Context;
/**
/**
* The main (start) Activity for the application.
*/
startActivity: android.app.Activity;
/**
/**
* The name of the application package.
*/
packageName: string;
/**
/**
* This method is called by the JavaScript Bridge when navigation to a new activity is triggered.
* The return value of this method should be com.tns.NativeScriptActivity.extends implementation.
* @param intent - Native (android) intent used to create the activity.
* Returns com.tns.NativeScriptActivity.extend implementation.
*/
getActivity(intent: android.content.Intent): any;
/**
* Direct handler of the android.app.Application.ActivityLifecycleCallbacks.onActivityCreated method.
/**
* Direct handler of the [onActivityCreated method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/
onActivityCreated: (activity: android.app.Activity, bundle: android.os.Bundle) => void;
/**
* Direct handler of the android.app.Application.ActivityLifecycleCallbacks.onActivityDestroyed method.
/**
* Direct handler of the [onActivityDestroyed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/
onActivityDestroyed: (activity: android.app.Activity) => void;
/**
* Direct handler of the android.app.Application.ActivityLifecycleCallbacks.onActivityDestroyed method.
/**
* Direct handler of the [onActivityDestroyed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/
onActivityStarted: (activity: android.app.Activity) => void;
/**
* Direct handler of the android.app.Application.ActivityLifecycleCallbacks.onActivityPaused method.
/**
* Direct handler of the [onActivityPaused method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/
onActivityPaused: (activity: android.app.Activity) => void;
/**
* Direct handler of the android.app.Application.ActivityLifecycleCallbacks.onActivityResumed method.
/**
* Direct handler of the [onActivityResumed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/
onActivityResumed: (activity: android.app.Activity) => void;
/**
* Direct handler of the android.app.Application.ActivityLifecycleCallbacks.onActivityStopped method.
/**
* Direct handler of the [onActivityStopped method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/
onActivityStopped: (activity: android.app.Activity) => void;
/**
* Direct handler of the android.app.Application.ActivityLifecycleCallbacks.onSaveActivityState method.
/**
* Direct handler of the [onActivitySaveInstanceState method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/
onSaveActivityState: (activity: android.app.Activity, bundle: android.os.Bundle) => void;
/**
* Direct handler of the onActivityResult method.
*/
onActivityResult: (requestCode: number, resultCode: number, data: android.content.Intent) => void
}
/**
/* tslint:disable */
/**
* The abstraction of an iOS-specific application object.
*/
interface iOSApplication {
/**
export interface iOSApplication {
/* tslint:enable */
/**
* The root view controller for the application.
*/
rootController: UIKit.UIViewController;
rootController: UIViewController;
/**
* The android.app.Application object instance provided to the init of the module.
/**
* The [UIApplication](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html) object instance provided to the init of the module.
*/
nativeApp: UIKit.UIApplication;
nativeApp: UIApplication;
}
}

View File

@@ -1,116 +1,192 @@

/*
Current launch sequence for iOS looks like:
var app = require("application");
app.tk.ui.Application.current.onLaunch = function() {
log("tk.ui.Application.current.onLaunch");
var myViewController = new MyViewController();
var navController = new UIKit.UINavigationController(myViewController);
return navController;
}
log("JavaScript loading started.");
app.tk.ui.ios.initApp(null);
log("JavaScript loading ended.");
log("JavaScript loading ended.");
*/
import appModule = require("application/application-common");
import appModule = require("application/application-common");
import frame = require("ui/frame");
import utils = require("utils/utils");
import types = require("utils/types");
import view = require("ui/core/view");
import definition = require("application");
// merge the exports of the application_common file with the exports of this file
declare var exports;
require("utils/module-merge").merge(appModule, exports);
var initialized;
export var init = function (nativeApp: any) {
if (initialized) {
return;
export var mainModule: string;
class Window extends UIWindow {
private _content: view.View;
initWithFrame(frame: CGRect): UIWindow {
var window = super.initWithFrame(frame);
if (window) {
window.autoresizingMask = UIViewAutoresizing.UIViewAutoresizingNone;
}
return window;
}
var app = new iOSApplication(nativeApp);
exports.ios = app;
app.init();
public get content(): view.View {
return this._content;
}
public set content(value: view.View) {
this._content = value;
}
initialized = true;
public layoutSubviews(): void {
if (!this._content) {
// TODO: Invalid setup, throw an exception?
return;
}
var statusFrame = UIApplication.sharedApplication().statusBarFrame;
var statusBarHeight = 0;
try {
statusBarHeight = Math.min(statusFrame.size.width, statusFrame.size.height);
} catch (ex) {
console.log("exception: " + ex);
}
var isLandscape = utils.ios.isLandscape();
var iOSMajorVersion = utils.ios.MajorVersion;
// in iOS 8 when in landscape statusbar is hidden.
if (isLandscape && iOSMajorVersion > 7) {
statusBarHeight = 0;
}
var deviceFrame = UIScreen.mainScreen().bounds;
var size = deviceFrame.size;
var width = size.width;
var height = size.height;
// in iOS 7 when in landscape we switch width with height because on device they don't change even when rotated.
if (iOSMajorVersion < 8 && isLandscape) {
width = size.height;
height = size.width;
}
var origin = deviceFrame.origin;
var left = origin.x;
var top = origin.y + statusBarHeight;
var widthSpec = utils.layout.makeMeasureSpec(width, utils.layout.EXACTLY);
var heightSpec = utils.layout.makeMeasureSpec(height - statusBarHeight, utils.layout.EXACTLY);
this._content.measure(widthSpec, heightSpec);
this._content.layout(left, top, width, height);
}
}
class iOSApplication {
class TNSAppDelegate extends UIResponder implements UIApplicationDelegate {
// An array of protocols to be implemented by the native class
public static ObjCProtocols = [UIApplicationDelegate];
public window: Window;
applicationDidFinishLaunchingWithOptions(application: UIApplication, launchOptions: NSDictionary): boolean {
this.window = <Window>Window.alloc().initWithFrame(UIScreen.mainScreen().bounds);
this.window.backgroundColor = UIColor.whiteColor();
if (exports.onLaunch) {
exports.onLaunch();
}
var topFrame = frame.topmost();
if (!topFrame) {
if (mainModule) {
topFrame = new frame.Frame();
topFrame.navigate(mainModule);
} else {
// TODO: Throw an exception?
// throw new Error("A Frame must be used to navigate to a Page.");
return;
}
}
this.window.content = topFrame;
this.window.rootViewController = topFrame.ios.controller;
var app: IOSApplication = exports.ios;
app.rootController = this.window.rootViewController;
this.window.makeKeyAndVisible();
return true;
}
applicationDidBecomeActive(application: UIApplication) {
if (exports.onResume) {
exports.onResume();
}
}
applicationWillResignActive(application: UIApplication) {
//
}
applicationDidEnterBackground(application: UIApplication) {
if (exports.onSuspend) {
exports.onSuspend();
}
}
applicationWillEnterForeground(application: UIApplication) {
//
}
applicationWillTerminate(application: UIApplication) {
if (exports.onExit) {
exports.onExit();
}
}
applicationDidReceiveMemoryWarning(application: UIApplication) {
if (exports.onLowMemory) {
exports.onLowMemory();
}
}
applicationOpenURLSourceApplicationAnnotation(application: UIApplication, url: NSURL, sourceApplication: string, annotation: any): boolean {
var dictionary = new NSMutableDictionary();
dictionary.setObjectForKey(url, "TLKApplicationOpenURL");
dictionary.setObjectForKey(application, "TLKApplication");
NSNotificationCenter.defaultCenter().postNotificationNameObjectUserInfo("com.telerik.TLKApplicationOpenURL", null, dictionary);
return true; // or should we return false???
}
}
class IOSApplication implements definition.iOSApplication {
public nativeApp: any;
public rootController: any;
private _tnsAppdelegate: TNSAppDelegate;
constructor(nativeApp: any) {
constructor() {
// TODO: in iOS there is the singleton instance, while in Android such does not exist hence we pass it as argument
// this.nativeApp = nativeApp;
this.nativeApp = UIKit.UIApplication.sharedApplication();
this.nativeApp = UIApplication.sharedApplication();
}
public init() {
var that = this;
UIKit.UIResponder.extends({/*TODO: Empty parameter here, needs API improvement*/}, {
name: "TNSAppDelegate",
}).implements({
protocol: "UIApplicationDelegate",
implementation: {
applicationDidFinishLaunchingWithOptions: function () {
log("Application launched: applicationDidFinishLaunchingWithOptions.");
this._tnsAppdelegate = new TNSAppDelegate();
}
}
this.window = new UIKit.UIWindow(UIKit.UIScreen.mainScreen().bounds);
this.window.backgroundColor = UIKit.UIColor.whiteColor();
this.window.makeKeyAndVisible();
// TODO: If we have nested require(application) calls we may enter unfinished module state, which will create two delegates, resulting in an exception
var app = new IOSApplication();
exports.ios = app;
app.init();
if (exports.onLaunch) {
that.rootController = exports.onLaunch();
this.window.rootViewController = that.rootController;
} else {
log("Missing Application.onLaunch");
}
exports.start = function () {
appModule.loadCss();
try {
// The "UIApplicationMain" enters a modal loop and the call will not return while the application is running.
// This try-catch block here will catch JavaScript errors but no Objective C ones.
// TODO: We need to implement better error handling for our native calls and to use the "error" parameter of the iOS APIs.
UIApplicationMain(0, null, null, "TNSAppDelegate");
}
catch (error) {
// At this point the main application loop is exited and no UI May be created.
if (!types.isFunction(exports.onUncaughtError)) {
return;
}
log("applicationDidFinishLaunchingWithOptions finished.");
return true;
},
applicationDidBecomeActive: function (application) {
log("applicationDidBecomeActive: " + application);
if (exports.onResume) {
exports.onResume();
}
},
applicationWillResignActive: function (application) {
log("applicationWillResignActive: " + application);
},
applicationDidEnterBackground: function (application) {
log("applicationDidEnterBackground: " + application);
if (exports.onSuspend) {
exports.onSuspend();
}
},
applicationWillEnterForeground: function (application) {
log("applicationWillEnterForeground: " + application);
},
applicationWillTerminate: function (application) {
log("applicationWillTerminate: " + application);
if (exports.onExit) {
exports.onExit();
}
},
applicationDidReceiveMemoryWarning: function (application) {
log("applicationDidReceiveMemoryWarning: " + application);
if (exports.onLowMemory) {
exports.onLowMemory();
}
}
}
});
exports.onUncaughtError(error);
}
}

View File

@@ -1,2 +0,0 @@
declare var module, require;
module.exports = require("application/application");

2
application/package.json Normal file
View File

@@ -0,0 +1,2 @@
{ "name" : "application",
"main" : "application.js" }