mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
120 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c463b065c7 | ||
|
|
5883da20fd | ||
|
|
b224a65f22 | ||
|
|
e1948be1f8 | ||
|
|
248a1ceced | ||
|
|
75cf887f91 | ||
|
|
32c5bed546 | ||
|
|
4f3e91bdfa | ||
|
|
236e7f8393 | ||
|
|
ea710044ef | ||
|
|
efd6605f98 | ||
|
|
aaa3cac917 | ||
|
|
4cc54eeb5d | ||
|
|
cfdba88754 | ||
|
|
7c583938a2 | ||
|
|
d659676ba2 | ||
|
|
e555eae1f5 | ||
|
|
5742540a36 | ||
|
|
6978bb551f | ||
|
|
e7ac15f9be | ||
|
|
2ab8385ee0 | ||
|
|
616786b387 | ||
|
|
6b5f9f113f | ||
|
|
2bba548253 | ||
|
|
1497d83a0e | ||
|
|
7f7f60ede5 | ||
|
|
73f6a82446 | ||
|
|
893ef725e9 | ||
|
|
4ea843440b | ||
|
|
f2946e77e6 | ||
|
|
ebdf22d2d3 | ||
|
|
dd66f9a7a9 | ||
|
|
6b848a04b3 | ||
|
|
af363581da | ||
|
|
33960f1a5a | ||
|
|
e5df0625b2 | ||
|
|
22747e3588 | ||
|
|
dc280b4199 | ||
|
|
fae5365b12 | ||
|
|
ecde0ae70f | ||
|
|
c8be8e254c | ||
|
|
356240883e | ||
|
|
c4e9b5d343 | ||
|
|
9f17b388d2 | ||
|
|
49e0c3701a | ||
|
|
ee766e1de8 | ||
|
|
74c5871ac4 | ||
|
|
8ec70ee02a | ||
|
|
ae4be669bb | ||
|
|
c91223bfb2 | ||
|
|
b1803510e3 | ||
|
|
70809caa8d | ||
|
|
88b2e8316d | ||
|
|
199cb00444 | ||
|
|
9bfd286dfa | ||
|
|
ac4dd6fea2 | ||
|
|
2646ebedf1 | ||
|
|
a77bb2c1d5 | ||
|
|
c963745888 | ||
|
|
2bd89feb0f | ||
|
|
c38cc28c5f | ||
|
|
9d4c94a7ac | ||
|
|
ad8d8ed2c3 | ||
|
|
0ba33d943f | ||
|
|
e0c830962c | ||
|
|
dac887092e | ||
|
|
e5b3eb7c8b | ||
|
|
c60588a290 | ||
|
|
77fcaef436 | ||
|
|
9c2181b8f9 | ||
|
|
4db20a648c | ||
|
|
f6d6596912 | ||
|
|
39e7da3840 | ||
|
|
9b3fb78a68 | ||
|
|
559f4d3bd5 | ||
|
|
f1a676e4c2 | ||
|
|
1573043f4e | ||
|
|
0a49648fe8 | ||
|
|
599bf3df5e | ||
|
|
fce5d8a04f | ||
|
|
108fc0fc3f | ||
|
|
521402b548 | ||
|
|
921ccbb79e | ||
|
|
c08de08d5f | ||
|
|
4199accdc2 | ||
|
|
70ab2a4e74 | ||
|
|
eacc5d4f23 | ||
|
|
112d4f5490 | ||
|
|
f42e81b02b | ||
|
|
9b5c0e035b | ||
|
|
4e56458b5c | ||
|
|
b5bfda2c42 | ||
|
|
200fa935b8 | ||
|
|
66faa1d959 | ||
|
|
b248eb7508 | ||
|
|
c7b2b186ec | ||
|
|
86210750d5 | ||
|
|
794d88d455 | ||
|
|
a48d02a966 | ||
|
|
d028a29d0e | ||
|
|
288c00a641 | ||
|
|
3b5c34c801 | ||
|
|
f2dc8b24b1 | ||
|
|
547ab8d8ef | ||
|
|
e2b3d753a7 | ||
|
|
3fb0371927 | ||
|
|
59f97e780d | ||
|
|
468dcd32fa | ||
|
|
cfd9e3b3a9 | ||
|
|
86e2742d58 | ||
|
|
8c207e827e | ||
|
|
fdacbbf1d0 | ||
|
|
ac04710b8a | ||
|
|
d0cad6b31e | ||
|
|
f5ef1ca552 | ||
|
|
830f885a06 | ||
|
|
54cdf00454 | ||
|
|
5bb3e73296 | ||
|
|
ae94f5ecea | ||
|
|
b87d212829 |
30
.github/ISSUE_TEMPLATE.md
vendored
30
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,15 +1,18 @@
|
||||
**Resources:**
|
||||
Before submitting an issue, please consult our troubleshooting guide (http://ionicframework.com/docs/troubleshooting/) and developer resources (http://ionicframework.com/docs/developer-resources/)
|
||||
<!-- Before submitting an issue, please consult our troubleshooting guide (http://ionicframework.com/docs/troubleshooting/) and developer resources (http://ionicframework.com/docs/developer-resources/) -->
|
||||
|
||||
<!-- Please make sure you are posting an issue pertaining to the Ionic Framework. If you are having an issue with the Ionic Pro services (Ionic View, Ionic Deploy, etc.) please consult the Ionic Pro support portal (http://support.ionicjs.com) -->
|
||||
|
||||
**Ionic version:** (check one with "x")
|
||||
[ ] **1.x** (For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
|
||||
(For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
|
||||
[ ] **2.x**
|
||||
[ ] **3.x**
|
||||
[ ] **4.x**
|
||||
|
||||
**I'm submitting a ...** (check one with "x")
|
||||
[ ] bug report
|
||||
[ ] feature request
|
||||
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
|
||||
|
||||
Please do not submit support requests or "How to" questions here. Instead, please use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
|
||||
|
||||
**Current behavior:**
|
||||
<!-- Describe how the bug manifests. -->
|
||||
@@ -18,17 +21,22 @@ Before submitting an issue, please consult our troubleshooting guide (http://ion
|
||||
<!-- Describe what the behavior would be without the bug. -->
|
||||
|
||||
**Steps to reproduce:**
|
||||
<!-- If you are able to illustrate the bug or feature request with an example, please provide steps to reproduce and if possible a demo using one of the following templates:
|
||||
|
||||
For Ionic V1 issues - http://plnkr.co/edit/Xo1QyAUx35ny1Xf9ODHx?p=preview
|
||||
|
||||
For Ionic issues - http://plnkr.co/edit/cpeRJs?p=preview
|
||||
-->
|
||||
<!-- Please explain the steps required to duplicate the issue, especially if you are able to provide a sample application. -->
|
||||
|
||||
**Related code:**
|
||||
|
||||
<!-- If you are able to illustrate the bug or feature request with an example, please provide a sample application via one of the following means:
|
||||
|
||||
A sample application via GitHub
|
||||
|
||||
StackBlitz (https://stackblitz.com)
|
||||
|
||||
Plunker (http://plnkr.co/edit/cpeRJs?p=preview)
|
||||
|
||||
-->
|
||||
|
||||
```
|
||||
insert any relevant code here
|
||||
insert short code snippets here
|
||||
```
|
||||
|
||||
**Other information:**
|
||||
|
||||
278
CHANGELOG.md
278
CHANGELOG.md
@@ -1,3 +1,281 @@
|
||||
<a name="3.9.1"></a>
|
||||
## [3.9.1](https://github.com/ionic-team/ionic/compare/v3.9.0...v3.9.1) (2017-11-08)
|
||||
|
||||
## Upgrade Instructions
|
||||
`ionic-angular` 3.9.1 is patch release of `ionic-angular` 3.9.0. To upgrade, follow the instructions [here](https://github.com/ionic-team/ionic/blob/master/CHANGELOG.md#390-2017-11-08) for updating to `ionic-angular` 3.9.0. After completing those steps, update the `ionic-angular` version to 3.9.1.
|
||||
|
||||
```
|
||||
npm install ionic-angular@3.9.1 --save
|
||||
```
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** avoid adding cancel and done button repeatedly ([248a1ce](https://github.com/ionic-team/ionic/commit/248a1ce))
|
||||
|
||||
|
||||
|
||||
<a name="3.9.0"></a>
|
||||
# [3.9.0](https://github.com/ionic-team/ionic/compare/v3.8.0...v3.9.0) (2017-11-08)
|
||||
|
||||
### Upgrade Instructions
|
||||
`ionic-angular` 3.9.0 adds support for `@angular` 5.0.0 :tada:! It is a drop-in replacement for `ionic-angular` 3.8.x.
|
||||
|
||||
To update, remove existing `node_modules` and any lock files, and then update `package.json` to the following deps.
|
||||
|
||||
```
|
||||
"dependencies" : {
|
||||
...
|
||||
"@angular/common": "5.0.0",
|
||||
"@angular/compiler": "5.0.0",
|
||||
"@angular/compiler-cli": "5.0.0",
|
||||
"@angular/core": "5.0.0",
|
||||
"@angular/forms": "5.0.0",
|
||||
"@angular/http": "5.0.0",
|
||||
"@angular/platform-browser": "5.0.0",
|
||||
"@angular/platform-browser-dynamic": "5.0.0",
|
||||
"@ionic/storage": "2.1.3",
|
||||
"ionic-angular": "3.9.0",
|
||||
"rxjs": "5.5.2",
|
||||
"zone.js": "0.8.18"
|
||||
...
|
||||
},
|
||||
"devDependencies: {
|
||||
"@ionic/app-scripts": "3.1.0"
|
||||
"typescript" : "2.4.2"
|
||||
}
|
||||
```
|
||||
|
||||
If your app uses RXJS, see the instructions below to update.
|
||||
|
||||
### RXJS 5.5.2 Updates
|
||||
|
||||
The recent update of RXJS includes a change in how operators are applied.
|
||||
|
||||
Traditionally, operators were applied like this:
|
||||
|
||||
```typescript
|
||||
import 'rxjs/add/operator/debounceTime';
|
||||
import 'rxjs/add/operator/switchMap';
|
||||
|
||||
export MyClass {
|
||||
|
||||
|
||||
someMethod(){
|
||||
// Using Reactive Forms
|
||||
this.input.valueChanges
|
||||
.debounceTime(500)
|
||||
.switchMap(inputVal => this.service.get(inputVal))
|
||||
.subscribe(res => console.log(res))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This approach involved modifying the Observable prototype and patching on the
|
||||
methods.
|
||||
|
||||
RXJS 5.5 introduces a different way to do this that can lead to significantly
|
||||
smaller code bundles, lettable operators.
|
||||
|
||||
To use lettable operators, modify the code from above to look like this:
|
||||
|
||||
```typescript
|
||||
//Use Deep imports here for smallest bunlde size
|
||||
import { debounceTime } from 'rxjs/operators/debounceTime';
|
||||
import { switch } from 'rxjs/operators/switchMap';
|
||||
|
||||
export MyClass {
|
||||
|
||||
|
||||
someMethod(){
|
||||
// Using Reactive Forms
|
||||
// We use the new `.pipe` method on the observable
|
||||
// too apply operators now
|
||||
|
||||
this.input.valueChanges
|
||||
.pipe(
|
||||
debounceTime(500),
|
||||
switchMap(inputVal => this.service.get(inputVal))
|
||||
)
|
||||
.subscribe(res => console.log(res))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This slight change allows only import the operators we need in our code. This will result in a smaller, faster application. This example uses Deep Imports, which allow the module we want to import to be isolated.
|
||||
|
||||
Take a look at [this
|
||||
doc](https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md) for more information.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **action-sheet:** move box-shadow to first group ([4f3e91b](https://github.com/ionic-team/ionic/commit/4f3e91b))
|
||||
* **alert:** focus input after it is ready ([#13259](https://github.com/ionic-team/ionic/issues/13259)) ([e555eae](https://github.com/ionic-team/ionic/commit/e555eae))
|
||||
* **datetime:** use spread operator to copy pickerOptions ([#13202](https://github.com/ionic-team/ionic/issues/13202)) ([2ab8385](https://github.com/ionic-team/ionic/commit/2ab8385)), closes [#11641](https://github.com/ionic-team/ionic/issues/11641)
|
||||
* **input:** better support for WKKeyboard ([#13106](https://github.com/ionic-team/ionic/issues/13106)) ([e7ac15f](https://github.com/ionic-team/ionic/commit/e7ac15f))
|
||||
* **tabs:** no safe area padding for top tabs ([236e7f8](https://github.com/ionic-team/ionic/commit/236e7f8))
|
||||
* **tap-click:** clear activated state on activable element when appropriate ([#13258](https://github.com/ionic-team/ionic/issues/13258)) ([5742540](https://github.com/ionic-team/ionic/commit/5742540)), closes [#13044](https://github.com/ionic-team/ionic/issues/13044)
|
||||
* **VirtualScroll:** stop from resizing while out of view ([#13143](https://github.com/ionic-team/ionic/issues/13143)) ([6978bb5](https://github.com/ionic-team/ionic/commit/6978bb5))
|
||||
|
||||
|
||||
|
||||
<a name="3.8.0"></a>
|
||||
# [3.8.0](https://github.com/ionic-team/ionic/compare/v3.7.1...v3.8.0) (2017-10-26)
|
||||
|
||||
|
||||
### Upgrade Instructions
|
||||
|
||||
This release includes improvements for iOS11 and specifically, the iPhone X. Please also read over the [iOS 11 checklist](http://blog.ionic.io/ios-11-checklist/) blog post for additional information.
|
||||
|
||||
To update, install the latest version of `ionic-angular` and `@ionic/app-scripts`:
|
||||
|
||||
```bash
|
||||
npm install ionic-angular@latest --save
|
||||
npm install @ionic/app-scripts@latest --save-dev
|
||||
```
|
||||
|
||||
This release uses version `4.4.4` of Angular. Please update the version number of any `@angular` packages in your `package.json` file:
|
||||
|
||||
```
|
||||
"dependencies": {
|
||||
"@angular/common": "4.4.4",
|
||||
"@angular/compiler": "4.4.4",
|
||||
"@angular/compiler-cli": "4.4.4",
|
||||
"@angular/core": "4.4.4",
|
||||
"@angular/forms": "4.4.4",
|
||||
"@angular/http": "4.4.4",
|
||||
"@angular/platform-browser": "4.4.4",
|
||||
"@angular/platform-browser-dynamic": "4.4.4",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **action-sheet:** fix action sheet so it will scroll when the options exceed the screen ([#13049](https://github.com/ionic-team/ionic/issues/13049)) ([199cb00](https://github.com/ionic-team/ionic/commit/199cb00))
|
||||
* **content:** reize on orientationchange only ([6b848a0](https://github.com/ionic-team/ionic/commit/6b848a0))
|
||||
* **cordova:** size footer correctly ([33960f1](https://github.com/ionic-team/ionic/commit/33960f1))
|
||||
* **item:** safe-padding on last item only ([af36358](https://github.com/ionic-team/ionic/commit/af36358))
|
||||
* **nav:** remove bad assert ([ae4be66](https://github.com/ionic-team/ionic/commit/ae4be66))
|
||||
* **navigation:** account for condition of toggling one view with tabs to another view with tabs ([c963745](https://github.com/ionic-team/ionic/commit/c963745))
|
||||
* **navigation:** add defaultHistory support to ion-tabs ([2646ebe](https://github.com/ionic-team/ionic/commit/2646ebe))
|
||||
* **navigation:** unregister root navs when appropriate ([2bd89fe](https://github.com/ionic-team/ionic/commit/2bd89fe))
|
||||
* **overlay:** onWillDismiss is called as expected ([#12056](https://github.com/ionic-team/ionic/issues/12056)) ([c91223b](https://github.com/ionic-team/ionic/commit/c91223b)), closes [#11702](https://github.com/ionic-team/ionic/issues/11702)
|
||||
* **popover:** improve positioning in ios11 ([73f6a82](https://github.com/ionic-team/ionic/commit/73f6a82))
|
||||
* **select:** overlay types should use shared interface ([c4e9b5d](https://github.com/ionic-team/ionic/commit/c4e9b5d)), closes [#13103](https://github.com/ionic-team/ionic/issues/13103)
|
||||
* **swiper:** add safe-guards when user tries to zoom a slide without an image ([#12931](https://github.com/ionic-team/ionic/issues/12931)) ([e0c8309](https://github.com/ionic-team/ionic/commit/e0c8309)), closes [#12861](https://github.com/ionic-team/ionic/issues/12861)
|
||||
* **swiper:** allow for multiple swipers on a page ([#12213](https://github.com/ionic-team/ionic/issues/12213)) ([dd66f9a](https://github.com/ionic-team/ionic/commit/dd66f9a)), closes [#12008](https://github.com/ionic-team/ionic/issues/12008)
|
||||
* **tabs:** emit viewDidEnter and viewDidLeave on app during tab change ([c8be8e2](https://github.com/ionic-team/ionic/commit/c8be8e2))
|
||||
* **tabs:** return promises where appropriate ([a77bb2c](https://github.com/ionic-team/ionic/commit/a77bb2c))
|
||||
* **virtual-scroll:** flickering issue fixes ([88b2e83](https://github.com/ionic-team/ionic/commit/88b2e83))
|
||||
* **viewController** move resize logic to viewCtrl ([ebdf22d](https://github.com/ionic-team/ionic/commit/ebdf22d))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **alert:** export AlertButton interface ([0ba33d9](https://github.com/ionic-team/ionic/commit/0ba33d9)), closes [#12545](https://github.com/ionic-team/ionic/issues/12545)
|
||||
* **input:** add dir attribute for different language directions ([#13043](https://github.com/ionic-team/ionic/issues/13043)) ([b180351](https://github.com/ionic-team/ionic/commit/b180351))
|
||||
* improved ios11 support ([49e0c37](https://github.com/ionic-team/ionic/commit/49e0c37))
|
||||
|
||||
|
||||
|
||||
<a name="3.7.1"></a>
|
||||
## [3.7.1](https://github.com/ionic-team/ionic/compare/v3.7.0...v3.7.1) (2017-09-29)
|
||||
|
||||
|
||||
### Upgrade Instructions
|
||||
|
||||
This release includes the latest version of `zone.js`. Update your `package.json` to match the following dependencies, remove the existing `node_modules` directory, and then run `npm install`:
|
||||
|
||||
```
|
||||
"dependencies": {
|
||||
...
|
||||
"ionic-angular": "3.7.1",
|
||||
...
|
||||
"zone.js": "0.8.18"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** set default to max if max before current only [#9846](https://github.com/ionic-team/ionic/issues/9846) ([39e7da3](https://github.com/ionic-team/ionic/commit/39e7da3))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **datetime:** add default picker value input ([b87d212](https://github.com/ionic-team/ionic/commit/b87d212))
|
||||
* **datetime:** default to now or max. Fixes [#9846](https://github.com/ionic-team/ionic/issues/9846) ([559f4d3](https://github.com/ionic-team/ionic/commit/559f4d3))
|
||||
|
||||
|
||||
|
||||
<a name="3.7.0"></a>
|
||||
# [3.7.0](https://github.com/ionic-team/ionic/compare/v3.6.1...v3.7.0) (2017-09-28)
|
||||
|
||||
### Notes
|
||||
This release adds support for the latest version of Angular (4.4.3) as well as the initial iteration of support for the iPhone X.
|
||||
|
||||
### Upgrade Instructions
|
||||
|
||||
These are the latest versions of `@angular`, `rxjs`, `zone.js` and `ionic-angular`. Update your `package.json` to match the following dependencies, remove the existing `node_modules` directory, and then run `npm install`:
|
||||
|
||||
```
|
||||
...
|
||||
"dependencies": {
|
||||
"@angular/common": "4.4.3",
|
||||
"@angular/compiler": "4.4.3",
|
||||
"@angular/compiler-cli": "4.4.3",
|
||||
"@angular/core": "4.4.3",
|
||||
"@angular/forms": "4.4.3",
|
||||
"@angular/http": "4.4.3",
|
||||
"@angular/platform-browser": "4.4.3",
|
||||
"@angular/platform-browser-dynamic": "4.4.3",
|
||||
"ionic-angular": "3.7.0",
|
||||
"rxjs": "5.4.3",
|
||||
"zone.js": "0.8.17"
|
||||
}
|
||||
"devDependencies": {
|
||||
"@ionic/app-scripts": "3.0.0"
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
If you're using a `package-lock.json` file, make sure that is updated as well.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **input:** mark ion-input touched on blur instead of changed ([#12812](https://github.com/ionic-team/ionic/issues/12812)) ([d0cad6b](https://github.com/ionic-team/ionic/commit/d0cad6b)), closes [#12102](https://github.com/ionic-team/ionic/issues/12102)
|
||||
* **swiper:** change var to let to avoid variable shadowing ([f5ef1ca](https://github.com/ionic-team/ionic/commit/f5ef1ca))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* initial iphoneX support ([112d4f5](https://github.com/ionic-team/ionic/commit/112d4f5))
|
||||
|
||||
|
||||
<a name="3.6.1"></a>
|
||||
## [3.6.1](https://github.com/ionic-team/ionic/compare/v3.6.0...v3.6.1) (2017-09-07)
|
||||
|
||||
### Upgrade Instructions
|
||||
|
||||
`ionic-angular@3.6.1` is a drop-in replacement for 3.6.0. To install it, please run:
|
||||
|
||||
```
|
||||
npm install -g ionic@latest
|
||||
npm install @ionic/app-scripts@2.1.4 --save-dev
|
||||
npm install ionic-angular@3.6.1 --save
|
||||
```
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **generators:** Update documentation URLs for templates ([475b722](https://github.com/ionic-team/ionic/commit/475b722))
|
||||
* **navigation:** check existence of done transition callback ([#12640](https://github.com/ionic-team/ionic/issues/12640)) ([0a6bb3b](https://github.com/ionic-team/ionic/commit/0a6bb3b))
|
||||
* **navigation:** ensure secondaryId always has a string value ([#12641](https://github.com/ionic-team/ionic/issues/12641)) ([1069505](https://github.com/ionic-team/ionic/commit/1069505))
|
||||
* **navigation:** fix popTo signature and make usage uniform ([3187375](https://github.com/ionic-team/ionic/commit/3187375))
|
||||
* **slider:** guard the processing of _slides ([b809665](https://github.com/ionic-team/ionic/commit/b809665)), closes [#12791](https://github.com/ionic-team/ionic/issues/12791)
|
||||
|
||||
|
||||
|
||||
<a name="3.6.0"></a>
|
||||
# [3.6.0](https://github.com/ionic-team/ionic/compare/v3.5.3...v3.6.0) (2017-07-27)
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -20,4 +20,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -7,6 +7,7 @@ jobs:
|
||||
branches:
|
||||
ignore:
|
||||
- mono-refactor
|
||||
- core
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
|
||||
@@ -16,7 +16,7 @@ export class PageOne {
|
||||
|
||||
filterItems(ev: any) {
|
||||
this.setItems();
|
||||
let val = ev.value;
|
||||
let val = ev.target.value;
|
||||
|
||||
if (val && val.trim() !== '') {
|
||||
this.items = this.items.filter(function(item) {
|
||||
|
||||
4118
package-lock.json
generated
4118
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
35
package.json
35
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "ionic2",
|
||||
"version": "3.6.0",
|
||||
"version": "3.9.1",
|
||||
"description": "A powerful framework for building mobile and progressive web apps with JavaScript and Angular",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -26,20 +26,20 @@
|
||||
"tsc": "tsc --outdir .tmp"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/common": "4.1.3",
|
||||
"@angular/compiler": "4.1.3",
|
||||
"@angular/compiler-cli": "4.1.3",
|
||||
"@angular/core": "4.1.3",
|
||||
"@angular/forms": "4.1.3",
|
||||
"@angular/http": "4.1.3",
|
||||
"@angular/platform-browser": "4.1.3",
|
||||
"@angular/platform-browser-dynamic": "4.1.3",
|
||||
"@angular/common": "4.4.6",
|
||||
"@angular/compiler": "4.4.6",
|
||||
"@angular/compiler-cli": "4.4.6",
|
||||
"@angular/core": "4.4.6",
|
||||
"@angular/forms": "4.4.6",
|
||||
"@angular/http": "4.4.6",
|
||||
"@angular/platform-browser": "4.4.6",
|
||||
"@angular/platform-browser-dynamic": "4.4.6",
|
||||
"ionicons": "~3.0.0",
|
||||
"rxjs": "5.4.0",
|
||||
"zone.js": "0.8.12"
|
||||
"rxjs": "5.5.2",
|
||||
"zone.js": "0.8.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/app-scripts": "^1.3.11",
|
||||
"@ionic/app-scripts": "nightly",
|
||||
"@ionic/commit-hooks": "1.0.3",
|
||||
"@types/connect": "3.4.30",
|
||||
"@types/del": "2.2.31",
|
||||
@@ -52,7 +52,7 @@
|
||||
"@types/lodash": "4.14.35",
|
||||
"@types/merge2": "0.3.29",
|
||||
"@types/mkdirp": "0.3.29",
|
||||
"@types/node": "^6.0.34",
|
||||
"@types/node": "^6.0.88",
|
||||
"@types/protractor": "^4.0.0",
|
||||
"@types/run-sequence": "0.0.28",
|
||||
"@types/semver": "5.3.30",
|
||||
@@ -64,7 +64,7 @@
|
||||
"canonical-path": "0.0.2",
|
||||
"connect": "3.5.0",
|
||||
"conventional-changelog": "1.1.0",
|
||||
"core-js": "2.4.1",
|
||||
"core-js": "2.5.1",
|
||||
"cpr": "2.0.0",
|
||||
"cross-spawn": "^5.1.0",
|
||||
"del": "2.2.2",
|
||||
@@ -131,12 +131,11 @@
|
||||
"sw-toolbox": "3.4.0",
|
||||
"systemjs": "0.19.38",
|
||||
"through2": "2.0.1",
|
||||
"ts-node": "1.3.0",
|
||||
"ts-node": "3.3.0",
|
||||
"tslint": "^5.4.3",
|
||||
"tslint-ionic-rules": "0.0.11",
|
||||
"typescript": "~2.3.3",
|
||||
"typescript": "~2.4.2",
|
||||
"vinyl": "1.2.0",
|
||||
"webpack": "^2.1.0-beta.27",
|
||||
"yargs": "5.0.0"
|
||||
},
|
||||
"config": {
|
||||
@@ -148,4 +147,4 @@
|
||||
"pre-push#master": [
|
||||
"test"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
<ion-app></ion-app>
|
||||
|
||||
<script src="./build/polyfills.js"></script>
|
||||
<script src="./build/vendor.js"></script>
|
||||
<script src="./build/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
}
|
||||
</script>
|
||||
<script src="./build/polyfills.ng.js"></script>
|
||||
<script src="./build/vendor.js"></script>
|
||||
<script src="./build/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { task } from 'gulp';
|
||||
import { join } from 'path';
|
||||
import { DIST_BUILD_ROOT, DIST_BUILD_ES2015_ROOT, DIST_BUILD_UMD_ROOT, ES5, ES_2015, PROJECT_ROOT, UMD_MODULE } from '../constants';
|
||||
import { DIST_BUILD_ES2015_ROOT, DIST_BUILD_ROOT, DIST_BUILD_UMD_ROOT, ES5, ES_2015, PROJECT_ROOT, UMD_MODULE } from '../constants';
|
||||
import { copySourceToDest, createTempTsConfig, deleteFiles, runNgc, runTsc } from '../util';
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as s3 from 's3';
|
||||
import { argv } from 'yargs';
|
||||
|
||||
|
||||
import { DEMOS_SRC_ROOT, ES_2015, PROJECT_ROOT } from '../constants';
|
||||
import { DEMOS_SRC_ROOT, ES_2015, ES5, PROJECT_ROOT } from '../constants';
|
||||
import { createTempTsConfig, getFolderInfo, runAppScriptsBuild, writePolyfills } from '../util';
|
||||
|
||||
import * as pAll from 'p-all';
|
||||
@@ -59,9 +59,9 @@ function getDemosEntryPoints() {
|
||||
|
||||
|
||||
function buildDemos(filePaths: string[]) {
|
||||
var batches = chunkArrayInGroups(filePaths, argv.batches || 1);
|
||||
var batch = argv.batch || 0;
|
||||
if(batch >= batches.length) {
|
||||
const batches = chunkArrayInGroups(filePaths, argv.batches || 1);
|
||||
const batch = argv.batch || 0;
|
||||
if (batch >= batches.length) {
|
||||
throw new Error(`Batch number higher than total number of batches.`);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ function buildDemo(filePath: string) {
|
||||
const pathToWriteFile = join(distTestRoot, 'tsconfig.json');
|
||||
const pathToReadFile = join(PROJECT_ROOT, 'tsconfig.json');
|
||||
|
||||
createTempTsConfig(includeGlob, ES_2015, ES_2015, pathToReadFile, pathToWriteFile, { removeComments: true});
|
||||
createTempTsConfig(includeGlob, ES5, ES_2015, pathToReadFile, pathToWriteFile, { removeComments: true});
|
||||
|
||||
const sassConfigPath = join('scripts', 'demos', 'sass.config.js');
|
||||
const copyConfigPath = join('scripts', 'demos', 'copy.config.js');
|
||||
@@ -99,15 +99,23 @@ function buildDemo(filePath: string) {
|
||||
const appNgModulePath = join(dirname(filePath), 'app.module.ts');
|
||||
const distDir = join(distTestRoot, 'www');
|
||||
|
||||
const minifyCss = argv.noMinifyCss ? false : true;
|
||||
const minifyJs = argv.noMinifyJs ? false : true;
|
||||
const optimizeJs = argv.noOptimizeJs ? false : true;
|
||||
|
||||
return runAppScriptsBuild(
|
||||
appEntryPoint,
|
||||
appNgModulePath,
|
||||
ionicAngularDir,
|
||||
distDir,
|
||||
pathToWriteFile,
|
||||
ionicAngularDir,
|
||||
sassConfigPath,
|
||||
copyConfigPath
|
||||
appEntryPoint,
|
||||
appNgModulePath,
|
||||
ionicAngularDir,
|
||||
distDir,
|
||||
pathToWriteFile,
|
||||
ionicAngularDir,
|
||||
sassConfigPath,
|
||||
copyConfigPath,
|
||||
false,
|
||||
minifyCss,
|
||||
minifyJs,
|
||||
optimizeJs
|
||||
).then(() => {
|
||||
const end = Date.now();
|
||||
console.log(`${filePath} took a total of ${(end - start) / 1000} seconds to build`);
|
||||
@@ -116,8 +124,8 @@ function buildDemo(filePath: string) {
|
||||
}
|
||||
|
||||
function chunkArrayInGroups(arr, size) {
|
||||
var result = [];
|
||||
for(var i = 0; i < arr.length; i++) {
|
||||
const result = [];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (!Array.isArray(result[i % size])) {
|
||||
result[i % size] = [];
|
||||
}
|
||||
@@ -129,7 +137,7 @@ function chunkArrayInGroups(arr, size) {
|
||||
function uploadToS3(path) {
|
||||
// fail silently if envars not present
|
||||
if (!process.env.AWS_KEY || !process.env.AWS_SECRET) {
|
||||
return new Promise((resolve) => {resolve();});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
let client = s3.createClient({
|
||||
@@ -143,23 +151,23 @@ function uploadToS3(path) {
|
||||
let demo = path.split('/')[path.split('/').length - 2];
|
||||
|
||||
let params = {
|
||||
localDir: path.replace('tsconfig.json',''),
|
||||
deleteRemoved: true,
|
||||
localDir: path.replace('tsconfig.json', ''),
|
||||
deleteRemoved: true,
|
||||
s3Params: {
|
||||
Bucket: "ionic-demos",
|
||||
Bucket: 'ionic-demos',
|
||||
Prefix: demo,
|
||||
},
|
||||
};
|
||||
|
||||
var uploader = client.uploadDir(params);
|
||||
const uploader = client.uploadDir(params);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uploader.on('error', function(err) {
|
||||
console.error("s3 Upload Error:", err.stack);
|
||||
console.error('s3 Upload Error:', err.stack);
|
||||
reject();
|
||||
});
|
||||
uploader.on('end', function() {
|
||||
console.log(demo, " demo uploaded to s3");
|
||||
console.log(demo, ' demo uploaded to s3');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@@ -167,7 +175,7 @@ function uploadToS3(path) {
|
||||
|
||||
task('demos.download', (done: Function) => {
|
||||
if (!process.env.AWS_KEY || !process.env.AWS_SECRET) {
|
||||
return new Promise((resolve) => {resolve();});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
let client = s3.createClient({
|
||||
@@ -180,23 +188,23 @@ task('demos.download', (done: Function) => {
|
||||
let params = {
|
||||
localDir: join(process.cwd(), 'dist', 'demos', 'src'),
|
||||
s3Params: {
|
||||
Bucket: "ionic-demos",
|
||||
Bucket: 'ionic-demos',
|
||||
},
|
||||
};
|
||||
|
||||
let uploader = client.downloadDir(params);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uploader.on('error', function(err) {
|
||||
console.error("s3 Download Error:", err.stack);
|
||||
console.error('s3 Download Error:', err.stack);
|
||||
reject();
|
||||
});
|
||||
uploader.on('end', function() {
|
||||
console.log("Demos downloaded from s3");
|
||||
console.log('Demos downloaded from s3');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
task('demos.clean', (done: Function) => {
|
||||
// this is a super hack, but it works for now
|
||||
|
||||
@@ -22,34 +22,10 @@ task('demos.polyfill', (done: Function) => {
|
||||
});
|
||||
});
|
||||
|
||||
task('demos.copyAndCompile', (done: (err: any) => void) => {
|
||||
runSequence(
|
||||
'demos.copySource',
|
||||
'demos.compileTests',
|
||||
'demos.bundle',
|
||||
done);
|
||||
});
|
||||
|
||||
task('demos.copyExternalDependencies', () => {
|
||||
src([`${SCRIPTS_ROOT}/${DEMOS_NAME}/*.css`]).pipe(dest(`${DIST_DEMOS_ROOT}/css`));
|
||||
});
|
||||
|
||||
task('demos.sass', () => {
|
||||
// ensure there is a version.scss file
|
||||
setSassIonicVersion(`E2E-${createTimestamp()}`);
|
||||
return compileSass(`${DIST_DEMOS_ROOT}/css`);
|
||||
});
|
||||
|
||||
task('demos.fonts', () => {
|
||||
return copyFonts(`${DIST_DEMOS_ROOT}/fonts`);
|
||||
});
|
||||
|
||||
task('demos.serve', function() {
|
||||
connect.server({
|
||||
root: './',
|
||||
port: LOCAL_SERVER_PORT,
|
||||
livereload: {
|
||||
port: 35700
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -133,7 +133,11 @@ function buildTest(filePath: string) {
|
||||
const appNgModulePath = join(dirname(appEntryPoint), 'app.module.ts');
|
||||
const distDir = join(distTestRoot, 'www');
|
||||
|
||||
return runAppScriptsBuild(appEntryPoint, appNgModulePath, ionicAngularDir, distDir, pathToWriteFile, ionicAngularDir, sassConfigPath, copyConfigPath, argv.dev).then(() => {
|
||||
const minifyCss = argv.minifyCss ? true : false;
|
||||
const minifyJs = argv.minifyJs ? true : false;
|
||||
const optimizeJs = argv.optimizeJs ? true : false;
|
||||
|
||||
return runAppScriptsBuild(appEntryPoint, appNgModulePath, ionicAngularDir, distDir, pathToWriteFile, ionicAngularDir, sassConfigPath, copyConfigPath, argv.dev, minifyCss, minifyJs, optimizeJs).then(() => {
|
||||
const end = Date.now();
|
||||
console.log(`${filePath} took a total of ${(end - start) / 1000} seconds to build`);
|
||||
}).catch((err) => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { task, src, dest } from 'gulp';
|
||||
import { writePolyfills } from '../util';
|
||||
import { dest, src, task } from 'gulp';
|
||||
import { readFileAsync, writeFileAsync, writePolyfills } from '../util';
|
||||
import { join } from 'path';
|
||||
|
||||
task('polyfill', ['polyfill.copy-readme', 'polyfill.write']);
|
||||
@@ -13,6 +13,9 @@ task('polyfill.write', (done: Function) => {
|
||||
});
|
||||
|
||||
task('polyfill.copy-readme', (done: Function) => {
|
||||
return src(join('scripts', 'polyfill', 'readme.md'))
|
||||
.pipe(dest(join('dist', 'ionic-angular', 'polyfills')), done);
|
||||
return readFileAsync(join('scripts', 'polyfill', 'readme.md')).then((fileContent: string) => {
|
||||
return writeFileAsync(join('dist', 'ionic-angular', 'polyfills', 'readme.md'), fileContent);
|
||||
}).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ import * as runSequence from 'run-sequence';
|
||||
import * as semver from 'semver';
|
||||
import { obj } from 'through2';
|
||||
|
||||
import { DIST_BUILD_UMD_BUNDLE_ENTRYPOINT, DIST_BUILD_ROOT, DIST_BUNDLE_ROOT, PROJECT_ROOT, SCRIPTS_ROOT, SRC_ROOT } from '../constants';
|
||||
import { DIST_BUILD_ROOT, DIST_BUILD_UMD_BUNDLE_ENTRYPOINT, DIST_BUNDLE_ROOT, PROJECT_ROOT, SCRIPTS_ROOT, SRC_ROOT } from '../constants';
|
||||
import { compileSass, copyFonts, createTimestamp, setSassIonicVersion, writePolyfills } from '../util';
|
||||
|
||||
var promptAnswers;
|
||||
@@ -85,7 +85,7 @@ task('release.publishGithubRelease', (done: Function) => {
|
||||
return changelog({
|
||||
preset: 'angular'
|
||||
})
|
||||
.pipe(obj(function(file, enc, cb){
|
||||
.pipe(obj(function(file, enc, cb) {
|
||||
github.releases.createRelease({
|
||||
owner: 'ionic-team',
|
||||
repo: 'ionic',
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { spawn } from 'cross-spawn';
|
||||
import { NODE_MODULES_ROOT, SRC_ROOT } from './constants';
|
||||
import { src, dest } from 'gulp';
|
||||
import { dirname, join } from 'path';
|
||||
import { ensureDirSync, readdirSync, readFile, readFileSync, statSync, writeFile, writeFileSync } from 'fs-extra';
|
||||
import { dest, src } from 'gulp';
|
||||
import { dirname, join, resolve } from 'path';
|
||||
import { ensureDirSync, readFile, readFileSync, readdirSync, statSync, writeFile, writeFileSync } from 'fs-extra';
|
||||
import { rollup } from 'rollup';
|
||||
import { Replacer } from 'strip-function';
|
||||
import * as commonjs from 'rollup-plugin-commonjs';
|
||||
@@ -25,10 +25,10 @@ export function mergeObjects(obj1: any, obj2: any ) {
|
||||
obj2 = {};
|
||||
}
|
||||
var obj3 = {};
|
||||
for (var attrname in obj1) {
|
||||
for (let attrname in obj1) {
|
||||
(<any>obj3)[attrname] = obj1[attrname];
|
||||
}
|
||||
for (var attrname in obj2) {
|
||||
for (let attrname in obj2) {
|
||||
(<any>obj3)[attrname] = obj2[attrname];
|
||||
}
|
||||
return obj3;
|
||||
@@ -214,7 +214,8 @@ export function runAppScriptsServe(testOrDemoName: string, appEntryPoint: string
|
||||
'--ionicAngularDir', ionicAngularDir,
|
||||
'--sass', sassConfigPath,
|
||||
'--copy', copyConfigPath,
|
||||
'--enableLint', 'false'
|
||||
'--enableLint', 'false',
|
||||
'--skipIonicAngularVersion', 'true'
|
||||
];
|
||||
if (devApp) {
|
||||
scriptArgs.push('--bonjour');
|
||||
@@ -246,10 +247,10 @@ export function runAppScriptsServe(testOrDemoName: string, appEntryPoint: string
|
||||
});
|
||||
}
|
||||
|
||||
export function runAppScriptsBuild(appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, isDev: boolean = false) {
|
||||
export function runAppScriptsBuild(appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, isDev: boolean = false, minifyCss: boolean = true, minifyJs: boolean = true, optimizeJs: boolean = true) {
|
||||
const pathToAppScripts = join(NODE_MODULES_ROOT, '.bin', 'ionic-app-scripts');
|
||||
const debug: boolean = argv.debug;
|
||||
return runWorker(pathToAppScripts, debug, appEntryPoint, appNgModulePath, srcDir, distDir, tsConfig, ionicAngularDir, sassConfigPath, copyConfigPath, isDev);
|
||||
return runWorker(pathToAppScripts, debug, appEntryPoint, appNgModulePath, srcDir, distDir, tsConfig, ionicAngularDir, sassConfigPath, copyConfigPath, isDev, minifyCss, minifyJs, optimizeJs);
|
||||
}
|
||||
|
||||
/** Resolves the path for a node package executable. */
|
||||
@@ -325,7 +326,7 @@ export function writePolyfills(outputDirectory: string) {
|
||||
promises.push(bundlePolyfill(NG_ENTRIES, join(outputDirectory, 'polyfills.ng.js')));
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
}
|
||||
|
||||
function bundlePolyfill(pathsToIncludeInPolyfill: string[], outputPath: string) {
|
||||
return rollup({
|
||||
@@ -349,6 +350,8 @@ function bundlePolyfill(pathsToIncludeInPolyfill: string[], outputPath: string)
|
||||
moduleName: 'MyBundle',
|
||||
dest: outputPath
|
||||
});
|
||||
}).catch(err => {
|
||||
console.log('caught rollup error: ', err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { dirname, join } from 'path';
|
||||
|
||||
import { MessageToWorker, WorkerProcess } from './interfaces';
|
||||
|
||||
export function runWorker(pathToAppScripts: string, debug: boolean, appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, isDev: boolean) {
|
||||
export function runWorker(pathToAppScripts: string, debug: boolean, appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, isDev: boolean, minifyCss: boolean, minifyJs: boolean, optimizeJs: boolean) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const msgToWorker: MessageToWorker = {
|
||||
@@ -17,7 +17,10 @@ export function runWorker(pathToAppScripts: string, debug: boolean, appEntryPoin
|
||||
ionicAngularDir: ionicAngularDir,
|
||||
sassConfigPath: sassConfigPath,
|
||||
copyConfigPath: copyConfigPath,
|
||||
isDev: isDev
|
||||
isDev: isDev,
|
||||
minifyCss: minifyCss,
|
||||
minifyJs: minifyJs,
|
||||
optimizeJs: optimizeJs
|
||||
};
|
||||
|
||||
const worker = <ChildProcess>createWorker(msgToWorker);
|
||||
@@ -73,6 +76,7 @@ export function createWorker(msg: MessageToWorker): any {
|
||||
'--sass', msg.sassConfigPath,
|
||||
'--copy', msg.copyConfigPath,
|
||||
'--enableLint', 'false',
|
||||
'--skipIonicAngularVersion', 'true'
|
||||
];
|
||||
|
||||
// TODO, use prod once we're a little more settled
|
||||
@@ -84,6 +88,18 @@ export function createWorker(msg: MessageToWorker): any {
|
||||
scriptArgs.push('--debug');
|
||||
}
|
||||
|
||||
if (msg.minifyJs) {
|
||||
scriptArgs.push('--minifyJs');
|
||||
}
|
||||
|
||||
if (msg.minifyCss) {
|
||||
scriptArgs.push('--minifyCss');
|
||||
}
|
||||
|
||||
if (msg.optimizeJs) {
|
||||
scriptArgs.push('--optimizeJs');
|
||||
}
|
||||
|
||||
const workerModule = join(process.cwd(), 'node_modules', '@ionic', 'app-scripts', 'bin', 'ionic-app-scripts.js');
|
||||
const worker = fork(workerModule, scriptArgs, {
|
||||
env: {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
export interface WorkerProcess {
|
||||
appEntryPoint: string;
|
||||
worker: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface MessageToWorker {
|
||||
pathToAppScripts: string;
|
||||
@@ -16,4 +16,8 @@ export interface MessageToWorker {
|
||||
sassConfigPath: string;
|
||||
copyConfigPath: string;
|
||||
isDev: boolean;
|
||||
};
|
||||
minifyJs: boolean;
|
||||
minifyCss: boolean;
|
||||
optimizeJs: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,15 +12,5 @@
|
||||
"module": "index.js",
|
||||
"es2015": "es2015/index.js",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "",
|
||||
"@angular/compiler": "",
|
||||
"@angular/compiler-cli": "",
|
||||
"@angular/core": "",
|
||||
"@angular/forms": "",
|
||||
"@angular/http": "",
|
||||
"@angular/platform-browser": "",
|
||||
"@angular/platform-browser-dynamic": "",
|
||||
"rxjs": "",
|
||||
"zone.js": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
/*
|
||||
Generated class for the $CLASSNAME provider.
|
||||
@@ -11,7 +10,7 @@ import 'rxjs/add/operator/map';
|
||||
@Injectable()
|
||||
export class $CLASSNAME {
|
||||
|
||||
constructor(public http: Http) {
|
||||
constructor(public http: HttpClient) {
|
||||
console.log('Hello $CLASSNAME Provider');
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import { ViewController } from '../../navigation/view-controller';
|
||||
'{{b.text}}' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'<div class="action-sheet-group" *ngIf="cancelButton">' +
|
||||
'<div class="action-sheet-group action-sheet-group-cancel" *ngIf="cancelButton">' +
|
||||
'<button ion-button="action-sheet-button" (click)="click(cancelButton)" class="action-sheet-cancel disable-hover" [attr.icon-start]="cancelButton.icon ? \'\' : null" [ngClass]="cancelButton.cssClass">' +
|
||||
'<ion-icon [name]="cancelButton.icon" *ngIf="cancelButton.icon" class="action-sheet-icon"></ion-icon>' +
|
||||
'{{cancelButton.text}}' +
|
||||
|
||||
@@ -39,10 +39,10 @@ import { Config } from '../../config/config';
|
||||
*
|
||||
* export class MyClass{
|
||||
*
|
||||
* constructor(public actionSheetCtrl: ActionSheetController) {}
|
||||
* constructor(public actionSheetCtrl: ActionSheetController) { }
|
||||
*
|
||||
* presentActionSheet() {
|
||||
* let actionSheet = this.actionSheetCtrl.create({
|
||||
* const actionSheet = this.actionSheetCtrl.create({
|
||||
* title: 'Modify your album',
|
||||
* buttons: [
|
||||
* {
|
||||
@@ -115,7 +115,7 @@ import { Config } from '../../config/config';
|
||||
* out first, *then* start the next transition.
|
||||
*
|
||||
* ```ts
|
||||
* let actionSheet = this.actionSheetCtrl.create({
|
||||
* const actionSheet = this.actionSheetCtrl.create({
|
||||
* title: 'Hello',
|
||||
* buttons: [{
|
||||
* text: 'Ok',
|
||||
|
||||
@@ -21,6 +21,9 @@ $action-sheet-ios-padding-bottom: $action-sheet-ios-paddin
|
||||
/// @prop - Padding start of the action sheet
|
||||
$action-sheet-ios-padding-start: $action-sheet-ios-padding-end !default;
|
||||
|
||||
/// @prop - Top margin of the action sheet button group
|
||||
$action-sheet-ios-group-margin-top: 10px !default;
|
||||
|
||||
/// @prop - Bottom margin of the action sheet button group
|
||||
$action-sheet-ios-group-margin-bottom: 10px !default;
|
||||
|
||||
@@ -89,6 +92,11 @@ $action-sheet-ios-button-cancel-font-weight: 600 !default;
|
||||
@include text-align($action-sheet-ios-text-align);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-wrapper {
|
||||
@include margin(constant(safe-area-inset-top), auto, constant(safe-area-inset-bottom), auto);
|
||||
@include margin(env(safe-area-inset-top), auto, env(safe-area-inset-bottom), auto);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-container {
|
||||
@include deprecated-variable(padding, $action-sheet-ios-padding) {
|
||||
@include padding($action-sheet-ios-padding-top, $action-sheet-ios-padding-end, $action-sheet-ios-padding-bottom, $action-sheet-ios-padding-start);
|
||||
@@ -99,9 +107,19 @@ $action-sheet-ios-button-cancel-font-weight: 600 !default;
|
||||
@include border-radius($action-sheet-ios-border-radius);
|
||||
@include margin(null, null, $action-sheet-ios-group-margin-bottom - 2, null);
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
background: $action-sheet-ios-background;
|
||||
|
||||
// scss-lint:disable VendorPrefix
|
||||
// TODO Removing this temporarily because it causes a flicker
|
||||
// when there are not enough elements to overflow
|
||||
// https://github.com/ionic-team/ionic/issues/13262
|
||||
// -webkit-overflow-scrolling: touch;
|
||||
// Prevents borders from going outside of the container
|
||||
// -webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-group:first-child {
|
||||
@include margin($action-sheet-ios-group-margin-top, null, null, null);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-group:last-child {
|
||||
|
||||
@@ -9,8 +9,11 @@ $action-sheet-md-text-align: start !default;
|
||||
/// @prop - Background color of the action sheet
|
||||
$action-sheet-md-background: #fafafa !default;
|
||||
|
||||
/// @prop - Bottom margin of the action sheet button group
|
||||
$action-sheet-md-group-margin-bottom: 8px !default;
|
||||
/// @prop - Padding top of the action sheet
|
||||
$action-sheet-md-padding-top: .8rem !default;
|
||||
|
||||
/// @prop - Padding bottom of the action sheet
|
||||
$action-sheet-md-padding-bottom: .8rem !default;
|
||||
|
||||
/// @prop - Color of the action sheet title
|
||||
$action-sheet-md-title-color: #757575 !default;
|
||||
@@ -90,11 +93,6 @@ $action-sheet-md-icon-margin-bottom: 0 !default;
|
||||
/// @prop - Margin start of the icon in the action sheet button
|
||||
$action-sheet-md-icon-margin-start: 0 !default;
|
||||
|
||||
.action-sheet-md .action-sheet-container {
|
||||
@include padding(.8rem, 0);
|
||||
|
||||
background: $action-sheet-md-background;
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-title {
|
||||
@include text-align($action-sheet-md-text-align);
|
||||
@@ -144,7 +142,15 @@ $action-sheet-md-icon-margin-start: 0 !default;
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-group {
|
||||
overflow: hidden;
|
||||
background: $action-sheet-md-background;
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-group:first-child {
|
||||
@include padding($action-sheet-md-padding-top, null, null, null);
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-group:last-child {
|
||||
@include padding(null, null, $action-sheet-md-padding-bottom, null);
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-group .button-inner {
|
||||
|
||||
@@ -22,7 +22,7 @@ ion-action-sheet {
|
||||
}
|
||||
|
||||
.action-sheet-wrapper {
|
||||
@include position(null, 0, 0, 0);
|
||||
@include position(0, 0, 0, 0);
|
||||
@include margin(auto);
|
||||
@include transform(translate3d(0, 100%, 0));
|
||||
|
||||
@@ -32,8 +32,35 @@ ion-action-sheet {
|
||||
|
||||
width: $action-sheet-width;
|
||||
max-width: $action-sheet-max-width;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.action-sheet-button {
|
||||
width: $action-sheet-width;
|
||||
}
|
||||
|
||||
.action-sheet-container {
|
||||
display: flex;
|
||||
|
||||
flex-flow: column;
|
||||
|
||||
justify-content: flex-end;
|
||||
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.action-sheet-group {
|
||||
overflow: scroll;
|
||||
|
||||
flex-shrink: 2;
|
||||
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.action-sheet-group-cancel {
|
||||
overflow: hidden;
|
||||
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,12 @@ $action-sheet-wp-text-align: start !default;
|
||||
/// @prop - Background color of the action sheet
|
||||
$action-sheet-wp-background: #fff !default;
|
||||
|
||||
/// @prop - Padding top of the action sheet
|
||||
$action-sheet-wp-padding-top: .8rem !default;
|
||||
|
||||
/// @prop - Padding bottom of the action sheet
|
||||
$action-sheet-wp-padding-bottom: .8rem !default;
|
||||
|
||||
/// @prop - Box shadow color of the action sheet
|
||||
$action-sheet-wp-box-shadow-color: rgba(0, 0, 0, .2) !default;
|
||||
|
||||
@@ -100,10 +106,6 @@ $action-sheet-wp-icon-margin-bottom: 0 !default;
|
||||
$action-sheet-wp-icon-margin-start: 0 !default;
|
||||
|
||||
|
||||
.action-sheet-wp .action-sheet-wrapper {
|
||||
box-shadow: $action-sheet-wp-box-shadow;
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-title {
|
||||
@include text-align($action-sheet-wp-title-text-align);
|
||||
|
||||
@@ -147,12 +149,20 @@ $action-sheet-wp-icon-margin-start: 0 !default;
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-container {
|
||||
@include padding(.8rem, 0);
|
||||
|
||||
.action-sheet-wp .action-sheet-group {
|
||||
background: $action-sheet-wp-background;
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-group:first-child {
|
||||
@include padding($action-sheet-wp-padding-top, null, null, null);
|
||||
|
||||
box-shadow: $action-sheet-wp-box-shadow;
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-group:last-child {
|
||||
@include padding(null, null, $action-sheet-wp-padding-bottom, null);
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-group .button-inner {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,12 @@
|
||||
|
||||
<ion-content padding>
|
||||
|
||||
<button ion-button block class="e2eOpenActionSheet" (click)="presentActionSheet1()">Present Action Sheet 1</button>
|
||||
<button ion-button block (click)="presentActionSheet2()">Present Action Sheet 2</button>
|
||||
<button ion-button block (click)="presentActionSheet3()">Present Action Sheet 3</button>
|
||||
<button ion-button block class="e2eOpenActionSheet" (click)="presentBasic()">Basic</button>
|
||||
<button ion-button block (click)="presentNoBackdropDismiss()">No Backdrop Dismiss</button>
|
||||
<button ion-button block (click)="presentAlert()">Alert from Action Sheet</button>
|
||||
<button ion-button block (click)="presentScroll()">Scrollable Options</button>
|
||||
<button ion-button block (click)="presentScrollNoCancel()">Scroll Without Cancel</button>
|
||||
<button ion-button block (click)="presentCancelOnly()">Cancel Only</button>
|
||||
|
||||
<pre>
|
||||
Result: {{result}}
|
||||
|
||||
@@ -12,7 +12,7 @@ export class PageOne {
|
||||
|
||||
constructor(public actionSheetCtrl: ActionSheetController, public alertCtrl: AlertController, public modalCtrl: ModalController, public plt: Platform) {}
|
||||
|
||||
presentActionSheet1() {
|
||||
presentBasic() {
|
||||
this.result = '';
|
||||
|
||||
this.actionSheetCtrl.create()
|
||||
@@ -66,7 +66,7 @@ export class PageOne {
|
||||
.present();
|
||||
}
|
||||
|
||||
presentActionSheet2() {
|
||||
presentNoBackdropDismiss() {
|
||||
this.result = '';
|
||||
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
@@ -102,7 +102,7 @@ export class PageOne {
|
||||
actionSheet.present(actionSheet);
|
||||
}
|
||||
|
||||
presentActionSheet3() {
|
||||
presentAlert() {
|
||||
this.result = '';
|
||||
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
@@ -150,4 +150,168 @@ export class PageOne {
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
presentScroll() {
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Add Reaction',
|
||||
handler: () => {
|
||||
console.log('Add Reaction clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Text',
|
||||
handler: () => {
|
||||
console.log('Copy Text clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Share Text',
|
||||
handler: () => {
|
||||
console.log('Share Text clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Link to Message',
|
||||
handler: () => {
|
||||
console.log('Copy Link to Message clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Remind Me',
|
||||
handler: () => {
|
||||
console.log('Remind Me clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Pin File',
|
||||
handler: () => {
|
||||
console.log('Pin File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Star File',
|
||||
handler: () => {
|
||||
console.log('Star File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Mark Unread',
|
||||
handler: () => {
|
||||
console.log('Mark Unread clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Edit Title',
|
||||
handler: () => {
|
||||
console.log('Edit Title clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Save Image',
|
||||
handler: () => {
|
||||
console.log('Save Image clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Image',
|
||||
handler: () => {
|
||||
console.log('Copy Image clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Delete File',
|
||||
role: 'destructive',
|
||||
handler: () => {
|
||||
console.log('Delete File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Cancel',
|
||||
role: 'cancel', // will always sort to be on the bottom
|
||||
handler: () => {
|
||||
console.log('Cancel clicked');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
presentScrollNoCancel() {
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Add Reaction',
|
||||
handler: () => {
|
||||
console.log('Add Reaction clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Text',
|
||||
handler: () => {
|
||||
console.log('Copy Text clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Share Text',
|
||||
handler: () => {
|
||||
console.log('Share Text clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Link to Message',
|
||||
handler: () => {
|
||||
console.log('Copy Link to Message clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Remind Me',
|
||||
handler: () => {
|
||||
console.log('Remind Me clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Pin File',
|
||||
handler: () => {
|
||||
console.log('Pin File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Star File',
|
||||
handler: () => {
|
||||
console.log('Star File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Mark Unread',
|
||||
handler: () => {
|
||||
console.log('Mark Unread clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Edit Title',
|
||||
handler: () => {
|
||||
console.log('Edit Title clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Save Image',
|
||||
handler: () => {
|
||||
console.log('Save Image clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Image',
|
||||
handler: () => {
|
||||
console.log('Copy Image clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Delete File',
|
||||
role: 'destructive',
|
||||
handler: () => {
|
||||
console.log('Delete File clicked');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
presentCancelOnly() {
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel', // will always sort to be on the bottom
|
||||
handler: () => {
|
||||
console.log('Cancel clicked');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ import { AlertButton, AlertInputOptions, AlertOptions } from './alert-options';
|
||||
'<ng-template ngSwitchDefault>' +
|
||||
'<div class="alert-input-group">' +
|
||||
'<div *ngFor="let i of d.inputs" class="alert-input-wrapper">' +
|
||||
'<input [placeholder]="i.placeholder" [(ngModel)]="i.value" [type]="i.type" [min]="i.min" [max]="i.max" [attr.id]="i.id" class="alert-input">' +
|
||||
'<input [placeholder]="i.placeholder" [(ngModel)]="i.value" [type]="i.type" dir="auto" [min]="i.min" [max]="i.max" [attr.id]="i.id" class="alert-input">' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</ng-template>' +
|
||||
@@ -204,7 +204,7 @@ export class AlertCmp {
|
||||
// and ionViewDidEnter is not in the same callstack as the touch event :(
|
||||
const focusableEle = this._elementRef.nativeElement.querySelector('input,button');
|
||||
if (focusableEle) {
|
||||
focusableEle.focus();
|
||||
setTimeout(() => focusableEle.focus());
|
||||
}
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
@@ -51,12 +51,10 @@ import { Config } from '../../config/config';
|
||||
* ```ts
|
||||
* import { AlertController } from 'ionic-angular';
|
||||
*
|
||||
* constructor(private alertCtrl: AlertController) {
|
||||
*
|
||||
* }
|
||||
* constructor(public alertCtrl: AlertController) { }
|
||||
*
|
||||
* presentAlert() {
|
||||
* let alert = this.alertCtrl.create({
|
||||
* const alert = this.alertCtrl.create({
|
||||
* title: 'Low battery',
|
||||
* subTitle: '10% of battery remaining',
|
||||
* buttons: ['Dismiss']
|
||||
@@ -65,7 +63,7 @@ import { Config } from '../../config/config';
|
||||
* }
|
||||
*
|
||||
* presentConfirm() {
|
||||
* let alert = this.alertCtrl.create({
|
||||
* const alert = this.alertCtrl.create({
|
||||
* title: 'Confirm purchase',
|
||||
* message: 'Do you want to buy this book?',
|
||||
* buttons: [
|
||||
@@ -88,7 +86,7 @@ import { Config } from '../../config/config';
|
||||
* }
|
||||
*
|
||||
* presentPrompt() {
|
||||
* let alert = this.alertCtrl.create({
|
||||
* const alert = this.alertCtrl.create({
|
||||
* title: 'Login',
|
||||
* inputs: [
|
||||
* {
|
||||
@@ -181,14 +179,14 @@ import { Config } from '../../config/config';
|
||||
* out first, *then* start the next transition.
|
||||
*
|
||||
* ```ts
|
||||
* let alert = this.alertCtrl.create({
|
||||
* const alert = this.alertCtrl.create({
|
||||
* title: 'Hello',
|
||||
* buttons: [{
|
||||
* text: 'Ok',
|
||||
* handler: () => {
|
||||
* // user has clicked the alert button
|
||||
* // begin the alert's dismiss transition
|
||||
* let navTransition = alert.dismiss();
|
||||
* const navTransition = alert.dismiss();
|
||||
*
|
||||
* // start some async method
|
||||
* someAsyncOperation().then(() => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, ComponentFactoryResolver, ElementRef, Inject, OnInit, OpaqueToken, Renderer, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
import { Component, ComponentFactoryResolver, ElementRef, Inject, InjectionToken, OnInit, Renderer, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
|
||||
import { App } from './app';
|
||||
import { assert } from '../../util/util';
|
||||
@@ -8,7 +8,7 @@ import { OverlayPortal } from './overlay-portal';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import * as Constants from './app-constants';
|
||||
|
||||
export const AppRootToken = new OpaqueToken('USERROOT');
|
||||
export const AppRootToken = new InjectionToken<any>('USERROOT');
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
|
||||
@@ -274,6 +274,13 @@ export class App {
|
||||
this._rootNavs.set(nav.id, nav);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
unregisterRootNav(nav: NavigationContainer) {
|
||||
this._rootNavs.delete(nav.id);
|
||||
}
|
||||
|
||||
|
||||
getActiveNavContainers(): NavigationContainer[] {
|
||||
// for each root nav container, get it's active nav
|
||||
|
||||
@@ -10,7 +10,7 @@ describe('App', () => {
|
||||
|
||||
describe('goBack', () => {
|
||||
|
||||
it('should not select the previous tab', () => {
|
||||
it('should not select the previous tab', (done: Function) => {
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
@@ -23,24 +23,26 @@ describe('App', () => {
|
||||
|
||||
nav.registerChildNav(tabs);
|
||||
|
||||
tabs.select(tab1);
|
||||
tabs.select(tab2);
|
||||
|
||||
expect(tabs._selectHistory).toEqual([tab1.id, tab2.id]);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(tabs, 'select');
|
||||
spyOn(tab1, 'pop');
|
||||
spyOn(tab2, 'pop');
|
||||
spyOn(portal, 'pop');
|
||||
|
||||
app.goBack();
|
||||
|
||||
expect(tabs.select).not.toHaveBeenCalled();
|
||||
expect(tab1.pop).not.toHaveBeenCalled();
|
||||
expect(tab2.pop).not.toHaveBeenCalled();
|
||||
expect(portal.pop).not.toHaveBeenCalled();
|
||||
expect(plt.exitApp).toHaveBeenCalled();
|
||||
tabs.select(tab1).then(() => {
|
||||
return tabs.select(tab2);
|
||||
}).then(() => {
|
||||
expect(tabs._selectHistory).toEqual([tab1.id, tab2.id]);
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(tabs, 'select');
|
||||
spyOn(tab1, 'pop');
|
||||
spyOn(tab2, 'pop');
|
||||
spyOn(portal, 'pop');
|
||||
return app.goBack();
|
||||
}).then(() => {
|
||||
expect(tabs.select).not.toHaveBeenCalled();
|
||||
expect(tab1.pop).not.toHaveBeenCalled();
|
||||
expect(tab2.pop).not.toHaveBeenCalled();
|
||||
expect(portal.pop).not.toHaveBeenCalled();
|
||||
expect(plt.exitApp).toHaveBeenCalled();
|
||||
done();
|
||||
}).catch((err: Error) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should pop from the active tab, when tabs is nested is the root nav', () => {
|
||||
|
||||
@@ -126,6 +126,7 @@ export class Checkbox extends BaseInput<boolean> implements IonicTapInput, OnDes
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.value = !this.value;
|
||||
this._fireTouched();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,5 +142,4 @@ export class Checkbox extends BaseInput<boolean> implements IonicTapInput, OnDes
|
||||
_inputUpdated() {
|
||||
this._item && this._item.setElementClass('item-checkbox-checked', this._value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -91,40 +91,62 @@ ion-app [no-padding] .scroll-content {
|
||||
}
|
||||
|
||||
@mixin content-padding($mode, $content-padding) {
|
||||
ion-app.#{$mode} [padding],
|
||||
ion-app.#{$mode} [padding] .scroll-content {
|
||||
ion-app.#{$mode} [padding] {
|
||||
@include padding($content-padding);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-top],
|
||||
ion-app.#{$mode} [padding-top] .scroll-content {
|
||||
ion-app.#{$mode} [padding-top] {
|
||||
@include padding($content-padding, null, null, null);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-left],
|
||||
ion-app.#{$mode} [padding-left] .scroll-content {
|
||||
ion-app.#{$mode} [padding-left] {
|
||||
@include padding-horizontal($content-padding, null);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-right],
|
||||
ion-app.#{$mode} [padding-right] .scroll-content {
|
||||
ion-app.#{$mode} [padding-right] {
|
||||
@include padding-horizontal(null, $content-padding);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-bottom],
|
||||
ion-app.#{$mode} [padding-bottom] .scroll-content {
|
||||
ion-app.#{$mode} [padding-bottom] {
|
||||
@include padding(null, null, $content-padding, null);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-vertical],
|
||||
ion-app.#{$mode} [padding-vertical] .scroll-content {
|
||||
ion-app.#{$mode} [padding-vertical] {
|
||||
@include padding($content-padding, null, $content-padding, null);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-horizontal],
|
||||
ion-app.#{$mode} [padding-horizontal] .scroll-content {
|
||||
ion-app.#{$mode} [padding-horizontal] {
|
||||
@include padding-horizontal($content-padding);
|
||||
}
|
||||
|
||||
// Scroll content should use safe-area-padding
|
||||
ion-app.#{$mode} [padding] .scroll-content {
|
||||
@include safe-area-padding($content-padding);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-top] .scroll-content {
|
||||
@include safe-area-padding($content-padding, null, null, null);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-left] .scroll-content {
|
||||
@include safe-area-padding-horizontal($content-padding, null);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-right] .scroll-content {
|
||||
@include safe-area-padding-horizontal(null, $content-padding);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-bottom] .scroll-content {
|
||||
@include safe-area-padding(null, null, $content-padding, null);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-vertical] .scroll-content {
|
||||
@include safe-area-padding($content-padding, null, $content-padding, null);
|
||||
}
|
||||
|
||||
ion-app.#{$mode} [padding-horizontal] .scroll-content {
|
||||
@include safe-area-padding-horizontal($content-padding);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -227,6 +227,8 @@ export class Content extends Ion implements OnDestroy, AfterViewInit, IContent {
|
||||
/** @internal */
|
||||
_scrollDownOnLoad: boolean = false;
|
||||
|
||||
_viewCtrl: any;
|
||||
|
||||
private _imgReqBfr: number;
|
||||
private _imgRndBfr: number;
|
||||
private _imgVelMax: number;
|
||||
@@ -410,6 +412,8 @@ export class Content extends Ion implements OnDestroy, AfterViewInit, IContent {
|
||||
}
|
||||
|
||||
if (viewCtrl) {
|
||||
this._viewCtrl = viewCtrl;
|
||||
|
||||
// content has a view controller
|
||||
viewCtrl._setIONContent(this);
|
||||
viewCtrl._setIONContentRef(elementRef);
|
||||
@@ -635,6 +639,10 @@ export class Content extends Ion implements OnDestroy, AfterViewInit, IContent {
|
||||
*/
|
||||
addScrollPadding(newPadding: number) {
|
||||
assert(typeof this._scrollPadding === 'number', '_scrollPadding must be a number');
|
||||
if (newPadding === 0) {
|
||||
this._inputPolling = false;
|
||||
this._scrollPadding = -1;
|
||||
}
|
||||
if (newPadding > this._scrollPadding) {
|
||||
console.debug(`content, addScrollPadding, newPadding: ${newPadding}, this._scrollPadding: ${this._scrollPadding}`);
|
||||
|
||||
@@ -659,13 +667,13 @@ export class Content extends Ion implements OnDestroy, AfterViewInit, IContent {
|
||||
|
||||
this._keyboard.onClose(() => {
|
||||
console.debug(`content, clearScrollPaddingFocusOut _keyboard.onClose`);
|
||||
this._inputPolling = false;
|
||||
this._scrollPadding = -1;
|
||||
this.addScrollPadding(0);
|
||||
}, 200, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tell the content to recalculate its dimensions. This should be called
|
||||
* after dynamically adding/removing headers, footers, or tabs.
|
||||
|
||||
@@ -8,10 +8,11 @@ import { PickerColumn } from '../picker/picker-options';
|
||||
import { Form } from '../../util/form';
|
||||
import { BaseInput } from '../../util/base-input';
|
||||
import { Item } from '../item/item';
|
||||
import { assert, clamp, deepCopy, isArray, isBlank, isObject, isPresent, isString } from '../../util/util';
|
||||
import { assert, clamp, isArray, isBlank, isObject, isPresent, isString } from '../../util/util';
|
||||
import {
|
||||
DateTimeData,
|
||||
LocaleData,
|
||||
compareDates,
|
||||
convertDataToISO,
|
||||
convertFormatToKey,
|
||||
dateDataSortValue,
|
||||
@@ -321,6 +322,14 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
|
||||
*/
|
||||
@Input() displayFormat: string;
|
||||
|
||||
/**
|
||||
* @input {string} The default datetime selected in picker modal if field value is empty.
|
||||
* Value must be a date string following the
|
||||
* [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime),
|
||||
* `1996-12-19`.
|
||||
*/
|
||||
@Input() initialValue: string;
|
||||
|
||||
/**
|
||||
* @input {string} The format of the date and time picker columns the user selects.
|
||||
* A datetime input can have one or many datetime parts, each getting their
|
||||
@@ -510,22 +519,26 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
|
||||
if (this.isFocus() || this._disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.debug('datetime, open picker');
|
||||
|
||||
// the user may have assigned some options specifically for the alert
|
||||
const pickerOptions = deepCopy(this.pickerOptions);
|
||||
// the user may have assigned some options specifically for the picker
|
||||
const pickerOptions = {...this.pickerOptions};
|
||||
|
||||
// Configure picker under the hood
|
||||
const picker = this._picker = this._pickerCtrl.create(pickerOptions);
|
||||
picker.addButton({
|
||||
// Add a cancel and done button by default to the picker
|
||||
const defaultButtons = [{
|
||||
text: this.cancelText,
|
||||
role: 'cancel',
|
||||
handler: () => this.ionCancel.emit(this)
|
||||
});
|
||||
picker.addButton({
|
||||
}, {
|
||||
text: this.doneText,
|
||||
handler: (data: any) => this.value = data,
|
||||
});
|
||||
}];
|
||||
|
||||
pickerOptions.buttons = (pickerOptions.buttons || []).concat(defaultButtons);
|
||||
|
||||
// Configure picker under the hood
|
||||
const picker = this._picker = this._pickerCtrl.create(pickerOptions);
|
||||
|
||||
picker.ionChange.subscribe(() => {
|
||||
this.validate();
|
||||
@@ -598,7 +611,7 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
|
||||
|
||||
// cool, we've loaded up the columns with options
|
||||
// preselect the option for this column
|
||||
const optValue = getValueFromFormat(this.getValue(), format);
|
||||
const optValue = getValueFromFormat(this.getValueOrDefault(), format);
|
||||
const selectedIndex = column.options.findIndex(opt => opt.value === optValue);
|
||||
if (selectedIndex >= 0) {
|
||||
// set the select index for this column's options
|
||||
@@ -774,6 +787,51 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
|
||||
return this._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
getValueOrDefault(): DateTimeData {
|
||||
if (this.hasValue()) {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
const initialDateString = this.getDefaultValueDateString();
|
||||
const _default = {};
|
||||
updateDate(_default, initialDateString);
|
||||
return _default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value as a date string
|
||||
* @hidden
|
||||
*/
|
||||
getDefaultValueDateString() {
|
||||
if (this.initialValue) {
|
||||
return this.initialValue;
|
||||
}
|
||||
|
||||
const nowString = (new Date).toISOString();
|
||||
if (this.max) {
|
||||
const now = parseDate(nowString);
|
||||
const max = parseDate(this.max);
|
||||
|
||||
let v;
|
||||
for (let i in max) {
|
||||
v = (<any>max)[i];
|
||||
if (v === null) {
|
||||
(<any>max)[i] = (<any>now)[i];
|
||||
}
|
||||
}
|
||||
|
||||
const diff = compareDates(now, max);
|
||||
// If max is before current time, return max
|
||||
if (diff > 0) {
|
||||
return this.max;
|
||||
}
|
||||
}
|
||||
return nowString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@@ -837,7 +895,6 @@ export class DateTime extends BaseInput<DateTimeData> implements AfterContentIni
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
|
||||
<ion-item>
|
||||
<ion-label>MM DD YY</ion-label>
|
||||
<ion-datetime displayFormat="MM DD YY" [(ngModel)]="placeholderDate" placeholder="Select Date"></ion-datetime>
|
||||
<ion-datetime pickerFormat="YYYY-MM-DDThh:mm" [pickerOptions]="customOptions" [(ngModel)]="placeholderDate" placeholder="Select Date"></ion-datetime>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>MM DD YY</ion-label>
|
||||
<ion-datetime displayFormat="MM DD YY" [(ngModel)]="placeholderDate" placeholder="Select Date" initialValue="1987-10-19"></ion-datetime>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
@@ -77,6 +82,11 @@
|
||||
<ion-datetime monthValues="6,7,8" yearValues="2014,2015" dayValues="01,02,03,04,05,06,08,09,10, 11, 12, 13, 14" displayFormat="DD/MMM/YYYY" [(ngModel)]="specificDaysMonthsYears"></ion-datetime>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Default value</ion-label>
|
||||
<ion-datetime max="2100" pickerDefault="2017-08-06" [(ngModel)]="defaultValue"></ion-datetime>
|
||||
</ion-item>
|
||||
|
||||
<p aria-hidden="true" padding>
|
||||
<code>monthOnly: {{monthOnly}}</code><br>
|
||||
<code>wwwInvented: {{wwwInvented}}</code><br>
|
||||
@@ -88,6 +98,7 @@
|
||||
<code>time: {{time}}</code><br>
|
||||
<code>Leap year, summer months: {{leapYearsSummerMonths}}</code><br>
|
||||
<code>Specific days/months/years: {{specificDaysMonthsYears}}</code><br>
|
||||
<code>Default value: {{defaultValue}}</code><br>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -17,6 +17,7 @@ export class RootPage {
|
||||
leapYearsSummerMonths = '';
|
||||
convertedDate = '';
|
||||
specificDaysMonthsYears = '';
|
||||
defaultValue: any;
|
||||
|
||||
leapYearsArray = [2020, 2016, 2008, 2004, 2000, 1996];
|
||||
|
||||
@@ -30,6 +31,16 @@ export class RootPage {
|
||||
'l\u00f8r'
|
||||
];
|
||||
|
||||
customOptions: any = {
|
||||
buttons: [{
|
||||
text: 'Save',
|
||||
handler: () => console.log('Clicked Save!')
|
||||
}, {
|
||||
text: 'Log',
|
||||
handler: () => console.log('Clicked Log!')
|
||||
}]
|
||||
};
|
||||
|
||||
onChange(ev: any) {
|
||||
console.log('Changed', ev);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { DateTime } from '../datetime';
|
||||
import { Form } from '../../../util/form';
|
||||
import { Picker } from '../../picker/picker';
|
||||
import { PickerController } from '../../picker/picker-controller';
|
||||
import * as datetime from '../../../util/datetime-util';
|
||||
import * as datetimeUtil from '../../../util/datetime-util';
|
||||
import { mockApp, mockConfig, mockElementRef, mockRenderer } from '../../../util/mock-providers';
|
||||
|
||||
|
||||
@@ -491,6 +491,53 @@ describe('DateTime', () => {
|
||||
|
||||
});
|
||||
|
||||
describe('defaultValue', () => {
|
||||
it('should default to now if no initial value or bounds supplied', () => {
|
||||
const now = datetimeUtil.parseDate(new Date().toISOString());
|
||||
datetime.pickerFormat = 'YYYY-MM-DDThh:mm';
|
||||
datetime.generate();
|
||||
var columns = picker.getColumns();
|
||||
expect(columns[0].options[columns[0].selectedIndex].value).toEqual(now.year);
|
||||
expect(columns[1].options[columns[1].selectedIndex].value).toEqual(now.month);
|
||||
expect(columns[2].options[columns[2].selectedIndex].value).toEqual(now.day);
|
||||
expect(columns[3].options[columns[3].selectedIndex].value).toEqual(now.hour % 12);
|
||||
expect(columns[4].options[columns[4].selectedIndex].value).toEqual(now.minute);
|
||||
});
|
||||
|
||||
it('should default to max if no initial value supplied but max specified and max before current', () => {
|
||||
datetime.max = '1987-10-19';
|
||||
datetime.generate();
|
||||
var columns = picker.getColumns();
|
||||
expect(columns[0].options[columns[0].selectedIndex].value).toEqual(10);
|
||||
expect(columns[1].options[columns[1].selectedIndex].value).toEqual(19);
|
||||
expect(columns[2].options[columns[2].selectedIndex].value).toEqual(1987);
|
||||
});
|
||||
|
||||
it('should default to current if no initial value supplied but max specified and max after current', () => {
|
||||
const now = datetimeUtil.parseDate(new Date().toISOString());
|
||||
datetime.max = '2100-10-19';
|
||||
datetime.generate();
|
||||
var columns = picker.getColumns();
|
||||
expect(columns[0].options[columns[0].selectedIndex].value).toEqual(now.month);
|
||||
expect(columns[1].options[columns[1].selectedIndex].value).toEqual(now.day);
|
||||
expect(columns[2].options[columns[2].selectedIndex].value).toEqual(now.year);
|
||||
});
|
||||
|
||||
it('should use pickerDefault if has no value', zoned(() => {
|
||||
datetime.max = '2100-12-31';
|
||||
datetime.pickerFormat = 'DD MMMM YYYY';
|
||||
datetime.initialValue = '2004-08-06';
|
||||
|
||||
datetime.generate();
|
||||
var columns = picker.getColumns();
|
||||
|
||||
expect(columns[0].options[columns[0].selectedIndex].value).toEqual(6);
|
||||
expect(columns[1].options[columns[1].selectedIndex].value).toEqual(8);
|
||||
expect(columns[2].options[columns[2].selectedIndex].value).toEqual(2004);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('setValue', () => {
|
||||
|
||||
it('should update existing time value with 12-hour PM DateTimeData value', zoned(() => {
|
||||
@@ -680,10 +727,10 @@ describe('DateTime', () => {
|
||||
datetime._picker = picker = new Picker(mockApp(), null, mockConfig());
|
||||
});
|
||||
|
||||
console.warn = function(){};
|
||||
console.warn = function() {};
|
||||
|
||||
// pt-br
|
||||
var customLocale: datetime.LocaleData = {
|
||||
var customLocale: datetimeUtil.LocaleData = {
|
||||
dayNames: [
|
||||
'domingo',
|
||||
'segunda-feira',
|
||||
@@ -736,7 +783,7 @@ describe('DateTime', () => {
|
||||
|
||||
function zoned(fn: () => any): (done: DoneFn) => void {
|
||||
return () => {
|
||||
const zone = new NgZone(false);
|
||||
const zone = new NgZone({enableLongStackTrace: false});
|
||||
zone.run(fn);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -97,10 +97,16 @@ ion-fab {
|
||||
@include multi-dir() {
|
||||
right: $fab-content-margin;
|
||||
}
|
||||
|
||||
@include multi-dir() {
|
||||
right: calc(#{$fab-content-margin} + constant(safe-area-inset-right));
|
||||
right: calc(#{$fab-content-margin} + env(safe-area-inset-right));
|
||||
}
|
||||
}
|
||||
|
||||
&[end] {
|
||||
@include position-horizontal(null, $fab-content-margin);
|
||||
@include safe-position-horizontal(null, $fab-content-margin);
|
||||
}
|
||||
|
||||
&[bottom] {
|
||||
@@ -112,10 +118,16 @@ ion-fab {
|
||||
@include multi-dir() {
|
||||
left: $fab-content-margin;
|
||||
}
|
||||
|
||||
@include multi-dir() {
|
||||
left: calc(#{$fab-content-margin} + constant(safe-area-inset-left));
|
||||
left: calc(#{$fab-content-margin} + env(safe-area-inset-left));
|
||||
}
|
||||
}
|
||||
|
||||
&[start] {
|
||||
@include position-horizontal($fab-content-margin, null);
|
||||
@include safe-position-horizontal($fab-content-margin, null);
|
||||
}
|
||||
|
||||
&[top][edge] {
|
||||
|
||||
@@ -101,6 +101,7 @@ import { Platform } from '../../platform/platform';
|
||||
'(focus)="onFocus($event)" ' +
|
||||
'(keydown)="onKeydown($event)" ' +
|
||||
'[type]="_type" ' +
|
||||
'dir="auto" ' +
|
||||
'[attr.aria-labelledby]="_labelId" ' +
|
||||
'[attr.min]="min" ' +
|
||||
'[attr.max]="max" ' +
|
||||
@@ -283,19 +284,24 @@ export class TextInput extends BaseInput<string> implements IonicFormInput {
|
||||
return;
|
||||
}
|
||||
|
||||
const blurOnScroll = config.getBoolean('hideCaretOnScroll', false);
|
||||
if (blurOnScroll) {
|
||||
const hideCaretOnScroll = config.getBoolean('hideCaretOnScroll', false);
|
||||
if (hideCaretOnScroll) {
|
||||
this._enableHideCaretOnScroll();
|
||||
}
|
||||
|
||||
const resizeAssist = config.getBoolean('resizeAssist', false);
|
||||
if (resizeAssist) {
|
||||
this._keyboardHeight = 60;
|
||||
this._enableResizeAssist();
|
||||
const win = _plt.win() as any;
|
||||
const keyboardPlugin = win.Ionic && win.Ionic.keyboardPlugin;
|
||||
if (keyboardPlugin) {
|
||||
const keyboardResizes = config.getBoolean('keyboardResizes', false);
|
||||
if (keyboardResizes) {
|
||||
this._keyboardHeight = config.getNumber('keyboardSafeArea', 60);
|
||||
this._enableScrollMove();
|
||||
} else {
|
||||
this._enableScrollPadding();
|
||||
this._enableScrollMove();
|
||||
}
|
||||
|
||||
} else {
|
||||
this._useAssist = config.getBoolean('scrollAssist', false);
|
||||
|
||||
const usePadding = config.getBoolean('scrollPadding', this._useAssist);
|
||||
if (usePadding) {
|
||||
this._enableScrollPadding();
|
||||
@@ -527,9 +533,8 @@ export class TextInput extends BaseInput<string> implements IonicFormInput {
|
||||
|
||||
this.ionFocus.subscribe(() => {
|
||||
const content = this._content;
|
||||
|
||||
// add padding to the bottom of the scroll view (if needed)
|
||||
content.addScrollPadding(this._getScrollData().scrollPadding);
|
||||
const scrollPadding = this._getScrollData().scrollPadding;
|
||||
content.addScrollPadding(scrollPadding);
|
||||
content.clearScrollPaddingFocusOut();
|
||||
});
|
||||
}
|
||||
@@ -559,13 +564,13 @@ export class TextInput extends BaseInput<string> implements IonicFormInput {
|
||||
}
|
||||
}
|
||||
|
||||
_enableResizeAssist() {
|
||||
_enableScrollMove() {
|
||||
assert(this._content, 'content is undefined');
|
||||
|
||||
console.debug('Input: enableAutoScroll');
|
||||
this.ionFocus.subscribe(() => {
|
||||
const scrollData = this._getScrollData();
|
||||
if (Math.abs(scrollData.scrollAmount) > 100) {
|
||||
if (Math.abs(scrollData.scrollAmount) > 4) {
|
||||
this._content.scrollTo(0, scrollData.scrollTo, scrollData.scrollDuration);
|
||||
}
|
||||
});
|
||||
@@ -721,7 +726,8 @@ export function getScrollData(
|
||||
inputOffsetHeight: number,
|
||||
scrollViewDimensions: ContentDimensions,
|
||||
keyboardHeight: number,
|
||||
plaformHeight: number): ScrollData {
|
||||
plaformHeight: number
|
||||
): ScrollData {
|
||||
// compute input's Y values relative to the body
|
||||
const inputTop = (inputOffsetTop + scrollViewDimensions.contentTop - scrollViewDimensions.scrollTop);
|
||||
const inputBottom = (inputTop + inputOffsetHeight);
|
||||
@@ -752,6 +758,15 @@ export function getScrollData(
|
||||
|
||||
const scrollData: ScrollData = newScrollData();
|
||||
|
||||
// when auto-scrolling, there also needs to be enough
|
||||
// content padding at the bottom of the scroll view
|
||||
// always add scroll padding when a text input has focus
|
||||
// this allows for the content to scroll above of the keyboard
|
||||
// content behind the keyboard would be blank
|
||||
// some cases may not need it, but when jumping around it's best
|
||||
// to have the padding already rendered so there's no jank
|
||||
scrollData.scrollPadding = keyboardHeight;
|
||||
|
||||
if (inputTopWithinSafeArea && inputBottomWithinSafeArea) {
|
||||
// Input top within safe area, bottom within safe area
|
||||
// no need to scroll to a position, it's good as-is
|
||||
@@ -787,15 +802,6 @@ export function getScrollData(
|
||||
// figure out where it should scroll to for the best position to the input
|
||||
scrollData.scrollTo = (scrollViewDimensions.scrollTop - scrollData.scrollAmount);
|
||||
|
||||
// when auto-scrolling, there also needs to be enough
|
||||
// content padding at the bottom of the scroll view
|
||||
// always add scroll padding when a text input has focus
|
||||
// this allows for the content to scroll above of the keyboard
|
||||
// content behind the keyboard would be blank
|
||||
// some cases may not need it, but when jumping around it's best
|
||||
// to have the padding already rendered so there's no jank
|
||||
scrollData.scrollPadding = keyboardHeight;
|
||||
|
||||
// calculate animation duration
|
||||
const distance = Math.abs(scrollData.scrollAmount);
|
||||
const duration = distance / SCROLL_ASSIST_SPEED;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
$reorder-initial-transform: 160% !default;
|
||||
$reorder-initial-transform: 300% !default;
|
||||
|
||||
// Item reorder
|
||||
// --------------------------------------------------
|
||||
|
||||
@@ -76,6 +76,10 @@ ion-item-options .button {
|
||||
box-shadow: none;
|
||||
|
||||
box-sizing: content-box;
|
||||
|
||||
&:last-child {
|
||||
@include safe-area-padding-horizontal(null, .7em);
|
||||
}
|
||||
}
|
||||
|
||||
ion-item-options:not([icon-left]) .button:not([icon-only]), // deprecated
|
||||
|
||||
@@ -60,6 +60,7 @@ $item-ios-sliding-content-background: $list-ios-background-color !default;
|
||||
|
||||
.item-ios {
|
||||
@include padding-horizontal($item-ios-padding-start, null);
|
||||
@include safe-area-padding-horizontal($item-ios-padding-start, null);
|
||||
@include border-radius(0);
|
||||
|
||||
position: relative;
|
||||
@@ -124,6 +125,7 @@ $item-ios-sliding-content-background: $list-ios-background-color !default;
|
||||
|
||||
.item-ios.item-block .item-inner {
|
||||
@include padding-horizontal(null, $item-ios-padding-end / 2);
|
||||
@include safe-area-padding-horizontal(null, $item-ios-padding-end / 2);
|
||||
|
||||
border-bottom: $hairlines-width solid $list-ios-border-color;
|
||||
}
|
||||
@@ -219,9 +221,13 @@ $item-ios-sliding-content-background: $list-ios-background-color !default;
|
||||
.item-ios[detail-push] .item-inner,
|
||||
button.item-ios:not([detail-none]) .item-inner,
|
||||
a.item-ios:not([detail-none]) .item-inner {
|
||||
$safe-area-position: calc(#{$item-ios-padding-end - 2} + constant(safe-area-inset-right));
|
||||
$safe-area-position-env: calc(#{$item-ios-padding-end - 2} + env(safe-area-inset-right));
|
||||
@include svg-background-image($item-ios-detail-push-svg, true);
|
||||
@include padding-horizontal(null, 32px);
|
||||
@include background-position(end, $item-ios-padding-end - 2, center);
|
||||
@include background-position(end, $safe-area-position, center);
|
||||
@include background-position(end, $safe-area-position-env, center);
|
||||
|
||||
background-repeat: no-repeat;
|
||||
background-size: 14px 14px;
|
||||
@@ -247,6 +253,7 @@ ion-item-group .item-wrapper:last-child .item-ios .item-inner {
|
||||
|
||||
.item-divider-ios {
|
||||
@include padding-horizontal($item-ios-padding-start, null);
|
||||
@include safe-area-padding-horizontal($item-ios-padding-start, null);
|
||||
|
||||
color: $item-ios-divider-color;
|
||||
background-color: $item-ios-divider-background;
|
||||
|
||||
@@ -179,6 +179,7 @@ $list-ios-header-background-color: transparent !default;
|
||||
|
||||
.list-header-ios {
|
||||
@include padding-horizontal($list-ios-header-padding-start, null);
|
||||
@include safe-area-padding-horizontal($list-ios-header-padding-start, null);
|
||||
|
||||
position: relative;
|
||||
|
||||
|
||||
@@ -47,12 +47,12 @@ import { LoadingOptions } from './loading-options';
|
||||
*
|
||||
* @usage
|
||||
* ```ts
|
||||
* constructor(public loadingCtrl: LoadingController) {
|
||||
* import { LoadingController } from 'ionic-angular';
|
||||
*
|
||||
* }
|
||||
* constructor(public loadingCtrl: LoadingController) { }
|
||||
*
|
||||
* presentLoadingDefault() {
|
||||
* let loading = this.loadingCtrl.create({
|
||||
* const loading = this.loadingCtrl.create({
|
||||
* content: 'Please wait...'
|
||||
* });
|
||||
*
|
||||
@@ -64,7 +64,7 @@ import { LoadingOptions } from './loading-options';
|
||||
* }
|
||||
*
|
||||
* presentLoadingCustom() {
|
||||
* let loading = this.loadingCtrl.create({
|
||||
* const loading = this.loadingCtrl.create({
|
||||
* spinner: 'hide',
|
||||
* content: `
|
||||
* <div class="custom-spinner-container">
|
||||
@@ -81,7 +81,7 @@ import { LoadingOptions } from './loading-options';
|
||||
* }
|
||||
*
|
||||
* presentLoadingText() {
|
||||
* let loading = this.loadingCtrl.create({
|
||||
* const loading = this.loadingCtrl.create({
|
||||
* spinner: 'hide',
|
||||
* content: 'Loading Please Wait...'
|
||||
* });
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ViewController } from '../../navigation/view-controller';
|
||||
* @name MenuToggle
|
||||
* @description
|
||||
* The `menuToggle` directive can be placed on any button to toggle a menu open or closed.
|
||||
* If it is added to the [NavBar](../../navbar/NavBar) of a page, the button will only appear
|
||||
* If it is added to the [NavBar](../../toolbar/Navbar) of a page, the button will only appear
|
||||
* when the page it's in is currently a root page. See the [Menu Navigation Bar Behavior](../Menu#navigation-bar-behavior)
|
||||
* docs for more information.
|
||||
*
|
||||
|
||||
@@ -38,12 +38,10 @@ import { DeepLinker } from '../../navigation/deep-linker';
|
||||
* @Component(...)
|
||||
* class HomePage {
|
||||
*
|
||||
* constructor(public modalCtrl: ModalController) {
|
||||
*
|
||||
* }
|
||||
* constructor(public modalCtrl: ModalController) { }
|
||||
*
|
||||
* presentProfileModal() {
|
||||
* let profileModal = this.modalCtrl.create(Profile, { userId: 8675309 });
|
||||
* const profileModal = this.modalCtrl.create(Profile, { userId: 8675309 });
|
||||
* profileModal.present();
|
||||
* }
|
||||
*
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ion-split-pane>
|
||||
<ion-tabs>
|
||||
<ion-tab tabIcon="heart" [root]="tabs1Tab1" tabTitle="Heart"></ion-tab>
|
||||
<ion-tab tabIcon="star" [root]="tabs1Tab2" tabTitle="Star"></ion-tab>
|
||||
</ion-tabs>
|
||||
<ion-tabs>
|
||||
<ion-tab tabIcon="aperture" [root]="tabs2Tab1" tabTitle="Aperture"></ion-tab>
|
||||
<ion-tab tabIcon="apps" [root]="tabs2Tab2" tabTitle="Apps"></ion-tab>
|
||||
</ion-tabs>
|
||||
</ion-split-pane>
|
||||
`
|
||||
})
|
||||
export class AppComponent {
|
||||
tabs1Tab1 = 'TabsOneTabOnePageOne';
|
||||
tabs1Tab2 = 'TabsOneTabTwoPageOne';
|
||||
tabs2Tab1 = 'TabsTwoTabOnePageOne';
|
||||
tabs2Tab2 = 'TabsTwoTabTwoPageOne';
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { IonicApp, IonicModule } from '../../../../..';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
IonicModule.forRoot(AppComponent, { swipeBackEnabled: true, preloadModules: true }),
|
||||
],
|
||||
bootstrap: [IonicApp]
|
||||
})
|
||||
export class AppModule {}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsOneTabOnePageOne } from './tab-one-page-one';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsOneTabOnePageOne)
|
||||
],
|
||||
declarations: [
|
||||
TabsOneTabOnePageOne
|
||||
]
|
||||
})
|
||||
export class TabsOneTabOnePageOneModule { }
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsOneTabOnePageOne'
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 1 Tab 1 Page 1</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 1 Tab 1 Page 1
|
||||
<button ion-button (click)="nextPage()">Go to Next Page</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsOneTabOnePageOne {
|
||||
constructor(public nav: NavController) {
|
||||
}
|
||||
|
||||
nextPage() {
|
||||
this.nav.push('TabsOneTabOnePageTwo', { userId: '123', name: 'Andy Bernard'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsOneTabOnePageThree } from './tab-one-page-three';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsOneTabOnePageThree)
|
||||
],
|
||||
declarations: [
|
||||
TabsOneTabOnePageThree
|
||||
]
|
||||
})
|
||||
export class TabsOneTabOnePageThreeModule { }
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsOneTabOnePageThree/paramOne/:paramOne/paramTwo/:paramTwo',
|
||||
defaultHistory: ['TabsOneTabOnePageOne']
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 1 Tab 1 Page 3</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 1 Tab 1 Page 3
|
||||
<div>
|
||||
Param One: {{paramOne}}
|
||||
</div>
|
||||
<div>
|
||||
Name: {{paramTwo}}
|
||||
</div>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsOneTabOnePageThree {
|
||||
paramOne: string;
|
||||
paramTwo: string;
|
||||
constructor(public nav: NavController, navParams: NavParams) {
|
||||
this.paramOne = navParams.data.paramOne;
|
||||
this.paramTwo = navParams.data.paramTwo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsOneTabOnePageTwo } from './tab-one-page-two';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsOneTabOnePageTwo)
|
||||
],
|
||||
declarations: [
|
||||
TabsOneTabOnePageTwo
|
||||
]
|
||||
})
|
||||
export class TabsOneTabOnePageTwoModule { }
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsOneTabOnePageTwo/userId/:userId/name/:name',
|
||||
defaultHistory: ['TabsOneTabOnePageOne']
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 1 Tab 1 Page 2</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 1 Tab 1 Page 2
|
||||
<div>
|
||||
User ID: {{userId}}
|
||||
</div>
|
||||
<div>
|
||||
Name: {{name}}
|
||||
</div>
|
||||
<button ion-button (click)="goToNext()">Next</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsOneTabOnePageTwo {
|
||||
userId: string;
|
||||
name: string;
|
||||
constructor(public nav: NavController, navParams: NavParams) {
|
||||
this.userId = navParams.data.userId;
|
||||
this.name = navParams.data.name;
|
||||
}
|
||||
|
||||
goToNext() {
|
||||
this.nav.push('TabsOneTabOnePageThree', { paramOne: 'Scranton', paramTwo: 'PA'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsOneTabTwoPageOne } from './tab-two-page-one';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsOneTabTwoPageOne)
|
||||
],
|
||||
declarations: [
|
||||
TabsOneTabTwoPageOne
|
||||
]
|
||||
})
|
||||
export class TabsOneTabTwoPageOneModule { }
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsOneTabTwoPageOne'
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 1 Tab 2 Page 1</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 1 Tab 2 Page 1
|
||||
<button ion-button (click)="nextPage()">Go to Next Page</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsOneTabTwoPageOne {
|
||||
constructor(public nav: NavController) {
|
||||
}
|
||||
|
||||
nextPage() {
|
||||
this.nav.push('TabsOneTabTwoPageTwo', { userId: '456', name: 'Stanley Hudson'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsOneTabTwoPageThree } from './tab-two-page-three';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsOneTabTwoPageThree)
|
||||
],
|
||||
declarations: [
|
||||
TabsOneTabTwoPageThree
|
||||
]
|
||||
})
|
||||
export class TabsOneTabTwoPageThreeModule { }
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsOneTabTwoPageThree/paramOne/:paramOne/paramTwo/:paramTwo',
|
||||
defaultHistory: ['TabsOneTabTwoPageOne']
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 1 Tab 2 Page 3</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 1 Tab 2 Page 3
|
||||
<div>
|
||||
Param One: {{paramOne}}
|
||||
</div>
|
||||
<div>
|
||||
Param Two: {{paramTwo}}
|
||||
</div>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsOneTabTwoPageThree {
|
||||
paramOne: string;
|
||||
paramTwo: string;
|
||||
constructor(public nav: NavController, navParams: NavParams) {
|
||||
this.paramOne = navParams.data.paramOne;
|
||||
this.paramTwo = navParams.data.paramTwo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsOneTabTwoPageTwo } from './tab-two-page-two';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsOneTabTwoPageTwo)
|
||||
],
|
||||
declarations: [
|
||||
TabsOneTabTwoPageTwo
|
||||
]
|
||||
})
|
||||
export class TabsOneTabTwoPageTwoModule { }
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsOneTabTwoPageTwo/userId/:userId/name/:name',
|
||||
defaultHistory: ['TabsOneTabTwoPageOne']
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 1 Tab 2 Page 2</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 1 Tab 2 Page 2
|
||||
<div>
|
||||
User ID: {{userId}}
|
||||
</div>
|
||||
<div>
|
||||
Name: {{name}}
|
||||
</div>
|
||||
<button ion-button (click)="goToNext()">Next</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsOneTabTwoPageTwo {
|
||||
userId: string;
|
||||
name: string;
|
||||
constructor(public nav: NavController, navParams: NavParams) {
|
||||
this.userId = navParams.data.userId;
|
||||
this.name = navParams.data.name;
|
||||
}
|
||||
|
||||
goToNext() {
|
||||
this.nav.push('TabsOneTabTwoPageThree', { paramOne: 'Nashua', paramTwo: 'NH'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsTwoTabOnePageOne } from './tab-one-page-one';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsTwoTabOnePageOne)
|
||||
],
|
||||
declarations: [
|
||||
TabsTwoTabOnePageOne
|
||||
]
|
||||
})
|
||||
export class TabsTwoTabOnePageOneModule { }
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsTwoTabOnePageOne'
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 2 Tab 1 Page 1</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 2 Tab 1 Page 1
|
||||
<button ion-button (click)="nextPage()">Go to Next Page</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsTwoTabOnePageOne {
|
||||
constructor(public nav: NavController) {
|
||||
}
|
||||
|
||||
nextPage() {
|
||||
this.nav.push('TabsTwoTabOnePageTwo', { userId: '234', name: 'Phillis Vance - Vance Refridgeration'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsTwoTabOnePageThree } from './tab-one-page-three';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsTwoTabOnePageThree)
|
||||
],
|
||||
declarations: [
|
||||
TabsTwoTabOnePageThree
|
||||
]
|
||||
})
|
||||
export class TabsTwoTabOnePageThreeModule { }
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsTwoTabOnePageThree/paramOne/:paramOne/paramTwo/:paramTwo',
|
||||
defaultHistory: ['TabsTwoTabOnePageOne']
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 2 Tab 1 Page 3</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 2 Tab 1 Page 3
|
||||
<div>
|
||||
Param One: {{paramOne}}
|
||||
</div>
|
||||
<div>
|
||||
Param Two: {{paramTwo}}
|
||||
</div>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsTwoTabOnePageThree {
|
||||
paramOne: string;
|
||||
paramTwo: string;
|
||||
constructor(public nav: NavController, navParams: NavParams) {
|
||||
this.paramOne = navParams.data.paramOne;
|
||||
this.paramTwo = navParams.data.paramTwo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsTwoTabOnePageTwo } from './tab-one-page-two';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsTwoTabOnePageTwo)
|
||||
],
|
||||
declarations: [
|
||||
TabsTwoTabOnePageTwo
|
||||
]
|
||||
})
|
||||
export class TabsTwoTabOnePageTwoModule { }
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsTwoTabOnePageTwo/userId/:userId/name/:name',
|
||||
defaultHistory: ['TabsTwoTabOnePageOne']
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 2 Tab 1 Page 2</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 2 Tab 1 Page 2
|
||||
<div>
|
||||
User ID: {{userId}}
|
||||
</div>
|
||||
<div>
|
||||
Name: {{name}}
|
||||
</div>
|
||||
<button ion-button (click)="goToNext()">Next</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsTwoTabOnePageTwo {
|
||||
userId: string;
|
||||
name: string;
|
||||
constructor(public nav: NavController, navParams: NavParams) {
|
||||
this.userId = navParams.data.userId;
|
||||
this.name = navParams.data.name;
|
||||
}
|
||||
|
||||
goToNext() {
|
||||
this.nav.push('TabsTwoTabOnePageThree', { paramOne: 'Stamford', paramTwo: 'CT'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsTwoTabTwoPageOne } from './tab-two-page-one';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsTwoTabTwoPageOne)
|
||||
],
|
||||
declarations: [
|
||||
TabsTwoTabTwoPageOne
|
||||
]
|
||||
})
|
||||
export class TabsTwoTabTwoPageOneModule { }
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsTwoTabTwoPageOne'
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 2 Tab 2 Page 1</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 2 Tab 2 Page 1
|
||||
<button ion-button (click)="nextPage()">Go to Next Page</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsTwoTabTwoPageOne {
|
||||
constructor(public nav: NavController) {
|
||||
}
|
||||
|
||||
nextPage() {
|
||||
this.nav.push('TabsTwoTabTwoPageTwo', { userId: '456', name: 'Michael Scarn'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsTwoTabTwoPageThree } from './tab-two-page-three';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsTwoTabTwoPageThree)
|
||||
],
|
||||
declarations: [
|
||||
TabsTwoTabTwoPageThree
|
||||
]
|
||||
})
|
||||
export class TabsTwoTabTwoPageThreeModule { }
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsTwoTabTwoPageThree/paramOne/:paramOne/paramTwo/:paramTwo',
|
||||
defaultHistory: ['TabsTwoTabTwoPageOne']
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 2 Tab 2 Page 3</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 2 Tab 2 Page 3
|
||||
<div>
|
||||
Param One: {{paramOne}}
|
||||
</div>
|
||||
<div>
|
||||
Param Two: {{paramTwo}}
|
||||
</div>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsTwoTabTwoPageThree {
|
||||
paramOne: string;
|
||||
paramTwo: string;
|
||||
constructor(public nav: NavController, navParams: NavParams) {
|
||||
this.paramOne = navParams.data.paramOne;
|
||||
this.paramTwo = navParams.data.paramTwo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { TabsTwoTabTwoPageTwo } from './tab-two-page-two';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(TabsTwoTabTwoPageTwo)
|
||||
],
|
||||
declarations: [
|
||||
TabsTwoTabTwoPageTwo
|
||||
]
|
||||
})
|
||||
export class TabsTwoTabTwoPageTwoModule { }
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'TabsTwoTabTwoPageTwo/userId/:userId/name/:name',
|
||||
defaultHistory: ['TabsTwoTabTwoPageOne']
|
||||
})
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Tabs 2 Tab 2 Page 2</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Tabs 2 Tab 2 Page 2
|
||||
<div>
|
||||
User ID: {{userId}}
|
||||
</div>
|
||||
<div>
|
||||
Name: {{name}}
|
||||
</div>
|
||||
<button ion-button (click)="next()">Next</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class TabsTwoTabTwoPageTwo {
|
||||
userId: string;
|
||||
name: string;
|
||||
constructor(public nav: NavController, navParams: NavParams) {
|
||||
this.userId = navParams.data.userId;
|
||||
this.name = navParams.data.name;
|
||||
}
|
||||
|
||||
next() {
|
||||
this.nav.push('TabsTwoTabTwoPageThree', { paramOne: 'Albany', paramTwo: 'NY'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `<ion-nav [root]="root" name="default"></ion-nav>`
|
||||
})
|
||||
export class AppComponent {
|
||||
root = 'FirstPage';
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { IonicApp, IonicModule } from '../../../../..';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
IonicModule.forRoot(AppComponent, { swipeBackEnabled: true, preloadModules: true }),
|
||||
],
|
||||
bootstrap: [IonicApp]
|
||||
})
|
||||
export class AppModule {}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
@@ -0,0 +1,10 @@
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>First Page</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
Page One
|
||||
<button ion-button (click)="goToPageTwo()">Go to Page Two</button>
|
||||
<a href="#/nav/n4/user/123/name/ted">Using href</a>
|
||||
</ion-content>
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../..';
|
||||
import { FirstPage } from './first-page';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(FirstPage)
|
||||
],
|
||||
declarations: [
|
||||
FirstPage
|
||||
]
|
||||
})
|
||||
export class FirstPageModule { }
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, } from '../../../../../..';
|
||||
|
||||
@IonicPage()
|
||||
@Component({
|
||||
templateUrl: 'first-page.html'
|
||||
})
|
||||
export class FirstPage {
|
||||
constructor(public nav: NavController) {
|
||||
}
|
||||
|
||||
goToPageTwo() {
|
||||
this.nav.push('SecondPage', { userId: '123', name: 'ted'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Second Page</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<div>
|
||||
User ID: {{userId}}
|
||||
</div>
|
||||
<div>
|
||||
Name {{name}}
|
||||
</div>
|
||||
<div>
|
||||
<button ion-button (click)="goToNextPage()">Go to Next Page</button>
|
||||
</div>
|
||||
</ion-content>
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../..';
|
||||
import { SecondPage } from './second-page';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(SecondPage)
|
||||
],
|
||||
declarations: [
|
||||
SecondPage
|
||||
]
|
||||
})
|
||||
export class SecondPageModule { }
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'user/:userId/name/:name',
|
||||
defaultHistory: [
|
||||
'FirstPage'
|
||||
]
|
||||
})
|
||||
@Component({
|
||||
templateUrl: 'second-page.html'
|
||||
})
|
||||
export class SecondPage {
|
||||
|
||||
userId: string;
|
||||
name: string;
|
||||
constructor(public nav: NavController, public params: NavParams) {
|
||||
this.userId = this.params.data.userId;
|
||||
this.name = this.params.data.name;
|
||||
}
|
||||
|
||||
goToNextPage() {
|
||||
this.nav.push('ThirdPage', { paramOne: 'Hello', paramTwo: 'Its me'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Third Page</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<div>
|
||||
Param One: {{paramOne}}
|
||||
</div>
|
||||
<div>
|
||||
Param Two: {{paramTwo}}
|
||||
</div>
|
||||
</ion-content>
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../..';
|
||||
import { ThirdPage } from './third-page';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(ThirdPage)
|
||||
],
|
||||
declarations: [
|
||||
ThirdPage
|
||||
]
|
||||
})
|
||||
export class ThirdPageModule { }
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'paramOne/:paramOne/paramTwo/:paramTwo',
|
||||
defaultHistory: [
|
||||
'FirstPage'
|
||||
]
|
||||
})
|
||||
@Component({
|
||||
templateUrl: 'third-page.html'
|
||||
})
|
||||
export class ThirdPage {
|
||||
|
||||
paramOne: string;
|
||||
paramTwo: string;
|
||||
constructor(public nav: NavController, public params: NavParams) {
|
||||
this.paramOne = this.params.data.paramOne;
|
||||
this.paramTwo = this.params.data.paramTwo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `<ion-nav [root]="root"></ion-nav>`
|
||||
})
|
||||
export class AppComponent {
|
||||
root = 'LoginPage';
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { IonicApp, IonicModule } from '../../../../..';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
IonicModule.forRoot(AppComponent, { swipeBackEnabled: true, preloadModules: true }),
|
||||
],
|
||||
bootstrap: [IonicApp]
|
||||
})
|
||||
export class AppModule {}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../..';
|
||||
import { LoginPage } from './login-page';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(LoginPage)
|
||||
],
|
||||
declarations: [
|
||||
LoginPage
|
||||
]
|
||||
})
|
||||
export class LoginPageModule { }
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, } from '../../../../../..';
|
||||
|
||||
@IonicPage()
|
||||
@Component({
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Login</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<button ion-button (click)="clickMe()">Login</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class LoginPage {
|
||||
constructor(public nav: NavController) {
|
||||
}
|
||||
|
||||
clickMe() {
|
||||
this.nav.push('TabsPage');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>First Page</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
First Page
|
||||
<div>
|
||||
<button ion-button (click)="clickMe()">Go To Next Page</button>
|
||||
</div>
|
||||
</ion-content>
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { FirstPage } from './first-page';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(FirstPage)
|
||||
],
|
||||
declarations: [
|
||||
FirstPage
|
||||
]
|
||||
})
|
||||
export class FirstPageModule { }
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, } from '../../../../../../..';
|
||||
|
||||
@IonicPage()
|
||||
@Component({
|
||||
templateUrl: 'first-page.html'
|
||||
})
|
||||
export class FirstPage {
|
||||
constructor(public nav: NavController) {
|
||||
}
|
||||
|
||||
clickMe() {
|
||||
this.nav.push('SecondPage', { userId: '123', name: 'Phyllis Vance, Vance Refridgeration'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Second Page</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<div>
|
||||
User ID: {{userId}}
|
||||
</div>
|
||||
<div>
|
||||
Name {{name}}
|
||||
</div>
|
||||
<button ion-button (click)="goToNextPage()">Next Page</button>
|
||||
</ion-content>
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from '../../../../../../..';
|
||||
import { SecondPage } from './second-page';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicPageModule.forChild(SecondPage)
|
||||
],
|
||||
declarations: [
|
||||
SecondPage
|
||||
]
|
||||
})
|
||||
export class SecondPageModule { }
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from '../../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
segment: 'secondPage/user/:userId/name/:name',
|
||||
defaultHistory: ['FirstPage']
|
||||
})
|
||||
@Component({
|
||||
templateUrl: 'second-page.html'
|
||||
})
|
||||
export class SecondPage {
|
||||
|
||||
userId: string;
|
||||
name: string;
|
||||
constructor(public nav: NavController, public params: NavParams) {
|
||||
this.userId = this.params.data.userId;
|
||||
this.name = this.params.data.name;
|
||||
}
|
||||
|
||||
goToNextPage() {
|
||||
this.nav.push('ThirdPage', { paramOne: 'Tobey', paramTwo: 'Kevin'});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Third Page</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<h2>Third Page</h2>
|
||||
<div>
|
||||
Param One: {{paramOne}}
|
||||
</div>
|
||||
<div>
|
||||
Param Two: {{paramTwo}}
|
||||
</div>
|
||||
</ion-content>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user