mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
Merge branch 'master' into v4
This commit is contained in:
85
CHANGELOG.md
85
CHANGELOG.md
@ -1,3 +1,86 @@
|
|||||||
|
<a name="3.1.0"></a>
|
||||||
|
# [3.1.0](https://github.com/driftyco/ionic/compare/v3.0.1...v3.1.0) (2017-04-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Steps to Upgrade
|
||||||
|
|
||||||
|
Update your package.json to match the following dependencies, remove the existing `node_modules` directory, and then run `npm install`:
|
||||||
|
|
||||||
|
```
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/common": "4.0.2",
|
||||||
|
"@angular/compiler": "4.0.2",
|
||||||
|
"@angular/compiler-cli": "4.0.2",
|
||||||
|
"@angular/core": "4.0.2",
|
||||||
|
"@angular/forms": "4.0.2",
|
||||||
|
"@angular/http": "4.0.2",
|
||||||
|
"@angular/platform-browser": "4.0.2",
|
||||||
|
"@angular/platform-browser-dynamic": "4.0.2",
|
||||||
|
"@ionic-native/core": "3.4.2",
|
||||||
|
"@ionic-native/splash-screen": "3.4.2",
|
||||||
|
"@ionic-native/status-bar": "3.4.2",
|
||||||
|
"@ionic/storage": "2.0.1",
|
||||||
|
"ionic-angular": "3.1.0",
|
||||||
|
"ionicons": "3.0.0",
|
||||||
|
"rxjs": "5.1.1",
|
||||||
|
"sw-toolbox": "3.4.0",
|
||||||
|
"zone.js": "^0.8.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@ionic/app-scripts": "1.3.4",
|
||||||
|
"typescript": "~2.2.1"
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **input:** trigger inputUpdated on initialize ([5776f76](https://github.com/driftyco/ionic/commit/5776f76))
|
||||||
|
* **input:** make sure isDisabled gets set to a boolean ([bfa2362](https://github.com/driftyco/ionic/commit/bfa2362))
|
||||||
|
* **item-options:** rtl support ([#11188](https://github.com/driftyco/ionic/issues/11188)) ([ea6450e](https://github.com/driftyco/ionic/commit/ea6450e))
|
||||||
|
* **menu:** rtl support ([5311336](https://github.com/driftyco/ionic/commit/5311336))
|
||||||
|
* **menu:** rtl support ([51d5079](https://github.com/driftyco/ionic/commit/51d5079))
|
||||||
|
* **nav-controller:** print exceptions inside lifecycle events ([95c06a5](https://github.com/driftyco/ionic/commit/95c06a5)), closes [#10974](https://github.com/driftyco/ionic/issues/10974)
|
||||||
|
* **nav-controller:** filter null view-controllers ([8605672](https://github.com/driftyco/ionic/commit/8605672))
|
||||||
|
* **nav-controller:** queue lazy loading ([f88823a](https://github.com/driftyco/ionic/commit/f88823a))
|
||||||
|
* **nav-controller:** fix crash when it is destroyed ([cc1eb02](https://github.com/driftyco/ionic/commit/cc1eb02)), closes [#11338](https://github.com/driftyco/ionic/issues/11338)
|
||||||
|
* **navigation:** legacy deeplink config can have a defaultHistory entry that is a component ([35f3947](https://github.com/driftyco/ionic/commit/35f3947))
|
||||||
|
* **platform:** resize events are dispatched inside zone ([83509db](https://github.com/driftyco/ionic/commit/83509db))
|
||||||
|
* **scroll:** fix memory leak ([3c8edba](https://github.com/driftyco/ionic/commit/3c8edba))
|
||||||
|
* **searchbar:** debounce input for ionInput ([11a1c70](https://github.com/driftyco/ionic/commit/11a1c70))
|
||||||
|
* **select:** stores string | string[] ([ba44780](https://github.com/driftyco/ionic/commit/ba44780)), closes [#11337](https://github.com/driftyco/ionic/issues/11337)
|
||||||
|
* **slides:** fix fast rerendering crash ([#11100](https://github.com/driftyco/ionic/issues/11100)) ([78d427d](https://github.com/driftyco/ionic/commit/78d427d)), closes [#10830](https://github.com/driftyco/ionic/issues/10830)
|
||||||
|
* **sliding-gesture:** add missing return value ([3b32b8e](https://github.com/driftyco/ionic/commit/3b32b8e))
|
||||||
|
* **tabs:** invalid component comparison ([#11084](https://github.com/driftyco/ionic/issues/11084)) ([e423e08](https://github.com/driftyco/ionic/commit/e423e08))
|
||||||
|
* **toggle:** use correct toggle background color for iOS colors ([b3d68c9](https://github.com/driftyco/ionic/commit/b3d68c9))
|
||||||
|
* **util:** pass an option to default to right side in isRightSide ([7bcf5a0](https://github.com/driftyco/ionic/commit/7bcf5a0))
|
||||||
|
* **virtual-scroll:** create views inside zone ([fd3c6ba](https://github.com/driftyco/ionic/commit/fd3c6ba)), closes [#10451](https://github.com/driftyco/ionic/issues/10451)
|
||||||
|
* **virtual-scroll:** supports null records ([67af71b](https://github.com/driftyco/ionic/commit/67af71b))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **app:** add pull-left/right/start/end ([#11214](https://github.com/driftyco/ionic/issues/11214)) ([d9ac950](https://github.com/driftyco/ionic/commit/d9ac950))
|
||||||
|
* **app:** add text-start and text-end ([#11213](https://github.com/driftyco/ionic/issues/11213)) ([6cd719f](https://github.com/driftyco/ionic/commit/6cd719f))
|
||||||
|
* **app:** add responsive utility attributes by screen size ([#11228](https://github.com/driftyco/ionic/issues/11228)) ([cf24057](https://github.com/driftyco/ionic/commit/cf24057)), closes [#10567](https://github.com/driftyco/ionic/issues/10567)
|
||||||
|
* **item:** add sass variable to override avatar border radius ([b0dc856](https://github.com/driftyco/ionic/commit/b0dc856)), closes [#10763](https://github.com/driftyco/ionic/issues/10763)
|
||||||
|
* **label:** fix positioning of floating label for rtl ([#11324](https://github.com/driftyco/ionic/issues/11324)) ([0ec71cd](https://github.com/driftyco/ionic/commit/0ec71cd))
|
||||||
|
* **list:** rtl support for list-header ([#11328](https://github.com/driftyco/ionic/issues/11328)) ([e31a4da](https://github.com/driftyco/ionic/commit/e31a4da))
|
||||||
|
* **modal:** add cssClass to modal options ([5cb51ef](https://github.com/driftyco/ionic/commit/5cb51ef)), closes [#10020](https://github.com/driftyco/ionic/issues/10020)
|
||||||
|
* **platform:** add electron as a platform ([#10868](https://github.com/driftyco/ionic/issues/10868)) ([c0df862](https://github.com/driftyco/ionic/commit/c0df862))
|
||||||
|
* **rtl:** add start and end text-align for alert and picker ([cb5707d](https://github.com/driftyco/ionic/commit/cb5707d))
|
||||||
|
* **segment:** add segment rtl support ([#11215](https://github.com/driftyco/ionic/issues/11215)) ([dd0b293](https://github.com/driftyco/ionic/commit/dd0b293))
|
||||||
|
* **select:** add popover interface as an option ([745d808](https://github.com/driftyco/ionic/commit/745d808))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **toggle:** css containment ([93d1d02](https://github.com/driftyco/ionic/commit/93d1d02))
|
||||||
|
* **toggle:** events are not zoned ([bda624f](https://github.com/driftyco/ionic/commit/bda624f))
|
||||||
|
* **toggle:** toggle's button is not activated ([17c0543](https://github.com/driftyco/ionic/commit/17c0543))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="3.0.1"></a>
|
<a name="3.0.1"></a>
|
||||||
## [3.0.1](https://github.com/driftyco/ionic/compare/v3.0.0...v3.0.1) (2017-04-06)
|
## [3.0.1](https://github.com/driftyco/ionic/compare/v3.0.0...v3.0.1) (2017-04-06)
|
||||||
|
|
||||||
@ -14,7 +97,7 @@
|
|||||||
# [3.0.0](https://github.com/driftyco/ionic/compare/v2.3.0...v3.0.0) (2017-04-05)
|
# [3.0.0](https://github.com/driftyco/ionic/compare/v2.3.0...v3.0.0) (2017-04-05)
|
||||||
|
|
||||||
|
|
||||||
### Steps to Upgrade
|
### Steps to Upgrade to 3.0
|
||||||
|
|
||||||
With this release comes a major update to Angular (Angular 4.0!), the latest version of TypeScript, and some optional structural changes to your application.
|
With this release comes a major update to Angular (Angular 4.0!), the latest version of TypeScript, and some optional structural changes to your application.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<ion-slides loop="true" style="background-color: black">
|
<ion-slides loop="true" style="background-color: black">
|
||||||
<ion-slide *ngFor="let image of [1,2,3,4,5]">
|
<ion-slide *ngFor="let image of [1,2,3,4,5]">
|
||||||
<img data-src="./slide{{image}}.jpeg">
|
<img data-src="../assets/slide{{image}}.jpeg">
|
||||||
</ion-slide>
|
</ion-slide>
|
||||||
</ion-slides>
|
</ion-slides>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "ionic2",
|
"name": "ionic2",
|
||||||
"version": "3.0.1",
|
"version": "3.1.0",
|
||||||
"description": "A powerful framework for building mobile and progressive web apps with JavaScript and Angular 2",
|
"description": "A powerful framework for building mobile and progressive web apps with JavaScript and Angular 2",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"ionic",
|
"ionic",
|
||||||
|
@ -51,7 +51,7 @@ export class ItemOptions {
|
|||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
isRightSide(): boolean {
|
isRightSide(): boolean {
|
||||||
return isRightSide(this.side, this._plt.isRTL);
|
return isRightSide(this.side, this._plt.isRTL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +44,10 @@ $label-ios-margin: $item-ios-padding-top ($item-ios-padding-right /
|
|||||||
transition: transform 150ms ease-in-out;
|
transition: transform 150ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .label-ios[floating] {
|
||||||
|
transform-origin: right top;
|
||||||
|
}
|
||||||
|
|
||||||
.input-has-focus .label-ios[floating],
|
.input-has-focus .label-ios[floating],
|
||||||
.input-has-value .label-ios[floating] {
|
.input-has-value .label-ios[floating] {
|
||||||
transform: translate3d(0, 0, 0) scale(.8);
|
transform: translate3d(0, 0, 0) scale(.8);
|
||||||
|
@ -48,6 +48,10 @@ $label-md-margin: $item-md-padding-top ($item-md-padding-rig
|
|||||||
transition: transform 150ms ease-in-out;
|
transition: transform 150ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .label-md[floating] {
|
||||||
|
transform-origin: right top;
|
||||||
|
}
|
||||||
|
|
||||||
.label-md[stacked],
|
.label-md[stacked],
|
||||||
.label-md[floating] {
|
.label-md[floating] {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
@ -40,6 +40,11 @@ $label-wp-text-color-focused: color($colors-wp, primary) !default;
|
|||||||
transform-origin: left top;
|
transform-origin: left top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .label-wp[floating] {
|
||||||
|
transform: translate3d(-8px, 34px, 0);
|
||||||
|
transform-origin: right top;
|
||||||
|
}
|
||||||
|
|
||||||
.label-wp[stacked],
|
.label-wp[stacked],
|
||||||
.label-wp[floating] {
|
.label-wp[floating] {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
@ -182,6 +182,10 @@ $list-ios-header-background-color: transparent !default;
|
|||||||
background: $list-ios-header-background-color;
|
background: $list-ios-header-background-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .list-header-ios {
|
||||||
|
padding-right: $list-ios-header-padding-left;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Generate iOS List Header Colors
|
// Generate iOS List Header Colors
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -168,6 +168,11 @@ $list-md-header-color: #757575 !default;
|
|||||||
color: $list-md-header-color;
|
color: $list-md-header-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .list-header-md {
|
||||||
|
padding-right: $list-md-header-padding-left;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Generate Material Design List Header Colors
|
// Generate Material Design List Header Colors
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -165,6 +165,11 @@ $list-wp-header-color: $list-wp-text-color !default;
|
|||||||
color: $list-wp-header-color;
|
color: $list-wp-header-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .list-header-wp {
|
||||||
|
padding-right: $list-wp-header-padding-left;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Generate Windows List Header Colors
|
// Generate Windows List Header Colors
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -4,6 +4,7 @@ import { NgControl } from '@angular/forms';
|
|||||||
import { Config } from '../../config/config';
|
import { Config } from '../../config/config';
|
||||||
import { BaseInput } from '../../util/base-input';
|
import { BaseInput } from '../../util/base-input';
|
||||||
import { isPresent, isTrueProperty } from '../../util/util';
|
import { isPresent, isTrueProperty } from '../../util/util';
|
||||||
|
import { TimeoutDebouncer } from '../../util/debouncer';
|
||||||
import { Platform } from '../../platform/platform';
|
import { Platform } from '../../platform/platform';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,6 +64,7 @@ export class Searchbar extends BaseInput<string> {
|
|||||||
_isActive: boolean = false;
|
_isActive: boolean = false;
|
||||||
_showCancelButton: boolean = false;
|
_showCancelButton: boolean = false;
|
||||||
_animated: boolean = false;
|
_animated: boolean = false;
|
||||||
|
_inputDebouncer: TimeoutDebouncer = new TimeoutDebouncer(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @input {string} Set the the cancel button text. Default: `"Cancel"`.
|
* @input {string} Set the the cancel button text. Default: `"Cancel"`.
|
||||||
@ -89,6 +91,7 @@ export class Searchbar extends BaseInput<string> {
|
|||||||
}
|
}
|
||||||
set debounce(val: number) {
|
set debounce(val: number) {
|
||||||
this._debouncer.wait = val;
|
this._debouncer.wait = val;
|
||||||
|
this._inputDebouncer.wait = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,7 +291,9 @@ export class Searchbar extends BaseInput<string> {
|
|||||||
*/
|
*/
|
||||||
inputChanged(ev: any) {
|
inputChanged(ev: any) {
|
||||||
this.value = ev.target.value;
|
this.value = ev.target.value;
|
||||||
this.ionInput.emit(ev);
|
this._inputDebouncer.debounce(() => {
|
||||||
|
this.ionInput.emit(ev);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,12 +147,13 @@ import { SelectPopover, SelectPopoverOption } from './select-popover-component';
|
|||||||
providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: Select, multi: true } ],
|
providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: Select, multi: true } ],
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
})
|
})
|
||||||
export class Select extends BaseInput<string[]> implements AfterViewInit, OnDestroy {
|
export class Select extends BaseInput<string[]|string> implements AfterViewInit, OnDestroy {
|
||||||
|
|
||||||
_multi: boolean = false;
|
_multi: boolean = false;
|
||||||
_options: QueryList<Option>;
|
_options: QueryList<Option>;
|
||||||
_texts: string[] = [];
|
_texts: string[] = [];
|
||||||
_text: string = '';
|
_text: string = '';
|
||||||
|
_values: string[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @input {string} The text to display on the cancel button. Default: `Cancel`.
|
* @input {string} The text to display on the cancel button. Default: `Cancel`.
|
||||||
@ -394,7 +395,7 @@ export class Select extends BaseInput<string[]> implements AfterViewInit, OnDest
|
|||||||
set options(val: QueryList<Option>) {
|
set options(val: QueryList<Option>) {
|
||||||
this._options = val;
|
this._options = val;
|
||||||
|
|
||||||
if (this._value.length === 0) {
|
if (this._values.length === 0) {
|
||||||
// there are no values set at this point
|
// there are no values set at this point
|
||||||
// so check to see who should be selected
|
// so check to see who should be selected
|
||||||
// we use writeValue() because we don't want to update ngModel
|
// we use writeValue() because we don't want to update ngModel
|
||||||
@ -404,14 +405,7 @@ export class Select extends BaseInput<string[]> implements AfterViewInit, OnDest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_inputNormalize(val: any): string[] {
|
_inputShouldChange(val: string[]|string): boolean {
|
||||||
if (Array.isArray(val)) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
return [val + ''];
|
|
||||||
}
|
|
||||||
|
|
||||||
_inputShouldChange(val: string[]): boolean {
|
|
||||||
return !deepEqual(this._value, val);
|
return !deepEqual(this._value, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,11 +414,12 @@ export class Select extends BaseInput<string[]> implements AfterViewInit, OnDest
|
|||||||
*/
|
*/
|
||||||
_inputUpdated() {
|
_inputUpdated() {
|
||||||
this._texts.length = 0;
|
this._texts.length = 0;
|
||||||
|
this._values = Array.isArray(this._value) ? this._value : [this._value + ''];
|
||||||
|
|
||||||
if (this._options) {
|
if (this._options) {
|
||||||
this._options.forEach(option => {
|
this._options.forEach(option => {
|
||||||
// check this option if the option's value is in the values array
|
// check this option if the option's value is in the values array
|
||||||
option.selected = this._value.some(selectValue => {
|
option.selected = this._values.some(selectValue => {
|
||||||
return isCheckedProperty(selectValue, option.value);
|
return isCheckedProperty(selectValue, option.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ describe('Select', () => {
|
|||||||
corpus: [
|
corpus: [
|
||||||
[['hola'], ['hola']],
|
[['hola'], ['hola']],
|
||||||
[null, []],
|
[null, []],
|
||||||
['hola', ['hola']],
|
['hola', 'hola'],
|
||||||
[['hola', 'adios'], ['hola', 'adios']]
|
[['hola', 'adios'], ['hola', 'adios']]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -891,6 +891,11 @@ export function enableTouchControl(s: Slides) {
|
|||||||
|
|
||||||
// Cleanup dynamic styles
|
// Cleanup dynamic styles
|
||||||
function cleanupStyles(s: Slides) {
|
function cleanupStyles(s: Slides) {
|
||||||
|
if (!s.container || !s._wrapper) {
|
||||||
|
// fix #10830
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Container
|
// Container
|
||||||
removeClass(s.container, s._classNames);
|
removeClass(s.container, s._classNames);
|
||||||
s.container.removeAttribute('style');
|
s.container.removeAttribute('style');
|
||||||
|
@ -21,7 +21,7 @@ export function processRecords(stopAtHeight: number,
|
|||||||
let startRecordIndex: number;
|
let startRecordIndex: number;
|
||||||
let previousCell: VirtualCell;
|
let previousCell: VirtualCell;
|
||||||
let tmpData: any;
|
let tmpData: any;
|
||||||
let lastRecordIndex = (records.length - 1);
|
let lastRecordIndex = records ? (records.length - 1) : -1;
|
||||||
|
|
||||||
if (cells.length) {
|
if (cells.length) {
|
||||||
// we already have cells
|
// we already have cells
|
||||||
@ -131,11 +131,11 @@ export function populateNodeData(startCellIndex: number, endCellIndex: number, v
|
|||||||
cells: VirtualCell[], records: any[], nodes: VirtualNode[], viewContainer: ViewContainerRef,
|
cells: VirtualCell[], records: any[], nodes: VirtualNode[], viewContainer: ViewContainerRef,
|
||||||
itmTmp: TemplateRef<VirtualContext>, hdrTmp: TemplateRef<VirtualContext>, ftrTmp: TemplateRef<VirtualContext>,
|
itmTmp: TemplateRef<VirtualContext>, hdrTmp: TemplateRef<VirtualContext>, ftrTmp: TemplateRef<VirtualContext>,
|
||||||
initialLoad: boolean): boolean {
|
initialLoad: boolean): boolean {
|
||||||
const recordsLength = records.length;
|
if (!records || records.length === 0) {
|
||||||
if (!recordsLength) {
|
|
||||||
nodes.length = 0;
|
nodes.length = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
const recordsLength = records.length;
|
||||||
|
|
||||||
let hasChanges = false;
|
let hasChanges = false;
|
||||||
let node: VirtualNode;
|
let node: VirtualNode;
|
||||||
|
@ -14,7 +14,7 @@ export class SlideEdgeGesture extends SlideGesture {
|
|||||||
|
|
||||||
constructor(plt: Platform, element: HTMLElement, opts: any = {}) {
|
constructor(plt: Platform, element: HTMLElement, opts: any = {}) {
|
||||||
defaults(opts, {
|
defaults(opts, {
|
||||||
edge: 'left',
|
edge: 'start',
|
||||||
maxEdgeStart: 50
|
maxEdgeStart: 50
|
||||||
});
|
});
|
||||||
super(plt, element, opts);
|
super(plt, element, opts);
|
||||||
@ -29,7 +29,7 @@ export class SlideEdgeGesture extends SlideGesture {
|
|||||||
switch (value) {
|
switch (value) {
|
||||||
case 'start': return isRTL ? 'right' : 'left';
|
case 'start': return isRTL ? 'right' : 'left';
|
||||||
case 'end': return isRTL ? 'left' : 'right';
|
case 'end': return isRTL ? 'left' : 'right';
|
||||||
default: value;
|
default: return value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -216,6 +216,10 @@ export class NavControllerBase extends Ion implements NavController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_success(result: NavResult, ti: TransitionInstruction) {
|
_success(result: NavResult, ti: TransitionInstruction) {
|
||||||
|
if (this._queue === null) {
|
||||||
|
this._fireError('nav controller was destroyed', ti);
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._init = true;
|
this._init = true;
|
||||||
this._trnsId = null;
|
this._trnsId = null;
|
||||||
|
|
||||||
@ -237,6 +241,10 @@ export class NavControllerBase extends Ion implements NavController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_failed(rejectReason: any, ti: TransitionInstruction) {
|
_failed(rejectReason: any, ti: TransitionInstruction) {
|
||||||
|
if (this._queue === null) {
|
||||||
|
this._fireError('nav controller was destroyed', ti);
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._trnsId = null;
|
this._trnsId = null;
|
||||||
this._queue.length = 0;
|
this._queue.length = 0;
|
||||||
|
|
||||||
@ -245,6 +253,10 @@ export class NavControllerBase extends Ion implements NavController {
|
|||||||
this._swipeBackCheck();
|
this._swipeBackCheck();
|
||||||
this._nextTrns();
|
this._nextTrns();
|
||||||
|
|
||||||
|
this._fireError(rejectReason, ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
_fireError(rejectReason: any, ti: TransitionInstruction) {
|
||||||
if (ti.done) {
|
if (ti.done) {
|
||||||
ti.done(false, false, rejectReason);
|
ti.done(false, false, rejectReason);
|
||||||
}
|
}
|
||||||
|
@ -1068,6 +1068,23 @@ describe('NavController', () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('destroy', () => {
|
||||||
|
|
||||||
|
it('should not crash when destroyed while transitioning', (done) => {
|
||||||
|
let view1 = mockView(MockView1);
|
||||||
|
nav.push(view1).then(() => {
|
||||||
|
fail('it should not succeed');
|
||||||
|
done();
|
||||||
|
}).catch((err: any) => {
|
||||||
|
expect(err).toEqual('nav controller was destroyed');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
nav.destroy();
|
||||||
|
}, 10000);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
let nav: NavControllerBase;
|
let nav: NavControllerBase;
|
||||||
let trnsDone: jasmine.Spy;
|
let trnsDone: jasmine.Spy;
|
||||||
|
|
||||||
|
@ -238,6 +238,16 @@ export class BaseInput<T> extends Ion implements CommonInput<T> {
|
|||||||
return this._isFocus;
|
return this._isFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
hasValue(): boolean {
|
||||||
|
const val = this._value;
|
||||||
|
return isArray(val)
|
||||||
|
? val.length > 0
|
||||||
|
: isPresent(val);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
@ -260,12 +270,7 @@ export class BaseInput<T> extends Ion implements CommonInput<T> {
|
|||||||
if (!this._item) {
|
if (!this._item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this._item.setElementClass('input-has-value', this.hasValue());
|
||||||
const hasValue = isArray(val)
|
|
||||||
? val.length > 0
|
|
||||||
: isPresent(val);
|
|
||||||
|
|
||||||
this._item.setElementClass('input-has-value', hasValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,15 +128,24 @@ export function isCheckedProperty(a: any, b: any): boolean {
|
|||||||
return (a == b); // tslint:disable-line
|
return (a == b); // tslint:disable-line
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
export type Side = 'left' | 'right' | 'start' | 'end';
|
export type Side = 'left' | 'right' | 'start' | 'end';
|
||||||
|
|
||||||
export function isRightSide(side: Side, isRTL: boolean): boolean {
|
/**
|
||||||
|
* @hidden
|
||||||
|
* Given a side, return if it should be on the right
|
||||||
|
* based on the value of dir
|
||||||
|
* @param side the side
|
||||||
|
* @param isRTL whether the application dir is rtl
|
||||||
|
* @param defaultRight whether the default side is right
|
||||||
|
*/
|
||||||
|
export function isRightSide(side: Side, isRTL: boolean, defaultRight: boolean = false): boolean {
|
||||||
switch (side) {
|
switch (side) {
|
||||||
case 'right': return true;
|
case 'right': return true;
|
||||||
case 'left': return false;
|
case 'left': return false;
|
||||||
case 'end': return !isRTL;
|
case 'end': return !isRTL;
|
||||||
// 'start' by default
|
case 'start': return isRTL;
|
||||||
default: return isRTL;
|
default: return defaultRight ? !isRTL : isRTL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user