This commit is contained in:
Adam Bradley
2015-06-24 10:28:12 -05:00
parent e5caeb9b8f
commit 535dbf990f
8 changed files with 616 additions and 160 deletions

View File

@ -1,21 +1,13 @@
import {bootstrap} from 'angular2/angular2';
import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
import {Component, Directive, onInit} from 'angular2/src/core/annotations_impl/annotations';
import {View} from 'angular2/src/core/annotations_impl/view';
import {ComponentRef, onDestroy, DomRenderer, ApplicationRef} from 'angular2/angular2';
import {Promise} from 'angular2/src/facade/async';
import {isPresent, Type} from 'angular2/src/facade/lang';
import {Compiler} from 'angular2/angular2';
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
import {Injector} from 'angular2/di';
import {Parent} from 'angular2/src/core/annotations_impl/visibility';
import {bind} from 'angular2/di';
import {Injectable} from 'angular2/src/di/decorators';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
import {IonicConfig} from '../../config/config';
import {ViewController} from '../view/view-controller';
import {Platform} from '../../platform/platform';
import * as util from '../../util/util';
export class IonicApp {
@ -24,6 +16,72 @@ export class IonicApp {
this.overlays = [];
}
config(val) {
if (arguments.length) {
this._config = val;
}
return this._config;
}
url(val) {
if (arguments.length) {
this._url = val;
this._qs = util.getQuerystring(val);
}
return this._url;
}
query(key) {
return (this._qs || {})[key];
}
userAgent(val) {
if (arguments.length) {
this._ua = val;
}
return this._ua;
}
matchesQuery(queryKey, queryValue) {
const val = this.query(queryKey);
return !!(val && val == queryValue);
}
matchesUserAgent(userAgentExpression) {
const rx = new RegExp(userAgentExpression, 'i');
return rx.test(this._ua);
}
matchesPlatform(platformQueryValue, platformUserAgentExpression) {
if (!platformUserAgentExpression) {
platformUserAgentExpression = platformQueryValue;
}
return this.matchesQuery('ionicplatform', platformQueryValue) ||
this.matchesUserAgent(platformUserAgentExpression);
}
matchesDevice(deviceQueryValue, deviceUserAgentExpression) {
if (!deviceUserAgentExpression) {
deviceUserAgentExpression = deviceQueryValue;
}
return this.matchesQuery('ionicdevice', deviceQueryValue) ||
this.matchesUserAgent(deviceUserAgentExpression);
}
width(val) {
if (arguments.length) {
this._w = val;
}
return this._w || 0;
}
height(val) {
if (arguments.length) {
this._h = val;
}
return this._h || 0;
}
/**
* Create and append the given component into the root
* element of the app.
@ -67,9 +125,9 @@ export class IonicApp {
});
}
ref() {
ref(val) {
if (arguments.length) {
this._ref = arguments[0];
this._ref = val;
}
return this._ref;
}
@ -78,26 +136,52 @@ export class IonicApp {
export function ionicBootstrap(ComponentType, config) {
return new Promise((resolve, reject) => {
try {
let app = new IonicApp();
config = config || new IonicConfig();
app.url(window.location.href);
app.userAgent(window.navigator.userAgent);
app.width(window.innerWidth);
app.height(window.innerHeight);
let componentInjectableBindings = [
let platform = Platform.getActivePlatform(app);
config = config || new IonicConfig();
config.platform(platform);
GlobalIonicConfig = config;
let injectableBindings = [
bind(IonicApp).toValue(app),
bind(Platform).toValue(platform),
bind(IonicConfig).toValue(config)
];
bootstrap(ComponentType, componentInjectableBindings).then(appRef => {
bootstrap(ComponentType, injectableBindings).then(appRef => {
app.ref(appRef);
resolve(app);
let rootPlatform = platform.root();
rootPlatform.runAll();
resolve({
app,
config,
platform
});
}).catch(err => {
console.error('ionicBootstrap', err);
reject(err);
});
} catch (err) {
console.error('ionicBootstrap', err);
reject(err);
}
});
}
export let GlobalIonicConfig = null;
export function load(app) {
if (!app) {
console.error('Invalid app module');

View File

@ -149,12 +149,32 @@ export class ModalSecondPage {
}
export function main(ionicBootstrap) {
// crazy config
let myConfig = new IonicConfig();
ionicBootstrap(MyApp, myConfig).then(app => {
// crazy run
console.log('ionicBootstrap', app);
let myConfig = new IonicConfig({
'adams': 'config',
'tabBarPlacement': 'adam'
});
// myConfig.platform('ios', {
// 'tabBarPlacement': 'ios'
// });
// myConfig.device('ipad', {
// 'tabBarPlacement': 'ipad'
// });
// myConfig.platform('android', {
// 'tabBarPlacement': 'android'
// });
ionicBootstrap(MyApp, myConfig).then(root => {
console.log('mobile', root.platform.is('mobile'))
console.log('ipad', root.platform.is('ipad'))
console.log('tablet', root.platform.is('tablet'))
console.log('ios', root.platform.is('ios'))
console.log('android', root.platform.is('android'))
});
}

View File

@ -3,8 +3,7 @@ import {DirectiveMetadata} from 'angular2/src/render/api';
import * as util from 'ionic/util';
import {Platform} from 'ionic/platform/platform';
const platformMode = Platform.getMode();
import {GlobalIonicConfig} from '../components/app/app';
export class IonicDirective extends Directive {
@ -23,8 +22,6 @@ function appendModeConfig(ComponentType) {
let config = ComponentType.config;
config.host = config.host || {};
// let host = DirectiveMetadata.parseHostConfig(config.host);
const defaultProperties = config.defaultProperties;
config.properties = config.properties || [];
@ -56,20 +53,13 @@ function appendModeConfig(ComponentType) {
continue;
}
// get the property values from a global user config
var globalPropertyValue = null;
if (globalPropertyValue) {
// get the property values from a global user/platform config
let configVal = GlobalIonicConfig.setting(prop);
if (configVal) {
instance[prop] = globalPropertyValue;
continue;
}
// get the property values provided by this mode/platform
var modePropertyValue = null;
if (modePropertyValue) {
instance[prop] = modePropertyValue;
continue;
}
// wasn't set yet, so go with property's default value
instance[prop] = defaultProperties[prop];
}
@ -92,8 +82,14 @@ function appendModeConfig(ComponentType) {
};
}
if (!platformMode) {
platformMode = GlobalIonicConfig.setting('mode');
}
let id = config.classId || (config.selector && config.selector.replace('ion-', ''));
config.host['class'] = (id + ' ' + id + '-' + platformMode);
return config;
}
let platformMode = null;

View File

@ -1,9 +1,123 @@
import {isString, isObject, isDefined} from '../util/util';
export class IonicConfig {
constructor() {
this.canWe = true;
constructor(settings={}) {
this._settings = settings;
this._settings.platforms = this._settings.platforms || {};
}
platform(val) {
if (arguments.length) {
this._platform = val;
}
return this._platform;
}
setting() {
const args = arguments;
const arg0 = args[0];
const arg1 = args[1];
const arg2 = args[2];
const arg3 = args[3];
const argLength = args.length;
let s = this._settings;
if (argLength === 0) {
// setting() = get settings object
return s;
} else if (argLength === 1) {
// setting({...}) = set settings object
// setting('key') = get value
if (isObject(arg0)) {
// setting({...}) = set settings object
// arg0 = setting object
s = arg0;
} else if (isString(arg0)) {
// setting('key') = get value
// arg0 = key
return s[arg0]
}
} else if (argLength === 2) {
// setting('key', 'value') = set key/value pair
// arg0 = key
// arg1 = value
s[arg0] = arg1;
} else if (argLength > 2) {
// create platform object and platformKey object if needed
// arg0 = key
// arg1 = platform key
s.platforms = s.platforms || {};
s.platforms[arg1] = s.platforms[arg1] || {};
if (argLength === 3) {
// setting('key', 'ios', 'value') = set key/value pair for platform
// arg0 = key
// arg1 = platform key
// arg2 = value
s.platforms[arg1][arg0] = arg2;
} else if (argLength === 4) {
// setting('key', 'ios', 'ipad', 'value') = set key/value pair for platform/device
// arg0 = key
// arg1 = platform key
// arg2 = device key
// arg3 = value
s.platforms[arg1] = s.platforms[arg1] || {};
}
}
if (arguments.length > 1) {
this._settings[key] = val;
} else {
// 1) user platform settings
// 2) user settings
// 3) platform settings
let tmp = null;
if (this._platform) {
tmp = this.platformSetting( this._platform.name() );
if (isDefined(tmp)) {
return tmp;
}
}
tmp = this._settings[key];
if (util.isDefined(tmp)) {
return tmp;
}
if (this._platform) {
return this._platform.setting(key);
}
return null;
}
}
platformSettings(platformName, platformSettings) {
let settings = this._settings.platforms[platformName] = this._settings.platforms[platformName] || {};
if (arguments.length > 1) {
settings = platformSettings || {};
}
return settings;
}
platformSetting(platformName, key, val) {
let settings = this._settings.platforms[platformName] = this._settings.platforms[platformName] || {};
if (arguments.length > 2) {
settings[key] = val;
}
return settings[key];
}
}

View File

@ -1,10 +1,15 @@
export * from 'ionic/config/config'
export * from 'ionic/config/ionic-directive'
export * from 'ionic/config/component'
export * from 'ionic/config/ionic-view'
export * from 'ionic/components'
export * from 'ionic/platform/platform'
// export * from 'ionic/platform/core'
// export * from 'ionic/platform/android'
// export * from 'ionic/platform/ios'
export * from 'ionic/routing/router'
export * from 'ionic/util/click-block'

View File

@ -1,144 +1,224 @@
import * as util from '../util/util';
import {Tap} from '../util/tap';
let registry = {};
let platformRegistry = {};
let defaultPlatform;
let activePlatform;
class PlatformController {
export class Platform {
constructor(platformQuerystring, userAgent) {
this.pqs = platformQuerystring;
this.ua = userAgent;
load(platformName) {
this._c = Platform.get(platformName);
}
get() {
if (util.isUndefined(activePlatform)) {
this.set(this.detect());
}
return activePlatform || defaultPlatform;
name() {
return this._c.name;
}
getName() {
return this.get().name;
settings() {
return this._c.settings || {};
}
getMode() {
let plt = this.get();
return plt.mode || plt.name;
}
register(platform) {
registry[platform.name] = platform;
}
getPlatform(name) {
return registry[name];
}
set(platform) {
activePlatform = platform;
this._applyBodyClasses();
}
setDefault(platform) {
defaultPlatform = platform;
}
isRegistered(platformName) {
return registry.some(platform => {
return platform.name === platformName;
})
}
detect() {
for (let name in registry) {
if (registry[name].isMatch(this.pqs, this.ua)) {
return registry[name];
}
}
return null;
}
_applyBodyClasses() {
if(!activePlatform) {
return;
}
document.body.classList.add('platform-' + activePlatform.name);
subsets() {
return this._c.subsets || [];
}
run() {
activePlatform && activePlatform.run();
this._c.run && this._c.run();
}
/**
* Check if the platform matches the provided one.
*/
is(platform) {
if(!activePlatform) { return false; }
return activePlatform.name === platform;
parent(val) {
if (arguments.length) {
this._parent = val;
}
return this._parent;
}
/**
* Check if the loaded device matches the provided one.
*/
isDevice(device) {
if(!activePlatform) { return false; }
return activePlatform.getDevice() === device;
child(val) {
if (arguments.length) {
this._child = val;
}
return this._child;
}
isMatch(app) {
if (!this._c.isMatch) {
return true;
}
return this._c.isMatch(app);
}
getRoot(app, childPlatform) {
if (this.isMatch(app)) {
let parents = Platform.getSubsetParents(this.name());
if (!parents.length) {
platform = new Platform();
platform.load(this.name());
platform.child(childPlatform);
return platform;
}
let platform = null;
let rootPlatform = null;
for (let i = 0; i < parents.length; i++) {
platform = new Platform();
platform.load(parents[i]);
platform.child(this);
rootPlatform = platform.getRoot(app, this);
if (rootPlatform) {
this.parent(platform);
return rootPlatform;
}
}
}
return null;
}
static getActivePlatform(app) {
let platform = new Platform();
platform.load('tablet');
let root = platform.getRoot(app, null);
console.log(root)
}
static register(platform) {
platformRegistry[platform.name] = platform;
}
static get(platformName) {
return platformRegistry[platformName] || {};
}
static getSubsetParents(subsetPlatformName) {
let parentPlatformNames = [];
let platform = null;
for (let platformName in platformRegistry) {
platform = platformRegistry[platformName];
if (platform.subsets && platform.subsets.indexOf(subsetPlatformName) > -1) {
parentPlatformNames.push(platformName);
}
}
return parentPlatformNames;
}
}
export let Platform = new PlatformController((util.getQuerystring('ionicplatform')).toLowerCase(), window.navigator.userAgent);
let rootPlatform = null;
Platform.register({
name: 'core',
subsets: [
'mobile'
],
settings: {
mode: 'a'
},
run() {
console.log('Core');
}
});
Platform.register({
name: 'mobile',
subsets: [
'android',
'ios'
],
settings: {
mode: 'b'
},
run() {
console.log('Mobile');
}
});
Platform.register({
name: 'android',
mode: 'md',
isMatch(platformQuerystring, userAgent) {
if (platformQuerystring) {
return platformQuerystring == 'android';
}
return /android/i.test(userAgent);
subsets: [
'tablet'
],
settings: {
mode: 'c'
},
getDevice: function() {
return 'android';
isMatch(app) {
return app.matchesPlatform('android');
},
run() {
console.log('Android');
}
});
Platform.register({
name: 'ios',
isMatch(platformQuerystring, userAgent) {
if (platformQuerystring) {
return platformQuerystring == 'ios';
}
return /ipad|iphone|ipod/i.test(userAgent);
name: 'tablet',
settings: {
mode: 'd'
},
getDevice: function() {
if(/ipad/i.test(userAgent)) {
return 'ipad';
}
if(/iphone/i.test(userAgent)) {
return 'iphone';
}
isMatch(app) {
return app.height() >= 800 || app.width() >= 800;
},
run() {
console.log('Tablet');
}
});
Platform.register({
name: 'ios',
subsets: [
'ipad',
'iphone'
],
settings: {
mode: 'e'
},
isMatch(app) {
return app.matchesPlatform('ios');
},
run() {
console.log('iOS');
Tap.run();
}
});
// Last case is a catch-all
// TODO(mlynch): don't default to iOS, default to core,
// also make sure to remove getPlatform and set to detect()
Platform.setDefault({
name: 'ios'
});
Platform.set( Platform.getPlatform('ios') );//Platform.detect() );
// If the platform needs to do some initialization (like load a custom
// tap strategy), run it now
Platform.run();
Platform.register({
name: 'ipad',
subsets: [
'tablet'
],
settings: {
mode: 'f'
},
isMatch(app) {
return app.matchesDevice('ipad');
},
run() {
console.log('iPad');
}
});
Platform.register({
name: 'iphone',
settings: {
mode: 'g'
},
isMatch(app) {
return app.matchesDevice('iphone');
},
run() {
console.log('iPhone');
}
});

View File

@ -0,0 +1,155 @@
// import * as util from '../util/util';
// import {IonicConfig} from '../config/config';
// let platformRegistry = {};
// export class Platform extends IonicConfig {
// constructor(settings={}) {
// super(settings);
// this._chld = {};
// this._parent = null;
// }
// parent(val) {
// if (arguments.length) {
// this._parent = val;
// }
// return this._parent;
// }
// app(val) {
// if (arguments.length) {
// this._app = val;
// }
// return this._app;
// }
// name(val) {
// if (arguments.length) {
// this._name = val;
// }
// return this._name;
// }
// is(platformName, climbToRoot) {
// if (this._name == platformName) {
// return true;
// }
// let platform = null;
// if (climbToRoot !== false) {
// platform = this._parent
// while (platform) {
// if (platform.name() == platformName) {
// return true;
// }
// platform = platform._parent;
// }
// }
// for (let childPlatform in this._chld) {
// platform = this._chld[childPlatform];
// platform.app(this._app);
// if (platform.is(platformName, false) == platform.isMatch()) {
// return true;
// }
// }
// return false;
// }
// matchesQuery(queryKey, queryValue) {
// const qs = this._app.query()[queryKey];
// return !!(qs && qs == queryValue);
// }
// matchesUserAgent(userAgentExpression) {
// const rx = new RegExp(userAgentExpression, 'i');
// return rx.test( this._app.userAgent() );
// }
// matchesPlatform(platformQueryValue, platformUserAgentExpression) {
// return this.matchesQuery('ionicplatform', platformQueryValue) ||
// this.matchesUserAgent(platformUserAgentExpression);
// }
// matchesDevice(deviceQueryValue, deviceUserAgentExpression) {
// return this.matchesQuery('ionicdevice', deviceQueryValue) ||
// this.matchesUserAgent(deviceUserAgentExpression);
// }
// registerChild(platformName, PlatformClass) {
// let platform = new PlatformClass();
// platform.name(platformName);
// platform.parent(this);
// this._chld[platformName] = platform;
// }
// root() {
// let rootPlatform = this;
// while (rootPlatform._parent) {
// rootPlatform = rootPlatform._parent;
// }
// return rootPlatform;
// }
// runAll() {
// let platform = null;
// if (this.isMatch()) {
// this.run();
// for (let childPlatform in this._chld) {
// this._chld[childPlatform].app(this._app);
// this._chld[childPlatform].runAll();
// }
// }
// }
// getActive() {
// let platform = null;
// if (this.isMatch()) {
// for (let childPlatform in this._chld) {
// this._chld[childPlatform].app(this._app);
// platform = this._chld[childPlatform].getActive();
// if (platform) {
// return platform;
// }
// }
// return this;
// }
// return null;
// }
// /* Methods to Override */
// isMatch() { return true; }
// run() {}
// /* Static Methods */
// static register(platformName, PlatformClass) {
// basePlatform.registerChild(platformName, PlatformClass);
// }
// static getActivePlatform(app) {
// basePlatform.app(app);
// return basePlatform.getActive(app);
// }
// static setBase(PlatformClass) {
// basePlatform = new PlatformClass();
// }
// }
// let basePlatform = null;
console.log('')

View File

@ -134,11 +134,12 @@ export const array = {
* Grab the query string param value for the given key.
* @param key the key to look for
*/
export function getQuerystring(key) {
export function getQuerystring(url, key) {
var queryParams = {};
const startIndex = window.location.href.indexOf('?');
if (url) {
const startIndex = url.indexOf('?');
if (startIndex !== -1) {
const queries = window.location.href.slice(startIndex + 1).split('&');
const queries = url.slice(startIndex + 1).split('&');
if (queries.length) {
queries.forEach((param) => {
var split = param.split('=');
@ -149,5 +150,6 @@ export function getQuerystring(key) {
if (key) {
return queryParams[key] || '';
}
}
return queryParams;
}