mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
* The ActionSheet is a modal menu with options to select based on an action.
|
||||
*/
|
||||
|
||||
import {Component, View, Injectable, NgFor, NgIf} from 'angular2/angular2';
|
||||
import {Component, Injectable, NgFor, NgIf} from 'angular2/angular2';
|
||||
|
||||
import {OverlayController} from '../overlay/overlay-controller';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -54,9 +54,7 @@ import * as util from 'ionic/util';
|
||||
* ```
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-action-sheet'
|
||||
})
|
||||
@View({
|
||||
selector: 'ion-action-sheet',
|
||||
template:
|
||||
'<backdrop (click)="_cancel()" tappable disable-activated></backdrop>' +
|
||||
'<action-sheet-wrapper>' +
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Directive, ElementRef, Renderer} from 'angular2/angular2';
|
||||
import {Directive, ElementRef, Renderer, Attribute} from 'angular2/angular2';
|
||||
|
||||
import {IonicConfig} from '../../config/config';
|
||||
|
||||
@@ -14,18 +14,13 @@ export class Button {
|
||||
constructor(
|
||||
config: IonicConfig,
|
||||
elementRef: ElementRef,
|
||||
renderer: Renderer
|
||||
renderer: Renderer,
|
||||
@Attribute('type') type: string
|
||||
) {
|
||||
let element = elementRef.nativeElement;
|
||||
|
||||
if (config.get('hoverCSS') === false) {
|
||||
element.classList.add('disable-hover');
|
||||
}
|
||||
|
||||
// TODO this isn't working in the popup
|
||||
if (element.hasAttribute('type')) {
|
||||
let type = element.getAttribute("type");
|
||||
renderer.setElementAttribute(elementRef, type, "");
|
||||
renderer.setElementClass(elementRef, 'disable-hover', true);
|
||||
}
|
||||
|
||||
if (element.hasAttribute('ion-item')) {
|
||||
@@ -33,6 +28,10 @@ export class Button {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type) {
|
||||
renderer.setElementAttribute(elementRef, type, '');
|
||||
}
|
||||
|
||||
// figure out if and where the icon lives in the button
|
||||
let childNodes = element.childNodes;
|
||||
let childNode;
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
<button block>button[block]</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a button block href="#"><icon help-circle></icon> a[button][block] icon</a>
|
||||
<button block><icon help-circle></icon> button[block] icon</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a button block outline secondary href="#">a[button][block][outline][secondary]</a>
|
||||
<button block outline secondary>button[block][outline][secondary]</button>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import {Component, View, Directive, ElementRef, Optional, NgControl} from 'angular2/angular2';
|
||||
import {Component, Directive, Optional, NgControl, ElementRef, Renderer} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonInput} from '../form/input';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {IonicForm} from '../form/form';
|
||||
|
||||
/**
|
||||
* The checkbox is no different than the HTML checkbox input, except it's styled differently
|
||||
@@ -25,7 +24,6 @@ import {IonicConfig} from '../../config/config';
|
||||
'id'
|
||||
],
|
||||
host: {
|
||||
'class': 'item',
|
||||
'role': 'checkbox',
|
||||
'tappable': 'true',
|
||||
'[attr.tab-index]': 'tabIndex',
|
||||
@@ -33,32 +31,26 @@ import {IonicConfig} from '../../config/config';
|
||||
'[attr.aria-disabled]': 'disabled',
|
||||
'[attr.aria-labelledby]': 'labelId',
|
||||
'(click)': 'click($event)'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
},
|
||||
template:
|
||||
'<media-checkbox disable-activated>' +
|
||||
'<checkbox-icon></checkbox-icon>' +
|
||||
'</media-checkbox>' +
|
||||
'<ion-item-content id="{{labelId}}">' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</ion-item-content>'
|
||||
'<media-checkbox disable-activated>' +
|
||||
'<checkbox-icon></checkbox-icon>' +
|
||||
'</media-checkbox>' +
|
||||
'<ion-item-content id="{{labelId}}">' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</ion-item-content>'
|
||||
})
|
||||
export class Checkbox extends Ion {
|
||||
/**
|
||||
* TODO
|
||||
* @param {ElementRef} elementRef TODO
|
||||
* @param {IonicConfig} ionicConfig TODO
|
||||
* @param {NgControl=} ngControl TODO
|
||||
*/
|
||||
export class Checkbox {
|
||||
|
||||
constructor(
|
||||
form: IonicForm,
|
||||
@Optional() ngControl: NgControl,
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig,
|
||||
@Optional() ngControl: NgControl
|
||||
renderer: Renderer
|
||||
) {
|
||||
super(elementRef, config);
|
||||
this.tabIndex = 0;
|
||||
this.id = IonInput.nextId();
|
||||
renderer.setElementClass(elementRef, 'item', true);
|
||||
this.form = form;
|
||||
form.register(this);
|
||||
|
||||
this.onChange = (_) => {};
|
||||
this.onTouched = (_) => {};
|
||||
@@ -72,8 +64,7 @@ export class Checkbox extends Ion {
|
||||
* TODO
|
||||
*/
|
||||
onInit() {
|
||||
super.onInit();
|
||||
this.labelId = 'label-' + this.id;
|
||||
this.labelId = 'label-' + this.inputId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,4 +112,8 @@ export class Checkbox extends Ion {
|
||||
* @param {Function} fn onTouched event handler.
|
||||
*/
|
||||
registerOnTouched(fn) { this.onTouched = fn; }
|
||||
|
||||
onDestroy() {
|
||||
this.form.deregister(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, View, ElementRef, Optional, Host} from 'angular2/angular2';
|
||||
import {Component, ElementRef, Optional} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -25,11 +25,7 @@ import {ScrollTo} from '../../animations/scroll-to';
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-content',
|
||||
inputs: [
|
||||
'parallax'
|
||||
]
|
||||
})
|
||||
@View({
|
||||
inputs: ['parallax'],
|
||||
template: '<scroll-content><ng-content></ng-content></scroll-content>'
|
||||
})
|
||||
export class Content extends Ion {
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
import {Component, Directive, View, Host, Attribute, ElementRef, forwardRef} from 'angular2/angular2';
|
||||
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {IonInput} from './input';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
@Component({
|
||||
selector: 'focus-holder'
|
||||
})
|
||||
@View({
|
||||
template: '<input tabindex="999"><input tabindex="1001"><input tabindex="1002">',
|
||||
directives: [forwardRef(() => FocusInput)]
|
||||
})
|
||||
export class FocusHolder {
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
constructor() {
|
||||
this.i = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} inputType TODO
|
||||
*/
|
||||
setFocusHolder(inputType) {
|
||||
this.i[2].type = inputType;
|
||||
this.i[2].setFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} tabIndex TODO
|
||||
*/
|
||||
receivedFocus(tabIndex) {
|
||||
if (tabIndex === '999') {
|
||||
// focus on the previous input
|
||||
IonInput.focusPrevious();
|
||||
|
||||
} else if (tabIndex === '1001') {
|
||||
// focus on the next input
|
||||
IonInput.focusNext();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} input TODO
|
||||
*/
|
||||
register(input) {
|
||||
this.i.push(input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: 'input',
|
||||
host: {
|
||||
'[type]': 'type',
|
||||
'(focus)': 'holder.receivedFocus(tabindex)',
|
||||
'(keydown)': 'keydown($event)'
|
||||
}
|
||||
})
|
||||
class FocusInput {
|
||||
constructor(
|
||||
elementRef: ElementRef,
|
||||
@Host() holder: FocusHolder,
|
||||
@Attribute('tabindex') tabindex: string
|
||||
) {
|
||||
this.elementRef = elementRef;
|
||||
this.holder = holder;
|
||||
this.tabindex = tabindex;
|
||||
this.holder.register(this);
|
||||
}
|
||||
|
||||
setFocus() {
|
||||
this.elementRef.nativeElement.focus();
|
||||
}
|
||||
|
||||
keydown(ev) {
|
||||
// prevent any keyboard typing when a holder has focus
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
get type() {
|
||||
// default to text type if unknown
|
||||
return this._t || 'text';
|
||||
}
|
||||
|
||||
set type(val) {
|
||||
this._t = val;
|
||||
}
|
||||
}
|
||||
@@ -66,27 +66,33 @@ select[readonly] {
|
||||
// Focus Utils
|
||||
// -------------------------------
|
||||
|
||||
focus-holder input {
|
||||
focus-ctrl {
|
||||
position: fixed;
|
||||
top: 1px;
|
||||
width: 9px;
|
||||
left: -9999px;
|
||||
z-index: 9999;
|
||||
|
||||
input,
|
||||
button {
|
||||
position: fixed;
|
||||
top: 1px;
|
||||
width: 9px;
|
||||
left: -9999px;
|
||||
z-index: 9999;
|
||||
}
|
||||
}
|
||||
|
||||
/*focus-holder input[tabindex="999"] {
|
||||
|
||||
/*focus-ctrl input[tabindex="999"] {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
focus-holder input[tabindex="1001"] {
|
||||
focus-ctrl input[tabindex="1001"] {
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
focus-holder input[tabindex="1002"] {
|
||||
focus-ctrl input[tabindex="1002"] {
|
||||
left: auto;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
focus-holder input:focus {
|
||||
focus-ctrl input:focus {
|
||||
background: red;
|
||||
}*/
|
||||
|
||||
248
ionic/components/form/form.ts
Normal file
248
ionic/components/form/form.ts
Normal file
@@ -0,0 +1,248 @@
|
||||
import {Injectable, NgZone} from 'angular2/angular2';
|
||||
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {raf} from '../../util/dom';
|
||||
|
||||
/**
|
||||
* The Input component is used to focus text input elements.
|
||||
*
|
||||
* The `focusNext()` and `focusPrevious()` methods make it easy to focus input elements across all devices.
|
||||
*
|
||||
* @usage
|
||||
* ```html
|
||||
* <ion-input>
|
||||
* <ion-label>Name</ion-label>
|
||||
* <input value="Name" type="text">
|
||||
* </ion-input>
|
||||
* ```
|
||||
*/
|
||||
@Injectable()
|
||||
export class IonicForm {
|
||||
|
||||
constructor(config: IonicConfig, zone: NgZone) {
|
||||
this._config = config;
|
||||
this._zone = zone;
|
||||
|
||||
this._inputs = [];
|
||||
this._ids = -1;
|
||||
this._focused = null;
|
||||
|
||||
zone.runOutsideAngular(() => {
|
||||
this.initHolders(document, this._config.get('keyboardScrollAssist'));
|
||||
|
||||
if (this._config.get('keyboardInputListener') !== false) {
|
||||
this.initKeyInput(document);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
initKeyInput(document) {
|
||||
/* Focus Outline
|
||||
* --------------------------------------------------
|
||||
* When a keydown event happens, from a tab key, then the
|
||||
* 'key-input' class is added to the body element so focusable
|
||||
* elements have an outline. On a mousedown or touchstart
|
||||
* event then the 'key-input' class is removed.
|
||||
*/
|
||||
|
||||
let isKeyInputEnabled = false;
|
||||
|
||||
function keyDown(ev) {
|
||||
if (!isKeyInputEnabled && ev.keyCode == 9) {
|
||||
isKeyInputEnabled = true;
|
||||
raf(enableKeyInput);
|
||||
}
|
||||
}
|
||||
|
||||
function pointerDown() {
|
||||
isKeyInputEnabled = false;
|
||||
raf(enableKeyInput);
|
||||
}
|
||||
|
||||
|
||||
function enableKeyInput() {
|
||||
document.body.classList[isKeyInputEnabled ? 'add' : 'remove']('key-input');
|
||||
|
||||
document.removeEventListener('mousedown', pointerDown);
|
||||
document.removeEventListener('touchstart', pointerDown);
|
||||
|
||||
if (isKeyInputEnabled) {
|
||||
document.addEventListener('mousedown', pointerDown);
|
||||
document.addEventListener('touchstart', pointerDown);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', keyDown);
|
||||
}
|
||||
|
||||
initHolders(document, scrollAssist) {
|
||||
// raw DOM fun
|
||||
this._ctrl = document.createElement('focus-ctrl');
|
||||
this._ctrl.setAttribute('aria-hidden', true);
|
||||
|
||||
if (scrollAssist) {
|
||||
this._prev = document.createElement('input');
|
||||
this._prev.tabIndex = NO_FOCUS_TAB_INDEX;
|
||||
this._ctrl.appendChild(this._prev);
|
||||
|
||||
this._next = document.createElement('input');
|
||||
this._next.tabIndex = NO_FOCUS_TAB_INDEX;
|
||||
this._ctrl.appendChild(this._next);
|
||||
|
||||
this._temp = document.createElement('input');
|
||||
this._temp.tabIndex = NO_FOCUS_TAB_INDEX;
|
||||
this._ctrl.appendChild(this._temp);
|
||||
}
|
||||
|
||||
this._blur = document.createElement('button');
|
||||
this._blur.tabIndex = NO_FOCUS_TAB_INDEX;
|
||||
this._ctrl.appendChild(this._blur);
|
||||
|
||||
document.body.appendChild(this._ctrl);
|
||||
|
||||
function preventDefault(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
if (scrollAssist) {
|
||||
this._prev.addEventListener('keydown', preventDefault);
|
||||
this._next.addEventListener('keydown', preventDefault);
|
||||
this._temp.addEventListener('keydown', preventDefault);
|
||||
|
||||
this._prev.addEventListener('focus', () => {
|
||||
this.focusPrevious();
|
||||
});
|
||||
|
||||
this._next.addEventListener('focus', () => {
|
||||
this.focusNext();
|
||||
});
|
||||
|
||||
let self = this;
|
||||
let resetTimer;
|
||||
function queueReset() {
|
||||
clearTimeout(resetTimer);
|
||||
|
||||
resetTimer = setTimeout(function() {
|
||||
self._zone.run(() => {
|
||||
self.resetInputs();
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
document.addEventListener('focusin', queueReset);
|
||||
document.addEventListener('focusout', queueReset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
focusOut() {
|
||||
console.debug('focusOut')
|
||||
this._blur.tabIndex = NORMAL_FOCUS_TAB_INDEX;
|
||||
this._blur.focus();
|
||||
this._blur.tabIndex = NO_FOCUS_TAB_INDEX;
|
||||
}
|
||||
|
||||
setFocusHolder(type) {
|
||||
if (this._temp) {
|
||||
this._temp.tabIndex = TEMP_TAB_INDEX;
|
||||
|
||||
this._temp.type = type || 'text';
|
||||
console.debug('setFocusHolder', this._temp.type);
|
||||
this._temp.focus();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TODO} input TODO
|
||||
*/
|
||||
register(input) {
|
||||
console.debug('register input', input);
|
||||
|
||||
input.inputId = ++this._ids;
|
||||
input.tabIndex = NORMAL_FOCUS_TAB_INDEX;
|
||||
this._inputs.push(input);
|
||||
}
|
||||
|
||||
deregister(input) {
|
||||
console.debug('deregister input', input);
|
||||
|
||||
let index = this._inputs.indexOf(input);
|
||||
if (index > -1) {
|
||||
this._inputs.splice(index, 1);
|
||||
}
|
||||
if (input === this._focused) {
|
||||
this._focused = null;
|
||||
}
|
||||
}
|
||||
|
||||
resetInputs() {
|
||||
this._focused = null;
|
||||
|
||||
for (let i = 0, ii = this._inputs.length; i < ii; i++) {
|
||||
if (!this._focused && this._inputs[i].hasFocus) {
|
||||
this._focused = this._inputs[i];
|
||||
this._focused.tabIndex = ACTIVE_FOCUS_TAB_INDEX;
|
||||
|
||||
} else {
|
||||
this._inputs[i].tabIndex = NORMAL_FOCUS_TAB_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
if (this._temp) {
|
||||
this._temp.tabIndex = NO_FOCUS_TAB_INDEX;
|
||||
|
||||
if (this._focused) {
|
||||
// there's a focused input
|
||||
this._prev.tabIndex = PREV_TAB_INDEX;
|
||||
this._next.tabIndex = NEXT_TAB_INDEX;
|
||||
|
||||
} else {
|
||||
this._prev.tabIndex = this._next.tabIndex = NO_FOCUS_TAB_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses the previous input element, if it exists.
|
||||
*/
|
||||
focusPrevious() {
|
||||
console.debug('focusPrevious');
|
||||
this.focusMove(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses the next input element, if it exists.
|
||||
*/
|
||||
focusNext() {
|
||||
console.debug('focusNext');
|
||||
this.focusMove(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} inc TODO
|
||||
*/
|
||||
focusMove(inc) {
|
||||
let input = this._focused;
|
||||
if (input) {
|
||||
let index = this._inputs.indexOf(input);
|
||||
if (index > -1 && (index + inc) < this._inputs.length) {
|
||||
let siblingInput = this._inputs[index + inc];
|
||||
if (siblingInput) {
|
||||
return siblingInput.initFocus();
|
||||
}
|
||||
}
|
||||
this._focused.initFocus();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const NO_FOCUS_TAB_INDEX = -1;
|
||||
const NORMAL_FOCUS_TAB_INDEX = 0;
|
||||
const PREV_TAB_INDEX = 999;
|
||||
const ACTIVE_FOCUS_TAB_INDEX = 1000;
|
||||
const NEXT_TAB_INDEX = 1001;
|
||||
const TEMP_TAB_INDEX = 2000;
|
||||
@@ -1,87 +0,0 @@
|
||||
import {Directive, ElementRef, Query, QueryList} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
|
||||
|
||||
let inputRegistry = [];
|
||||
let inputItemIds = -1;
|
||||
let activeInput = null;
|
||||
let lastInput = null;
|
||||
|
||||
/**
|
||||
* The Input component is used to focus text input elements.
|
||||
*
|
||||
* The `focusNext()` and `focusPrevious()` methods make it easy to focus input elements across all devices.
|
||||
*
|
||||
* @usage
|
||||
* ```html
|
||||
* <ion-input>
|
||||
* <ion-label>Name</ion-label>
|
||||
* <input value="Name" type="text">
|
||||
* </ion-input>
|
||||
* ```
|
||||
*/
|
||||
export class IonInput extends Ion {
|
||||
/**
|
||||
* @param {TODO} input TODO
|
||||
*/
|
||||
static registerInput(input) {
|
||||
inputRegistry.push(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} input TODO
|
||||
*/
|
||||
static setAsLastInput(input) {
|
||||
lastInput = input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses the previous input element, if it exists.
|
||||
*/
|
||||
static focusPrevious() {
|
||||
this.focusMove(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses the next input element, if it exists.
|
||||
*/
|
||||
static focusNext() {
|
||||
this.focusMove(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} inc TODO
|
||||
*/
|
||||
static focusMove(inc) {
|
||||
let input = activeInput || lastInput;
|
||||
if (input) {
|
||||
|
||||
let index = inputRegistry.indexOf(input);
|
||||
if (index > -1 && (index + inc) < inputRegistry.length) {
|
||||
let siblingInput = inputRegistry[index + inc];
|
||||
siblingInput && siblingInput.initFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Number} The ID of the next input element.
|
||||
*/
|
||||
static nextId() {
|
||||
return ++inputItemIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
static clearTabIndexes() {
|
||||
for (let i = 0; i < inputRegistry.length; i++) {
|
||||
inputRegistry[i].tabIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,9 +3,6 @@ import {Directive, ElementRef, Attribute, Renderer} from 'angular2/angular2';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'icon',
|
||||
inputs: [
|
||||
@@ -15,17 +12,11 @@ import {IonicConfig} from '../../config/config';
|
||||
'isActive'
|
||||
],
|
||||
host: {
|
||||
'[attr.aria-label]': 'label',
|
||||
'role': 'img'
|
||||
}
|
||||
})
|
||||
export class Icon {
|
||||
/**
|
||||
* TODO
|
||||
* @param {ElementRef} elementRef TODO
|
||||
* @param {IonicConfig} config TODO
|
||||
* @param {Renderer} renderer TODO
|
||||
*/
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
config: IonicConfig,
|
||||
@@ -37,9 +28,6 @@ export class Icon {
|
||||
this.mode = config.get('iconMode');
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
onInit() {
|
||||
let ele = this.eleRef.nativeElement;
|
||||
|
||||
@@ -101,7 +89,8 @@ export class Icon {
|
||||
this._name = this.name;
|
||||
this.renderer.setElementClass(this.elementRef, this.name, true);
|
||||
|
||||
this.label = this.name.replace('ion-', '').replace('ios-', '').replace('md-', '').replace('-', ' ');
|
||||
this.renderer.setElementAttribute(this.elementRef, 'aria-label',
|
||||
this.name.replace('ion-', '').replace('ios-', '').replace('md-', '').replace('-', ' '));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ export class ItemGroupTitle {
|
||||
* TODO
|
||||
* @param {ElementRef} elementRef TODO
|
||||
*/
|
||||
constructor(elementRef: ElementRef, config: IonicConfig, @Host() content: Content) {
|
||||
constructor(elementRef: ElementRef, config: IonicConfig, @Optional() @Host() content: Content) {
|
||||
this.isSticky = true;
|
||||
this.content = content;
|
||||
this.ele = elementRef.nativeElement;
|
||||
@@ -46,6 +46,7 @@ export class ItemGroupTitle {
|
||||
}
|
||||
|
||||
onInit() {
|
||||
if(!this.content) { return; }
|
||||
|
||||
this.scrollContent = this.content.elementRef.nativeElement.children[0];
|
||||
|
||||
@@ -85,7 +86,7 @@ export class ItemGroupTitle {
|
||||
if (element.style[CSS.transform] == transformString) {
|
||||
}
|
||||
else {
|
||||
element.style[CSS.transform] = transformString;
|
||||
element.style[CSS.transform] = transformString;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,12 +95,12 @@ export class ItemGroupTitle {
|
||||
// if immediate execution is requested, then just execute immediately
|
||||
// if not, execute in the animation frame.
|
||||
if (executeImmediately) {
|
||||
this.applyTransform(element, translateDyPixelsUp);
|
||||
this.applyTransform(element, translateDyPixelsUp);
|
||||
}
|
||||
else {
|
||||
// see http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
// see http://ionicframework.com/docs/api/utility/ionic.DomUtil/
|
||||
requestAnimationFrame( a => this.applyTransform(element, translateDyPixelsUp) );
|
||||
// see http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
// see http://ionicframework.com/docs/api/utility/ionic.DomUtil/
|
||||
requestAnimationFrame( a => this.applyTransform(element, translateDyPixelsUp) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,10 +123,10 @@ export class ItemGroupTitle {
|
||||
// if you want to experiment, always use the throttled one and just click on the page
|
||||
// you will see all affix elements stacked on top
|
||||
if (scrollTop == 0) {
|
||||
this.calculateScrollLimits(scrollTop);
|
||||
this.calculateScrollLimits(scrollTop);
|
||||
}
|
||||
else {
|
||||
this.throttledCalculateScrollLimits(scrollTop);
|
||||
this.throttledCalculateScrollLimits(scrollTop);
|
||||
}
|
||||
|
||||
// when we scrolled to the container, create the clone of element and place it on top
|
||||
@@ -136,9 +137,9 @@ export class ItemGroupTitle {
|
||||
var cloneCreatedJustNow = false;
|
||||
|
||||
if (!this.affixClone) {
|
||||
this.affixClone = this.createAffixClone();
|
||||
cloneCreatedJustNow = true;
|
||||
this.isSticking = true;
|
||||
this.affixClone = this.createAffixClone();
|
||||
cloneCreatedJustNow = true;
|
||||
this.isSticking = true;
|
||||
}
|
||||
|
||||
// if we're reaching towards the end of the container, apply some nice translation to move up/down the clone
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, Directive, View, ElementRef, NgIf, Host, Optional} from 'angular2/angular2';
|
||||
import {Component, Directive, ElementRef, NgIf, Host, Optional, Renderer} from 'angular2/angular2';
|
||||
|
||||
import {Gesture} from 'ionic/gestures/gesture';
|
||||
import {DragGesture} from 'ionic/gestures/drag-gesture';
|
||||
@@ -30,22 +30,17 @@ import {CSS, raf} from 'ionic/util/dom';
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-item-sliding,[ion-item-sliding]',
|
||||
host: {
|
||||
'class': 'item'
|
||||
},
|
||||
properties: [
|
||||
inputs: [
|
||||
'sliding'
|
||||
]
|
||||
})
|
||||
@View({
|
||||
],
|
||||
template:
|
||||
'<ng-content select="ion-item-options"></ng-content>' +
|
||||
'<ion-item-sliding-content>' +
|
||||
'<ion-item-content>' +
|
||||
'<ng-content></ng-content>'+
|
||||
'</ion-item-content>' +
|
||||
'<ng-content select="[item-right]"></ng-content>' +
|
||||
'</ion-item-sliding-content>',
|
||||
'<ng-content select="ion-item-options"></ng-content>' +
|
||||
'<ion-item-sliding-content>' +
|
||||
'<ion-item-content>' +
|
||||
'<ng-content></ng-content>'+
|
||||
'</ion-item-content>' +
|
||||
'<ng-content select="[item-right]"></ng-content>' +
|
||||
'</ion-item-sliding-content>',
|
||||
directives: [NgIf]
|
||||
})
|
||||
export class ItemSliding {
|
||||
@@ -53,7 +48,9 @@ export class ItemSliding {
|
||||
* TODO
|
||||
* @param {ElementRef} elementRef A reference to the component's DOM element.
|
||||
*/
|
||||
constructor(elementRef: ElementRef, @Optional() @Host() list: List) {
|
||||
constructor(elementRef: ElementRef, renderer: Renderer, @Optional() @Host() list: List) {
|
||||
renderer.setElementClass(elementRef, 'item', true);
|
||||
|
||||
this._isOpen = false;
|
||||
this._isSlideActive = false;
|
||||
this._isTransitioning = false;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, View, ElementRef, Renderer} from 'angular2/angular2';
|
||||
import {Component, ElementRef, Renderer} from 'angular2/angular2';
|
||||
|
||||
|
||||
/**
|
||||
@@ -18,9 +18,7 @@ import {Component, View, ElementRef, Renderer} from 'angular2/angular2';
|
||||
* ```
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-item,[ion-item]'
|
||||
})
|
||||
@View({
|
||||
selector: 'ion-item,[ion-item]',
|
||||
template:
|
||||
'<ng-content select="[item-left]"></ng-content>' +
|
||||
'<ng-content select="[item-right]"></ng-content>' +
|
||||
|
||||
@@ -149,7 +149,7 @@ $item-md-sliding-transition: transform 250ms ease-in-out !default;
|
||||
}
|
||||
|
||||
icon[item-left] + ion-item-content,
|
||||
icon[item-left] + .text-input {
|
||||
icon[item-left] + [text-input] {
|
||||
margin-left: $item-md-padding-left + ($item-md-padding-left / 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Directive, ElementRef} from 'angular2/angular2';
|
||||
import {Directive, ElementRef, Renderer} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -22,10 +22,7 @@ import * as util from 'ionic/util';
|
||||
'items',
|
||||
'virtual',
|
||||
'content'
|
||||
],
|
||||
host: {
|
||||
'class': 'list'
|
||||
}
|
||||
]
|
||||
})
|
||||
export class List extends Ion {
|
||||
/**
|
||||
@@ -33,8 +30,9 @@ export class List extends Ion {
|
||||
* @param {ElementRef} elementRef TODO
|
||||
* @param {IonicConfig} config TODO
|
||||
*/
|
||||
constructor(elementRef: ElementRef, config: IonicConfig) {
|
||||
constructor(elementRef: ElementRef, config: IonicConfig, renderer: Renderer) {
|
||||
super(elementRef, config);
|
||||
renderer.setElementClass(elementRef, 'list', true);
|
||||
this.ele = elementRef.nativeElement;
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {forwardRef, Directive, Host, View, EventEmitter, ElementRef} from 'angular2/angular2';
|
||||
import {forwardRef, Directive, Host, EventEmitter, ElementRef} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicApp} from '../app/app';
|
||||
@@ -54,12 +54,10 @@ import * as gestures from './menu-gestures';
|
||||
'side': 'left',
|
||||
'type': 'reveal'
|
||||
},
|
||||
outputs: ['opening'],
|
||||
host: {
|
||||
'role': 'navigation'
|
||||
},
|
||||
outputs: ['opening']
|
||||
})
|
||||
@View({
|
||||
template: '<ng-content></ng-content><backdrop tappable disable-activated></backdrop>',
|
||||
directives: [forwardRef(() => MenuBackdrop)]
|
||||
})
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
$navbar-ios-height: 4.4rem !default;
|
||||
|
||||
|
||||
.nav .navbar-container {
|
||||
.navbar-container {
|
||||
min-height: $navbar-ios-height;
|
||||
}
|
||||
|
||||
@@ -5,23 +5,19 @@
|
||||
$navbar-md-height: 5.6rem !default;
|
||||
|
||||
|
||||
.nav {
|
||||
|
||||
.navbar-container {
|
||||
min-height: $navbar-md-height;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
margin: 0 0 0 12px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.back-button-icon {
|
||||
margin: 0;
|
||||
min-width: 44px;
|
||||
font-size: 2.4rem;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.navbar-container {
|
||||
min-height: $navbar-md-height;
|
||||
}
|
||||
|
||||
.toolbar .back-button {
|
||||
margin: 0 0 0 12px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.toolbar .back-button-icon {
|
||||
margin: 0;
|
||||
min-width: 44px;
|
||||
font-size: 2.4rem;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, Directive, View, Optional, ElementRef, TemplateRef, forwardRef, Inject} from 'angular2/angular2';
|
||||
import {Component, Directive, Optional, ElementRef, Renderer, TemplateRef, forwardRef, Inject} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {Icon} from '../icon/icon';
|
||||
@@ -51,11 +51,6 @@ class BackButtonText extends Ion {
|
||||
|
||||
@Component({
|
||||
selector: 'ion-navbar',
|
||||
host: {
|
||||
'class': 'toolbar'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
template:
|
||||
'<div class="toolbar-inner">' +
|
||||
'<button class="back-button">' +
|
||||
@@ -77,9 +72,11 @@ export class Navbar extends ToolbarBase {
|
||||
app: IonicApp,
|
||||
@Optional() viewCtrl: ViewController,
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig
|
||||
config: IonicConfig,
|
||||
renderer: Renderer
|
||||
) {
|
||||
super(elementRef, config);
|
||||
renderer.setElementClass(elementRef, 'toolbar', true);
|
||||
|
||||
this.app = app;
|
||||
viewCtrl && viewCtrl.navbarView(this);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {ComponentRef, Compiler, ElementRef, Injector, bind, NgZone, DynamicComponentLoader, AppViewManager} from 'angular2/angular2';
|
||||
import {Compiler, ElementRef, Injector, bind, NgZone, DynamicComponentLoader, AppViewManager} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {makeComponent} from '../../config/decorators';
|
||||
@@ -188,7 +188,7 @@ export class NavController extends Ion {
|
||||
let enteringView = new ViewController(this, componentType, params);
|
||||
|
||||
// add the view to the stack
|
||||
this.add(enteringView);
|
||||
this._add(enteringView);
|
||||
|
||||
if (this.router) {
|
||||
// notify router of the state change
|
||||
@@ -253,12 +253,13 @@ export class NavController extends Ion {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Pop to a specific view in the history stack
|
||||
*
|
||||
* @param view {Component} to pop to
|
||||
* @param view {ViewController} to pop to
|
||||
* @param opts {object} pop options
|
||||
*/
|
||||
popTo(view, opts = {}) {
|
||||
_popTo(view, opts = {}) {
|
||||
|
||||
// Get the target index of the view to pop to
|
||||
let viewIndex = this._views.indexOf(view);
|
||||
@@ -304,7 +305,7 @@ export class NavController extends Ion {
|
||||
* @param opts extra animation options
|
||||
*/
|
||||
popToRoot(opts = {}) {
|
||||
this.popTo(this._views[0]);
|
||||
this._popTo(this.first());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,6 +332,27 @@ export class NavController extends Ion {
|
||||
|
||||
this._incrementId(viewCtrl);
|
||||
this._views.splice(index, 0, viewCtrl);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a view from the nav stack at the specified index.
|
||||
* @param {TODO} index TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
remove(index) {
|
||||
if (index < 0 || index >= this._views.length) {
|
||||
return Promise.reject("Index out of range");
|
||||
}
|
||||
|
||||
let viewToRemove = this._views[index];
|
||||
if (this.isActive(viewToRemove)){
|
||||
return this.pop();
|
||||
} else {
|
||||
this._remove(index);
|
||||
viewToRemove.destroy();
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,7 +405,7 @@ export class NavController extends Ion {
|
||||
viewCtrl.shouldCache = false;
|
||||
|
||||
// add the item to the stack
|
||||
this.add(viewCtrl);
|
||||
this._add(viewCtrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -505,7 +527,7 @@ export class NavController extends Ion {
|
||||
* @private
|
||||
* TODO
|
||||
*/
|
||||
createViewComponetRef(type, hostProtoViewRef, viewContainer, viewCtrlBindings) {
|
||||
createViewComponentRef(type, hostProtoViewRef, viewContainer, viewCtrlBindings) {
|
||||
let bindings = this.bindings.concat(viewCtrlBindings);
|
||||
|
||||
// the same guts as DynamicComponentLoader.loadNextToLocation
|
||||
@@ -520,7 +542,14 @@ export class NavController extends Ion {
|
||||
viewContainer.remove(index);
|
||||
}
|
||||
};
|
||||
return new ComponentRef(newLocation, component, type, null, dispose);
|
||||
|
||||
// TODO: make-shift ComponentRef_, this is pretty much going to
|
||||
// break in future versions of ng2, keep an eye on it
|
||||
return {
|
||||
location: newLocation,
|
||||
instance: component,
|
||||
dispose: dispose
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -749,7 +778,7 @@ export class NavController extends Ion {
|
||||
});
|
||||
|
||||
destroys.forEach(view => {
|
||||
this.remove(view);
|
||||
this._remove(view);
|
||||
view.destroy();
|
||||
});
|
||||
|
||||
@@ -873,11 +902,12 @@ export class NavController extends Ion {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* TODO
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
add(view) {
|
||||
_add(view) {
|
||||
this._incrementId(view);
|
||||
this._views.push(view);
|
||||
}
|
||||
@@ -887,11 +917,12 @@ export class NavController extends Ion {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* TODO
|
||||
* @param {TODO} viewOrIndex TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
remove(viewOrIndex) {
|
||||
_remove(viewOrIndex) {
|
||||
util.array.remove(this._views, viewOrIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, Directive, View, ElementRef, Host, Optional, forwardRef, Inject, NgZone, Compiler, AppViewManager, DynamicComponentLoader, Renderer, ViewContainerRef} from 'angular2/angular2';
|
||||
import {Component, Directive, ElementRef, Host, Optional, forwardRef, Inject, NgZone, Compiler, AppViewManager, DynamicComponentLoader, Renderer, ViewContainerRef} from 'angular2/angular2';
|
||||
|
||||
import {IonicApp} from '../app/app';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -129,9 +129,7 @@ import {NavController} from './nav-controller';
|
||||
],
|
||||
defaultInputs: {
|
||||
'swipeBackEnabled': true
|
||||
}
|
||||
})
|
||||
@View({
|
||||
},
|
||||
template: '<template pane-anchor></template>',
|
||||
directives: [forwardRef(() => NavPaneAnchor)]
|
||||
})
|
||||
@@ -195,11 +193,11 @@ export class Nav extends NavController {
|
||||
// the component being loaded is an <ion-tabs>
|
||||
// Tabs is essentially a pane, cuz it has its own navbar and content containers
|
||||
let contentContainerRef = this._viewManager.getViewContainer(this.anchorElementRef());
|
||||
let viewComponetRef = this.createViewComponetRef(componentType, hostProtoViewRef, contentContainerRef, this.getBindings(viewCtrl));
|
||||
viewComponetRef.instance._paneView = true;
|
||||
let viewComponentRef = this.createViewComponentRef(componentType, hostProtoViewRef, contentContainerRef, this.getBindings(viewCtrl));
|
||||
viewComponentRef.instance._paneView = true;
|
||||
|
||||
viewCtrl.disposals.push(() => {
|
||||
viewComponetRef.dispose();
|
||||
viewComponentRef.dispose();
|
||||
});
|
||||
|
||||
viewCtrl.onReady().then(() => {
|
||||
@@ -210,9 +208,9 @@ export class Nav extends NavController {
|
||||
// normal ion-view going into pane
|
||||
this.getPane(structure, viewCtrl, (pane) => {
|
||||
// add the content of the view into the pane's content area
|
||||
let viewComponetRef = this.createViewComponetRef(componentType, hostProtoViewRef, pane.contentContainerRef, this.getBindings(viewCtrl));
|
||||
let viewComponentRef = this.createViewComponentRef(componentType, hostProtoViewRef, pane.contentContainerRef, this.getBindings(viewCtrl));
|
||||
viewCtrl.disposals.push(() => {
|
||||
viewComponetRef.dispose();
|
||||
viewComponentRef.dispose();
|
||||
|
||||
// remove the pane if there are no view items left
|
||||
pane.totalViews--;
|
||||
@@ -226,10 +224,10 @@ export class Nav extends NavController {
|
||||
|
||||
// a new ComponentRef has been created
|
||||
// set the ComponentRef's instance to this ViewController
|
||||
viewCtrl.setInstance(viewComponetRef.instance);
|
||||
viewCtrl.setInstance(viewComponentRef.instance);
|
||||
|
||||
// remember the ElementRef to the content that was just created
|
||||
viewCtrl.viewElementRef(viewComponetRef.location);
|
||||
viewCtrl.viewElementRef(viewComponentRef.location);
|
||||
|
||||
// get the NavController's container for navbars, which is
|
||||
// the place this NavController will add each ViewController's navbar
|
||||
@@ -406,12 +404,7 @@ class ContentAnchor {
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-pane',
|
||||
host: {
|
||||
'class': 'nav'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
template: '' +
|
||||
template:
|
||||
'<section class="navbar-container">' +
|
||||
'<template navbar-anchor></template>' +
|
||||
'</section>' +
|
||||
@@ -437,9 +430,7 @@ class Pane {
|
||||
|
||||
showNavbar(hasNavbar) {
|
||||
this.navbar = hasNavbar;
|
||||
if (!hasNavbar) {
|
||||
this.renderer.setElementAttribute(this.elementRef, 'no-navbar', '');
|
||||
}
|
||||
this.renderer.setElementAttribute(this.elementRef, 'no-navbar', hasNavbar ? null : '' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ class SecondPage {
|
||||
<p>
|
||||
<button id="from3To2" (click)="pop()">Pop (Go back to 2nd)</button>
|
||||
<button id="insert" (click)="insert()">Insert first page into history before this</button>
|
||||
<button id="remove" (click)="removeSecond()">Remove second page in history</button>
|
||||
</p>
|
||||
<div class="yellow"><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f></div>
|
||||
</ion-content>
|
||||
@@ -124,6 +125,10 @@ class ThirdPage {
|
||||
this.nav.insert(FirstPage, 2);
|
||||
}
|
||||
|
||||
removeSecond() {
|
||||
this.nav.remove(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test';
|
||||
// import {
|
||||
// ddescribe,
|
||||
// describe,
|
||||
// xdescribe,
|
||||
// it,
|
||||
// iit,
|
||||
// xit,
|
||||
// expect,
|
||||
// beforeEach,
|
||||
// afterEach,
|
||||
// AsyncTestCompleter,
|
||||
// inject,
|
||||
// beforeEachBindings
|
||||
// } from 'angular2/test';
|
||||
|
||||
import {Compiler} from 'angular2/angular2';
|
||||
// import {Compiler} from 'angular2/angular2';
|
||||
|
||||
import {
|
||||
NavController,
|
||||
@@ -23,18 +23,43 @@ import {
|
||||
} from 'ionic/ionic';
|
||||
|
||||
|
||||
@Page({
|
||||
template: ''
|
||||
})
|
||||
class SomePage {}
|
||||
|
||||
export function run() {
|
||||
describe("NavController", () => {
|
||||
let nav;
|
||||
|
||||
beforeEach(inject([Compiler], compiler => {
|
||||
nav = new NavController(null, null, new IonicConfig(), null, compiler, null, null, null);
|
||||
}));
|
||||
class FirstPage {}
|
||||
class SecondPage {}
|
||||
class ThirdPage {}
|
||||
|
||||
function mockTransitionFn(enteringView, leavingView, opts, cb) {
|
||||
let destroys = [];
|
||||
|
||||
nav._views.forEach(view => {
|
||||
if (view) {
|
||||
if (view.shouldDestroy) {
|
||||
destroys.push(view);
|
||||
|
||||
} else if (view.state === 2 && view.shouldCache) {
|
||||
view.shouldCache = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
destroys.forEach(view => {
|
||||
nav._remove(view);
|
||||
view.destroy();
|
||||
});
|
||||
cb();
|
||||
}
|
||||
|
||||
function mockCanGoBackFn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// beforeEach(inject([Compiler], compiler => {
|
||||
beforeEach(() => {
|
||||
nav = new NavController(null, null, new IonicConfig(), null, null, null, null, null);
|
||||
});
|
||||
|
||||
it('should exist', () => {
|
||||
expect(nav).not.toBeUndefined();
|
||||
@@ -50,7 +75,7 @@ export function run() {
|
||||
let activeView = new ViewController();
|
||||
activeView.state = 1; // ACTIVE_STATE
|
||||
|
||||
nav.add(activeView);
|
||||
nav._add(activeView);
|
||||
var active = nav.getActive();
|
||||
|
||||
expect(active).toBe(activeView);
|
||||
@@ -58,7 +83,7 @@ export function run() {
|
||||
let secondActiveView = new ViewController();
|
||||
secondActiveView.state = 1; // ACTIVE_STATE
|
||||
|
||||
nav.add(secondActiveView);
|
||||
nav._add(secondActiveView);
|
||||
active = nav.getActive();
|
||||
|
||||
expect(active).toBe(activeView);
|
||||
@@ -93,13 +118,128 @@ export function run() {
|
||||
expect(push).toThrow();
|
||||
});
|
||||
|
||||
it('be successful', () => {
|
||||
expect(SomePage).toBeDefined();
|
||||
it('to add the pushed page to the nav stack', (done) => {
|
||||
expect(FirstPage).toBeDefined();
|
||||
expect(nav._views.length).toBe(0);
|
||||
|
||||
nav.push(SomePage, {}, {});
|
||||
spyOn(nav, '_add').and.callThrough();
|
||||
|
||||
nav.transition = mockTransitionFn;
|
||||
nav.push(FirstPage, {}, {}).then(() => {
|
||||
expect(nav._add).toHaveBeenCalled();
|
||||
expect(nav._views.length).toBe(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("setViews", () => {
|
||||
it('should return a resolved Promise if components is falsy', done => {
|
||||
let s = jasmine.createSpy('success');
|
||||
let f = jasmine.createSpy('fail');
|
||||
|
||||
let promise = nav.setViews();
|
||||
|
||||
promise.then(s, f).then(() => {
|
||||
expect(s).toHaveBeenCalled();
|
||||
expect(f).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
it('replace views with the supplied views', () => {
|
||||
let vc1 = new ViewController(),
|
||||
vc2 = new ViewController(),
|
||||
vc3 = new ViewController();
|
||||
nav._views = [vc1, vc2, vc3];
|
||||
let arr = [FirstPage, SecondPage, ThirdPage];
|
||||
|
||||
nav.transition = mockTransitionFn;
|
||||
nav.setViews(arr);
|
||||
|
||||
//_views[0] will be transitioned out of
|
||||
expect(nav._views[1].componentType).toBe(FirstPage);
|
||||
expect(nav._views[2].componentType).toBe(SecondPage);
|
||||
expect(nav._views[3].componentType).toBe(ThirdPage);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("insert", () => {
|
||||
it('insert page at the specified index', () => {
|
||||
nav._views = [{}, {}, {}];
|
||||
expect(nav._views[2].componentType).toBeUndefined();
|
||||
nav.insert(FirstPage, 2);
|
||||
expect(nav._views[2].componentType).toBe(FirstPage);
|
||||
});
|
||||
|
||||
it('push page if index >= _views.length', () => {
|
||||
nav._views = [{}, {}, {}];
|
||||
spyOn(nav, 'push').and.callThrough();
|
||||
nav.insert(FirstPage, 2);
|
||||
expect(nav.push).not.toHaveBeenCalled();
|
||||
|
||||
nav.transition = mockTransitionFn;
|
||||
nav.insert(FirstPage, 4);
|
||||
expect(nav._views[4].componentType).toBe(FirstPage);
|
||||
expect(nav.push).toHaveBeenCalled();
|
||||
|
||||
nav.insert(FirstPage, 10);
|
||||
expect(nav._views[5].componentType).toBe(FirstPage);
|
||||
expect(nav.push.calls.count()).toBe(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("setRoot", () => {
|
||||
it('remove previous views and set root', () => {
|
||||
let vc1 = new ViewController(),
|
||||
vc2 = new ViewController(),
|
||||
vc3 = new ViewController();
|
||||
nav._views = [vc1, vc2, vc3];
|
||||
expect(nav._views.length).toBe(3);
|
||||
|
||||
nav.transition = mockTransitionFn;
|
||||
nav.setRoot(FirstPage);
|
||||
//_views[0] will be transitioned out of
|
||||
expect(nav._views.length).toBe(2);
|
||||
expect(nav._views[1].componentType).toBe(FirstPage);
|
||||
});
|
||||
});
|
||||
|
||||
describe("remove", () => {
|
||||
it('should remove the view at the specified index', () => {
|
||||
let vc1 = new ViewController(),
|
||||
vc2 = new ViewController(null, FirstPage),
|
||||
vc3 = new ViewController(null, SecondPage);
|
||||
nav._views = [vc1, vc2, vc3];
|
||||
expect(nav._views.length).toBe(3);
|
||||
expect(nav._views[1].componentType).toBe(FirstPage);
|
||||
|
||||
nav.remove(1);
|
||||
|
||||
expect(nav._views.length).toBe(2);
|
||||
expect(nav._views[1].componentType).toBe(SecondPage);
|
||||
});
|
||||
|
||||
it('should pop if index is of active view', () => {
|
||||
let vc1 = new ViewController(),
|
||||
vc2 = new ViewController(null, FirstPage),
|
||||
vc3 = new ViewController(null, SecondPage);
|
||||
|
||||
vc3.state = 1; //ACTIVE_STATE
|
||||
nav._views = [vc1, vc2, vc3];
|
||||
|
||||
spyOn(nav, 'pop').and.callThrough();
|
||||
|
||||
nav.remove(1);
|
||||
expect(nav.pop).not.toHaveBeenCalled();
|
||||
|
||||
nav.remove(1);
|
||||
expect(nav.pop).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
import {
|
||||
Directive,
|
||||
Component,
|
||||
View,
|
||||
bootstrap,
|
||||
Injectable,
|
||||
Inject,
|
||||
forwardRef,
|
||||
Inject,
|
||||
DynamicComponentLoader,
|
||||
ElementRef,
|
||||
Query,
|
||||
QueryList,
|
||||
ComponentRef
|
||||
} from 'angular2/angular2';
|
||||
|
||||
|
||||
@Injectable()
|
||||
class IonicModal {
|
||||
constructor() {
|
||||
console.log('IonicModal constructor');
|
||||
}
|
||||
open(componentType) {
|
||||
console.log('IonicModal open:', componentType.name);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class UserService {
|
||||
constructor() {
|
||||
console.log('UserService constructor');
|
||||
this.id = Math.random();
|
||||
}
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: 'button',
|
||||
host: {
|
||||
'ionic-button': 'true'
|
||||
}
|
||||
})
|
||||
class IonicButton {
|
||||
constructor() {
|
||||
console.log('IonicButton')
|
||||
}
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: 'button',
|
||||
host: {
|
||||
'user-button': 'true'
|
||||
}
|
||||
})
|
||||
class UserButton {
|
||||
constructor() {
|
||||
console.log('UserButton')
|
||||
}
|
||||
}
|
||||
|
||||
var IONIC_DIRECTIVES = [IonicButton];
|
||||
|
||||
@Component({
|
||||
selector: 'user-modal'
|
||||
})
|
||||
@View({
|
||||
template: `
|
||||
<div style="position:absolute;top:0;right:0;bottom:0;left:0;background:#ddd;">
|
||||
<h2>user modal</h2>
|
||||
<p>UserService: {{userService.id}}
|
||||
</div>
|
||||
`
|
||||
})
|
||||
class UserModal {
|
||||
constructor(userService: UserService) {
|
||||
console.log('UserModal constructor');
|
||||
this.userService = userService;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'user-app',
|
||||
hostInjector: [UserService]
|
||||
})
|
||||
@View({
|
||||
template: `
|
||||
<h1>user root component</h1>
|
||||
<button (click)="openModal()">Open Modal</button>
|
||||
<ng-content></ng-content>
|
||||
`,
|
||||
directives: IONIC_DIRECTIVES.concat([UserButton])
|
||||
})
|
||||
class UserRootComponent {
|
||||
constructor(ionicModal: IonicModal, userService: UserService) {
|
||||
console.log('UserRootComponent constructor');
|
||||
this.ionicModal = ionicModal;
|
||||
}
|
||||
openModal(){
|
||||
this.ionicModal.open(UserModal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: 'overlay-anchor'
|
||||
})
|
||||
class OverlayAnchor {
|
||||
constructor(
|
||||
userService: UserService,
|
||||
public elementRef: ElementRef,
|
||||
loader: DynamicComponentLoader)
|
||||
{
|
||||
console.log('OverlayAnchor constructor', userService);
|
||||
loader.loadNextToLocation(UserModal, elementRef).then((ref: ComponentRef) => {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ionicApp(userApp: Type) {
|
||||
function IonicRootComponent() {}
|
||||
IonicRootComponent.annotations = [
|
||||
new Component({
|
||||
selector: 'ion-app',
|
||||
viewInjector: [IonicModal]
|
||||
}),
|
||||
new View({
|
||||
template: `
|
||||
<user-app>
|
||||
<overlay-anchor></overlay-anchor>
|
||||
</user-app>`,
|
||||
directives: [userApp, OverlayAnchor]
|
||||
})
|
||||
];
|
||||
return IonicRootComponent;
|
||||
}
|
||||
|
||||
console.log('bootstrap')
|
||||
bootstrap(ionicApp(UserRootComponent)).catch(err => {
|
||||
console.error('bootstrap', err);
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, View, NgZone, Injectable, Renderer} from 'angular2/angular2';
|
||||
import {Component, NgZone, Injectable, Renderer} from 'angular2/angular2';
|
||||
|
||||
import {IonicApp} from '../app/app';
|
||||
import {Animation} from '../../animations/animation';
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import {Component, View, ElementRef, DynamicComponentLoader} from 'angular2/angular2';
|
||||
import {Component, ElementRef, DynamicComponentLoader} from 'angular2/angular2';
|
||||
|
||||
import {OverlayController} from './overlay-controller';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'ion-overlay'
|
||||
})
|
||||
@View({
|
||||
selector: 'ion-overlay',
|
||||
template: ''
|
||||
})
|
||||
export class OverlayAnchor {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {FORM_DIRECTIVES, NgControl, NgControlGroup,
|
||||
Component, View, ElementRef, Injectable, NgClass, NgIf, NgFor} from 'angular2/angular2';
|
||||
Component, ElementRef, Injectable, NgClass, NgIf, NgFor} from 'angular2/angular2';
|
||||
|
||||
import {OverlayController} from '../overlay/overlay-controller';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -265,25 +265,23 @@ export class Popup {
|
||||
|
||||
const OVERLAY_TYPE = 'popup';
|
||||
|
||||
@Component({
|
||||
selector: 'ion-popup'
|
||||
})
|
||||
// TODO add button type to button: [type]="button.type"
|
||||
@View({
|
||||
@Component({
|
||||
selector: 'ion-popup',
|
||||
template:
|
||||
'<backdrop (click)="_cancel($event)" tappable disable-activated></backdrop>' +
|
||||
'<popup-wrapper [ng-class]="cssClass">' +
|
||||
'<div class="popup-head">' +
|
||||
'<h2 class="popup-title" [inner-html]="title" *ng-if="title"></h2>' +
|
||||
'<h3 class="popup-sub-title" [inner-html]="subTitle" *ng-if="subTitle"></h3>' +
|
||||
'</div>' +
|
||||
'<div class="popup-body">' +
|
||||
'<div [inner-html]="template" *ng-if="template"></div>' +
|
||||
'<input type="{{inputType || \'text\'}}" placeholder="{{inputPlaceholder}}" *ng-if="showPrompt" class="prompt-input">' +
|
||||
'</div>' +
|
||||
'<div class="popup-buttons" *ng-if="buttons.length">' +
|
||||
'<button *ng-for="#button of buttons" (click)="buttonTapped(button, $event)" [inner-html]="button.text"></button>' +
|
||||
'</div>' +
|
||||
'<backdrop (click)="_cancel($event)" tappable disable-activated></backdrop>' +
|
||||
'<popup-wrapper [ng-class]="cssClass">' +
|
||||
'<div class="popup-head">' +
|
||||
'<h2 class="popup-title" [inner-html]="title" *ng-if="title"></h2>' +
|
||||
'<h3 class="popup-sub-title" [inner-html]="subTitle" *ng-if="subTitle"></h3>' +
|
||||
'</div>' +
|
||||
'<div class="popup-body">' +
|
||||
'<div [inner-html]="template" *ng-if="template"></div>' +
|
||||
'<input type="{{inputType || \'text\'}}" placeholder="{{inputPlaceholder}}" *ng-if="showPrompt" class="prompt-input">' +
|
||||
'</div>' +
|
||||
'<div class="popup-buttons" *ng-if="buttons.length">' +
|
||||
'<button *ng-for="#button of buttons" (click)="buttonTapped(button, $event)" [inner-html]="button.text"></button>' +
|
||||
'</div>' +
|
||||
'</popup-wrapper>',
|
||||
directives: [FORM_DIRECTIVES, NgClass, NgIf, NgFor, Button]
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, Directive, ElementRef, Host, Optional, NgControl, Query, QueryList, View} from 'angular2/angular2';
|
||||
import {Component, Directive, ElementRef, Renderer, Host, Optional, NgControl, Query, QueryList} from 'angular2/angular2';
|
||||
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {Ion} from '../ion';
|
||||
@@ -45,7 +45,6 @@ import {ListHeader} from '../list/list';
|
||||
@Directive({
|
||||
selector: 'ion-radio-group',
|
||||
host: {
|
||||
'class': 'list',
|
||||
'role': 'radiogroup',
|
||||
'[attr.aria-activedescendant]': 'activeId',
|
||||
'[attr.aria-describedby]': 'describedById'
|
||||
@@ -64,10 +63,13 @@ export class RadioGroup extends Ion {
|
||||
constructor(
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig,
|
||||
renderer: Renderer,
|
||||
@Optional() ngControl: NgControl,
|
||||
@Query(ListHeader) private headerQuery: QueryList<ListHeader>
|
||||
) {
|
||||
super(elementRef, config);
|
||||
renderer.setElementClass(elementRef, 'list', true);
|
||||
|
||||
this.id = ++radioGroupIds;
|
||||
this.radioIds = -1;
|
||||
this.onChange = (_) => {};
|
||||
@@ -170,7 +172,6 @@ export class RadioGroup extends Ion {
|
||||
'id'
|
||||
],
|
||||
host: {
|
||||
'class': 'item',
|
||||
'role': 'radio',
|
||||
'tappable': 'true',
|
||||
'[attr.id]': 'id',
|
||||
@@ -179,16 +180,14 @@ export class RadioGroup extends Ion {
|
||||
'[attr.aria-disabled]': 'disabled',
|
||||
'[attr.aria-labelledby]': 'labelId',
|
||||
'(click)': 'click($event)'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
},
|
||||
template:
|
||||
'<ion-item-content id="{{labelId}}">' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</ion-item-content>' +
|
||||
'<media-radio>' +
|
||||
'<radio-icon></radio-icon>' +
|
||||
'</media-radio>'
|
||||
'<ion-item-content id="{{labelId}}">' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</ion-item-content>' +
|
||||
'<media-radio>' +
|
||||
'<radio-icon></radio-icon>' +
|
||||
'</media-radio>'
|
||||
})
|
||||
export class RadioButton extends Ion {
|
||||
/**
|
||||
@@ -200,9 +199,12 @@ export class RadioButton extends Ion {
|
||||
constructor(
|
||||
@Host() @Optional() group: RadioGroup,
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig
|
||||
config: IonicConfig,
|
||||
renderer: Renderer
|
||||
) {
|
||||
super(elementRef, config)
|
||||
super(elementRef, config);
|
||||
renderer.setElementClass(elementRef, 'item', true);
|
||||
|
||||
this.group = group;
|
||||
this.tabIndex = 0;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {Component, View, NgIf, NgClass, ElementRef, EventEmitter, Host} from 'angular2/angular2'
|
||||
import {Component, NgIf, NgClass, ElementRef, EventEmitter, Host} from 'angular2/angular2'
|
||||
|
||||
import {Content} from '../content/content';
|
||||
|
||||
import * as util from 'ionic/util';
|
||||
import {raf, ready, CSS} from 'ionic/util/dom';
|
||||
|
||||
|
||||
/**
|
||||
* Allows you to add pull-to-refresh to an Content component.
|
||||
*
|
||||
@@ -50,20 +50,18 @@ import {raf, ready, CSS} from 'ionic/util/dom';
|
||||
'[class.active]': 'isActive',
|
||||
'[class.refreshing]': 'isRefreshing',
|
||||
'[class.refreshingTail]': 'isRefreshingTail'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
template: `<div class="refresher-content" [class.refresher-with-text]="pullingText || refreshingText">
|
||||
<div class="icon-pulling">
|
||||
<i class="icon" [ng-class]="pullingIcon"></i>
|
||||
</div>
|
||||
<div class="text-pulling" [inner-html]="pullingText" *ng-if="pullingText"></div>
|
||||
<div class="icon-refreshing">
|
||||
<!--<ion-spinner ng-if="showSpinner" icon="{{spinner}}"></ion-spinner>-->
|
||||
<i class="icon" [ng-class]="refreshingIcon"></i>
|
||||
</div>
|
||||
<div class="text-refreshing" [inner-html]="refreshingText" *ng-if="refreshingText"></div>
|
||||
</div>`,
|
||||
},
|
||||
template:
|
||||
'<div class="refresher-content" [class.refresher-with-text]="pullingText || refreshingText">' +
|
||||
'<div class="icon-pulling">' +
|
||||
'<i class="icon" [ng-class]="pullingIcon"></i>' +
|
||||
'</div>' +
|
||||
'<div class="text-pulling" [inner-html]="pullingText" *ng-if="pullingText"></div>' +
|
||||
'<div class="icon-refreshing">' +
|
||||
'<i class="icon" [ng-class]="refreshingIcon"></i>' +
|
||||
'</div>' +
|
||||
'<div class="text-refreshing" [inner-html]="refreshingText" *ng-if="refreshingText"></div>' +
|
||||
'</div>',
|
||||
directives: [NgIf, NgClass]
|
||||
})
|
||||
export class Refresher {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, View, ElementRef, onInit} from 'angular2/angular2';
|
||||
import {Component, ElementRef, onInit} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -21,9 +21,12 @@ import * as util from 'ionic/util';
|
||||
'[class.scroll-x]': 'scrollX',
|
||||
'[class.scroll-y]': 'scrollY'
|
||||
},
|
||||
})
|
||||
@View({
|
||||
template: '<scroll-content><div class="scroll-zoom-wrapper"><ng-content></ng-content></div></scroll-content>'
|
||||
template:
|
||||
'<scroll-content>' +
|
||||
'<div class="scroll-zoom-wrapper">' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</div>' +
|
||||
'</scroll-content>'
|
||||
})
|
||||
export class Scroll extends Ion {
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,7 @@ $search-bar-ios-input-close-icon-svg: "<svg xmlns='http://www.w3.org/2000/sv
|
||||
$search-bar-ios-input-close-icon-size: 17px !default;
|
||||
|
||||
|
||||
.search-bar {
|
||||
ion-search-bar {
|
||||
padding: $search-bar-ios-padding;
|
||||
background: $search-bar-ios-background-color;
|
||||
border-bottom: 1px solid $search-bar-ios-border-color;
|
||||
@@ -98,6 +98,14 @@ $search-bar-ios-input-close-icon-size: 17px !default;
|
||||
}
|
||||
}
|
||||
|
||||
&.hairlines .search-bar {
|
||||
.search-bar-cancel {
|
||||
@extend button[clear];
|
||||
transition: $search-bar-ios-cancel-transition;
|
||||
padding-left: 8px;
|
||||
min-height: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
&.hairlines ion-search-bar {
|
||||
border-bottom-width: 0.55px;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ $search-bar-md-input-close-icon-svg: "<svg xmlns='http://www.w3.org/2000/svg
|
||||
$search-bar-md-input-close-icon-size: 22px !default;
|
||||
|
||||
|
||||
.search-bar {
|
||||
ion-search-bar {
|
||||
padding: $search-bar-md-padding;
|
||||
background: $search-bar-md-background-color;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
.search-bar {
|
||||
ion-search-bar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {ElementRef, Pipe, NgControl, Renderer, View, FORM_DIRECTIVES, NgIf, NgClass} from 'angular2/angular2';
|
||||
import {ElementRef, Pipe, NgControl, Renderer, FORM_DIRECTIVES, NgIf, NgClass} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -33,17 +33,15 @@ import {ConfigComponent} from '../../config/decorators';
|
||||
this.element = this.elementRef.nativeElement.querySelector('input');
|
||||
this.element.blur();
|
||||
}
|
||||
}
|
||||
})
|
||||
@View({
|
||||
template: `
|
||||
<div class="search-bar-input-container" [class.left-align]="shouldLeftAlign">
|
||||
<div class="search-bar-search-icon"></div>
|
||||
<input (focus)="inputFocused()" (blur)="inputBlurred()"
|
||||
(input)="inputChanged($event)" class="search-bar-input" type="search" [attr.placeholder]="placeholder" [(ng-model)]="value">
|
||||
<div class="search-bar-close-icon" (click)="clearInput()"></div>
|
||||
</div>
|
||||
<button *ng-if="showCancel" (click)="cancelAction()" class="search-bar-cancel" [class.left-align]="shouldLeftAlign">{{cancelText}}</button>`,
|
||||
},
|
||||
template:
|
||||
'<div class="search-bar-input-container" [class.left-align]="shouldLeftAlign">' +
|
||||
'<div class="search-bar-search-icon"></div>' +
|
||||
'<input (focus)="inputFocused()" (blur)="inputBlurred()" ' +
|
||||
'(input)="inputChanged($event)" class="search-bar-input" type="search" [attr.placeholder]="placeholder" [(ng-model)]="value">' +
|
||||
'<div class="search-bar-close-icon" (click)="clearInput()"></div>' +
|
||||
'</div>' +
|
||||
'<button *ng-if="showCancel" (click)="cancelAction()" class="search-bar-cancel" [class.left-align]="shouldLeftAlign">{{cancelText}}</button>',
|
||||
directives: [FORM_DIRECTIVES, NgIf, NgClass]
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, Directive, View, Renderer, ElementRef, EventEmitter, Host, forwardRef, Optional} from 'angular2/angular2';
|
||||
import {Component, Directive, Renderer, ElementRef, EventEmitter, Host, forwardRef, Optional} from 'angular2/angular2';
|
||||
import {Control, NgControl, NgFormControl, ControlGroup, ControlDirective} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
@@ -25,9 +25,7 @@ import {dom} from 'ionic/util';
|
||||
'[class.ng-valid]': 'cd.control?.valid == true',
|
||||
'[class.ng-invalid]': 'cd.control?.valid == false'
|
||||
*/
|
||||
}
|
||||
})
|
||||
@View({
|
||||
},
|
||||
template: '<div class="ion-segment"><ng-content></ng-content></div>',
|
||||
directives: [forwardRef(() => SegmentButton)]
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Directive, Component, View, ElementRef, Host, NgIf, NgClass} from 'angular2/angular2';
|
||||
import {Directive, Component, ElementRef, Host, NgClass} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {Animation} from 'ionic/animations/animation';
|
||||
@@ -39,16 +39,15 @@ import {Scroll} from '../scroll/scroll';
|
||||
'zoom',
|
||||
'zoomDuration',
|
||||
'zoomMax'
|
||||
]
|
||||
})
|
||||
@View({
|
||||
template: `<div class="swiper-container">
|
||||
<div class="swiper-wrapper">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
<div [class.hide]="!showPager" class="swiper-pagination"></div>
|
||||
</div>`,
|
||||
directives: [NgIf, NgClass]
|
||||
],
|
||||
template:
|
||||
'<div class="swiper-container">' +
|
||||
'<div class="swiper-wrapper">' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</div>' +
|
||||
'<div [class.hide]="!showPager" class="swiper-pagination"></div>' +
|
||||
'</div>',
|
||||
directives: [NgClass]
|
||||
})
|
||||
export class Slides extends Ion {
|
||||
|
||||
@@ -448,10 +447,8 @@ export class Slides extends Ion {
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-slide',
|
||||
inputs: ['zoom']
|
||||
})
|
||||
@View({
|
||||
template: `<div class="slide-zoom"><ng-content></ng-content></div>`
|
||||
inputs: ['zoom'],
|
||||
template: '<div class="slide-zoom"><ng-content></ng-content></div>'
|
||||
})
|
||||
export class Slide {
|
||||
/**
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
import {
|
||||
Component,
|
||||
View,
|
||||
Directive,
|
||||
ElementRef,
|
||||
Host,
|
||||
Optional,
|
||||
NgControl,
|
||||
Inject,
|
||||
forwardRef
|
||||
} from 'angular2/angular2';
|
||||
import {Component, Directive, ElementRef, Renderer, Host, Optional, NgControl, Inject, forwardRef} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonInput} from '../form/input';
|
||||
import {IonicForm} from '../form/form';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {pointerCoord} from '../../util/dom';
|
||||
|
||||
@@ -85,7 +74,6 @@ class MediaSwitch {
|
||||
'id'
|
||||
],
|
||||
host: {
|
||||
'class': 'item',
|
||||
'role': 'checkbox',
|
||||
'tappable': 'true',
|
||||
'[attr.tab-index]': 'tabIndex',
|
||||
@@ -96,20 +84,18 @@ class MediaSwitch {
|
||||
'(mousedown)': 'pointerDown($event)',
|
||||
'(touchend)': 'pointerUp($event)',
|
||||
'(mouseup)': 'pointerUp($event)'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
},
|
||||
template:
|
||||
'<ng-content select="[item-left]"></ng-content>' +
|
||||
'<ion-item-content id="{{labelId}}">' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</ion-item-content>' +
|
||||
'<media-switch disable-activated>' +
|
||||
'<switch-icon></switch-icon>' +
|
||||
'</media-switch>',
|
||||
'<ng-content select="[item-left]"></ng-content>' +
|
||||
'<ion-item-content id="{{labelId}}">' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</ion-item-content>' +
|
||||
'<media-switch disable-activated>' +
|
||||
'<switch-icon></switch-icon>' +
|
||||
'</media-switch>',
|
||||
directives: [MediaSwitch]
|
||||
})
|
||||
export class Switch extends Ion {
|
||||
export class Switch {
|
||||
/**
|
||||
* TODO
|
||||
* @param {ElementRef} elementRef TODO
|
||||
@@ -117,24 +103,27 @@ export class Switch extends Ion {
|
||||
* @param {NgControl=} ngControl TODO
|
||||
*/
|
||||
constructor(
|
||||
form: IonicForm,
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig,
|
||||
renderer: Renderer,
|
||||
@Optional() private ngControl: NgControl
|
||||
) {
|
||||
super(elementRef, config);
|
||||
let self = this;
|
||||
this.form = form;
|
||||
form.register(this);
|
||||
|
||||
self.id = IonInput.nextId();
|
||||
self.tabIndex = 0;
|
||||
self.lastTouch = 0;
|
||||
self.mode = config.get('mode');
|
||||
renderer.setElementClass(elementRef, 'item', true);
|
||||
|
||||
self.onChange = (_) => {};
|
||||
self.onTouched = (_) => {};
|
||||
this.lastTouch = 0;
|
||||
this.mode = config.get('mode');
|
||||
|
||||
this.onChange = (_) => {};
|
||||
this.onTouched = (_) => {};
|
||||
|
||||
if (ngControl) ngControl.valueAccessor = this;
|
||||
|
||||
|
||||
let self = this;
|
||||
function pointerMove(ev) {
|
||||
let currentX = pointerCoord(ev).x;
|
||||
|
||||
@@ -156,21 +145,20 @@ export class Switch extends Ion {
|
||||
}
|
||||
|
||||
this.addMoveListener = function() {
|
||||
this.switchEle.addEventListener('touchmove', pointerMove);
|
||||
this.switchEle.addEventListener('mousemove', pointerMove);
|
||||
self.switchEle.addEventListener('touchmove', pointerMove);
|
||||
self.switchEle.addEventListener('mousemove', pointerMove);
|
||||
elementRef.nativeElement.addEventListener('mouseout', pointerOut);
|
||||
};
|
||||
|
||||
this.removeMoveListener = function() {
|
||||
this.switchEle.removeEventListener('touchmove', pointerMove);
|
||||
this.switchEle.removeEventListener('mousemove', pointerMove);
|
||||
self.switchEle.removeEventListener('touchmove', pointerMove);
|
||||
self.switchEle.removeEventListener('mousemove', pointerMove);
|
||||
elementRef.nativeElement.removeEventListener('mouseout', pointerOut);
|
||||
};
|
||||
}
|
||||
|
||||
onInit() {
|
||||
super.onInit();
|
||||
this.labelId = 'label-' + this.id;
|
||||
this.labelId = 'label-' + this.inputId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,6 +222,7 @@ export class Switch extends Ion {
|
||||
onDestroy() {
|
||||
this.removeMoveListener();
|
||||
this.switchEle = this.addMoveListener = this.removeMoveListener = null;
|
||||
this.form.deregister(this);
|
||||
}
|
||||
|
||||
isDisabled(ev) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Directive, Component, View, Host, ElementRef, Compiler, DynamicComponentLoader, AppViewManager, forwardRef, Injector, NgZone, ViewContainerRef} from 'angular2/angular2';
|
||||
import {Directive, Component, Host, ElementRef, Compiler, DynamicComponentLoader, AppViewManager, forwardRef, Injector, NgZone, ViewContainerRef} from 'angular2/angular2';
|
||||
|
||||
import {IonicApp} from '../app/app';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -63,9 +63,7 @@ import {Tabs} from './tabs';
|
||||
'[attr.aria-labelledby]': 'labeledBy',
|
||||
'[attr.aria-hidden]': 'isNotSelected',
|
||||
'role': 'tabpanel'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
},
|
||||
template: '<template content-anchor></template><ng-content></ng-content>',
|
||||
directives: [forwardRef(() => TabContentAnchor)]
|
||||
})
|
||||
@@ -155,17 +153,17 @@ export class Tab extends NavController {
|
||||
|
||||
loadContainer(componentType, hostProtoViewRef, viewCtrl, done) {
|
||||
|
||||
let viewComponetRef = this.createViewComponetRef(componentType, hostProtoViewRef, this.contentContainerRef, this.getBindings(viewCtrl));
|
||||
let viewComponentRef = this.createViewComponentRef(componentType, hostProtoViewRef, this.contentContainerRef, this.getBindings(viewCtrl));
|
||||
viewCtrl.disposals.push(() => {
|
||||
viewComponetRef.dispose();
|
||||
viewComponentRef.dispose();
|
||||
});
|
||||
|
||||
// a new ComponentRef has been created
|
||||
// set the ComponentRef's instance to this ViewController
|
||||
viewCtrl.setInstance(viewComponetRef.instance);
|
||||
viewCtrl.setInstance(viewComponentRef.instance);
|
||||
|
||||
// remember the ElementRef to the content that was just created
|
||||
viewCtrl.viewElementRef(viewComponetRef.location);
|
||||
viewCtrl.viewElementRef(viewComponentRef.location);
|
||||
|
||||
// get the NavController's container for navbars, which is
|
||||
// the place this NavController will add each ViewController's navbar
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, Directive, View, Injector, ElementRef, Compiler, DynamicComponentLoader, AppViewManager, NgZone, Optional, Host, NgFor, forwardRef, ViewContainerRef} from 'angular2/angular2';
|
||||
import {Component, Directive, Injector, ElementRef, Compiler, DynamicComponentLoader, AppViewManager, NgZone, Optional, Host, NgFor, forwardRef, ViewContainerRef} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicApp} from '../app/app';
|
||||
@@ -65,10 +65,8 @@ import * as dom from 'ionic/util/dom';
|
||||
defaultInputs: {
|
||||
'tabBarPlacement': 'bottom',
|
||||
'tabBarIcons': 'top'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
template: '' +
|
||||
},
|
||||
template:
|
||||
'<section class="navbar-container">' +
|
||||
'<template navbar-anchor></template>' +
|
||||
'</section>' +
|
||||
@@ -146,7 +144,7 @@ export class Tabs extends NavController {
|
||||
* TODO
|
||||
*/
|
||||
addTab(tab) {
|
||||
this.add(tab.viewCtrl);
|
||||
this._add(tab.viewCtrl);
|
||||
|
||||
// return true/false if it's the initial tab
|
||||
return (this.length() === 1);
|
||||
|
||||
@@ -32,7 +32,7 @@ ion-input[floating-label] {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.text-input {
|
||||
[text-input] {
|
||||
align-self: stretch;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import {pointerCoord, hasPointerMoved} from '../../util/dom';
|
||||
],
|
||||
host: {
|
||||
'[attr.id]': 'id',
|
||||
'class': 'input-label',
|
||||
'(touchstart)': 'pointerStart($event)',
|
||||
'(touchend)': 'pointerEnd($event)',
|
||||
'(mousedown)': 'pointerStart($event)',
|
||||
|
||||
@@ -8,12 +8,12 @@ $input-label-ios-color: #7f7f7f !default;
|
||||
.list,
|
||||
ion-card {
|
||||
|
||||
.text-input {
|
||||
[text-input] {
|
||||
margin: $item-ios-padding-top ($item-ios-padding-right / 2) $item-ios-padding-bottom ($item-ios-padding-left / 2);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ion-input[inset] .text-input {
|
||||
ion-input[inset] [text-input] {
|
||||
margin: ($item-ios-padding-top / 2) $item-ios-padding-right ($item-ios-padding-bottom / 2) $item-ios-padding-left;
|
||||
padding: ($item-ios-padding-top / 2) ($item-ios-padding-right / 2) ($item-ios-padding-bottom / 2) ($item-ios-padding-left / 2);
|
||||
}
|
||||
@@ -28,8 +28,8 @@ ion-card {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
[stacked-label] .text-input,
|
||||
[floating-label] .text-input {
|
||||
[stacked-label] [text-input],
|
||||
[floating-label] [text-input] {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ $input-label-md-color: #999 !default;
|
||||
.list,
|
||||
ion-card {
|
||||
|
||||
.text-input {
|
||||
[text-input] {
|
||||
margin: $item-md-padding-top ($item-md-padding-right / 2) $item-md-padding-bottom ($item-md-padding-left / 2);
|
||||
padding: 0;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ ion-card {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
ion-input[inset] .text-input {
|
||||
ion-input[inset] [text-input] {
|
||||
margin: ($item-md-padding-top / 2) $item-md-padding-right ($item-md-padding-bottom / 2) $item-md-padding-left;
|
||||
padding: ($item-md-padding-top / 2) ($item-md-padding-right / 2) ($item-md-padding-bottom / 2) ($item-md-padding-left / 2);
|
||||
}
|
||||
@@ -48,8 +48,8 @@ ion-card {
|
||||
color: $text-input-highlight-color;
|
||||
}
|
||||
|
||||
[stacked-label] .text-input,
|
||||
[floating-label] .text-input {
|
||||
[stacked-label] [text-input],
|
||||
[floating-label] [text-input] {
|
||||
margin-bottom: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@ ion-input.item {
|
||||
}
|
||||
}
|
||||
|
||||
ion-input .text-input {
|
||||
ion-input [text-input] {
|
||||
flex: 1;
|
||||
background-color: $text-input-background-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
ion-input.has-focus .text-input {
|
||||
ion-input.has-focus [text-input] {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import {Directive, View, Host, Optional, ElementRef, Attribute, Query, QueryList, NgZone} from 'angular2/angular2';
|
||||
import {Directive, Host, Optional, ElementRef, Renderer, Attribute, Query, QueryList, NgZone} from 'angular2/angular2';
|
||||
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {IonInput} from '../form/input';
|
||||
import {IonicForm} from '../form/form';
|
||||
import {Label} from './label';
|
||||
import {Ion} from '../ion';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {Content} from '../content/content';
|
||||
import * as dom from '../../util/dom';
|
||||
@@ -15,22 +14,17 @@ import {IonicPlatform} from '../../platform/platform';
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ion-input',
|
||||
inputs: [
|
||||
'tabIndex'
|
||||
],
|
||||
host: {
|
||||
'(focus)': 'receivedFocus(true)',
|
||||
'(blur)': 'receivedFocus(false)',
|
||||
'(touchstart)': 'pointerStart($event)',
|
||||
'(touchend)': 'pointerEnd($event)',
|
||||
'(mouseup)': 'pointerEnd($event)',
|
||||
'[class.has-focus]': 'inputHasFocus',
|
||||
'[class.has-value]': 'inputHasValue',
|
||||
'[tabIndex]': 'activeTabIndex',
|
||||
'class': 'item'
|
||||
'[class.has-focus]': 'hasFocus',
|
||||
'[class.has-value]': 'hasValue'
|
||||
}
|
||||
})
|
||||
export class TextInput extends Ion {
|
||||
export class TextInput {
|
||||
/**
|
||||
* TODO
|
||||
* @param {ElementRef} elementRef TODO
|
||||
@@ -42,31 +36,33 @@ export class TextInput extends Ion {
|
||||
* @param {QueryList<Label>} labelQry TODO
|
||||
*/
|
||||
constructor(
|
||||
form: IonicForm,
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig,
|
||||
renderer: Renderer,
|
||||
app: IonicApp,
|
||||
ngZone: NgZone,
|
||||
zone: NgZone,
|
||||
platform: IonicPlatform,
|
||||
@Optional() @Host() scrollView: Content
|
||||
) {
|
||||
super(elementRef, config);
|
||||
renderer.setElementClass(elementRef, 'item', true);
|
||||
|
||||
this.form = form;
|
||||
form.register(this);
|
||||
|
||||
this.app = app;
|
||||
this.elementRef = elementRef;
|
||||
this.zone = zone;
|
||||
this.platform = platform;
|
||||
|
||||
this.scrollView = scrollView;
|
||||
this.scrollAssist = config.get('keyboardScrollAssist');
|
||||
this.id = IonInput.nextId();
|
||||
IonInput.registerInput(this);
|
||||
|
||||
this.app = app;
|
||||
this.zone = ngZone;
|
||||
this.platform = platform;
|
||||
|
||||
this.keyboardHeight = this.config.get('keyboardHeight');
|
||||
this.keyboardHeight = config.get('keyboardHeight');
|
||||
}
|
||||
|
||||
registerInputElement(textInputElement) {
|
||||
registerInput(textInputElement) {
|
||||
this.input = textInputElement;
|
||||
this.type = textInputElement.type;
|
||||
textInputElement.tabIndex = -1;
|
||||
}
|
||||
|
||||
registerLabel(label) {
|
||||
@@ -77,17 +73,16 @@ export class TextInput extends Ion {
|
||||
* TODO
|
||||
*/
|
||||
onInit() {
|
||||
super.onInit();
|
||||
|
||||
if (this.input && this.label) {
|
||||
this.input.labelledBy = this.label.id = (this.label.id || 'label-' + this.id);
|
||||
this.label.id = (this.label.id || 'label-' + this.inputId)
|
||||
this.input.labelledBy(this.label.id);
|
||||
}
|
||||
|
||||
let self = this;
|
||||
self.scrollMove = (ev) => {
|
||||
self.deregListeners();
|
||||
|
||||
if (self.inputHasFocus) {
|
||||
if (self.hasFocus) {
|
||||
self.tempFocusMove();
|
||||
}
|
||||
};
|
||||
@@ -119,7 +114,7 @@ export class TextInput extends Ion {
|
||||
|
||||
// focus this input if the pointer hasn't moved XX pixels
|
||||
// and the input doesn't already have focus
|
||||
if (!dom.hasPointerMoved(8, this.startCoord, endCoord) && !this.inputHasFocus) {
|
||||
if (!dom.hasPointerMoved(8, this.startCoord, endCoord) && !this.hasFocus) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
@@ -149,7 +144,6 @@ export class TextInput extends Ion {
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
//TODO inconsistent return value, sometimes undefined
|
||||
initFocus() {
|
||||
let scrollView = this.scrollView;
|
||||
|
||||
@@ -327,12 +321,10 @@ export class TextInput extends Ion {
|
||||
setFocus() {
|
||||
this.zone.run(() => {
|
||||
// set focus on the input element
|
||||
this.input && this.input.setFocus();
|
||||
this.input && this.input.initFocus();
|
||||
|
||||
// ensure the body hasn't scrolled down
|
||||
document.body.scrollTop = 0;
|
||||
|
||||
IonInput.setAsLastInput(this);
|
||||
});
|
||||
|
||||
if (this.scrollAssist && this.scrollView) {
|
||||
@@ -343,25 +335,26 @@ export class TextInput extends Ion {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
tempFocusMove() {
|
||||
let focusHolder = this.app.focusHolder();
|
||||
focusHolder.setFocusHolder(this.type);
|
||||
this.form.setFocusHolder(this.type);
|
||||
}
|
||||
|
||||
get inputHasFocus() {
|
||||
get hasFocus() {
|
||||
return !!this.input && this.input.hasFocus;
|
||||
}
|
||||
|
||||
get inputHasValue() {
|
||||
get hasValue() {
|
||||
return !!this.input && this.input.hasValue;
|
||||
}
|
||||
|
||||
get activeTabIndex() {
|
||||
this.input.tabIndex = (this.inputHasFocus ? 1000 : -1);
|
||||
return -1;
|
||||
get tabIndex() {
|
||||
return this.input && this.input.tabIndex;
|
||||
}
|
||||
|
||||
set tabIndex(val) {
|
||||
if (this.input) {
|
||||
this.input.tabIndex = val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,7 +362,7 @@ export class TextInput extends Ion {
|
||||
* @param {boolean} receivedFocus TODO
|
||||
*/
|
||||
receivedFocus(receivedFocus) {
|
||||
if (receivedFocus && !this.inputHasFocus) {
|
||||
if (receivedFocus && !this.hasFocus) {
|
||||
this.initFocus();
|
||||
|
||||
} else {
|
||||
@@ -377,6 +370,11 @@ export class TextInput extends Ion {
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
this.deregListeners();
|
||||
this.form.deregister(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,33 +387,41 @@ export class TextInput extends Ion {
|
||||
'tabIndex'
|
||||
],
|
||||
host: {
|
||||
'[tabIndex]': 'tabIndex',
|
||||
'[attr.aria-labelledby]': 'labelledBy',
|
||||
'class': 'text-input input'
|
||||
'[tabIndex]': 'tabIndex'
|
||||
}
|
||||
})
|
||||
export class TextInputElement {
|
||||
/**
|
||||
* TODO
|
||||
* @param {string} type The value of the underlying element's type attribute.
|
||||
* @param {ElementRef} elementRef TODO
|
||||
* @param {IonicConfig} config TODO
|
||||
*/
|
||||
|
||||
constructor(
|
||||
form: IonicForm,
|
||||
@Attribute('type') type: string,
|
||||
elementRef: ElementRef,
|
||||
@Optional() textInput: TextInput
|
||||
renderer: Renderer,
|
||||
@Optional() textInputWrapper: TextInput
|
||||
) {
|
||||
this.form = form;
|
||||
this.type = type;
|
||||
this.elementRef = elementRef;
|
||||
this.tabIndex = this.tabIndex || '';
|
||||
textInput && textInput.registerInputElement(this);
|
||||
this.tabIndex = 0;
|
||||
|
||||
this.renderer = renderer;
|
||||
renderer.setElementAttribute(this.elementRef, 'text-input', '');
|
||||
|
||||
if (textInputWrapper) {
|
||||
// it's within ionic's ion-input, let ion-input handle what's up
|
||||
textInputWrapper.registerInput(this);
|
||||
|
||||
} else {
|
||||
// not within ion-input
|
||||
form.register(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the input.
|
||||
*/
|
||||
setFocus() {
|
||||
labelledBy(val) {
|
||||
this.renderer.setElementAttribute(this.elementRef, 'aria-labelledby', val);
|
||||
}
|
||||
|
||||
initFocus() {
|
||||
this.elementRef.nativeElement.focus();
|
||||
}
|
||||
|
||||
@@ -424,7 +430,7 @@ export class TextInputElement {
|
||||
* @returns {boolean} true if the input has focus, otherwise false.
|
||||
*/
|
||||
get hasFocus() {
|
||||
return dom.hasFocus(this.elementRef);
|
||||
return dom.hasFocus(this.elementRef.nativeElement);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -434,6 +440,10 @@ export class TextInputElement {
|
||||
get hasValue() {
|
||||
return (this.elementRef.nativeElement.value !== '');
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
this.form.deregister(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, Directive, View, Host, ElementRef, Optional, forwardRef, Inject} from 'angular2/angular2';
|
||||
import {Component, Directive, Host, ElementRef, Renderer, Optional, forwardRef, Inject} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
@@ -57,11 +57,6 @@ export class ToolbarBase extends Ion {
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-toolbar',
|
||||
host: {
|
||||
'class': 'toolbar'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
template:
|
||||
'<div class="toolbar-inner">' +
|
||||
'<ng-content select="[menu-toggle]"></ng-content>' +
|
||||
@@ -74,18 +69,18 @@ export class ToolbarBase extends Ion {
|
||||
export class Toolbar extends ToolbarBase {
|
||||
constructor(
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig
|
||||
config: IonicConfig,
|
||||
renderer: Renderer
|
||||
) {
|
||||
super(elementRef, config);
|
||||
renderer.setElementClass(elementRef, 'toolbar', true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'ion-title'
|
||||
})
|
||||
@View({
|
||||
selector: 'ion-title',
|
||||
template:
|
||||
'<div class="toolbar-title">' +
|
||||
'<ng-content></ng-content>' +
|
||||
|
||||
Reference in New Issue
Block a user