diff --git a/ionic/components/app/app.js b/ionic/components/app/app.js index e32724543d..47fbe90463 100644 --- a/ionic/components/app/app.js +++ b/ionic/components/app/app.js @@ -118,6 +118,23 @@ export class IonicApp { } +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 function ionicBootstrap(ComponentType, config) { return new Promise((resolve, reject) => { try { @@ -146,6 +163,11 @@ export function ionicBootstrap(ComponentType, config) { bootstrap(ComponentType, injectableBindings).then(appRef => { app.ref(appRef); + + // prepare the ready promise to fire....when ready + Platform.prepareReady(config); + + // resolve that the app has loaded resolve(app); }).catch(err => { @@ -160,25 +182,6 @@ 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) { if (!app) { console.error('Invalid app module'); @@ -190,3 +193,5 @@ export function load(app) { app.main(ionicBootstrap); } } + +export let GlobalIonicConfig = null; diff --git a/ionic/platform/platform.js b/ionic/platform/platform.js index 13b378e25f..1a2d6b8f44 100644 --- a/ionic/platform/platform.js +++ b/ionic/platform/platform.js @@ -11,6 +11,8 @@ export class PlatformCtrl { this._default = null; this._vMajor = 0; this._vMinor = 0; + + this._readyPromise = new Promise(res => { this._readyResolve = res; } ); } @@ -40,20 +42,35 @@ export class PlatformCtrl { } ready() { - // if a ready method was provided then it would - // override this default method - // fallback to use dom ready by default - return dom.ready(); + return this._readyPromise; + } + + prepareReady(config) { + let self = this; + + function resolve() { + self._readyResolve(config); + } + + if (this._engineReady) { + // the engine provide a ready promise, use this instead + this._engineReady(resolve); + + } else { + // there is no custom ready method from the engine + // use the default dom ready + dom.ready(resolve); + } } domReady() { - // helper method so its easy to access on Platform - return dom.ready(); + // convenience method so its easy to access on Platform + return dom.ready.apply(this, arguments); } windowLoad() { - // helper method so its easy to access on Platform - return dom.windowLoad(); + // convenience method so its easy to access on Platform + return dom.windowLoad.apply(this, arguments); } @@ -198,7 +215,10 @@ export class PlatformCtrl { // add any events which the engine would provide // for example, Cordova provides its own ready event - util.extend(this, engineNode.methods()); + let engineMethods = engineNode.methods(); + engineMethods._engineReady = engineMethods.ready; + delete engineMethods.ready; + util.extend(this, engineMethods); } let platformNode = rootPlatformNode; diff --git a/ionic/platform/registry.js b/ionic/platform/registry.js index 2e6f558061..f79091f261 100644 --- a/ionic/platform/registry.js +++ b/ionic/platform/registry.js @@ -66,7 +66,8 @@ Platform.register({ 'iphone' ], settings: { - mode: 'ios' + mode: 'ios', + tapPolyfill: true }, isMatch(p) { // SLEDGEHAMMER OVERRIDE FOR NOW @@ -121,11 +122,9 @@ Platform.register({ name: 'cordova', isEngine: true, methods: { - ready: function() { - return Platform.windowLoad().then(() => { - return new Promise(resolve => { - document.addEventListener("deviceready", resolve); - }); + ready: function(resolve) { + Platform.windowLoad(() => { + document.addEventListener("deviceready", resolve); }); } }, diff --git a/ionic/util/dom.js b/ionic/util/dom.js index e756ea338b..f6a6624476 100644 --- a/ionic/util/dom.js +++ b/ionic/util/dom.js @@ -111,37 +111,50 @@ function cssPromise(el:Element, eventNames, animationName) { }); } -export function ready() { - return new Promise(resolve => { - if (document.readyState === 'complete' || document.readyState === 'interactive') { - resolve(); +export function ready(callback) { + let promise = null; - } else { + if (!callback) { + // a callback wasn't provided, so let's return a promise instead + promise = new Promise(resolve => { callback = resolve; }); + } - function completed() { - document.removeEventListener('DOMContentLoaded', completed, false); - window.removeEventListener('load', completed, false); - resolve(); - } + if (document.readyState === 'complete' || document.readyState === 'interactive') { + callback(); - document.addEventListener('DOMContentLoaded', completed, false); - window.addEventListener('load', completed, false); + } else { + function completed() { + document.removeEventListener('DOMContentLoaded', completed, false); + window.removeEventListener('load', completed, false); + callback(); } - }) + + document.addEventListener('DOMContentLoaded', completed, false); + window.addEventListener('load', completed, false); + } + + return promise; } -export function windowLoad() { - return new Promise(resolve => { - if (document.readyState === 'complete') { - resolve(); +export function windowLoad(callback) { + let promise = null; - } else { - function completed() { - window.removeEventListener('load', completed, false); - resolve(); - } + if (!callback) { + // a callback wasn't provided, so let's return a promise instead + promise = new Promise(resolve => { callback = resolve; }); + } - window.addEventListener('load', completed, false); + if (document.readyState === 'complete') { + callback(); + + } else { + function completed() { + window.removeEventListener('load', completed, false); + callback(); } - }); + + window.addEventListener('load', completed, false); + } + + return promise; } diff --git a/ionic/util/tap.js b/ionic/util/tap.js index 9b4bd92d18..7b9c0500b9 100644 --- a/ionic/util/tap.js +++ b/ionic/util/tap.js @@ -1,5 +1,5 @@ -import {dom} from 'ionic/util' -import {Platform} from 'ionic/platform/platform' +import {dom} from './dom' +import {Platform} from '../platform/platform' /** * @ngdoc page @@ -96,27 +96,20 @@ var tapEventListeners = { 'touchcancel': tapTouchCancel, 'touchmove': tapTouchMove, - 'pointerdown': tapTouchStart, - 'pointerup': tapTouchEnd, - 'pointercancel': tapTouchCancel, - 'pointermove': tapTouchMove, - - 'MSPointerDown': tapTouchStart, - 'MSPointerUp': tapTouchEnd, - 'MSPointerCancel': tapTouchCancel, - 'MSPointerMove': tapTouchMove, - 'focusin': tapFocusIn, 'focusout': tapFocusOut }; -export let Tap = { +Platform.ready().then(config => { - run: function() { - dom.ready().then(() => { - Tap.register(document); - }); - }, + if (config.setting('tapPolyfill')) { + Tap.register(document); + } + +}); + + +export let Tap = { register: function(ele) { tapDoc = ele; @@ -125,23 +118,9 @@ export let Tap = { tapEventListener('mouseup'); tapEventListener('mousedown'); - if (window.navigator.pointerEnabled) { - tapEventListener('pointerdown'); - tapEventListener('pointerup'); - tapEventListener('pointcancel'); - tapTouchMoveListener = 'pointermove'; - - } else if (window.navigator.msPointerEnabled) { - tapEventListener('MSPointerDown'); - tapEventListener('MSPointerUp'); - tapEventListener('MSPointerCancel'); - tapTouchMoveListener = 'MSPointerMove'; - - } else { - tapEventListener('touchstart'); - tapEventListener('touchend'); - tapEventListener('touchcancel'); - } + tapEventListener('touchstart'); + tapEventListener('touchend'); + tapEventListener('touchcancel'); tapEventListener('focusin'); tapEventListener('focusout'); @@ -179,7 +158,7 @@ export let Tap = { }, isKeyboardElement: function(ele) { - if ( !Platform.is('ios') || Platform.isDevice('ipad') ) { + if (Platform.isDevice('ipad') ) { return Tap.isTextInput(ele) && !Tap.isDateInput(ele); } else { return Tap.isTextInput(ele) || ( !!ele && ele.tagName == "SELECT"); @@ -431,7 +410,7 @@ function tapTouchStart(e) { // TODO(mlynch): re-enable //ionic.activator.start(e); - if (Platform.is('ios') && Tap.isLabelWithTextInput(e.target)) { + if (Tap.isLabelWithTextInput(e.target)) { // if the tapped element is a label, which has a child input // then preventDefault so iOS doesn't ugly auto scroll to the input // but do not prevent default on Android or else you cannot move the text caret