diff --git a/gulpfile.js b/gulpfile.js index 3d46118d7e..cc2c453ebb 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -59,7 +59,7 @@ gulp.task('watch', function() { 'serve', function() { - watch(['ionic/**/*.js', 'ionic/components/*/test/**/*'], function() { + watch(['ionic/**/*.js', '!ionic/components/*/test/**/*'], function() { runSequence( 'transpile', 'bundle.js', diff --git a/ionic/components/app/app.js b/ionic/components/app/app.js index a58f508622..e32724543d 100644 --- a/ionic/components/app/app.js +++ b/ionic/components/app/app.js @@ -43,67 +43,6 @@ export class IonicApp { 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; - } - - matchQuery(queryValue) { - let val = this.query('ionicplatform'); - if (val) { - let valueSplit = val.toLowerCase().split(';'); - for (let i = 0; i < valueSplit.length; i++) { - if (valueSplit[i] == queryValue) { - return true; - } - } - } - return false; - } - - matchUserAgent(userAgentExpression) { - if (this._ua) { - let rx = new RegExp(userAgentExpression, 'i'); - return rx.exec(this._ua); - } - } - - isPlatform(queryValue, userAgentExpression) { - if (!userAgentExpression) { - userAgentExpression = queryValue; - } - return (this.matchQuery(queryValue)) || - (this.matchUserAgent(userAgentExpression) !== null); - } - - 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. @@ -154,13 +93,27 @@ export class IonicApp { return this._ref; } - applyCss(platform, config) { - let className = document.body.className; + applyCss(bodyEle, platform, config) { + let className = bodyEle.className; platform.platforms().forEach(platformName => { className += ' platform-' + platformName; }); className += ' mode-' + config.setting('mode'); - document.body.className = className.trim(); + bodyEle.className = className.trim(); + } + + isRTL(val) { + if (arguments.length) { + this._rtl = val; + } + return this._rtl; + } + + lang(val) { + if (arguments.length) { + this._lang = val; + } + return this._lang; } } @@ -168,24 +121,24 @@ export class IonicApp { export function ionicBootstrap(ComponentType, config) { return new Promise((resolve, reject) => { try { - let app = new IonicApp(); - app.url(window.location.href); - app.userAgent(window.navigator.userAgent); - app.width(window.innerWidth); - app.height(window.innerHeight); - - let platform = Platform.load(app); + // create the base IonicApp + let app = initApp(window, document) + // get the user config, or create one if wasn't passed in config = config || new IonicConfig(); // copy default platform settings into the user config platform settings // user config platform settings should override default platform settings - config.setPlatform(platform); - - app.applyCss(platform, config) + config.setPlatform(Platform); + // make the config global GlobalIonicConfig = config; + // config and platform settings have been figured out + // apply the correct CSS to the app + app.applyCss(document.body, Platform, config) + + // add injectables that will be available to all child components let injectableBindings = [ bind(IonicApp).toValue(app), bind(IonicConfig).toValue(config) @@ -193,14 +146,7 @@ export function ionicBootstrap(ComponentType, config) { bootstrap(ComponentType, injectableBindings).then(appRef => { app.ref(appRef); - - platform.run(); - - resolve({ - app, - config, - platform - }); + resolve(app); }).catch(err => { console.error('ionicBootstrap', err); @@ -214,6 +160,23 @@ export function ionicBootstrap(ComponentType, config) { }); } +function initApp(window, document) { + // create the base IonicApp + let app = new IonicApp(); + app.isRTL(document.documentElement.getAttribute('dir') == 'rtl'); + app.lang(document.documentElement.getAttribute('lang')); + + // load all platform data + // Platform is a global singleton + Platform.url(window.location.href); + Platform.userAgent(window.navigator.userAgent); + Platform.width(window.innerWidth); + Platform.height(window.innerHeight); + Platform.load(); + + return app; +} + export let GlobalIonicConfig = null; export function load(app) { diff --git a/ionic/components/modal/test/basic/index.js b/ionic/components/modal/test/basic/index.js index 1b0434b51a..828d37e4c3 100644 --- a/ionic/components/modal/test/basic/index.js +++ b/ionic/components/modal/test/basic/index.js @@ -4,7 +4,7 @@ import {Component, Directive} from 'angular2/src/core/annotations_impl/annotatio import {View} from 'angular2/src/core/annotations_impl/view'; import {Parent, Ancestor} from 'angular2/src/core/annotations_impl/visibility'; -import {IonicView, IonicConfig} from 'ionic/ionic'; +import {IonicView, IonicConfig, Platform} from 'ionic/ionic'; import {IonicComponent} from 'ionic/ionic'; import {Modal, NavController, NavParams, Animation, ActionMenu} from 'ionic/ionic'; @@ -17,7 +17,7 @@ import {Modal, NavController, NavParams, Animation, ActionMenu} from 'ionic/ioni @IonicView({ templateUrl: 'main.html' }) -class MyApp { +class MyAppCmp { constructor(Modal: Modal) { this.Modal = Modal; @@ -152,25 +152,28 @@ export function main(ionicBootstrap) { let myConfig = new IonicConfig(); - //myConfig.setting('someKey', 'userConfig'); + // myConfig.setting('someKey', 'userConfig'); // myConfig.setting('ios', 'someKey', 'iosConfig'); // myConfig.setting('ipad', 'someKey', 'ipadConfig'); - ionicBootstrap(MyApp, myConfig).then(root => { + ionicBootstrap(MyAppCmp, myConfig).then(app => { - console.log('platforms', root.platform.platforms()); + console.log('platforms', Platform.platforms()); console.log('mode', myConfig.setting('mode')); - console.log('core', root.platform.is('core')) - console.log('cordova', root.platform.is('cordova')) - console.log('mobile', root.platform.is('mobile')) - console.log('ipad', root.platform.is('ipad')) - console.log('iphone', root.platform.is('iphone')) - console.log('phablet', root.platform.is('phablet')) - console.log('tablet', root.platform.is('tablet')) - console.log('ios', root.platform.is('ios')) - console.log('android', root.platform.is('android')) - console.log('windows phone', root.platform.is('windowsphone')) + console.log('core', Platform.is('core')) + console.log('cordova', Platform.is('cordova')) + console.log('mobile', Platform.is('mobile')) + console.log('ipad', Platform.is('ipad')) + console.log('iphone', Platform.is('iphone')) + console.log('phablet', Platform.is('phablet')) + console.log('tablet', Platform.is('tablet')) + console.log('ios', Platform.is('ios')) + console.log('android', Platform.is('android')) + console.log('windows phone', Platform.is('windowsphone')) + + console.log('isRTL', app.isRTL()) + console.log('lang', app.lang()) }); } diff --git a/ionic/platform/platform.js b/ionic/platform/platform.js index 0d32ebcaa9..f364b9dce2 100644 --- a/ionic/platform/platform.js +++ b/ionic/platform/platform.js @@ -10,6 +10,67 @@ export class PlatformCtrl { this._default = null; } + 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; + } + + matchQuery(queryValue) { + let val = this.query('ionicplatform'); + if (val) { + let valueSplit = val.toLowerCase().split(';'); + for (let i = 0; i < valueSplit.length; i++) { + if (valueSplit[i] == queryValue) { + return true; + } + } + } + return false; + } + + matchUserAgent(userAgentExpression) { + if (this._ua) { + let rx = new RegExp(userAgentExpression, 'i'); + return rx.exec(this._ua); + } + } + + isPlatform(queryValue, userAgentExpression) { + if (!userAgentExpression) { + userAgentExpression = queryValue; + } + return (this.matchQuery(queryValue)) || + (this.matchUserAgent(userAgentExpression) !== null); + } + + width(val) { + if (arguments.length) { + this._w = val; + } + return this._w || 0; + } + + height(val) { + if (arguments.length) { + this._h = val; + } + return this._h || 0; + } + register(platformConfig) { this._registry[platformConfig.name] = platformConfig; } @@ -22,46 +83,16 @@ export class PlatformCtrl { this._default = platformName; } - load(app) { + load() { let rootPlatformNode = null; let engineNode = null; - - function matchPlatform(platformName) { - // build a PlatformNode and assign config data to it - // use it's getRoot method to build up its hierarchy - // depending on which platforms match - let platformNode = new PlatformNode(platformName); - let tmpPlatform = platformNode.getRoot(app, 0); - - if (tmpPlatform) { - tmpPlatform.depth = 0; - let childPlatform = tmpPlatform.child(); - while(childPlatform) { - tmpPlatform.depth++ - childPlatform = childPlatform.child(); - } - } - return tmpPlatform; - } - - function insertSuperset(platformNode) { - let supersetPlaformName = platformNode.superset(); - if (supersetPlaformName) { - // add a platform in between two exist platforms - // so we can build the correct hierarchy of active platforms - let supersetPlatform = new PlatformNode(supersetPlaformName); - supersetPlatform.parent(platformNode.parent()); - supersetPlatform.child(platformNode); - supersetPlatform.parent().child(supersetPlatform); - platformNode.parent(supersetPlatform); - } - } + let self = this; // figure out the most specific platform and active engine let tmpPlatform = null; for (let platformName in this._registry) { - tmpPlatform = matchPlatform(platformName); + tmpPlatform = matchPlatform(platformName, this); if (tmpPlatform) { // we found a platform match! // check if its more specific than the one we already have @@ -133,15 +164,6 @@ export class PlatformCtrl { return this._settings; } - run() { - let config = null; - - for (var i = 0; i < this._platforms.length; i++) { - config = Platform.get(this._platforms[i]); - config.run && config.run(); - } - } - platforms() { // get the array of active platforms, which also knows the hierarchy, // with the last one the most important @@ -154,6 +176,37 @@ export class PlatformCtrl { } +function matchPlatform(platformName, platform) { + // build a PlatformNode and assign config data to it + // use it's getRoot method to build up its hierarchy + // depending on which platforms match + let platformNode = new PlatformNode(platformName); + let tmpPlatform = platformNode.getRoot(platform, 0); + + if (tmpPlatform) { + tmpPlatform.depth = 0; + let childPlatform = tmpPlatform.child(); + while(childPlatform) { + tmpPlatform.depth++ + childPlatform = childPlatform.child(); + } + } + return tmpPlatform; +} + +function insertSuperset(platformNode) { + let supersetPlaformName = platformNode.superset(); + if (supersetPlaformName) { + // add a platform in between two exist platforms + // so we can build the correct hierarchy of active platforms + let supersetPlatform = new PlatformNode(supersetPlaformName); + supersetPlatform.parent(platformNode.parent()); + supersetPlatform.child(platformNode); + supersetPlatform.parent().child(supersetPlatform); + platformNode.parent(supersetPlatform); + } +} + class PlatformNode { @@ -174,15 +227,6 @@ class PlatformNode { return this.c.superset; } - runAll() { - let platform = this; - while (platform) { - platform.run(); - platform = platform.child(); - } - return false; - } - parent(val) { if (arguments.length) { this._parent = val; @@ -197,19 +241,19 @@ class PlatformNode { return this._child; } - isMatch(app) { + isMatch(p) { if (typeof this.c.isMatched !== 'boolean') { if (!this.c.isMatch) { this.c.isMatched = false; } else { - this.c.isMatched = this.c.isMatch(app); + this.c.isMatched = this.c.isMatch(p); } } return this.c.isMatched; } - getRoot(app) { - if (this.isMatch(app)) { + getRoot(p) { + if (this.isMatch(p)) { let parents = this.getSubsetParents(this.name()); @@ -224,7 +268,7 @@ class PlatformNode { platform = new PlatformNode(parents[i]); platform.child(this); - rootPlatform = platform.getRoot(app); + rootPlatform = platform.getRoot(p); if (rootPlatform) { this.parent(platform); return rootPlatform; diff --git a/ionic/platform/registry.js b/ionic/platform/registry.js index 792498189a..3d01ad1f09 100644 --- a/ionic/platform/registry.js +++ b/ionic/platform/registry.js @@ -17,9 +17,9 @@ Platform.register({ Platform.register({ name: 'phablet', - isMatch(app) { - let smallest = Math.min(app.width(), app.height()); - let largest = Math.max(app.width(), app.height()); + isMatch(p) { + let smallest = Math.min(p.width(), p.height()); + let largest = Math.max(p.width(), p.height()); // http://www.mydevice.io/devices/ return (smallest > 390 && smallest < 520) && (largest > 620 && largest < 800); @@ -29,9 +29,9 @@ Platform.register({ Platform.register({ name: 'tablet', - isMatch(app) { - let smallest = Math.min(app.width(), app.height()); - let largest = Math.max(app.width(), app.height()); + isMatch(p) { + let smallest = Math.min(p.width(), p.height()); + let largest = Math.max(p.width(), p.height()); // http://www.mydevice.io/devices/ return (smallest > 460 && smallest < 820) && (largest > 780 && largest < 1400); @@ -49,10 +49,10 @@ Platform.register({ settings: { mode: 'md' }, - isMatch(app) { + isMatch(p) { // "silk" is kindle fire let re = 'android| silk'; - return app.isPlatform('android', re); + return p.isPlatform('android', re); } }); @@ -68,14 +68,14 @@ Platform.register({ settings: { mode: 'ios' }, - isMatch(app) { + isMatch(p) { // SLEDGEHAMMER OVERRIDE FOR NOW return true; - return app.isPlatform('ios', 'iphone|ipad|ipod'); + return p.isPlatform('ios', 'iphone|ipad|ipod'); }, - versionParser(app) { - let val = app.matchUserAgent('OS (\d+)_(\d+)?'); + versionParser(p) { + let val = p.matchUserAgent('OS (\d+)_(\d+)?'); console.log(val); } }); @@ -84,8 +84,8 @@ Platform.register({ Platform.register({ name: 'ipad', superset: 'tablet', - isMatch(app) { - return app.isPlatform('ipad'); + isMatch(p) { + return p.isPlatform('ipad'); } }); @@ -95,8 +95,8 @@ Platform.register({ subsets: [ 'phablet' ], - isMatch(app) { - return app.isPlatform('iphone'); + isMatch(p) { + return p.isPlatform('iphone'); } }); @@ -111,8 +111,8 @@ Platform.register({ settings: { mode: 'wp' }, - isMatch(app) { - return app.isPlatform('windowsphone', 'windows phone'); + isMatch(p) { + return p.isPlatform('windowsphone', 'windows phone'); } }); @@ -129,7 +129,7 @@ Platform.register({ }); } }, - isMatch(app) { + isMatch(p) { return true; return !!(window.cordova || window.PhoneGap || window.phonegap); }