Merge branch 'master' into list-border-refactor

This commit is contained in:
Brandy Carney
2015-11-10 09:42:28 -05:00
23 changed files with 302 additions and 133 deletions

View File

@@ -108,9 +108,10 @@ export function getPageFor(hash) {
'icons': icons.BasicPage,
'lists': lists.BasicPage,
'list-lines': lists.BasicPage,
'list-no-lines': lists.NoLinesPage,
'avatar-list': lists.AvatarPage,
'icon-list': lists.IconPage,
'list-dividers': lists.LinesPage,
'inset-list': lists.InsetPage,
'list-headers': lists.HeadersPage,
'multiline-list': lists.MultilinePage,

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -4,7 +4,7 @@
</ion-navbar>
<ion-content class="has-header demo-list-icons">
<ion-list no-lines>
<ion-list>
<ion-item>Pokémon Yellow</ion-item>
<ion-item>Super Metroid</ion-item>
<ion-item>Mega Man X</ion-item>

View File

@@ -3,6 +3,6 @@ export * from './basic/pages';
export * from './headers/pages';
export * from './icon/pages';
export * from './inset/pages';
export * from './lines/pages';
export * from './no-lines/pages';
export * from './multiline/pages';
export * from './thumbnail/pages';

View File

@@ -3,10 +3,10 @@ import {forwardRef} from 'angular2/angular2';
import {AndroidAttribute} from '../../helpers';
@Page({
templateUrl: 'lists/lines/template.html',
templateUrl: 'lists/no-lines/template.html',
directives: [forwardRef(() => AndroidAttribute)]
})
export class LinesPage {
export class NoLinesPage {
constructor() {
}

View File

@@ -1,10 +1,10 @@
<ion-navbar *navbar hide-back-button class="show-navbar android-attr">
<ion-title>Dividers</ion-title>
<ion-title>No Lines</ion-title>
</ion-navbar>
<ion-content class="has-header demo-list-icons">
<ion-list>
<ion-list no-lines>
<ion-item>Pokémon Yellow</ion-item>
<ion-item>Super Metroid</ion-item>
<ion-item>Mega Man X</ion-item>

View File

@@ -0,0 +1,47 @@
<ion-toolbar class="android-attr">
<ion-title>
Description
</ion-title>
<ion-nav-items primary>
<button (click)="close()" *ng-if=" currentPlatform === 'ios' ">
Cancel
</button>
<button (click)="close()" *ng-if=" currentPlatform === 'android' ">
<icon close></icon>
</button>
</ion-nav-items>
</ion-toolbar>
<ion-content class="has-header">
<ion-list>
<ion-item>
<ion-avatar item-left>
<img src="{{character.image}}">
</ion-avatar>
<h2>{{character.name}}</h2>
<p>{{character.quote}}</p>
</ion-item>
<div *ng-for="#item of character['items']">
<ion-item>
{{item.title}}
<ion-note item-right>
{{item.note}}
</ion-note>
</ion-item>
</div>
</ion-list>
</ion-content>

View File

@@ -1,13 +0,0 @@
<ion-content padding>
<button block danger (click)="closeModal()">
<icon close></icon>
Close Modal
</button>
</ion-content>

View File

@@ -1,5 +1,5 @@
import {App, IonicApp, Animation, Modal, NavController, Page, Events} from 'ionic/ionic';
import {forwardRef} from 'angular2/angular2';
import {App, IonicApp, Animation, Modal, Platform, NavController, Page, Events} from 'ionic/ionic';
import {forwardRef, NgFor} from 'angular2/angular2';
import * as helpers from '../../helpers';
@@ -7,35 +7,75 @@ import * as helpers from '../../helpers';
templateUrl: 'modals/basic/template.html',
directives: [forwardRef(() => helpers.AndroidAttribute)]
})
class ModalsFirstPage {
class ModalsInitialPage {
constructor(
nav: NavController,
modal: Modal,
events: Events
) {
this.nav = nav;
this.modal = modal;
}
openModal() {
this.modal.open(ModalsContentPage);
openModal(characterNum) {
this.modal.open(ModalsContentPage, characterNum);
}
}
@Page({
templateUrl: 'modals/basic/modals-content.html',
directives: [forwardRef(() => helpers.AndroidAttribute)]
templateUrl: 'modals/basic/modal-content.html',
directives: [NgFor, forwardRef(() => helpers.AndroidAttribute)]
})
class ModalsContentPage {
constructor(
modal: Modal,
events: Events
) {
this.modal = modal;
constructor(
modal: Modal,
platform: Platform,
) {
this.modal = modal;
if (platform.is('android')) {
this.currentPlatform = 'android';
} else {
this.currentPlatform = 'ios';
}
var characters = [
{
name: 'Gollum',
quote: 'Sneaky little hobbitses!',
image: 'img/avatar-gollum.jpg',
items: [
{ title: 'Race', note: 'Hobbit' },
{ title: 'Culture', note: 'River Folk' },
{ title: 'Alter Ego', note: 'Smeagol' }
]
},
{
name: 'Frodo',
quote: 'Go back, Sam! I\'m going to Mordor alone!',
image: 'img/avatar-frodo.jpg',
items: [
{ title: 'Race', note: 'Hobbit' },
{ title: 'Culture', note: 'Shire Folk' },
{ title: 'Weapon', note: 'Sting' }
]
},
{
name: 'Samwise Gamgee',
quote: 'What we need is a few good taters.',
image: 'img/avatar-samwise.jpg',
items: [
{ title: 'Race', note: 'Hobbit' },
{ title: 'Culture', note: 'Shire Folk' },
{ title: 'Nickname', note: 'Sam' }
]
}
];
this.character = characters[this.modal._defaults.charNum];
}
closeModal() {
@@ -51,7 +91,7 @@ class ModalsContentPage {
})
export class BasicPage {
constructor(modal: Modal) {
this.rootView = ModalsFirstPage;
this.rootView = ModalsInitialPage;
this.modal = modal;
}
onPageWillLeave() {
@@ -61,3 +101,5 @@ export class BasicPage {
}
}
}

View File

@@ -1,10 +1,23 @@
<ion-navbar *navbar hide-back-button class="android-attr">
<ion-navbar *navbar class="android-attr">
<ion-title>Modals</ion-title>
</ion-navbar>
<ion-content padding class="has-header">
<button block (click)="openModal()">
Show Modal
</button>
<ion-content class="has-header">
<ion-list>
<ion-header>
Hobbits
</ion-header>
<a ion-item (click)="openModal({charNum: 0})">
Gollum
</a>
<a ion-item (click)="openModal({charNum: 1})">
Frodo Baggins
</a>
<a ion-item (click)="openModal({charNum: 2})">
Sam
</a>
</ion-list>
</ion-content>

View File

@@ -1,5 +1,5 @@
import {NavController, NavParams} from 'ionic/ionic';
import {Page, Events} from 'ionic/ionic';
import {Page} from 'ionic/ionic';
import {forwardRef} from 'angular2/angular2';
import * as helpers from '../../helpers';
@@ -8,7 +8,7 @@ import * as helpers from '../../helpers';
directives: [forwardRef(() => helpers.AndroidAttribute)]
})
class NavigationDetailsPage {
constructor(nav: NavController, params: NavParams, events: Events) {
constructor(nav: NavController, params: NavParams) {
this.nav = nav;
this.selection = { title: params.data.name };
var navData = {

View File

@@ -14,9 +14,7 @@ import * as helpers from '../../helpers';
directives: [forwardRef(() => helpers.AndroidAttribute)],
})
class TabTextCtrl {
constructor(nav: NavController, view: ViewController) {
this.nav = nav;
this.view = view;
constructor() {
}
}
@@ -29,8 +27,7 @@ class TabTextCtrl {
'</ion-tabs>',
})
export class BasicPage {
constructor(nav: NavController, params: NavParams) {
this.nav = nav;
constructor() {
this.tabOne = TabTextCtrl;
this.tabTwo = TabTextCtrl;
this.tabThree = TabTextCtrl;

View File

@@ -14,9 +14,7 @@ import * as helpers from '../../helpers';
directives: [forwardRef(() => helpers.AndroidAttribute)],
})
class TabIconTextCtrl {
constructor(nav: NavController, view: ViewController) {
this.nav = nav;
this.view = view;
constructor() {
}
}
@@ -30,8 +28,7 @@ class TabIconTextCtrl {
'</ion-tabs>',
})
export class IconTextPage {
constructor(nav: NavController, params: NavParams) {
this.nav = nav;
constructor() {
this.tabOne = TabIconTextCtrl;
this.tabTwo = TabIconTextCtrl;
this.tabThree = TabIconTextCtrl;

View File

@@ -14,9 +14,7 @@ import * as helpers from '../../helpers';
directives: [forwardRef(() => helpers.AndroidAttribute)],
})
class TabIconCtrl {
constructor(nav: NavController, view: ViewController) {
this.nav = nav;
this.view = view;
constructor() {
}
}
@@ -30,8 +28,7 @@ class TabIconCtrl {
'</ion-tabs>',
})
export class IconPage {
constructor(nav: NavController, params: NavParams) {
this.nav = nav;
constructor() {
this.tabOne = TabIconCtrl;
this.tabTwo = TabIconCtrl;
this.tabThree = TabIconCtrl;

View File

@@ -27,7 +27,7 @@ export class Animation {
constructor(ele, opts={}) {
this.reset();
this._opts = extend({
renderDelay: 36
renderDelay: 16
}, opts);
this.elements(ele);
@@ -238,15 +238,31 @@ export class Animation {
// stage all animations and child animations at their starting point
self.stage();
// synchronously call all onPlay()'s before play()
self._onPlay();
let resolve;
let promise = new Promise(res => { resolve = res; });
function kickoff() {
// synchronously call all onPlay()'s before play()
self._onPlay();
return new Promise(resolve => {
beginPlay().then(() => {
self._onFinish();
resolve();
});
});
}
if (self._duration > 16) {
// begin each animation when everything is rendered in their starting point
// give the browser some time to render everything in place before starting
setTimeout(kickoff, this._opts.renderDelay);
} else {
// no need to render everything in there place before animating in
// just kick it off immediately to render them in their "to" locations
kickoff();
}
return promise;
}
// this is a child animation, it is told exactly when to
@@ -586,11 +602,13 @@ class Animate {
// lock in where the element will stop at
// if the playbackRate is negative then it needs to return
// to its "from" effects
inlineStyle(self.ele, self.rate < 0 ? self.fromEffect : self.toEffect);
if (self.ani) {
inlineStyle(self.ele, self.rate < 0 ? self.fromEffect : self.toEffect);
self.ani = null;
self.ani = self.ani.onfinish = null;
done && done();
done && done();
}
};
}

View File

@@ -91,13 +91,15 @@ export class Tab extends NavController {
} else if (this.tabs.preloadTabs) {
setTimeout(() => {
let opts = {
animate: false,
preload: true
};
this.load(opts, () => {
this.hideNavbars(true);
});
if (!this._loaded) {
let opts = {
animate: false,
preload: true
};
this.load(opts, () => {
this.hideNavbars(true);
});
}
}, 1000 * this.index);
}
}

View File

@@ -65,14 +65,15 @@ export class RippleActivator extends Activator {
upAction(forceFadeOut) {
this.deactivate();
let ripple;
for (let rippleId in this.ripples) {
let rippleId, ripple;
for (rippleId in this.ripples) {
ripple = this.ripples[rippleId];
if (!ripple.fade || forceFadeOut) {
// ripple has not been let up yet
// speed up the rate if the animation is still going
setTimeout(() => {
clearTimeout(ripple.fadeStart);
ripple.fadeStart = setTimeout(() => {
// speed up the rate if the animation is still going
ripple.expand && ripple.expand.playbackRate(EXPAND_OUT_PLAYBACK_RATE);
ripple.fade = new Animation(ripple.ele);
ripple.fade
@@ -87,7 +88,7 @@ export class RippleActivator extends Activator {
})
.play();
}, 16);
});
}
}
@@ -95,15 +96,15 @@ export class RippleActivator extends Activator {
}
next(forceComplete) {
let ripple, rippleEle;
for (let rippleId in this.ripples) {
let rippleId, ripple;
for (rippleId in this.ripples) {
ripple = this.ripples[rippleId];
if ((ripple.expanded && ripple.faded && ripple.ele) ||
forceComplete || parseInt(rippleId) + 5000 < Date.now()) {
if ((ripple.expanded && ripple.faded && ripple.ele) || forceComplete) {
// finished expanding and the user has lifted the pointer
ripple.remove = true;
raf(() => {
this.remove(rippleId);
this.remove();
});
}
}
@@ -114,14 +115,17 @@ export class RippleActivator extends Activator {
this.next(true);
}
remove(rippleId) {
let ripple = this.ripples[rippleId];
if (ripple) {
ripple.expand && ripple.expand.dispose();
ripple.fade && ripple.fade.dispose();
removeElement(ripple.ele);
ripple.ele = ripple.expand = ripple.fade = null;
delete this.ripples[rippleId];
remove() {
let rippleId, ripple;
for (rippleId in this.ripples) {
ripple = this.ripples[rippleId];
if (ripple.remove || parseInt(rippleId, 10) + 4000 < Date.now()) {
ripple.expand && ripple.expand.dispose();
ripple.fade && ripple.fade.dispose();
removeElement(ripple.ele);
ripple.ele = ripple.expand = ripple.fade = null;
delete this.ripples[rippleId];
}
}
}

View File

@@ -10,7 +10,7 @@ let lastActivated = 0;
let disableNativeClickUntil = 0;
let disableNativeClickAmount = 3000;
let activator = null;
let isEnabled = false;
let isTapPolyfill = false;
let app = null;
let config = null;
let win = null;
@@ -24,13 +24,15 @@ export function initTapClick(windowInstance, documentInstance, appInstance, conf
config = configInstance;
activator = (config.get('mdRipple') ? new RippleActivator(app, config) : new Activator(app, config));
isEnabled = (config.get('tapPolyfill') !== false);
isTapPolyfill = (config.get('tapPolyfill') === true);
addListener('click', click, true);
addListener('touchstart', touchStart);
addListener('touchend', touchEnd);
addListener('touchcancel', touchCancel);
if (isTapPolyfill) {
addListener('touchstart', touchStart);
addListener('touchend', touchEnd);
addListener('touchcancel', touchCancel);
}
addListener('mousedown', mouseDown, true);
addListener('mouseup', mouseUp, true);
@@ -45,7 +47,7 @@ function touchStart(ev) {
function touchEnd(ev) {
touchAction();
if (isEnabled && startCoord && app.isEnabled() && !ev.defaultPrevented) {
if (startCoord && app.isEnabled()) {
let endCoord = pointerCoord(ev);
if (!hasPointerMoved(pointerTolerance, startCoord, endCoord)) {
@@ -111,8 +113,8 @@ function pointerStart(ev) {
}
function pointerEnd(ev) {
activator.upAction();
moveListeners(false);
activator.upAction();
}
function pointerMove(ev) {
@@ -130,14 +132,27 @@ function pointerCancel(ev) {
}
function moveListeners(shouldAdd) {
removeListener('touchmove', pointerMove);
if (isTapPolyfill) {
removeListener('touchmove', pointerMove);
}
removeListener('mousemove', pointerMove);
if (shouldAdd) {
addListener('touchmove', pointerMove);
if (isTapPolyfill) {
addListener('touchmove', pointerMove);
}
addListener('mousemove', pointerMove);
}
}
<<<<<<< HEAD
=======
function setDisableNativeClick() {
if (isTapPolyfill) {
disableNativeClickTime = Date.now() + disableNativeClickLimit;
}
}
>>>>>>> master
function isDisabledNativeClick() {
return disableNativeClickUntil > Date.now();
}
@@ -156,6 +171,8 @@ function click(ev) {
console.debug('click prevent', preventReason);
ev.preventDefault();
ev.stopPropagation();
} else {
activator.upAction();
}
}

View File

@@ -10,8 +10,56 @@ import {Platform} from '../platform/platform';
import {isObject, isDefined, isFunction, isArray, extend} from '../util/util';
/**
* TODO
*/
* Config lets you change multiple or a single value in an apps mode configuration. Things such as tab placement, icon changes, and view animations can be set here.
*
* ```ts
* import {Config} from 'ionic/ionic';
* @App({
* template: `<ion-nav [root]="root"></ion-nav>`
* config: {
* backButtonText: 'Go Back',
* iconMode: 'ios',
* modalEnter: 'modal-slide-in',
* modalLeave: 'modal-slide-out',
* tabbarPlacement: 'bottom',
* viewTransition: 'ios',
* }
* })
* ```
*
* Config can be overwritting at multiple levels, allowing deeper configuration. Taking the example from earlier, we can override any setting we want based on a platform.
* ```ts
* import {Config} from 'ionic/ionic';
* @App({
* template: `<ion-nav [root]="root"></ion-nav>`
* config: {
* 'tabbarPlacement': 'bottom',
* platform: {
* ios: {
* 'tabbarPlacement': 'top',
* }
* }
* }
* })
* ```
*
* We could also configure these values at a component level. Take `tabbarPlacement`, we can configure this as a property on our `ion-tabs`.
*
* ```html
* <ion-tabs tabbar-placement="top">
* <ion-tab tab-title="Dash" tab-icon="pulse" [root]="DashRoot"></ion-tab>
* </ion-tabs>
* ```
*
* The property will override anything else set in the apps.
*
* The last way we could configure is through URL query strings. This is useful for testing while in the browser.
* Simply add `?ionic<PROPERTYNAME>=<value>` to the url.
*
* ```
* http://localhost:8100/?IonictabbarPlacement=bottom
* ```
**/
export class Config {
/**
@@ -27,27 +75,10 @@ export class Config {
* For setting and getting multiple config values
*/
/**
/**
* @private
* @name settings()
* @description
* Config lets you change multiple or a single value in an apps mode configuration. Things such as tab placement, icon changes, and view animations can be set here.
*
*
* @usage
* ```ts
* import {Config} from 'ionic/ionic';
* @App({
* template: `<ion-nav [root]="root"></ion-nav>`
* config: {
* backButtonText: 'Go Back',
* iconMode: 'ios',
* modalEnter: 'modal-slide-in',
* modalLeave: 'modal-slide-out',
* tabbarPlacement: 'bottom',
* viewTransition: 'ios',
* }
* })
* ```
*/
settings() {
const args = arguments;
@@ -74,9 +105,14 @@ export class Config {
return this;
}
/**
* For setting a single config values
*/
/**
* For setting a single config values
*/
/**
* @private
* @name set()
* @description
*/
set() {
const args = arguments;
const arg0 = args[0];
@@ -109,6 +145,11 @@ export class Config {
/**
* For getting a single config values
*/
/**
* @private
* @name get()
* @description
*/
get(key) {
if (!isDefined(this._c[key])) {

View File

@@ -30,7 +30,9 @@ export class Platform {
/**
* @param {string} platformName
* @returns {bool}
* @returns {bool} returns true/false based on platform you place
* @description
* Depending on the platform name, isPlatform will return true or flase
*
* ```
* import {Platform} 'ionic/ionic';
@@ -74,22 +76,25 @@ export class Platform {
return this._platforms;
}
/**
* TODO
* @param {string} platformName
* @returns {object}
* @param {string} optional platformName
* @returns {object} An object with various platform info
* - `{object=} `cordova`
* - `{object=}` `platformOS` {str: "9.1", num: 9.1, major: 9, minor: 1}
* - `{object=} `deviceName` Returns the name of the device
* - `{object=}` `device platform` R
* @description
* Returns an object containing the os version
* Returns an object conta
*
* ```
* import {Platform} 'ionic/ionic';
* export MyClass {
* constructor(platform: Platform){
* this.platform = platform;
* console.log(this.platform.versions('android'));
* // Returns an object with the os version as a string,
* // The Major version as a string
* // The Minor version as a string
* console.log(this.platform.versions());
* // or pass in a platform name
* console.log(this.platform.versions('ios'));
* }
* }
* ```
@@ -106,7 +111,6 @@ export class Platform {
}
/**
* TODO
* @returns {promise}
* @description
* Returns a promise when the platform is ready and native functionality can be called

View File

@@ -74,10 +74,12 @@ Platform.register({
scrollAssist: function(p) {
return /iphone|ipad|ipod/i.test(p.navigatorPlatform());
},
tapPolyfill: function(p) {
return /iphone|ipad|ipod/i.test(p.navigatorPlatform());
},
keyboardHeight: 290,
hoverCSS: false,
swipeBackEnabled: function(p) {
return true; // TODO: remove me! Force it to always work for iOS mode for now
return /iphone|ipad|ipod/i.test(p.navigatorPlatform());
},
swipeBackThreshold: 40,