rename Platform to IonicPlatform

Make IonicPlatform an injectable. Closes #99
This commit is contained in:
Adam Bradley
2015-09-13 00:39:19 -05:00
parent 0039647515
commit 8fbf53e1b7
18 changed files with 288 additions and 329 deletions

View File

@@ -2,7 +2,7 @@ import {Component, View, bootstrap, ElementRef, NgZone, bind, DynamicComponentLo
import {ROUTER_BINDINGS, HashLocationStrategy, LocationStrategy, Router} from 'angular2/router';
import {IonicConfig} from '../../config/config';
import {Platform} from '../../platform/platform';
import {IonicPlatform, Platform} from '../../platform/platform';
import * as util from '../../util/util';
// injectables
@@ -180,50 +180,6 @@ export class IonicApp {
return this.rootAnchor.append(componentType);
}
/**
* TODO
*
* @param {Element} bodyEle the body element
* @param {TODO} platform TODO
* @param {TODO} config TODO
*/
applyBodyCss(bodyEle, platform, config) {
let versions = platform.versions();
platform.platforms().forEach(platformName => {
// platform-ios
let platformClass = 'platform-' + platformName;
bodyEle.classList.add(platformClass);
let platformVersion = versions[platformName];
if (platformVersion) {
// platform-ios9
platformClass += platformVersion.major;
bodyEle.classList.add(platformClass);
// platform-ios9_3
bodyEle.classList.add(platformClass + '_' + platformVersion.minor);
}
});
bodyEle.classList.add(config.setting('mode'));
/**
* Hairline Shim
* Add the "hairline" CSS class name to the body tag
* if the browser supports subpixels.
*/
if (window.devicePixelRatio >= 2) {
var hairlineEle = document.createElement('div');
hairlineEle.style.border = '.5px solid transparent';
bodyEle.appendChild(hairlineEle);
if (hairlineEle.offsetHeight === 1) {
bodyEle.classList.add('hairlines');
}
bodyEle.removeChild(hairlineEle);
}
}
/**
* If val is defined, specifies whether app text is RTL. If val is undefined
* returns whether app text is RTL.
@@ -240,26 +196,6 @@ export class IonicApp {
}
function initApp(window, document, config) {
// create the base IonicApp
let app = new IonicApp();
app.isRTL(document.documentElement.getAttribute('dir') == 'rtl');
// load all platform data
// Platform is a global singleton
Platform.url(window.location.href);
Platform.userAgent(window.navigator.userAgent);
Platform.navigatorPlatform(window.navigator.platform);
Platform.load(config);
setTimeout(() => {
// start listening for resizes XXms after the app starts
window.addEventListener('resize', Platform.winResize);
}, 2500);
return app;
}
@Component({
selector: 'root-anchor'
})
@@ -280,6 +216,38 @@ class RootAnchor {
}
}
function initApp(window, document, config, platform) {
// create the base IonicApp
let app = new IonicApp();
app.isRTL(document.dir == 'rtl');
// load all platform data
platform.url(window.location.href);
platform.userAgent(window.navigator.userAgent);
platform.navigatorPlatform(window.navigator.platform);
platform.load(config);
// copy default platform settings into the user config platform settings
// user config platform settings should override default platform settings
config.setPlatform(platform);
// config and platform settings have been figured out
// apply the correct CSS to the app
applyBodyCss(document.body, config, platform);
// prepare the ready promise to fire....when ready
platform.prepareReady(config);
setTimeout(function() {
// start listening for resizes XXms after the app starts
window.addEventListener('resize', function() {
platform.winResize();
});
}, 2500);
return app;
}
/**
* TODO
*
@@ -295,19 +263,10 @@ export function ionicBootstrap(rootComponentType, config) {
config = new IonicConfig(config);
}
let platform = new IonicPlatform(window);
// create the base IonicApp
let app = initApp(window, document, config);
// copy default platform settings into the user config platform settings
// user config platform settings should override default platform settings
config.setPlatform(Platform);
// config and platform settings have been figured out
// apply the correct CSS to the app
app.applyBodyCss(document.body, Platform, config);
// prepare the ready promise to fire....when ready
Platform.prepareReady(config);
let app = initApp(window, document, config, platform);
// TODO: probs need a better way to inject global injectables
let activator = new Activator(app, config, window, document);
@@ -319,6 +278,7 @@ export function ionicBootstrap(rootComponentType, config) {
let appBindings = Injector.resolve([
bind(IonicApp).toValue(app),
bind(IonicConfig).toValue(config),
bind(IonicPlatform).toValue(platform),
bind(Activator).toValue(activator),
bind(ActionMenu).toValue(actionMenu),
bind(Modal).toValue(modal),
@@ -357,3 +317,42 @@ export function ionicBootstrap(rootComponentType, config) {
}
});
}
function applyBodyCss(bodyEle, config, platform) {
let versions = platform.versions();
platform.platforms().forEach(platformName => {
// platform-ios
let platformClass = 'platform-' + platformName;
bodyEle.classList.add(platformClass);
let platformVersion = versions[platformName];
if (platformVersion) {
// platform-ios9
platformClass += platformVersion.major;
bodyEle.classList.add(platformClass);
// platform-ios9_3
bodyEle.classList.add(platformClass + '_' + platformVersion.minor);
}
});
// set the mode class name
// ios
bodyEle.classList.add(config.setting('mode'));
/**
* Hairline Shim
* Add the "hairline" CSS class name to the body tag
* if the browser supports subpixels.
*/
if (window.devicePixelRatio >= 2) {
var hairlineEle = document.createElement('div');
hairlineEle.style.border = '.5px solid transparent';
bodyEle.appendChild(hairlineEle);
if (hairlineEle.offsetHeight === 1) {
bodyEle.classList.add('hairlines');
}
bodyEle.removeChild(hairlineEle);
}
}

View File

@@ -1,8 +1,6 @@
import {Component, Directive, View, Host, Attribute, ElementRef, forwardRef} from 'angular2/angular2';
import {IonicConfig} from '../../config/config';
import * as dom from '../../util/dom';
import {Platform} from '../../platform/platform';
import {IonInput} from './input';
/**
@@ -15,7 +13,7 @@ import {IonInput} from './input';
template: '<input tabindex="999"><input tabindex="1001"><input tabindex="1002">',
directives: [forwardRef(() => FocusInput)]
})
export class FocusHolder {
export class FocusHolder {
/**
* TODO
*/

View File

@@ -1,6 +1,6 @@
import {IonicConfig} from '../config/config';
import {Platform} from '../platform/platform';
import * as util from 'ionic/util';
import {isArray} from 'ionic/util';
import * as dom from 'ionic/util/dom';
/**
@@ -47,27 +47,6 @@ export class Ion {
}
}
getDelegate(delegateName) {
let cls = this.constructor;
if (cls.delegates) {
let cases = cls.delegates[delegateName] || [];
for (let i = 0; i < cases.length; i++) {
let delegateCase = cases[i];
if (util.isArray(delegateCase)) {
let [ check, DelegateConstructor ] = delegateCase;
if (check(this)) {
return new DelegateConstructor(this);
}
} else {
return new delegateCase(this);
}
}
}
}
getElementRef() {
return this.elementRef;
}
@@ -76,12 +55,16 @@ export class Ion {
return this.elementRef.nativeElement;
}
getDimensions() {
return dom.getDimensions(this.elementRef.nativeElement);
}
width() {
return Platform.getDimensions(this).w;
return this.getDimensions().width;
}
height() {
return Platform.getDimensions(this).h;
return this.getDimensions().height;
}
}

View File

@@ -1,4 +1,4 @@
import {App, IonicView, IonicApp, IonicConfig, Platform} from 'ionic/ionic';
import {App, IonicView, IonicApp, IonicConfig, IonicPlatform} from 'ionic/ionic';
import {Modal, ActionMenu, NavController, NavParams, Animation} from 'ionic/ionic';
@@ -7,27 +7,27 @@ import {Modal, ActionMenu, NavController, NavParams, Animation} from 'ionic/ioni
})
class MyAppCmp {
constructor(modal: Modal, app: IonicApp, ionicConfig: IonicConfig) {
constructor(modal: Modal, app: IonicApp, config: IonicConfig, platform: IonicPlatform) {
this.modal = modal;
console.log('platforms', Platform.platforms());
console.log('mode', ionicConfig.setting('mode'));
console.log('platforms', platform.platforms());
console.log('mode', config.setting('mode'));
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('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())
Platform.ready().then(() => {
console.log('Platform.ready')
platform.ready().then(() => {
console.log('platform.ready')
});
}

View File

@@ -13,25 +13,25 @@ import {raf, ready, CSS} from 'ionic/util/dom';
* Place it as the first child of your ionContent or ionScroll element.
*
* When refreshing is complete, call `refresher.complete()` from your controller.
*
*
* @usage
* ```ts
* <ion-refresher (starting)="doStarting()" (refresh)="doRefresh($event, refresher)" (pulling)="doPulling($event, amt)">
*
*
*
* doRefresh(refresher) {
* console.log('Refreshing!', refresher);
*
*
* setTimeout(() => {
* console.log('Pull to refresh complete!', refresher);
* refresher.complete();
* })
* }
*
*
* doStarting() {
* console.log('Pull started!');
* }
*
*
* doPulling(amt) {
* console.log('You have pulled', amt);
* }
@@ -326,15 +326,6 @@ export class Refresher {
this.startY = parseInt(e.touches[0].screenY, 10);
}
// kitkat fix for touchcancel events http://updates.html5rocks.com/2014/05/A-More-Compatible-Smoother-Touch
/*
if (ionic.Platform.isAndroid() && ionic.Platform.version() === 4.4 && scrollHost.scrollTop === 0) {
isDragging = true;
e.preventDefault();
}
*/
// how far have we dragged so far?
this.deltaY = parseInt(e.touches[0].screenY, 10) - this.startY;

View File

@@ -1,12 +1,13 @@
import {Directive, Attribute, NgZone} from 'angular2/angular2'
import {Platform} from '../../platform/platform';
import {IonicPlatform} from '../../platform/platform';
class DisplayWhen {
constructor(conditions, ngZone) {
constructor(conditions, platform, ngZone) {
this.isMatch = false;
this.platform = platform;
if (!conditions) return;
@@ -15,7 +16,7 @@ class DisplayWhen {
// check if its one of the matching platforms first
// a platform does not change during the life of an app
for (let i = 0; i < this.conditions.length; i++) {
if (this.conditions[i] && Platform.is(this.conditions[i])) {
if (this.conditions[i] && platform.is(this.conditions[i])) {
this.isMatch = true;
return;
}
@@ -23,7 +24,7 @@ class DisplayWhen {
if ( this.orientation() ) {
// add window resize listener
Platform.onResize(() => {
platform.onResize(() => {
ngZone.run(() => {
this.orientation();
});
@@ -35,18 +36,16 @@ class DisplayWhen {
orientation() {
for (let i = 0; i < this.conditions.length; i++) {
var condition = this.conditions[i];
if (condition == 'portrait') {
this.isMatch = Platform.isPortrait();
if (this.conditions[i] == 'portrait') {
this.isMatch = this.platform.isPortrait();
return true;
}
if (condition == 'landscape') {
this.isMatch = Platform.isLandscape();
if (this.conditions[i] == 'landscape') {
this.isMatch = this.platform.isLandscape();
return true;
}
}
}
@@ -69,9 +68,10 @@ export class ShowWhen extends DisplayWhen {
*/
constructor(
@Attribute('show-when') showWhen: string,
platform: IonicPlatform,
ngZone: NgZone
) {
super(showWhen, ngZone);
super(showWhen, platform, ngZone);
}
get hidden() {
@@ -97,9 +97,10 @@ export class HideWhen extends DisplayWhen {
*/
constructor(
@Attribute('hide-when') hideWhen: string,
platform: IonicPlatform,
ngZone: NgZone
) {
super(hideWhen, ngZone);
super(hideWhen, platform, ngZone);
}
get hidden() {

View File

@@ -8,7 +8,6 @@ import {DragGesture} from 'ionic/gestures/drag-gesture';
import {IonicComponent, IonicDirective} from '../../config/annotations';
import {IonicConfig} from '../../config/config';
import {dom} from 'ionic/util';
import {Platform} from 'ionic/platform/platform';
import {CSS} from '../../util/dom';
import * as util from 'ionic/util';

View File

@@ -3,7 +3,6 @@ import {TextInput} from 'ionic/ionic';
export function run() {
it('should scroll, top and bottom below safe area, no room to scroll', () => {
let inputOffsetTop = 350;
let inputOffsetHeight = 35;
let scrollViewDimensions = {
@@ -13,16 +12,16 @@ export function run() {
scrollHeight: 700
};
let keyboardHeight = 400;
let platformHeight = 800;
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight);
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight);
expect(scrollData.scrollAmount).toBe(-178.5);
expect(scrollData.scrollTo).toBe(208.5);
expect(scrollData.scrollPadding).toBe(523.5);
expect(scrollData.scrollAmount).toBe(-205);
expect(scrollData.scrollTo).toBe(235);
expect(scrollData.scrollPadding).toBe(550);
});
it('should scroll, top and bottom below safe area, room to scroll', () => {
let inputOffsetTop = 350;
let inputOffsetHeight = 35;
let scrollViewDimensions = {
@@ -32,11 +31,12 @@ export function run() {
scrollHeight: 1000
};
let keyboardHeight = 400;
let platformHeight = 800;
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight);
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight);
expect(scrollData.scrollAmount).toBe(-178.5);
expect(scrollData.scrollTo).toBe(208.5);
expect(scrollData.scrollAmount).toBe(-205);
expect(scrollData.scrollTo).toBe(235);
expect(scrollData.scrollPadding).toBe(0);
});
@@ -51,8 +51,9 @@ export function run() {
scrollHeight: 700
};
let keyboardHeight = 400;
let platformHeight = 800;
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight);
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight);
expect(scrollData.scrollAmount).toBe(150);
expect(scrollData.scrollTo).toBe(100);
@@ -70,12 +71,13 @@ export function run() {
scrollHeight: 700
};
let keyboardHeight = 400;
let platformHeight = 800;
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight);
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight);
expect(scrollData.scrollAmount).toBe(-80);
expect(scrollData.scrollTo).toBe(100);
expect(scrollData.scrollPadding).toBe(523.5);
expect(scrollData.scrollPadding).toBe(550);
});
it('should scroll, top in safe, bottom below safe, below more than top in, enough padding', () => {
@@ -87,8 +89,9 @@ export function run() {
scrollTop: 0,
};
let keyboardHeight = 400;
let platformHeight = 800;
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight);
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight);
expect(scrollData.scrollAmount).toBe(-20);
expect(scrollData.scrollTo).toBe(20);
@@ -104,11 +107,12 @@ export function run() {
scrollTop: 0,
};
let keyboardHeight = 400;
let platformHeight = 800;
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight);
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight);
expect(scrollData.scrollAmount).toBe(-153.5);
expect(scrollData.scrollTo).toBe(153.5);
expect(scrollData.scrollAmount).toBe(-180);
expect(scrollData.scrollTo).toBe(180);
expect(scrollData.scrollPadding).toBe(0);
});
@@ -122,8 +126,9 @@ export function run() {
keyboardTop: 400
};
let keyboardHeight = 400;
let platformHeight = 800;
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight);
let scrollData = TextInput.getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight);
expect(scrollData.noScroll).toBe(true);
});

View File

@@ -9,7 +9,7 @@ import {IonicApp} from '../app/app';
import {Content} from '../content/content';
import {ClickBlock} from '../../util/click-block';
import * as dom from '../../util/dom';
import {Platform} from '../../platform/platform';
import {IonicPlatform} from '../../platform/platform';
/**
@@ -104,6 +104,7 @@ export class TextInput extends Ion {
config: IonicConfig,
app: IonicApp,
ngZone: NgZone,
platform: IonicPlatform,
@Optional() @Host() scrollView: Content,
@Query(TextInputElement) inputQry: QueryList<TextInputElement>,
@Query(Label) labelQry: QueryList<Label>
@@ -117,8 +118,11 @@ export class TextInput extends Ion {
this.app = app;
this.zone = ngZone;
this.platform = platform;
this.inputQry = inputQry;
this.labelQry = labelQry;
this.keyboardHeight = this.config.setting('keyboardHeight');
}
/**
@@ -213,9 +217,7 @@ export class TextInput extends Ion {
// find out if text input should be manually scrolled into view
let ele = this.elementRef.nativeElement;
let keyboardHeight = this.config.setting('keyboardHeight');
let scrollData = TextInput.getScollData(ele.offsetTop, ele.offsetHeight, scrollView.getDimensions(), keyboardHeight);
let scrollData = TextInput.getScollData(ele.offsetTop, ele.offsetHeight, scrollView.getDimensions(), this.keyboardHeight, this.platform.height());
if (scrollData.noScroll) {
// the text input is in a safe position that doesn't require
// it to be scrolled into view, just set focus now
@@ -261,14 +263,14 @@ export class TextInput extends Ion {
* @param {TODO} keyboardHeight TODO
* @returns {TODO} TODO
*/
static getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight) {
static getScollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, plaformHeight) {
// compute input's Y values relative to the body
let inputTop = (inputOffsetTop + scrollViewDimensions.contentTop - scrollViewDimensions.scrollTop);
let inputBottom = (inputTop + inputOffsetHeight);
// compute the safe area which is the viewable content area when the soft keyboard is up
let safeAreaTop = scrollViewDimensions.contentTop;
let safeAreaHeight = Platform.height() - keyboardHeight - safeAreaTop;
let safeAreaHeight = plaformHeight - keyboardHeight - safeAreaTop;
safeAreaHeight /= 2;
let safeAreaBottom = safeAreaTop + safeAreaHeight;