mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
355 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bea21e73b6 | ||
|
|
e8e76324d9 | ||
|
|
210db5b265 | ||
|
|
13168b6d77 | ||
|
|
4fe3798787 | ||
|
|
0d56c51664 | ||
|
|
390ca65079 | ||
|
|
3dbffa89b1 | ||
|
|
c28c45f493 | ||
|
|
478723c55f | ||
|
|
1dac5a46f5 | ||
|
|
b396e54d4f | ||
|
|
5bccf31bed | ||
|
|
0179aad2b3 | ||
|
|
db1fd1d72a | ||
|
|
1bfc1c0393 | ||
|
|
7b9515ffa3 | ||
|
|
708020551f | ||
|
|
63d4e877fb | ||
|
|
ec6a8dd86f | ||
|
|
2f8c13b696 | ||
|
|
1411d8a173 | ||
|
|
9e35ebed4a | ||
|
|
aff9612d11 | ||
|
|
22f92294ce | ||
|
|
ad8f3db725 | ||
|
|
023b835d16 | ||
|
|
8a5aba2068 | ||
|
|
676cc19b89 | ||
|
|
654d04c265 | ||
|
|
857bab6641 | ||
|
|
027306a258 | ||
|
|
0f10bb29e8 | ||
|
|
4a73544502 | ||
|
|
9ea75ebec7 | ||
|
|
1454539cd3 | ||
|
|
6dfa0da460 | ||
|
|
78b3029665 | ||
|
|
e116712275 | ||
|
|
1c7d1e5cf1 | ||
|
|
684293ddbf | ||
|
|
f9bf8dbe6f | ||
|
|
eef55bb007 | ||
|
|
637b082976 | ||
|
|
6c20fecab0 | ||
|
|
06c0c77673 | ||
|
|
dd007d55fe | ||
|
|
5ff786a23d | ||
|
|
f0efe4aed6 | ||
|
|
d8b6098e30 | ||
|
|
7356c40174 | ||
|
|
de0a899be7 | ||
|
|
0a3014d35e | ||
|
|
628e76668e | ||
|
|
d89508b1b5 | ||
|
|
fd9745ddcd | ||
|
|
bcc40c8d59 | ||
|
|
9fad4161be | ||
|
|
17fe23a3b9 | ||
|
|
e61d7a3aeb | ||
|
|
8d55564a0e | ||
|
|
f74d9c6b9b | ||
|
|
8fe8b4bbba | ||
|
|
7713f7fe74 | ||
|
|
9d0caf6de0 | ||
|
|
2dc5540910 | ||
|
|
f70e71a3d4 | ||
|
|
31c754dab7 | ||
|
|
70fefb5463 | ||
|
|
8853bd5045 | ||
|
|
e63c65b644 | ||
|
|
d97e167f31 | ||
|
|
48539093bf | ||
|
|
1535e95a5f | ||
|
|
70e0562dc9 | ||
|
|
b7baf24e50 | ||
|
|
ee21d3ae43 | ||
|
|
d8ca878cb1 | ||
|
|
fcdbb3ce98 | ||
|
|
fc6a754b38 | ||
|
|
048a1a8265 | ||
|
|
ec188990d6 | ||
|
|
81b1072322 | ||
|
|
87765564f6 | ||
|
|
ed98d9e658 | ||
|
|
b552daa6dd | ||
|
|
7f4b77ddba | ||
|
|
c6ab439efb | ||
|
|
209cd5adfa | ||
|
|
4be0dde283 | ||
|
|
42a2be136f | ||
|
|
6f5e304e18 | ||
|
|
637f26b364 | ||
|
|
63c2008a86 | ||
|
|
033abe994b | ||
|
|
7ce916cc7c | ||
|
|
3c4e65ba97 | ||
|
|
bb32cea5c9 | ||
|
|
fcd7a5620b | ||
|
|
109b5fc633 | ||
|
|
bc56c4aa7b | ||
|
|
9b0bbc86b8 | ||
|
|
a7b964279b | ||
|
|
8706ecf9c3 | ||
|
|
aed2dba5aa | ||
|
|
3050e9fe88 | ||
|
|
02c1724978 | ||
|
|
790e0c69ea | ||
|
|
19ee21a06c | ||
|
|
dea1c2635d | ||
|
|
17614cdcb3 | ||
|
|
bfb704e2d2 | ||
|
|
9688f4d42f | ||
|
|
f4818a1f3a | ||
|
|
71b8853ff4 | ||
|
|
77658e61cc | ||
|
|
cdfd82a750 | ||
|
|
9f5ed231c3 | ||
|
|
3c846a7b06 | ||
|
|
cb26f73f80 | ||
|
|
a02319b06b | ||
|
|
c101dfe6db | ||
|
|
7768ab2307 | ||
|
|
26f50ca651 | ||
|
|
44ad07480b | ||
|
|
8a52c7d66b | ||
|
|
20ffc95ff1 | ||
|
|
b4d92c6241 | ||
|
|
a28e501272 | ||
|
|
f4b97fd74a | ||
|
|
8ca97ce42c | ||
|
|
eab0865fba | ||
|
|
c79e74b91f | ||
|
|
cf223e40c1 | ||
|
|
446cf78e58 | ||
|
|
0f05ea4245 | ||
|
|
bfa17d1594 | ||
|
|
61f04e50b1 | ||
|
|
e90e960294 | ||
|
|
1e081c0a22 | ||
|
|
bf2953cf85 | ||
|
|
7f76f94c9d | ||
|
|
a74754179c | ||
|
|
c5e1290dfe | ||
|
|
6b9abf22f0 | ||
|
|
e98769edd0 | ||
|
|
123d0f38b6 | ||
|
|
1b9593963e | ||
|
|
e7cbafd4b3 | ||
|
|
f7027fc9ad | ||
|
|
4a900964dd | ||
|
|
73dd70d756 | ||
|
|
aec2936725 | ||
|
|
70ba488502 | ||
|
|
151548b0bc | ||
|
|
1cbb52c55c | ||
|
|
e62780411f | ||
|
|
fea061215d | ||
|
|
2d39c07fec | ||
|
|
4e544f1d90 | ||
|
|
a3f345c06d | ||
|
|
e27962dcaf | ||
|
|
ff2aaadf41 | ||
|
|
696be833dc | ||
|
|
c15ae7cbf5 | ||
|
|
d9514801a8 | ||
|
|
923312ecd5 | ||
|
|
d9610cdbdf | ||
|
|
c959d75633 | ||
|
|
4cfd29f574 | ||
|
|
a81653bcdc | ||
|
|
07140cf2c5 | ||
|
|
c7b302c7a6 | ||
|
|
d1ee36b2c8 | ||
|
|
3d935978b3 | ||
|
|
4c30878fc7 | ||
|
|
9751f145e1 | ||
|
|
6eca5b0d7f | ||
|
|
93f2064927 | ||
|
|
da5d3f0e04 | ||
|
|
e1fa461e9b | ||
|
|
0e18f049c2 | ||
|
|
ef34402960 | ||
|
|
03bffc5d95 | ||
|
|
c3044f59df | ||
|
|
4902de4631 | ||
|
|
d031434b5d | ||
|
|
7f6664708c | ||
|
|
48a27636c7 | ||
|
|
b3c7436e01 | ||
|
|
a65d897214 | ||
|
|
3e63b3c2c4 | ||
|
|
d4db3af881 | ||
|
|
c7b6c7d563 | ||
|
|
b1c8fa39d6 | ||
|
|
fa958a5764 | ||
|
|
fb7098080a | ||
|
|
547f648433 | ||
|
|
0e8ab49d7f | ||
|
|
f2cfdf1bad | ||
|
|
c610406ba6 | ||
|
|
50a92c026c | ||
|
|
62a04d76f1 | ||
|
|
2923aac44e | ||
|
|
c6051e89a5 | ||
|
|
27d042fe38 | ||
|
|
c3871b0cda | ||
|
|
919c73f66d | ||
|
|
e0fa4a5276 | ||
|
|
3b51f8f27c | ||
|
|
cd75428785 | ||
|
|
45a59d13cc | ||
|
|
67ed89ded8 | ||
|
|
cbd230c67e | ||
|
|
5a2c441b3c | ||
|
|
fd65765bdf | ||
|
|
624e118b56 | ||
|
|
7f39f8c357 | ||
|
|
930b271a4a | ||
|
|
0b1e23f754 | ||
|
|
a2b7d57336 | ||
|
|
ce192713c3 | ||
|
|
94e525c10b | ||
|
|
30ca46ab12 | ||
|
|
e33cf854a9 | ||
|
|
e8cdda0fae | ||
|
|
1187dc2fc7 | ||
|
|
3c925bb27e | ||
|
|
ea3fdae2dd | ||
|
|
a5d3c6bcd2 | ||
|
|
5f869796be | ||
|
|
7c48500f27 | ||
|
|
e4357f9823 | ||
|
|
fb81966973 | ||
|
|
4ec74f8535 | ||
|
|
c9f7c47571 | ||
|
|
39f076847f | ||
|
|
c473b3ed92 | ||
|
|
6d7b221b86 | ||
|
|
a1b00a7804 | ||
|
|
2f7e3dbacd | ||
|
|
04b350ce0b | ||
|
|
7f4d3a36df | ||
|
|
cb149ddd19 | ||
|
|
a633db1688 | ||
|
|
3ec9607281 | ||
|
|
84e306c1a6 | ||
|
|
713ea8adaa | ||
|
|
8f7853c5e9 | ||
|
|
f94300cbb3 | ||
|
|
3a22105375 | ||
|
|
6bbdb80871 | ||
|
|
7cd68b59fc | ||
|
|
d237e808c2 | ||
|
|
e043ea9dae | ||
|
|
f9579bcd1d | ||
|
|
23f327ecb6 | ||
|
|
3e1dfc657b | ||
|
|
32bb1f7230 | ||
|
|
48352533ff | ||
|
|
e3a5d1f93a | ||
|
|
f08ac68e0b | ||
|
|
7951289460 | ||
|
|
9f32d0edd7 | ||
|
|
ee4c404bd3 | ||
|
|
27a68b3f7f | ||
|
|
962783bfba | ||
|
|
e82648bda2 | ||
|
|
9b85e13493 | ||
|
|
462cee5b2e | ||
|
|
d792560447 | ||
|
|
7272d481bf | ||
|
|
c83edd9329 | ||
|
|
a869ca0bba | ||
|
|
c2348f71a5 | ||
|
|
67ffe2f9cc | ||
|
|
2e02dc7319 | ||
|
|
b7761fe353 | ||
|
|
00891119f7 | ||
|
|
c91819c94f | ||
|
|
3ef6ecf422 | ||
|
|
7ba718c0db | ||
|
|
e8ab0fd317 | ||
|
|
815fa2eb06 | ||
|
|
c52b3b4997 | ||
|
|
23ce6fae9e | ||
|
|
a8455a90ff | ||
|
|
798103bf63 | ||
|
|
bd8ca63451 | ||
|
|
cf27063aae | ||
|
|
fb18f3ba25 | ||
|
|
71137a2ffa | ||
|
|
544e550286 | ||
|
|
854004cf2c | ||
|
|
6b5a59dc43 | ||
|
|
fbfc07688e | ||
|
|
9b075ef529 | ||
|
|
97fec92365 | ||
|
|
26e6d6f115 | ||
|
|
978cc39009 | ||
|
|
53179c475c | ||
|
|
7ae9303a97 | ||
|
|
045bc59b75 | ||
|
|
08af35aad2 | ||
|
|
5b932152f8 | ||
|
|
9993b73355 | ||
|
|
f1eeed1c91 | ||
|
|
ee81907713 | ||
|
|
1f40d8fffd | ||
|
|
723196a157 | ||
|
|
0b0dddf8ec | ||
|
|
e33bfc7f1d | ||
|
|
03c1d19e07 | ||
|
|
8beeff2c52 | ||
|
|
f060db5fe6 | ||
|
|
4a3ff61571 | ||
|
|
908f36f574 | ||
|
|
292cc867a5 | ||
|
|
ab20bf472d | ||
|
|
470615eb05 | ||
|
|
f56fea6a1f | ||
|
|
7fda509333 | ||
|
|
0031ab82b7 | ||
|
|
e059fc8048 | ||
|
|
7953088418 | ||
|
|
1add112be6 | ||
|
|
f16b118794 | ||
|
|
d71c1cd6b0 | ||
|
|
ccd46028f2 | ||
|
|
24840d4d99 | ||
|
|
a656dadf4b | ||
|
|
03c834c647 | ||
|
|
876ab41ba8 | ||
|
|
dfa2b13c3a | ||
|
|
c6bb2730a8 | ||
|
|
08daaeb1a3 | ||
|
|
1f51ab27c4 | ||
|
|
36a58df181 | ||
|
|
4038e0a60c | ||
|
|
6042b39313 | ||
|
|
dc04a4b8a9 | ||
|
|
98499acff9 | ||
|
|
2417d32316 | ||
|
|
735280168f | ||
|
|
ef10f190cd | ||
|
|
b9b60df0a4 | ||
|
|
b69fb69a1a | ||
|
|
92e0f98633 | ||
|
|
0d58101edc | ||
|
|
44c88ad908 | ||
|
|
45b82dc466 | ||
|
|
22ac160021 | ||
|
|
b46a025576 | ||
|
|
335e02aa44 | ||
|
|
017febed96 |
@@ -91,6 +91,75 @@ jobs:
|
||||
paths:
|
||||
- "*"
|
||||
|
||||
build-angular-server:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install
|
||||
working_directory: /tmp/workspace/packages/angular-server
|
||||
- run:
|
||||
command: npm run build.prod
|
||||
working_directory: /tmp/workspace/packages/angular-server
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- "*"
|
||||
|
||||
build-react:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: npm run build
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- "*"
|
||||
|
||||
build-react-router:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: sudo npm link @ionic/react
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- run:
|
||||
command: npm run build
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- "*"
|
||||
|
||||
test-core-clean-build:
|
||||
<<: *defaults
|
||||
steps:
|
||||
@@ -164,6 +233,64 @@ jobs:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/angular
|
||||
|
||||
test-react-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
|
||||
test-react-router-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
|
||||
test-react-spec:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: npm run test.spec
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
|
||||
test-react-router-spec:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: sudo npm link @ionic/react
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- run:
|
||||
command: npm run test.spec
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
|
||||
test-angular-e2e:
|
||||
<<: *defaults
|
||||
steps:
|
||||
@@ -173,6 +300,9 @@ jobs:
|
||||
- run:
|
||||
command: npm install
|
||||
working_directory: /tmp/workspace/angular/test/test-app
|
||||
- run:
|
||||
command: npm run sync
|
||||
working_directory: /tmp/workspace/angular/test/test-app
|
||||
- run:
|
||||
command: npm test
|
||||
working_directory: /tmp/workspace/angular/test/test-app
|
||||
@@ -205,7 +335,23 @@ workflows:
|
||||
|
||||
- build-angular:
|
||||
requires: [build-core]
|
||||
- build-angular-server:
|
||||
requires: [build-angular]
|
||||
- build-react:
|
||||
requires: [build-core]
|
||||
- build-react-router:
|
||||
requires: [build-core, build-react]
|
||||
- test-react-lint:
|
||||
requires: [build-react]
|
||||
- test-react-router-lint:
|
||||
requires: [build-react-router]
|
||||
- test-react-spec:
|
||||
requires: [build-react]
|
||||
- test-react-router-spec:
|
||||
requires: [build-react-router]
|
||||
- test-angular-lint:
|
||||
requires: [build-angular]
|
||||
- test-angular-e2e:
|
||||
requires: [build-angular]
|
||||
requires:
|
||||
- build-angular
|
||||
- build-angular-server
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -37,6 +37,7 @@ assignees: ''
|
||||
A sample application via GitHub
|
||||
|
||||
StackBlitz (https://stackblitz.com)
|
||||
Ionic Angular StackBlitz: https://stackblitz.com/edit/ionic-v4-angular-tabs
|
||||
|
||||
Plunker (http://plnkr.co/edit/cpeRJs?p=preview)
|
||||
|
||||
|
||||
6
.github/PROCESS.md
vendored
6
.github/PROCESS.md
vendored
@@ -64,7 +64,7 @@ If the issue is a support question, the submitter should be redirected to our [f
|
||||
|
||||
### Incomplete Template
|
||||
|
||||
If the issue template has not been filled out completely, the issue should be closed and locked. The submitter should be informed top re-submit the issue making sure they fill the form out completely. Use the `ionitron: missing template` label to accomplish this.
|
||||
If the issue template has not been filled out completely, the issue should be closed and locked. The submitter should be informed to re-submit the issue making sure they fill the form out completely. Use the `ionitron: missing template` label to accomplish this.
|
||||
|
||||
### Issues with Open Questions
|
||||
|
||||
@@ -77,7 +77,7 @@ NOTE: be sure to perform those actions in the order stated. If you add the comme
|
||||
|
||||
If there is a response to the question, the bot will remove the `needs: reply` and apply the `triage` label. The issue will then go through the triage handling again.
|
||||
|
||||
if there is no response within 30 days, the issue will be closed and locked.
|
||||
If there is no response within 30 days, the issue will be closed and locked.
|
||||
|
||||
## Workflow
|
||||
|
||||
@@ -248,4 +248,4 @@ Hotfixes bypass `master` and should only be used for urgent fixes that can't wai
|
||||
|
||||
1. Rewrite the commit message to `merge release-[VERSION]` with the proper release branch. For example, if this release is for `4.5.0`, the message would be `merge release-4.5.0`.
|
||||
|
||||
1. Submit a pull request from the release branch into `master`. Merge this pull request using the same commit format in the last step, to ensure any changes made on the release branch get added to future releases.
|
||||
1. Submit a pull request from the release branch into `master`. Merge this pull request using the same commit format in the last step, to ensure any changes made on the release branch get added to future releases.
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -57,8 +57,9 @@ prerender-static.html
|
||||
|
||||
# stencil
|
||||
angular/css/
|
||||
packages/react/css/
|
||||
core/css/
|
||||
core/hydrated/
|
||||
core/hydrate/
|
||||
core/loader/
|
||||
core/www/
|
||||
.stencil/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const execa = require('execa');
|
||||
const inquirer = require('inquirer');
|
||||
const Listr = require('listr');
|
||||
const semver = require('semver');
|
||||
const tc = require('turbocolor');
|
||||
@@ -11,6 +12,8 @@ const packages = [
|
||||
'core',
|
||||
'docs',
|
||||
'angular',
|
||||
'packages/react',
|
||||
'packages/react-router'
|
||||
];
|
||||
|
||||
function readPkg(project) {
|
||||
@@ -32,37 +35,79 @@ function projectPath(project) {
|
||||
return path.join(rootDir, project);
|
||||
}
|
||||
|
||||
async function askNpmTag(version) {
|
||||
const prompts = [
|
||||
{
|
||||
type: 'list',
|
||||
name: 'npmTag',
|
||||
message: 'Select npm tag or specify a new tag',
|
||||
choices: ['latest', 'next', 'v4-lts']
|
||||
.concat([
|
||||
new inquirer.Separator(),
|
||||
{
|
||||
name: 'Other (specify)',
|
||||
value: null
|
||||
}
|
||||
])
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: answers => {
|
||||
return `Will publish ${tc.cyan(version)} to ${tc.cyan(answers.npmTag)}. Continue?`;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const { npmTag, confirm } = await inquirer.prompt(prompts);
|
||||
return { npmTag, confirm };
|
||||
}
|
||||
|
||||
function checkGit(tasks) {
|
||||
tasks.push(
|
||||
{
|
||||
title: 'Check current branch',
|
||||
task: () => execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => {
|
||||
if (branch.indexOf('release') === -1 && branch.indexOf('hotfix') === -1) {
|
||||
throw new Error(`Must be on a "release" or "hotfix" branch.`);
|
||||
}
|
||||
})
|
||||
task: () =>
|
||||
execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => {
|
||||
if (branch.indexOf('release') === -1 && branch.indexOf('hotfix') === -1) {
|
||||
throw new Error(`Must be on a "release" or "hotfix" branch.`);
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Check local working tree',
|
||||
task: () => execa.stdout('git', ['status', '--porcelain']).then(status => {
|
||||
if (status !== '') {
|
||||
throw new Error(`Unclean working tree. Commit or stash changes first.`);
|
||||
}
|
||||
})
|
||||
task: () =>
|
||||
execa.stdout('git', ['status', '--porcelain']).then(status => {
|
||||
if (status !== '') {
|
||||
throw new Error(`Unclean working tree. Commit or stash changes first.`);
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Check remote history',
|
||||
task: () => execa.stdout('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD']).then(result => {
|
||||
if (result !== '0') {
|
||||
throw new Error(`Remote history differs. Please pull changes.`);
|
||||
}
|
||||
})
|
||||
task: () =>
|
||||
execa.stdout('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD']).then(result => {
|
||||
if (result !== '0') {
|
||||
throw new Error(`Remote history differs. Please pull changes.`);
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const isValidVersion = input => Boolean(semver.valid(input));
|
||||
function checkTestDist(tasks) {
|
||||
tasks.push({
|
||||
title: 'Check dist folders for required files',
|
||||
task: () =>
|
||||
execa.stdout('node', ['.scripts/test-dist.js']).then(status => {
|
||||
if (status.indexOf('✅ test.dist') === -1) {
|
||||
throw new Error(`Test Dist did not find some required files`);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
const isValidVersion = input => Boolean(semver.valid(input));
|
||||
|
||||
function preparePackage(tasks, package, version, install) {
|
||||
const projectRoot = projectPath(package);
|
||||
@@ -74,7 +119,9 @@ function preparePackage(tasks, package, version, install) {
|
||||
title: `${pkg.name}: validate new version`,
|
||||
task: () => {
|
||||
if (!isVersionGreater(pkg.version, version)) {
|
||||
throw new Error(`New version \`${version}\` should be higher than current version \`${pkg.version}\``);
|
||||
throw new Error(
|
||||
`New version \`${version}\` should be higher than current version \`${pkg.version}\``
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -82,7 +129,7 @@ function preparePackage(tasks, package, version, install) {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: install npm dependencies`,
|
||||
task: async () => {
|
||||
await fs.remove(path.join(projectRoot, 'node_modules'))
|
||||
await fs.remove(path.join(projectRoot, 'node_modules'));
|
||||
await execa('npm', ['i'], { cwd: projectRoot });
|
||||
}
|
||||
});
|
||||
@@ -95,6 +142,13 @@ function preparePackage(tasks, package, version, install) {
|
||||
title: `${pkg.name}: npm link @ionic/core`,
|
||||
task: () => execa('npm', ['link', '@ionic/core'], { cwd: projectRoot })
|
||||
});
|
||||
|
||||
if (package === 'packages/react-router') {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: npm link @ionic/react`,
|
||||
task: () => execa('npm', ['link', '@ionic/react'], { cwd: projectRoot })
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (version) {
|
||||
@@ -102,29 +156,33 @@ function preparePackage(tasks, package, version, install) {
|
||||
title: `${pkg.name}: lint`,
|
||||
task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot })
|
||||
});
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: update ionic/core dep to ${version}`,
|
||||
task: () => {
|
||||
updateDependency(pkg, "@ionic/core", version);
|
||||
writePkg(package, pkg);
|
||||
}
|
||||
});
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: test`,
|
||||
task: () => execa('npm', ['test'], { cwd: projectRoot })
|
||||
});
|
||||
// Disable tests for publish, these pass locally
|
||||
// projectTasks.push({
|
||||
// title: `${pkg.name}: test`,
|
||||
// task: async () => await execa('npm', ['test'], { cwd: projectRoot })
|
||||
// });
|
||||
}
|
||||
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: build`,
|
||||
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
|
||||
});
|
||||
if (package === 'core') {
|
||||
if (package === 'core' || package === 'packages/react') {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: npm link`,
|
||||
task: () => execa('npm', ['link'], { cwd: projectRoot })
|
||||
});
|
||||
}
|
||||
|
||||
if (version) {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: update ionic/core dep to ${version}`,
|
||||
task: () => {
|
||||
updateDependency(pkg, '@ionic/core', version);
|
||||
writePkg(package, pkg);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Add project tasks
|
||||
@@ -134,7 +192,6 @@ function preparePackage(tasks, package, version, install) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function prepareDevPackage(tasks, package, version) {
|
||||
const projectRoot = projectPath(package);
|
||||
const pkg = readPkg(package);
|
||||
@@ -152,7 +209,7 @@ function prepareDevPackage(tasks, package, version) {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: update ionic/core dep to ${version}`,
|
||||
task: () => {
|
||||
updateDependency(pkg, "@ionic/core", version);
|
||||
updateDependency(pkg, '@ionic/core', version);
|
||||
writePkg(package, pkg);
|
||||
}
|
||||
});
|
||||
@@ -162,7 +219,7 @@ function prepareDevPackage(tasks, package, version) {
|
||||
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
|
||||
});
|
||||
|
||||
if (package === 'core') {
|
||||
if (package === 'core' || package === 'packages/react') {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: npm link`,
|
||||
task: () => execa('npm', ['link'], { cwd: projectRoot })
|
||||
@@ -181,33 +238,38 @@ function updatePackageVersions(tasks, packages, version) {
|
||||
packages.forEach(package => {
|
||||
updatePackageVersion(tasks, package, version);
|
||||
|
||||
tasks.push(
|
||||
{
|
||||
title: `${package} update @ionic/core dependency, if present ${tc.dim(`(${version})`)}`,
|
||||
task: async () => {
|
||||
if (package !== 'core') {
|
||||
const pkg = readPkg(package);
|
||||
updateDependency(pkg, '@ionic/core', version);
|
||||
writePkg(package, pkg);
|
||||
}
|
||||
},
|
||||
tasks.push({
|
||||
title: `${package} update @ionic/core dependency, if present ${tc.dim(`(${version})`)}`,
|
||||
task: async () => {
|
||||
if (package !== 'core') {
|
||||
const pkg = readPkg(package);
|
||||
updateDependency(pkg, '@ionic/core', version);
|
||||
writePkg(package, pkg);
|
||||
}
|
||||
}
|
||||
)
|
||||
});
|
||||
if (package === 'packages/react-router') {
|
||||
tasks.push({
|
||||
title: `${package} update @ionic/react dependency, if present ${tc.dim(`(${version})`)}`,
|
||||
task: async () => {
|
||||
const pkg = readPkg(package);
|
||||
updateDependency(pkg, '@ionic/react', version);
|
||||
writePkg(package, pkg);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function updatePackageVersion(tasks, package, version) {
|
||||
const projectRoot = projectPath(package);
|
||||
|
||||
tasks.push(
|
||||
{
|
||||
title: `${package}: update package.json ${tc.dim(`(${version})`)}`,
|
||||
task: async () => {
|
||||
await execa('npm', ['version', version], { cwd: projectRoot });
|
||||
}
|
||||
tasks.push({
|
||||
title: `${package}: update package.json ${tc.dim(`(${version})`)}`,
|
||||
task: async () => {
|
||||
await execa('npm', ['version', version], { cwd: projectRoot });
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function publishPackages(tasks, packages, version, tag = 'latest') {
|
||||
@@ -237,7 +299,7 @@ function publishPackages(tasks, packages, version, tag = 'latest') {
|
||||
title: `${package}: publish to ${tag} tag`,
|
||||
task: async () => {
|
||||
await execa('npm', ['publish', '--tag', tag], { cwd: projectRoot });
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -249,6 +311,9 @@ function updateDependency(pkg, dependency, version) {
|
||||
if (pkg.devDependencies && pkg.devDependencies[dependency]) {
|
||||
pkg.devDependencies[dependency] = version;
|
||||
}
|
||||
if (pkg.peerDependencies && pkg.peerDependencies[dependency]) {
|
||||
pkg.peerDependencies[dependency] = version;
|
||||
}
|
||||
}
|
||||
|
||||
function isVersionGreater(oldVersion, newVersion) {
|
||||
@@ -258,11 +323,20 @@ function isVersionGreater(oldVersion, newVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function copyCDNLoader(tasks, version) {
|
||||
tasks.push({
|
||||
title: `Copy CDN loader`,
|
||||
task: () => execa('node', ['copy-cdn-loader.js', version], { cwd: path.join(rootDir, 'core', 'scripts') })
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
checkTestDist,
|
||||
checkGit,
|
||||
askNpmTag,
|
||||
isValidVersion,
|
||||
isVersionGreater,
|
||||
copyCDNLoader,
|
||||
packages,
|
||||
packagePath,
|
||||
prepareDevPackage,
|
||||
@@ -274,5 +348,5 @@ module.exports = {
|
||||
updateDependency,
|
||||
updatePackageVersion,
|
||||
updatePackageVersions,
|
||||
writePkg,
|
||||
writePkg
|
||||
};
|
||||
|
||||
@@ -107,15 +107,17 @@ async function preparePackages(packages, version, install) {
|
||||
});
|
||||
|
||||
// add update package.json of each project
|
||||
packages.forEach(package => {
|
||||
common.updatePackageVersion(tasks, package, version);
|
||||
});
|
||||
common.updatePackageVersions(tasks, packages, version);
|
||||
|
||||
// generate changelog
|
||||
generateChangeLog(tasks);
|
||||
|
||||
// check dist folders
|
||||
common.checkTestDist(tasks);
|
||||
|
||||
// update core readme with version number
|
||||
updateCoreReadme(tasks, version);
|
||||
common.copyCDNLoader(tasks, version);
|
||||
|
||||
const listr = new Listr(tasks, { showSubtasks: true });
|
||||
await listr.run();
|
||||
@@ -171,7 +173,6 @@ function updateCoreReadme(tasks, version) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const SEMVER_INCREMENTS = ['patch', 'minor', 'major'];
|
||||
|
||||
const isValidVersionInput = input => SEMVER_INCREMENTS.indexOf(input) !== -1 || common.isValidVersion(input);
|
||||
|
||||
@@ -38,6 +38,7 @@ async function main() {
|
||||
packages.forEach(package => {
|
||||
common.prepareDevPackage(tasks, package, devVersion);
|
||||
});
|
||||
common.copyCDNLoader(tasks, devVersion);
|
||||
common.publishPackages(tasks, packages, devVersion, DIST_NPM_TAG);
|
||||
|
||||
const listr = new Listr(tasks);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
const tc = require('turbocolor');
|
||||
const execa = require('execa');
|
||||
const Listr = require('listr');
|
||||
const path = require('path');
|
||||
const octokit = require('@octokit/rest')()
|
||||
const common = require('./common');
|
||||
const fs = require('fs-extra');
|
||||
@@ -12,10 +13,14 @@ const fs = require('fs-extra');
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const dryRun = process.argv.indexOf('--dry-run') > -1;
|
||||
|
||||
if (!process.env.GH_TOKEN) {
|
||||
throw new Error('env.GH_TOKEN is undefined');
|
||||
}
|
||||
|
||||
checkProductionRelease();
|
||||
|
||||
const tasks = [];
|
||||
const { version } = common.readPkg('core');
|
||||
const changelog = findChangelog();
|
||||
@@ -23,15 +28,31 @@ async function main() {
|
||||
// repo must be clean
|
||||
common.checkGit(tasks);
|
||||
|
||||
// publish each package in NPM
|
||||
common.publishPackages(tasks, common.packages, version);
|
||||
const { npmTag, confirm } = await common.askNpmTag(version);
|
||||
|
||||
// push tag to git remote
|
||||
publishGit(tasks, version, changelog);
|
||||
if (!confirm) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!dryRun) {
|
||||
// publish each package in NPM
|
||||
common.publishPackages(tasks, common.packages, version, npmTag);
|
||||
|
||||
// push tag to git remote
|
||||
publishGit(tasks, version, changelog, npmTag);
|
||||
}
|
||||
|
||||
const listr = new Listr(tasks);
|
||||
await listr.run();
|
||||
console.log(`\nionic ${version} published!! 🎉\n`);
|
||||
|
||||
// Dry run doesn't publish to npm or git
|
||||
if (dryRun) {
|
||||
console.log(`
|
||||
\n${tc.yellow('Did not publish. Remove the "--dry-run" flag to publish:')}\n${tc.green(version)} to ${tc.cyan(npmTag)}\n
|
||||
`);
|
||||
} else {
|
||||
console.log(`\nionic ${version} published to ${npmTag}!! 🎉\n`);
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.log('\n', tc.red(err), '\n');
|
||||
@@ -39,6 +60,15 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkProductionRelease() {
|
||||
const corePath = common.projectPath('core');
|
||||
const hasEsm = fs.existsSync(path.join(corePath, 'dist', 'esm'));
|
||||
const hasEsmEs5 = fs.existsSync(path.join(corePath, 'dist', 'esm-es5'));
|
||||
const hasCjs = fs.existsSync(path.join(corePath, 'dist', 'cjs'));
|
||||
if (!hasEsm || !hasEsmEs5 || !hasCjs) {
|
||||
throw new Error('core build is not a production build');
|
||||
}
|
||||
}
|
||||
|
||||
function publishGit(tasks, version, changelog) {
|
||||
const tag = `v${version}`;
|
||||
@@ -54,7 +84,7 @@ function publishGit(tasks, version, changelog) {
|
||||
},
|
||||
{
|
||||
title: 'Push tags to remove',
|
||||
task: () => execa('git', ['push', '--tags'], { cwd: common.rootDir })
|
||||
task: () => execa('git', ['push', '--follow-tags'], { cwd: common.rootDir })
|
||||
},
|
||||
{
|
||||
title: 'Publish Github release',
|
||||
|
||||
82
.scripts/test-dist.js
Normal file
82
.scripts/test-dist.js
Normal file
@@ -0,0 +1,82 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// Test dist build:
|
||||
// Double-triple check all the packages
|
||||
// and files are good to go before publishing
|
||||
[
|
||||
// core
|
||||
{
|
||||
files: ['../core/dist/index.js', '../core/dist/ionic/index.esm.js']
|
||||
},
|
||||
// angular
|
||||
{
|
||||
files: ['../angular/dist/fesm5.cjs.js']
|
||||
},
|
||||
// react
|
||||
{
|
||||
files: ['../packages/react/dist/index.js']
|
||||
},
|
||||
// react-router
|
||||
{
|
||||
files: ['../packages/react-router/dist/index.js']
|
||||
}
|
||||
].forEach(testPackage);
|
||||
|
||||
function testPackage(testPkg) {
|
||||
if (testPkg.packageJson) {
|
||||
const pkgDir = path.dirname(testPkg.packageJson);
|
||||
const pkgJson = require(testPkg.packageJson);
|
||||
|
||||
if (!pkgJson.name) {
|
||||
throw new Error('missing package.json name: ' + testPkg.packageJson);
|
||||
}
|
||||
|
||||
if (!pkgJson.main) {
|
||||
throw new Error('missing package.json main: ' + testPkg.packageJson);
|
||||
}
|
||||
|
||||
const pkgPath = path.join(pkgDir, pkgJson.main);
|
||||
const pkgImport = require(pkgPath);
|
||||
|
||||
if (testPkg.files) {
|
||||
if (!Array.isArray(pkgJson.files)) {
|
||||
throw new Error(testPkg.packageJson + ' missing "files" property');
|
||||
}
|
||||
testPkg.files.forEach(testPkgFile => {
|
||||
if (!pkgJson.files.includes(testPkgFile)) {
|
||||
throw new Error(testPkg.packageJson + ' missing file ' + testPkgFile);
|
||||
}
|
||||
|
||||
const filePath = path.join(__dirname, pkgDir, testPkgFile);
|
||||
fs.accessSync(filePath);
|
||||
});
|
||||
}
|
||||
|
||||
if (pkgJson.module) {
|
||||
const moduleIndex = path.join(__dirname, pkgDir, pkgJson.module);
|
||||
fs.accessSync(moduleIndex);
|
||||
}
|
||||
|
||||
if (pkgJson.types) {
|
||||
const pkgTypes = path.join(__dirname, pkgDir, pkgJson.types);
|
||||
fs.accessSync(pkgTypes);
|
||||
}
|
||||
|
||||
if (testPkg.exports) {
|
||||
testPkg.exports.forEach(exportName => {
|
||||
const m = pkgImport[exportName];
|
||||
if (!m) {
|
||||
throw new Error('export "' + exportName + '" not found in: ' + testPkg.packageJson);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (testPkg.files) {
|
||||
testPkg.files.forEach(file => {
|
||||
const filePath = path.join(__dirname, file);
|
||||
fs.statSync(filePath);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`✅ test.dist`);
|
||||
425
CHANGELOG.md
425
CHANGELOG.md
@@ -1,3 +1,428 @@
|
||||
## [4.11.13](https://github.com/ionic-team/ionic/compare/v4.11.12...v4.11.13) (2020-10-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** do not set ampm when the column doesn't exist ([#22224](https://github.com/ionic-team/ionic/issues/22224)) ([210db5b](https://github.com/ionic-team/ionic/commit/210db5b265c04dcdc847f173503c5c096fdb3374))
|
||||
|
||||
|
||||
|
||||
## [4.11.12](https://github.com/ionic-team/ionic/compare/v4.11.11...v4.11.12) (2020-09-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** remove the automatic switching from am to pm and vice versa ([#22208](https://github.com/ionic-team/ionic/issues/22208)) ([0d56c51](https://github.com/ionic-team/ionic/commit/0d56c5166497de38df9be432f8c7577b4b6c0e94)), closes [#18924](https://github.com/ionic-team/ionic/issues/18924)
|
||||
|
||||
|
||||
|
||||
## [4.11.11](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.11) (2020-09-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** do not reset to am when changing the hour and pm is set ([#22016](https://github.com/ionic-team/ionic/issues/22016)) ([1dac5a4](https://github.com/ionic-team/ionic/commit/1dac5a46f5e5adad9638e4e4e901bae1058c7287)), closes [#19175](https://github.com/ionic-team/ionic/issues/19175) [#19260](https://github.com/ionic-team/ionic/issues/19260) [#20026](https://github.com/ionic-team/ionic/issues/20026) [#16630](https://github.com/ionic-team/ionic/issues/16630)
|
||||
|
||||
|
||||
## [4.11.10](https://github.com/ionic-team/ionic/compare/v4.11.9...v4.11.10) (2020-01-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **input:** revert previous type change ([db1fd1d](https://github.com/ionic-team/ionic/commit/db1fd1d72a8a0ade824ad2309d1adb2953731f37))
|
||||
|
||||
|
||||
|
||||
## [4.11.9](https://github.com/ionic-team/ionic/compare/v4.11.8...v4.11.9) (2020-01-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** updating type of input value to accept numbers, fixes [#20173](https://github.com/ionic-team/ionic/issues/20173) ([#20267](https://github.com/ionic-team/ionic/issues/20267)) ([7080205](https://github.com/ionic-team/ionic/commit/708020551f9c51ca3b32d7b49bf4572db3dda12e))
|
||||
* **react:** adding missing overlay component events, fixes [#19923](https://github.com/ionic-team/ionic/issues/19923) ([#20266](https://github.com/ionic-team/ionic/issues/20266)) ([ec6a8dd](https://github.com/ionic-team/ionic/commit/ec6a8dd86f3854edba367f79a6ebac7d60eed839))
|
||||
* **react:** Don't render overlay children if isOpen is false, fixes [#20225](https://github.com/ionic-team/ionic/issues/20225) ([#20226](https://github.com/ionic-team/ionic/issues/20226)) ([aff9612](https://github.com/ionic-team/ionic/commit/aff9612d1197dca48eab6eff9d749032c380cf82))
|
||||
* **react:** re attach props on update, fixes 20192 ([#20228](https://github.com/ionic-team/ionic/issues/20228)) ([9e35ebe](https://github.com/ionic-team/ionic/commit/9e35ebed4a1590ef2521f5f8c393bdd9dea32a04))
|
||||
* **react:** remove leaving view when routerdirection is back, fixes [#20124](https://github.com/ionic-team/ionic/issues/20124) ([#20268](https://github.com/ionic-team/ionic/issues/20268)) ([63d4e87](https://github.com/ionic-team/ionic/commit/63d4e877fb18c90d70c4cbd5f66ffccb8ee6489c))
|
||||
* **react:** support routes without a path for notfound routes, fixes [#20259](https://github.com/ionic-team/ionic/issues/20259) ([#20261](https://github.com/ionic-team/ionic/issues/20261)) ([2f8c13b](https://github.com/ionic-team/ionic/commit/2f8c13b6960f9bcfb941c36fa6e1742b96f80ba9))
|
||||
* **react:** update icon types to be a string as well, fixes [#20229](https://github.com/ionic-team/ionic/issues/20229) ([#20230](https://github.com/ionic-team/ionic/issues/20230)) ([1411d8a](https://github.com/ionic-team/ionic/commit/1411d8a173bfefd7db5241218fd5641b7e9da823))
|
||||
|
||||
|
||||
|
||||
## [4.11.8](https://github.com/ionic-team/ionic/compare/v4.11.7...v4.11.8) (2020-01-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** add missing react memory router ([8a5aba2](https://github.com/ionic-team/ionic/commit/8a5aba206865ce2af7f8bb85f4e7cd8dec37831d))
|
||||
* **react:** fixing type of icon in ToastOptions, ActionSheetOptions, fixes [#20100](https://github.com/ionic-team/ionic/issues/20100) ([857bab6](https://github.com/ionic-team/ionic/commit/857bab66419a851c6d189cd1456cd67c1c2d934c))
|
||||
* **react:** supporting ios and md props on icons ([#20170](https://github.com/ionic-team/ionic/issues/20170)) ([676cc19](https://github.com/ionic-team/ionic/commit/676cc19b89cd6374346aaac9cc3292872c7148fa))
|
||||
|
||||
|
||||
|
||||
## [4.11.7](https://github.com/ionic-team/ionic/compare/v4.11.6...v4.11.7) (2019-12-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** fire lifecycle events on initial render, fixes [#20071](https://github.com/ionic-team/ionic/issues/20071) ([9ea75eb](https://github.com/ionic-team/ionic/commit/9ea75ebec7b1367fc0e319fe61c1f42516357e10))
|
||||
|
||||
|
||||
|
||||
## [4.11.6](https://github.com/ionic-team/ionic/compare/v4.11.5...v4.11.6) (2019-12-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** don't show back button when not appropriate ([684293d](https://github.com/ionic-team/ionic/commit/684293ddbf1ad4edce590d56f7ff66fcd6c817a5))
|
||||
* **react:** first render performance improvements ([1c7d1e5](https://github.com/ionic-team/ionic/commit/1c7d1e5cf1ad7e53ebbee2566e8fa89f567f7fb5))
|
||||
* **react:** fix refs for controllers, overlays, ionpage, and ionrouteroutlet, fixes [#19924](https://github.com/ionic-team/ionic/issues/19924) ([#20012](https://github.com/ionic-team/ionic/issues/20012)) ([eef55bb](https://github.com/ionic-team/ionic/commit/eef55bb0072a9e54b1fd7d1c8c69e7fd43b2a5c5))
|
||||
* **react:** support for 'root' router direction, fixes [#19982](https://github.com/ionic-team/ionic/issues/19982) ([#20052](https://github.com/ionic-team/ionic/issues/20052)) ([e116712](https://github.com/ionic-team/ionic/commit/e1167122758b23221935e897bcd65839b75c59aa))
|
||||
* **react:** support navigating to same page and route updates in IonRouterOutlet, fixes [#19891](https://github.com/ionic-team/ionic/issues/19891), [#19892](https://github.com/ionic-team/ionic/issues/19892), [#19986](https://github.com/ionic-team/ionic/issues/19986) ([f9bf8db](https://github.com/ionic-team/ionic/commit/f9bf8dbe6f952ee53b6b213a4c0d043d25f49b93))
|
||||
|
||||
### Upgrade Note
|
||||
|
||||
If you run into a "Property 'translate' is missing in type" error building after updating to 4.11.6, update your React Typings library to the latest:
|
||||
|
||||
npm i @types/react@latest @types/react-dom@latest
|
||||
|
||||
## [4.11.5](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.5) (2019-11-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** improved lifecycle hooks to deal with stale closures, fixes [#19873](https://github.com/ionic-team/ionic/issues/19873) ([#19874](https://github.com/ionic-team/ionic/issues/19874)) ([5ff786a](https://github.com/ionic-team/ionic/commit/5ff786a23d5aa32281bbf5daaa7f8156de39caca))
|
||||
|
||||
|
||||
## [4.11.4](https://github.com/ionic-team/ionic/compare/v4.11.1...v4.11.4) (2019-11-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** check for component unmount, fixes [#19859](https://github.com/ionic-team/ionic/issues/19859) ([7356c40](https://github.com/ionic-team/ionic/commit/7356c401742ce2b3241d6ab05fce0fa65d2f1f8a))
|
||||
* **react:** adding multiple subscriptions to lifecycle events, fixes [#19792](https://github.com/ionic-team/ionic/issues/19792) ([#19858](https://github.com/ionic-team/ionic/issues/19858)) ([0a3014d](https://github.com/ionic-team/ionic/commit/0a3014d35e2102570fd3d8c5ada29eb01aab18e9))
|
||||
* **react:** add check to warn if no ionpage is found, fixes [#19832](https://github.com/ionic-team/ionic/issues/19832) ([#19857](https://github.com/ionic-team/ionic/issues/19857)) ([628e766](https://github.com/ionic-team/ionic/commit/628e76668ea72baebdb02b9dcfe24c0da837fb08))
|
||||
* **react:** expand the location stack to better support back button, fixes [#19748](https://github.com/ionic-team/ionic/issues/19748) ([#19856](https://github.com/ionic-team/ionic/issues/19856)) ([d89508b](https://github.com/ionic-team/ionic/commit/d89508b1b58481d518b89362a8792d05f3f451c9))
|
||||
* **react:** adding hardware back button support, fixes(19819) ([#19851](https://github.com/ionic-team/ionic/issues/19851)) ([fd9745d](https://github.com/ionic-team/ionic/commit/fd9745ddcddded76d64220838aef0f599bf4352f))
|
||||
* **react:** adding swipe back functionality and routerOutlet ready improvements, fixes [#19818](https://github.com/ionic-team/ionic/issues/19818) ([#19849](https://github.com/ionic-team/ionic/issues/19849)) ([bcc40c8](https://github.com/ionic-team/ionic/commit/bcc40c8d59b723bbdb1dfd318bfb2219eb8df3cf))
|
||||
* **react:** create a new overlay each time component is presented, fixes [#19841](https://github.com/ionic-team/ionic/issues/19841), [#19823](https://github.com/ionic-team/ionic/issues/19823) ([#19842](https://github.com/ionic-team/ionic/issues/19842)) ([9fad416](https://github.com/ionic-team/ionic/commit/9fad4161be4859969e14d4d33169ef022052d6bf))
|
||||
|
||||
|
||||
## [4.11.3](https://github.com/ionic-team/ionic/compare/v4.11.1...v4.11.3) (2019-10-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** adding change events to iontabs, fixes [#19665](https://github.com/ionic-team/ionic/issues/19665) ([#19711](https://github.com/ionic-team/ionic/issues/19711)) ([b7baf24](https://github.com/ionic-team/ionic/commit/b7baf24e5053a379156e6c3d82c2b5d3afa999f1))
|
||||
* **react:** adding HashRouter to available ion routers, fixes [#19621](https://github.com/ionic-team/ionic/issues/19621) ([#19683](https://github.com/ionic-team/ionic/issues/19683)) ([fcdbb3c](https://github.com/ionic-team/ionic/commit/fcdbb3ce98747d3b37107904ca110daad95e48bc))
|
||||
* **react:** checking if node is actually an element before treating it like one, fixes [#19769](https://github.com/ionic-team/ionic/issues/19769) ([#19783](https://github.com/ionic-team/ionic/issues/19783)) ([9d0caf6](https://github.com/ionic-team/ionic/commit/9d0caf6de070145c4af618847b27e24c49027b8e))
|
||||
* **react:** checking isOpen again after async call before opening overlay, fixes [#19755](https://github.com/ionic-team/ionic/issues/19755) ([f70e71a](https://github.com/ionic-team/ionic/commit/f70e71a3d461cdab65626a5a7e1b6f4d03b852b1))
|
||||
* **react:** don't remove current view, provide a better method to determine showGoBack fixes [#19731](https://github.com/ionic-team/ionic/issues/19731) and [#19732](https://github.com/ionic-team/ionic/issues/19732) ([31c754d](https://github.com/ionic-team/ionic/commit/31c754dab7ada494ff5f0026d5cf3f7f65198eff))
|
||||
* **react:** removing pages from DOM on nav, fixes [#19701](https://github.com/ionic-team/ionic/issues/19701) ([#19712](https://github.com/ionic-team/ionic/issues/19712)) ([ee21d3a](https://github.com/ionic-team/ionic/commit/ee21d3ae43d8c6b076387a58bca655a56c920bcd))
|
||||
* **react:** unmount leaving view when using browser back button, fixes [#19749](https://github.com/ionic-team/ionic/issues/19749) ([#19781](https://github.com/ionic-team/ionic/issues/19781)) ([2dc5540](https://github.com/ionic-team/ionic/commit/2dc554091056612f1bcd2751d6eeb41cae488751))
|
||||
|
||||
|
||||
|
||||
## [4.11.2](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.2) (2019-10-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** ensure all elements are cleaned up when calling .destroy() ([#19654](https://github.com/ionic-team/ionic/issues/19654)) ([d97e167](https://github.com/ionic-team/ionic/commit/d97e167))
|
||||
* **header:** collapsible header works in tabs ([#19658](https://github.com/ionic-team/ionic/issues/19658)) ([4853909](https://github.com/ionic-team/ionic/commit/4853909)), closes [#19640](https://github.com/ionic-team/ionic/issues/19640)
|
||||
* **ios:** hide leaving view after nav transition to avoid flicker ([#19691](https://github.com/ionic-team/ionic/issues/19691)) ([70e0562](https://github.com/ionic-team/ionic/commit/70e0562)), closes [#19674](https://github.com/ionic-team/ionic/issues/19674)
|
||||
* **menu:** clamp out of bounds swipe value ([#19684](https://github.com/ionic-team/ionic/issues/19684)) ([1535e95](https://github.com/ionic-team/ionic/commit/1535e95)), closes [#18927](https://github.com/ionic-team/ionic/issues/18927)
|
||||
* **react:** add IonPicker as controller component, fixes [#19620](https://github.com/ionic-team/ionic/issues/19620) ([#19643](https://github.com/ionic-team/ionic/issues/19643)) ([ed98d9e](https://github.com/ionic-team/ionic/commit/ed98d9e))
|
||||
* **react:** adding change events to IonTabs, fixes [#19665](https://github.com/ionic-team/ionic/issues/19665) ([#19711](https://github.com/ionic-team/ionic/issues/19711)) ([b7baf24](https://github.com/ionic-team/ionic/commit/b7baf24))
|
||||
* **react:** adding HashRouter to available ion routers, fixes [#19621](https://github.com/ionic-team/ionic/issues/19621) ([#19683](https://github.com/ionic-team/ionic/issues/19683)) ([fcdbb3c](https://github.com/ionic-team/ionic/commit/fcdbb3c))
|
||||
* **react:** pages no longer hidden when navigating between tabs, fixes [#19646](https://github.com/ionic-team/ionic/issues/19646) ([#19647](https://github.com/ionic-team/ionic/issues/19647)) ([8776556](https://github.com/ionic-team/ionic/commit/8776556))
|
||||
* **react:** ensure views are removed from DOM after navigating back, fixes [#19701](https://github.com/ionic-team/ionic/issues/19701) ([#19712](https://github.com/ionic-team/ionic/issues/19712)) ([ee21d3a](https://github.com/ionic-team/ionic/commit/ee21d3a))
|
||||
|
||||
|
||||
|
||||
## [4.11.1](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.1) (2019-10-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **build:** properly update peer dependencies ([#19639](https://github.com/ionic-team/ionic/issues/19639)) ([b552daa](https://github.com/ionic-team/ionic/commit/b552daa))
|
||||
* **react:** add IonPicker as controller component, fixes [#19620](https://github.com/ionic-team/ionic/issues/19620) ([#19643](https://github.com/ionic-team/ionic/issues/19643)) ([ed98d9e](https://github.com/ionic-team/ionic/commit/ed98d9e))
|
||||
* **react:** handle tab back nav better, fixes [#19646](https://github.com/ionic-team/ionic/issues/19646) ([#19647](https://github.com/ionic-team/ionic/issues/19647)) ([8776556](https://github.com/ionic-team/ionic/commit/8776556))
|
||||
* **react:** moving tslint and friends to devDependencies ([#19624](https://github.com/ionic-team/ionic/issues/19624)) ([7f4b77d](https://github.com/ionic-team/ionic/commit/7f4b77d))
|
||||
|
||||
|
||||
|
||||
# [4.11.0 Sodium](https://github.com/ionic-team/ionic/compare/v4.10.3...v4.11.0) (2019-10-09)
|
||||
|
||||
Ionic React! Enjoy! 🧂 🌊 🐼
|
||||
|
||||
## [4.10.3](https://github.com/ionic-team/ionic/compare/v4.10.2...v4.10.3) (2019-10-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **content:** set overscroll only on iOS ([#19470](https://github.com/ionic-team/ionic/issues/19470)) ([63c2008](https://github.com/ionic-team/ionic/commit/63c2008a86de19847677fda7b9fedce73ed7669f)), closes [#19465](https://github.com/ionic-team/ionic/issues/19465)
|
||||
* **searchbar:** update alignment of chips and other elements in toolbar ([#19596](https://github.com/ionic-team/ionic/issues/19596)) ([637f26b](https://github.com/ionic-team/ionic/commit/637f26b3642a266b6ef3b9d3d71b7327a5d3cc37)), closes [#19495](https://github.com/ionic-team/ionic/issues/19495) [#19502](https://github.com/ionic-team/ionic/issues/19502)
|
||||
|
||||
|
||||
|
||||
## [4.10.2](https://github.com/ionic-team/ionic/compare/v4.10.1...v4.10.2) (2019-10-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **overlay:** ensure lifecycle events fire properly ([#19579](https://github.com/ionic-team/ionic/issues/19579)) ([a7b9642](https://github.com/ionic-team/ionic/commit/a7b9642)), closes [#19576](https://github.com/ionic-team/ionic/issues/19576)
|
||||
|
||||
|
||||
|
||||
## [4.10.1](https://github.com/ionic-team/ionic/compare/v4.10.0...v4.10.1) (2019-10-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animation:** animation timer fallback now accounts for iterations ([#19527](https://github.com/ionic-team/ionic/issues/19527)) ([9f5ed23](https://github.com/ionic-team/ionic/commit/9f5ed23))
|
||||
* **css:** update deprecations to remove wrap ([#19535](https://github.com/ionic-team/ionic/issues/19535)) ([bfb704e](https://github.com/ionic-team/ionic/commit/bfb704e)), closes [#19499](https://github.com/ionic-team/ionic/issues/19499)
|
||||
* **header:** fix collapsing iOS header when using with split pane ([#19480](https://github.com/ionic-team/ionic/issues/19480)) ([dea1c26](https://github.com/ionic-team/ionic/commit/dea1c26)), closes [#19541](https://github.com/ionic-team/ionic/issues/19541)
|
||||
* **list:** add bottom border for first item in inset list ([#19525](https://github.com/ionic-team/ionic/issues/19525)) ([71b8853](https://github.com/ionic-team/ionic/commit/71b8853)), closes [#19507](https://github.com/ionic-team/ionic/issues/19507)
|
||||
* **md:** fix flicker when navigating back in MD mode on certain Android devices ([#19553](https://github.com/ionic-team/ionic/issues/19553)) ([19ee21a](https://github.com/ionic-team/ionic/commit/19ee21a)), closes [#19491](https://github.com/ionic-team/ionic/issues/19491)
|
||||
* **searchbar:** update padding and button alignment ([#19532](https://github.com/ionic-team/ionic/issues/19532)) ([77658e6](https://github.com/ionic-team/ionic/commit/77658e6)), closes [#19502](https://github.com/ionic-team/ionic/issues/19502)
|
||||
|
||||
|
||||
|
||||
# [4.10.0 Neon](https://github.com/ionic-team/ionic/compare/v4.9.1...v4.10.0) (2019-09-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** add warning if initialized more than once ([#19393](https://github.com/ionic-team/ionic/issues/19393)) ([e98769e](https://github.com/ionic-team/ionic/commit/e98769e))
|
||||
* **animation:** set property defaults to avoid inconsistencies ([#19321](https://github.com/ionic-team/ionic/issues/19321)) ([1cbb52c](https://github.com/ionic-team/ionic/commit/1cbb52c))
|
||||
* **animation:** fallback to CSS Animations on older versions of Chrome ([#19288](https://github.com/ionic-team/ionic/issues/19288)) ([2d39c07](https://github.com/ionic-team/ionic/commit/2d39c07)), closes [#19272](https://github.com/ionic-team/ionic/issues/19272)
|
||||
* **animation:** animations of duration 0 now run in Safari ([#19287](https://github.com/ionic-team/ionic/issues/19287)) ([4e544f1](https://github.com/ionic-team/ionic/commit/4e544f1)), closes [#19285](https://github.com/ionic-team/ionic/issues/19285)
|
||||
* **components:** fix crash in IE11 when using classList add() or remove() ([#19460](https://github.com/ionic-team/ionic/issues/19460)) ([b4d92c6](https://github.com/ionic-team/ionic/commit/b4d92c6))
|
||||
* **components:** improve CSS Variable support in IE11 ([#19473](https://github.com/ionic-team/ionic/issues/19473)) ([44ad074](https://github.com/ionic-team/ionic/commit/44ad074))
|
||||
* **content:** remove pointer-events from iOS transition shadow ([#19471](https://github.com/ionic-team/ionic/issues/19471)) ([8a52c7d](https://github.com/ionic-team/ionic/commit/8a52c7d)), closes [#19466](https://github.com/ionic-team/ionic/issues/19466)
|
||||
* **menu:** menus show proper drop shadows ([#19454](https://github.com/ionic-team/ionic/issues/19454)) ([eab0865](https://github.com/ionic-team/ionic/commit/eab0865)), closes [#19387](https://github.com/ionic-team/ionic/issues/19387)
|
||||
* **radio-group:** get radios before caching value to avoid infinite loop ([#19448](https://github.com/ionic-team/ionic/issues/19448)) ([cf223e4](https://github.com/ionic-team/ionic/commit/cf223e4)), closes [#19277](https://github.com/ionic-team/ionic/issues/19277)
|
||||
* **react:** update events to use proper types ([c79e74b](https://github.com/ionic-team/ionic/commit/c79e74b))
|
||||
* **router-outlet:** hide leaving view after transition finishes ([#19335](https://github.com/ionic-team/ionic/issues/19335)) ([bfa17d1](https://github.com/ionic-team/ionic/commit/bfa17d1))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **config:** expose getMode() and deprecate Config.set() ([#19104](https://github.com/ionic-team/ionic/issues/19104)) ([0f05ea4](https://github.com/ionic-team/ionic/commit/0f05ea4))
|
||||
* **docs:** add VSCode docs support ([#19309](https://github.com/ionic-team/ionic/issues/19309)) ([a3f345c](https://github.com/ionic-team/ionic/commit/a3f345c))
|
||||
* **title:** add support for small title ([#19215](https://github.com/ionic-team/ionic/issues/19215)) ([e27962d](https://github.com/ionic-team/ionic/commit/e27962d)), closes [#18898](https://github.com/ionic-team/ionic/issues/18898)
|
||||
* **title:** add support for large title (experimental) ([#19268](https://github.com/ionic-team/ionic/issues/19268)) ([923312e](https://github.com/ionic-team/ionic/commit/923312e)), closes [#16885](https://github.com/ionic-team/ionic/issues/16885)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **animation:** avoid ngzone with requestAnimationFrame ([#19457](https://github.com/ionic-team/ionic/issues/19457)) ([8ca97ce](https://github.com/ionic-team/ionic/commit/8ca97ce))
|
||||
|
||||
|
||||
|
||||
## [4.9.1](https://github.com/ionic-team/ionic/compare/v4.9.0...v4.9.1) (2019-09-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **platform:** properly detect iPads running iPadOS ([#19258](https://github.com/ionic-team/ionic/issues/19258)) ([4a90096](https://github.com/ionic-team/ionic/commit/4a90096))
|
||||
|
||||
|
||||
|
||||
# [4.9.0 Fluorine](https://github.com/ionic-team/ionic/compare/v4.8.1...v4.9.0) (2019-09-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **all:** allow elements to be reused once removed from the DOM ([#18963](https://github.com/ionic-team/ionic/pull/18963)) ([48a2763](https://github.com/ionic-team/ionic/commit/48a2763)), closes [#18843](https://github.com/ionic-team/ionic/issues/18843) [#17344](https://github.com/ionic-team/ionic/issues/17344) [#16453](https://github.com/ionic-team/ionic/issues/16453) [#15879](https://github.com/ionic-team/ionic/issues/15879) [#15788](https://github.com/ionic-team/ionic/issues/15788) [#15484](https://github.com/ionic-team/ionic/issues/15484) [#17890](https://github.com/ionic-team/ionic/issues/17890) [#16364](https://github.com/ionic-team/ionic/issues/16364)
|
||||
* **animation:** add correct `onFinish` interface parameters ([#19199](https://github.com/ionic-team/ionic/issues/19199)) ([a81653b](https://github.com/ionic-team/ionic/commit/a81653b))
|
||||
* **animation:** improve Web Animation feature detection accuracy ([#19212](https://github.com/ionic-team/ionic/issues/19212)) ([6eca5b0](https://github.com/ionic-team/ionic/commit/6eca5b0)), closes [#19205](https://github.com/ionic-team/ionic/issues/19205)
|
||||
* **animation:** properly clean up elements when using `destroy` ([#19210](https://github.com/ionic-team/ionic/issues/19210)) ([93f2064](https://github.com/ionic-team/ionic/commit/93f2064))
|
||||
* **segment:** do not emit ionChange until didLoad ([#19218](https://github.com/ionic-team/ionic/issues/19218)) ([9751f14](https://github.com/ionic-team/ionic/commit/9751f14)), closes [#19204](https://github.com/ionic-team/ionic/issues/19204)
|
||||
|
||||
### Features
|
||||
|
||||
* **nav-link:** add `nav-link` and deprecate `nav-push`, `nav-pop`, and `nav-set-root` ([#18909](https://github.com/ionic-team/ionic/issues/18909)) ([c3044f5](https://github.com/ionic-team/ionic/commit/c3044f5))
|
||||
* **slides:** expose full Swiper API ([#19137](https://github.com/ionic-team/ionic/issues/19137)) ([e1fa461](https://github.com/ionic-team/ionic/commit/e1fa461))
|
||||
|
||||
|
||||
|
||||
## [4.8.1](https://github.com/ionic-team/ionic/compare/v4.8.0...v4.8.1) (2019-08-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animation:** enable backwards compatibility for overlay animations ([#19160](https://github.com/ionic-team/ionic/issues/19160)) ([fb70980](https://github.com/ionic-team/ionic/commit/fb70980))
|
||||
* **gesture:** account for negative step values with Web Animations ([#19196](https://github.com/ionic-team/ionic/issues/19196)) ([b3c7436](https://github.com/ionic-team/ionic/commit/b3c7436))
|
||||
* **ios:** clear opacity on toolbar background after iOS transition ([#19169](https://github.com/ionic-team/ionic/issues/19169)) ([fa958a5](https://github.com/ionic-team/ionic/commit/fa958a5))
|
||||
* **md:** set fill mode on MD transition to `both` ([#19161](https://github.com/ionic-team/ionic/issues/19161)) ([0e8ab49](https://github.com/ionic-team/ionic/commit/0e8ab49))
|
||||
|
||||
|
||||
|
||||
# [4.8.0 Oxygen](https://github.com/ionic-team/ionic/compare/v4.7.4...v4.8.0) (2019-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **alert:** apply styling to disabled items ([#18545](https://github.com/ionic-team/ionic/issues/18545)) ([67ed89d](https://github.com/ionic-team/ionic/commit/67ed89d))
|
||||
* **platform:** properly detect Electron platform ([#19044](https://github.com/ionic-team/ionic/issues/19044)) ([e8cdda0](https://github.com/ionic-team/ionic/commit/e8cdda0)), closes [#19043](https://github.com/ionic-team/ionic/issues/19043)
|
||||
* **toggle:** change background to use CSS variable ([#19012](https://github.com/ionic-team/ionic/issues/19012)) ([94e525c](https://github.com/ionic-team/ionic/commit/94e525c)), closes [#18940](https://github.com/ionic-team/ionic/issues/18940)
|
||||
* **transition:** enable iOS transition shadow by default ([#19051](https://github.com/ionic-team/ionic/issues/19051)) ([a5d3c6b](https://github.com/ionic-team/ionic/commit/a5d3c6b))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **animation:** add animation utility (experimental) ([#18918](https://github.com/ionic-team/ionic/issues/18918)) ([30ca46a](https://github.com/ionic-team/ionic/commit/30ca46a))
|
||||
* **gesture:** add gesture utility (experimental) ([#18918](https://github.com/ionic-team/ionic/issues/18918)) ([30ca46a](https://github.com/ionic-team/ionic/commit/30ca46a))
|
||||
* **searchbar:** add `inputmode` property ([#18980](https://github.com/ionic-team/ionic/issues/18980)) ([1187dc2](https://github.com/ionic-team/ionic/commit/1187dc2))
|
||||
* **spinner:** add circular spinner for MD default ([#19052](https://github.com/ionic-team/ionic/issues/19052)) ([e33cf85](https://github.com/ionic-team/ionic/commit/e33cf85))
|
||||
|
||||
|
||||
|
||||
## [4.7.4](https://github.com/ionic-team/ionic/compare/v4.7.3...v4.7.4) (2019-08-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** remove extra semicolons being rendered ([#19033](https://github.com/ionic-team/ionic/issues/19033)) ([39f0768](https://github.com/ionic-team/ionic/commit/39f0768))
|
||||
|
||||
|
||||
|
||||
## [4.7.3](https://github.com/ionic-team/ionic/compare/v4.7.2...v4.7.3) (2019-08-07)
|
||||
|
||||
* **core:** fix an issue with production builds of `@ionic/core`
|
||||
|
||||
|
||||
|
||||
## [4.7.2](https://github.com/ionic-team/ionic/compare/v4.7.1...v4.7.2) (2019-08-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** hardware back button subscribeWithPriority triggers change detection ([#18962](https://github.com/ionic-team/ionic/issues/18962)) ([3a22105](https://github.com/ionic-team/ionic/commit/3a22105)), closes [#18959](https://github.com/ionic-team/ionic/issues/18959)
|
||||
* **angular:** nested inputs no longer conflict with each other ([#18976](https://github.com/ionic-team/ionic/issues/18976)) ([6bbdb80](https://github.com/ionic-team/ionic/commit/6bbdb80)), closes [#18248](https://github.com/ionic-team/ionic/issues/18248)
|
||||
* **range:** ion-range value now submitted with form ([#19008](https://github.com/ionic-team/ionic/issues/19008)) ([8f7853c](https://github.com/ionic-team/ionic/commit/8f7853c))
|
||||
* **reorder:** only move item if reorder happens ([#19007](https://github.com/ionic-team/ionic/issues/19007)) ([d237e80](https://github.com/ionic-team/ionic/commit/d237e80))
|
||||
* **router:** partial swipe to go back gesture no longer breaks view([#18977](https://github.com/ionic-team/ionic/issues/18977)) ([713ea8a](https://github.com/ionic-team/ionic/commit/713ea8a)), closes [#18462](https://github.com/ionic-team/ionic/issues/18462)
|
||||
* **toast:** allow loading ion-icon from asset path ([#18969](https://github.com/ionic-team/ionic/issues/18969)) ([23f327e](https://github.com/ionic-team/ionic/commit/23f327e))
|
||||
* **vue:** rename swipeEnable to swipeGesture ([#17346](https://github.com/ionic-team/ionic/issues/17346)) ([c2348f7](https://github.com/ionic-team/ionic/commit/c2348f7)), closes [#16002](https://github.com/ionic-team/ionic/issues/16002)
|
||||
|
||||
|
||||
|
||||
## [4.7.1](https://github.com/ionic-team/ionic/compare/v4.7.0...v4.7.1) (2019-07-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** ensure change detection fires properly ([#18896](https://github.com/ionic-team/ionic/issues/18896)) ([962783b](https://github.com/ionic-team/ionic/commit/962783b)), closes [#18894](https://github.com/ionic-team/ionic/issues/18894)
|
||||
|
||||
|
||||
|
||||
# [4.7.0 Nitrogen](https://github.com/ionic-team/ionic/compare/v4.6.2...v4.7.0) (2019-07-24)
|
||||
|
||||
|
||||
### Angular 8 Support
|
||||
|
||||
With this version comes support for Angular 8! Follow the below steps to update.
|
||||
|
||||
1. Update `@ionic/angular` and `@ionic/angular-toolkit` to the latest releases:
|
||||
|
||||
```shell
|
||||
$ npm install @ionic/angular@4.7.0
|
||||
$ npm install @ionic/angular-toolkit@2.0.0 -D
|
||||
```
|
||||
|
||||
2. Update `@angular/core` and `@angular/cli`:
|
||||
|
||||
```shell
|
||||
$ npx ng update @angular/core @angular/cli
|
||||
```
|
||||
|
||||
3. Update `@angular-devkit` dependencies:
|
||||
|
||||
```shell
|
||||
$ npm i @angular-devkit/architect@latest @angular-devkit/build-angular@latest @angular-devkit/core@latest @angular-devkit/schematics@latest
|
||||
```
|
||||
|
||||
View our [Angular 8 Update Guide](https://docs.google.com/document/d/1QOpQeDifPSg6F9WycDLcbQnpqjN96ew-Ap0_CB7CcCQ/edit?usp=sharing) for tips on potential issues!
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** copy input form classes to parent ion-item ([#18820](https://github.com/ionic-team/ionic/issues/18820)) ([53179c4](https://github.com/ionic-team/ionic/commit/53179c4)), closes [#18800](https://github.com/ionic-team/ionic/issues/18800)
|
||||
* **angular:** add the swipeGesture method for enabling or disabling the ability to swipe open a menu ([#18806](https://github.com/ionic-team/ionic/issues/18806)) ([fbfc076](https://github.com/ionic-team/ionic/commit/fbfc076)), closes [#16002](https://github.com/ionic-team/ionic/issues/16002)
|
||||
* **angular:** webview "pause", "resume", and "resize" events now trigger change detection ([#18853](https://github.com/ionic-team/ionic/issues/18853)) ([544e550](https://github.com/ionic-team/ionic/commit/544e550)), closes [#18831](https://github.com/ionic-team/ionic/issues/18831)
|
||||
* **core:** apply translucent if backdrop-filter is supported ([#18832](https://github.com/ionic-team/ionic/issues/18832)) ([6b5a59d](https://github.com/ionic-team/ionic/commit/6b5a59d)), closes [ionic-team/ionic-docs#666](https://github.com/ionic-team/ionic-docs/issues/666)
|
||||
* **datetime:** allow AM/PM to be changed ([#18684](https://github.com/ionic-team/ionic/issues/18684)) ([b7761fe](https://github.com/ionic-team/ionic/commit/b7761fe)), closes [#18585](https://github.com/ionic-team/ionic/issues/18585)
|
||||
* **datetime:** properly apply disabled classes when updating columns ([#18875](https://github.com/ionic-team/ionic/issues/18875)) ([7ba718c](https://github.com/ionic-team/ionic/commit/7ba718c)), closes [#18793](https://github.com/ionic-team/ionic/issues/18793)
|
||||
* **hardware-back-button:** hardware back button no longer erroneously restarts app ([#18794](https://github.com/ionic-team/ionic/issues/18794)) ([978cc39](https://github.com/ionic-team/ionic/commit/978cc39)), closes [#18792](https://github.com/ionic-team/ionic/issues/18792)
|
||||
* **ripple-effect:** ensure ripple is removed from components after pointer release ([#18854](https://github.com/ionic-team/ionic/issues/18854)) ([71137a2](https://github.com/ionic-team/ionic/commit/71137a2)), closes [#18836](https://github.com/ionic-team/ionic/issues/18836)
|
||||
* **searchbar:** add aria and role for improved accessibility ([#18797](https://github.com/ionic-team/ionic/issues/18797)) ([798103b](https://github.com/ionic-team/ionic/commit/798103b)), closes [#18796](https://github.com/ionic-team/ionic/issues/18796)
|
||||
* **ssr:** avoid window reference ([#18865](https://github.com/ionic-team/ionic/issues/18865)) ([23ce6fa](https://github.com/ionic-team/ionic/commit/23ce6fa))
|
||||
* **ssr:** check for client runtime method ([#18866](https://github.com/ionic-team/ionic/issues/18866)) ([c52b3b4](https://github.com/ionic-team/ionic/commit/c52b3b4))
|
||||
* **textarea:** autogrow now resets textarea back to original number of rows when text is cleared ([#18822](https://github.com/ionic-team/ionic/issues/18822)) ([26e6d6f](https://github.com/ionic-team/ionic/commit/26e6d6f)), closes [#18744](https://github.com/ionic-team/ionic/issues/18744)
|
||||
* **theming:** update components to use the proper colors for dark themes ([#18735](https://github.com/ionic-team/ionic/issues/18735)) ([045bc59](https://github.com/ionic-team/ionic/commit/045bc59)), closes [#18713](https://github.com/ionic-team/ionic/issues/18713)
|
||||
* **virtual-scroll:** card rendering is no longer distorted ([#18877](https://github.com/ionic-team/ionic/issues/18877)) ([3ef6ecf](https://github.com/ionic-team/ionic/commit/3ef6ecf)), closes [#18870](https://github.com/ionic-team/ionic/issues/18870)
|
||||
* **virtual-scroll:** element dimensions are recalculated on resize ([#18878](https://github.com/ionic-team/ionic/issues/18878)) ([c91819c](https://github.com/ionic-team/ionic/commit/c91819c))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **core:** add support for Stackblitz ([#18846](https://github.com/ionic-team/ionic/issues/18846)) ([fb18f3b](https://github.com/ionic-team/ionic/commit/fb18f3b))
|
||||
* **ssr:** add @ionic/core/hydrate app ([#18867](https://github.com/ionic-team/ionic/issues/18867)) ([815fa2e](https://github.com/ionic-team/ionic/commit/815fa2e))
|
||||
* **navigation:** add experimental shadow to iOS page transitions ([#18695](https://github.com/ionic-team/ionic/issues/18695)) ([9b075ef](https://github.com/ionic-team/ionic/commit/9b075ef)), closes [#18661](https://github.com/ionic-team/ionic/issues/18661)
|
||||
* **virtual-scroll:** adds headerHeight and footerHeight to help prevent flickering ([#18851](https://github.com/ionic-team/ionic/issues/18851)) ([0089111](https://github.com/ionic-team/ionic/commit/0089111)), closes [#17540](https://github.com/ionic-team/ionic/issues/17540)
|
||||
|
||||
|
||||
### Performance
|
||||
|
||||
* **angular:** attach entering view before first change detection and detach leaving page ([#18821](https://github.com/ionic-team/ionic/issues/18821)) ([97fec92](https://github.com/ionic-team/ionic/commit/97fec92))
|
||||
|
||||
|
||||
## [4.6.2](https://github.com/ionic-team/ionic/compare/v4.6.1...v4.6.2) (2019-07-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **menu-button:** hide menu button when auto hide or split pane ([#18702](https://github.com/ionic-team/ionic/issues/18702)) ([24840d4](https://github.com/ionic-team/ionic/commit/24840d4)), closes [#18666](https://github.com/ionic-team/ionic/issues/18666)
|
||||
* **menu-button:** move font-size to host for easier customization ([#18699](https://github.com/ionic-team/ionic/issues/18699)) ([876ab41](https://github.com/ionic-team/ionic/commit/876ab41)), closes [#18667](https://github.com/ionic-team/ionic/issues/18667)
|
||||
* **overlays:** fallback to step color if overlay background variable is unset ([#18709](https://github.com/ionic-team/ionic/issues/18709)) ([f16b118](https://github.com/ionic-team/ionic/commit/f16b118)), closes [#18658](https://github.com/ionic-team/ionic/issues/18658)
|
||||
* **virtual-scroll:** remove runOutsideAngular error ([#18752](https://github.com/ionic-team/ionic/issues/18752)) ([8beeff2](https://github.com/ionic-team/ionic/commit/8beeff2)), closes [#18746](https://github.com/ionic-team/ionic/issues/18746)
|
||||
* **vue:** update imports for types and ionicons ([f56fea6](https://github.com/ionic-team/ionic/commit/f56fea6)), closes [#18701](https://github.com/ionic-team/ionic/issues/18701)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **all:** minify better by using arrow functions ([#18730](https://github.com/ionic-team/ionic/issues/18730)) ([03c1d19](https://github.com/ionic-team/ionic/commit/03c1d19))
|
||||
|
||||
|
||||
|
||||
## [4.6.1](https://github.com/ionic-team/ionic/compare/v4.6.0...v4.6.1) (2019-07-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **app:** add hydrated to hide white screen with multiple ionic dependencies ([#18649](https://github.com/ionic-team/ionic/issues/18649))
|
||||
* **datetime:** datetime no longer reports having a value if none is set ([#18541](https://github.com/ionic-team/ionic/issues/18541)) ([92e0f98](https://github.com/ionic-team/ionic/commit/92e0f98)), closes [#17979](https://github.com/ionic-team/ionic/issues/17979) [#18540](https://github.com/ionic-team/ionic/issues/18540)
|
||||
* **fab-button:** set opacity on disabled fab button ([#18685](https://github.com/ionic-team/ionic/issues/18685)) ([6042b39](https://github.com/ionic-team/ionic/commit/6042b39)), closes [#18682](https://github.com/ionic-team/ionic/issues/18682)
|
||||
* **icon:** load icons properly with baseHref ([#18650](https://github.com/ionic-team/ionic/issues/18650)), ([#18637](https://github.com/ionic-team/ionic/issues/18637))
|
||||
* **icon:** bind icon name properly ([#18707](https://github.com/ionic-team/ionic/issues/18707))
|
||||
* **infinite-scroll:** fix scroll listener ([0d58101](https://github.com/ionic-team/ionic/commit/0d58101))
|
||||
* **item:** do not disable entire item if there are multiple inputs ([#18696](https://github.com/ionic-team/ionic/issues/18696)) ([dfa2b13](https://github.com/ionic-team/ionic/commit/dfa2b13)), closes [#18655](https://github.com/ionic-team/ionic/issues/18655) [#18670](https://github.com/ionic-team/ionic/issues/18670)
|
||||
* **router-link:** add missing target prop ([#18659](https://github.com/ionic-team/ionic/issues/18659)) ([1f51ab2](https://github.com/ionic-team/ionic/commit/1f51ab2)), closes [#18655](https://github.com/ionic-team/ionic/issues/18655)
|
||||
* **router-outlet:** fix swipe to go back ([b69fb69](https://github.com/ionic-team/ionic/commit/b69fb69))
|
||||
* **scss:** copy all scss files ([36a58df](https://github.com/ionic-team/ionic/commit/36a58df))
|
||||
* **searchbar:** proper styling after navigating ([#18642](https://github.com/ionic-team/ionic/issues/18642))
|
||||
* **slides:** use correct order for pushing slides dynamically ([#18633](https://github.com/ionic-team/ionic/issues/18633))
|
||||
* **tabs:** select proper tab by default and do not emit tab change if selectedTab is undefined ([03c834c](https://github.com/ionic-team/ionic/commit/03c834c))
|
||||
* **overlay:** make create opts optional ([44c88ad](https://github.com/ionic-team/ionic/commit/44c88ad))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **angular:** skip zone ([e059fc8](https://github.com/ionic-team/ionic/commit/e059fc8))
|
||||
|
||||
|
||||
|
||||
# [4.6.0 Carbon](https://github.com/ionic-team/ionic/compare/v4.5.0...v4.6.0) (2019-06-26)
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Ionic is based on [Web Components](https://www.webcomponents.org/introduction) a
|
||||
| **Core** | [`@ionic/core`](https://www.npmjs.com/package/@ionic/core) | [](https://www.npmjs.com/package/@ionic/core) | [`README.md`](core/README.md)
|
||||
| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [](https://www.npmjs.com/package/@ionic/angular) | [`README.md`](angular/README.md)
|
||||
| **Vue** | [`@ionic/vue`](https://www.npmjs.com/package/@ionic/vue) | [](https://www.npmjs.com/package/@ionic/vue) | [`README.md`](vue/README.md)
|
||||
| **React** | [`@ionic/react`](https://www.npmjs.com/package/@ionic/react) | [](https://www.npmjs.com/package/@ionic/react) | [`README.md`](react/README.md)
|
||||
| **React** | [`@ionic/react`](https://www.npmjs.com/package/@ionic/react) | [](https://www.npmjs.com/package/@ionic/react) | [`README.md`](packages/react/README.md)
|
||||
|
||||
Looking for the `ionic-angular` package? Ionic 3 has been moved to the [`ionic-v3`](https://github.com/ionic-team/ionic-v3) repo. See [Earlier Versions](#earlier-versions).
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ A list of the breaking changes introduced to each component in Ionic Angular v4.
|
||||
|
||||
## Action Sheet
|
||||
|
||||
The `title`, `subTitle` and `enableBackdropDismiss` properties has been renamed to `header`, `subHeader` and `backdropDismiss` respectively.
|
||||
The `title`, `subTitle` and `enableBackdropDismiss` properties have been renamed to `header`, `subHeader` and `backdropDismiss` respectively.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
@@ -89,7 +89,7 @@ await actionSheet.present();
|
||||
|
||||
## Alert
|
||||
|
||||
The `title`, `subTitle` and `enableBackdropDismiss` properties has been renamed to `header`, `subHeader` and `backdropDismiss` respectively.
|
||||
The `title`, `subTitle` and `enableBackdropDismiss` properties have been renamed to `header`, `subHeader` and `backdropDismiss` respectively.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
@@ -498,7 +498,7 @@ The `<ion-fab>` container was previously placed inside of the fixed content by d
|
||||
|
||||
### Markup Changed
|
||||
|
||||
The Grid has been refactored in order to support css variables and a dynamic number of columns. The following column attributes have been changed.
|
||||
The Grid has been refactored in order to support CSS variables and a dynamic number of columns. The following column attributes have been changed.
|
||||
|
||||
_In the following examples, `{breakpoint}` refers to the optional screen breakpoint (xs, sm, md, lg, xl) and `{value}` refers to the number of columns (`auto` or a number between `1` and `12`)._
|
||||
|
||||
@@ -507,7 +507,7 @@ _In the following examples, `{breakpoint}` refers to the optional screen breakpo
|
||||
- `push-{breakpoint}-{value}` attributes have been renamed to `push-{breakpoint}=“{value}”`
|
||||
- `pull-{breakpoint}-{value}` attributes have been renamed to `pull-{breakpoint}=“{value}”`
|
||||
|
||||
Customizing the padding and width of a grid should now be done with css variables. For more information, see [Grid Layout](https://github.com/ionic-team/ionic-docs/blob/master/src/content/layout/grid.md).
|
||||
Customizing the padding and width of a grid should now be done with CSS variables. For more information, see [Grid Layout](https://github.com/ionic-team/ionic-docs/blob/master/src/content/layout/grid.md).
|
||||
|
||||
## Icon
|
||||
|
||||
@@ -1092,7 +1092,7 @@ openLoading() {
|
||||
```javascript
|
||||
async openLoading() {
|
||||
let loading = this.loadingCtrl.create({
|
||||
content: 'Loading...'
|
||||
message: 'Loading...'
|
||||
});
|
||||
|
||||
await loading.present();
|
||||
@@ -1798,7 +1798,7 @@ To include the stylesheet for testing such as in a Plunker, Codepen, or anywhere
|
||||
|
||||
#### Production
|
||||
|
||||
To use the css in production, we recommend importing it into a global file, such as `app/global.scss`:
|
||||
To use the CSS in production, we recommend importing it into a global file, such as `app/global.scss`:
|
||||
|
||||
```css
|
||||
/** Basic CSS for Ionic Apps */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "4.6.0",
|
||||
"version": "4.11.13",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -19,6 +19,10 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/ionic-team/ionic.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/ionic-team/ionic/issues"
|
||||
},
|
||||
"homepage": "https://ionicframework.com/",
|
||||
"scripts": {
|
||||
"build": "npm run clean && npm run build.core && npm run build.ng && npm run clean-generated",
|
||||
"build.core": "node scripts/build-core.js",
|
||||
@@ -38,29 +42,29 @@
|
||||
"validate": "npm i && npm run lint && npm run test && npm run build"
|
||||
},
|
||||
"module": "dist/fesm5.js",
|
||||
"main": "dist/fesm5.js",
|
||||
"main": "dist/fesm5.cjs.js",
|
||||
"types": "dist/core.d.ts",
|
||||
"files": [
|
||||
"dist/",
|
||||
"css/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/core": "4.6.0",
|
||||
"@ionic/core": "4.11.13",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular-devkit/core": "^7.2.1",
|
||||
"@angular-devkit/schematics": "^7.2.1",
|
||||
"@angular/core": "^7.2.1",
|
||||
"@angular/common": "^7.2.1",
|
||||
"@angular/forms": "^7.2.1",
|
||||
"@angular/router": "^7.2.1",
|
||||
"@angular/compiler": "^7.2.1",
|
||||
"@angular/compiler-cli": "^7.2.1",
|
||||
"@angular/platform-browser": "^7.2.1",
|
||||
"@angular/platform-browser-dynamic": "^7.2.1",
|
||||
"@angular-devkit/core": "7.2.1 - 8",
|
||||
"@angular-devkit/schematics": "7.2.1 - 8",
|
||||
"@angular/core": "7.2.1 - 8",
|
||||
"@angular/common": "7.2.1 - 8",
|
||||
"@angular/forms": "7.2.1 - 8",
|
||||
"@angular/router": "7.2.1 - 8",
|
||||
"@angular/compiler": "7.2.1 - 8",
|
||||
"@angular/compiler-cli": "7.2.1 - 8",
|
||||
"@angular/platform-browser": "7.2.1 - 8",
|
||||
"@angular/platform-browser-dynamic": "7.2.1 - 8",
|
||||
"rxjs": ">=6.2.0",
|
||||
"zone.js": "^0.8.26"
|
||||
"zone.js": ">=0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/core": "^7.2.1",
|
||||
@@ -73,17 +77,17 @@
|
||||
"@angular/platform-browser": "^7.2.1",
|
||||
"@angular/platform-browser-dynamic": "^7.2.1",
|
||||
"@angular/router": "^7.2.1",
|
||||
"@types/node": "~10.12.0",
|
||||
"@types/node": "~12.0.12",
|
||||
"fs-extra": "^7.0.0",
|
||||
"glob": "^7.1.3",
|
||||
"rollup": "^1.1.2",
|
||||
"rollup-plugin-node-resolve": "^4.0.0",
|
||||
"rxjs": "^6.2.0",
|
||||
"glob": "^7.1.4",
|
||||
"rollup": "~1.17.0",
|
||||
"rollup-plugin-node-resolve": "~5.2.0",
|
||||
"rxjs": "^6.5.2",
|
||||
"tsickle": "^0.34.0",
|
||||
"tslint": "^5.12.1",
|
||||
"tslint-ionic-rules": "0.0.21",
|
||||
"typescript": "3.2.4",
|
||||
"zone.js": "^0.8.28"
|
||||
"typescript": "~3.2.2",
|
||||
"zone.js": "~0.8.26"
|
||||
},
|
||||
"schematics": "./dist/schematics/collection.json"
|
||||
}
|
||||
|
||||
@@ -15,3 +15,7 @@
|
||||
npm run build.link ../ionic-conference-app
|
||||
|
||||
When the command above is ran from the `angular` directory, it will build `@ionic/angular` and copy the `dist` directory to the correct location of another local project. In the example above, the end result is that it copies the `dist` directory to `../ionic-conference-app/node_modules/@ionic/angular/dist`. The path given should be relative to the root of this mono repo.
|
||||
|
||||
## package.json note
|
||||
|
||||
The `package.json` file in this directory references __Ionic 3__ and is in here to get GitHub to properly show the Used By counts on the repo. __Do not remove it!__
|
||||
|
||||
6
angular/scripts/clean.js
vendored
6
angular/scripts/clean.js
vendored
@@ -1,12 +1,12 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
const ROOT_DIR = path.join(__dirname, '..');
|
||||
|
||||
const cleanDirs = [
|
||||
'dist'
|
||||
path.join(ROOT_DIR, 'dist')
|
||||
];
|
||||
|
||||
cleanDirs.forEach(dir => {
|
||||
const cleanDir = path.join(__dirname, '../', dir);
|
||||
fs.removeSync(cleanDir);
|
||||
fs.emptyDirSync(dir);
|
||||
});
|
||||
|
||||
16
angular/scripts/package.json
Normal file
16
angular/scripts/package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "ionic-angular",
|
||||
"version": "`gulp package` generates dist/package.json from this template using the root ./package.json",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ionic-team/ionic.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "umd/index.js",
|
||||
"module": "index.js",
|
||||
"es2015": "es2015/index.js",
|
||||
"peerDependencies": {
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,12 @@ import resolve from 'rollup-plugin-node-resolve';
|
||||
|
||||
export default {
|
||||
input: 'build/es2015/core.js',
|
||||
output: {
|
||||
file: 'dist/fesm2015.js',
|
||||
format: 'es'
|
||||
},
|
||||
output: [
|
||||
{
|
||||
file: 'dist/fesm2015.js',
|
||||
format: 'es'
|
||||
}
|
||||
],
|
||||
external: (id) => {
|
||||
// anything else is external
|
||||
// Windows: C:\xxxxxx\xxx
|
||||
|
||||
@@ -4,6 +4,15 @@ const newConfig = {
|
||||
...config,
|
||||
input: 'build/es5/core.js',
|
||||
};
|
||||
newConfig.output.file = 'dist/fesm5.js';
|
||||
newConfig.output = [
|
||||
{
|
||||
file: 'dist/fesm5.js',
|
||||
format: 'es'
|
||||
},
|
||||
{
|
||||
file: 'dist/fesm5.cjs.js',
|
||||
format: 'cjs'
|
||||
}
|
||||
];
|
||||
|
||||
export { newConfig as default };
|
||||
|
||||
@@ -1,56 +1,45 @@
|
||||
import { NgZone } from '@angular/core';
|
||||
import { applyPolyfills, defineCustomElements } from '@ionic/core/loader';
|
||||
|
||||
import { Config } from './providers/config';
|
||||
import { IonicWindow } from './types/interfaces';
|
||||
import { raf } from './util/util';
|
||||
|
||||
export function appInitialize(config: Config, doc: Document) {
|
||||
let didInitialize = false;
|
||||
|
||||
export const appInitialize = (config: Config, doc: Document, zone: NgZone) => {
|
||||
return (): any => {
|
||||
const win: IonicWindow | undefined = doc.defaultView as any;
|
||||
if (win) {
|
||||
if (didInitialize) {
|
||||
console.warn('Ionic Angular was already initialized. Make sure IonicModule.forRoot() is just called once.');
|
||||
}
|
||||
didInitialize = true;
|
||||
const Ionic = win.Ionic = win.Ionic || {};
|
||||
|
||||
Ionic.config = config;
|
||||
Ionic.config = {
|
||||
...config,
|
||||
_zoneGate: (h: any) => zone.run(h)
|
||||
};
|
||||
|
||||
const aelFn = '__zone_symbol__addEventListener' in (doc.body as any)
|
||||
? '__zone_symbol__addEventListener'
|
||||
: 'addEventListener';
|
||||
|
||||
return applyPolyfills().then(() => {
|
||||
return defineCustomElements(win, {
|
||||
exclude: ['ion-tabs', 'ion-tab'],
|
||||
syncQueue: true,
|
||||
raf: h => (win.__zone_symbol__requestAnimationFrame) ? win.__zone_symbol__requestAnimationFrame(h) : requestAnimationFrame(h),
|
||||
raf,
|
||||
jmp: (h: any) => zone.runOutsideAngular(h),
|
||||
ael(elm, eventName, cb, opts) {
|
||||
if ((elm as any).__zone_symbol__addEventListener && skipZone(eventName)) {
|
||||
(elm as any).__zone_symbol__addEventListener(eventName, cb, opts);
|
||||
} else {
|
||||
elm.addEventListener(eventName, cb, opts);
|
||||
}
|
||||
(elm as any)[aelFn](eventName, cb, opts);
|
||||
},
|
||||
rel(elm, eventName, cb, opts) {
|
||||
if ((elm as any).__zone_symbol__removeEventListener && skipZone(eventName)) {
|
||||
(elm as any).__zone_symbol__removeEventListener(eventName, cb, opts);
|
||||
} else {
|
||||
elm.removeEventListener(eventName, cb, opts);
|
||||
}
|
||||
elm.removeEventListener(eventName, cb, opts);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const SKIP_ZONE = [
|
||||
'scroll',
|
||||
'resize',
|
||||
|
||||
'touchstart',
|
||||
'touchmove',
|
||||
'touchend',
|
||||
|
||||
'mousedown',
|
||||
'mousemove',
|
||||
'mouseup',
|
||||
|
||||
'ionStyle',
|
||||
];
|
||||
|
||||
function skipZone(eventName: string) {
|
||||
return SKIP_ZONE.indexOf(eventName) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -25,8 +25,8 @@ export class BooleanValueAccessor extends ValueAccessor {
|
||||
setIonicClasses(this.el);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.checked'])
|
||||
_handleIonChange(value: any) {
|
||||
this.handleChangeEvent(value);
|
||||
@HostListener('ionChange', ['$event.target'])
|
||||
_handleIonChange(el: any) {
|
||||
this.handleChangeEvent(el, el.checked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ export class NumericValueAccessor extends ValueAccessor {
|
||||
super(el);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.value'])
|
||||
_handleIonChange(value: any) {
|
||||
this.handleChangeEvent(value);
|
||||
@HostListener('ionChange', ['$event.target'])
|
||||
_handleIonChange(el: any) {
|
||||
this.handleChangeEvent(el, el.value);
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: number | null) => void) {
|
||||
|
||||
@@ -20,8 +20,8 @@ export class RadioValueAccessor extends ValueAccessor {
|
||||
super(el);
|
||||
}
|
||||
|
||||
@HostListener('ionSelect', ['$event.target.checked'])
|
||||
_handleIonSelect(value: any) {
|
||||
this.handleChangeEvent(value);
|
||||
@HostListener('ionSelect', ['$event.target'])
|
||||
_handleIonSelect(el: any) {
|
||||
this.handleChangeEvent(el, el.checked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ export class SelectValueAccessor extends ValueAccessor {
|
||||
super(el);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.value'])
|
||||
_handleChangeEvent(value: any) {
|
||||
this.handleChangeEvent(value);
|
||||
@HostListener('ionChange', ['$event.target'])
|
||||
_handleChangeEvent(el: any) {
|
||||
this.handleChangeEvent(el, el.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ export class TextValueAccessor extends ValueAccessor {
|
||||
super(el);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.value'])
|
||||
_handleInputEvent(value: any) {
|
||||
this.handleChangeEvent(value);
|
||||
@HostListener('ionChange', ['$event.target'])
|
||||
_handleInputEvent(el: any) {
|
||||
this.handleChangeEvent(el, el.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor } from '@angular/forms';
|
||||
|
||||
import { raf } from '../../util/util';
|
||||
|
||||
export class ValueAccessor implements ControlValueAccessor {
|
||||
|
||||
private onChange: (value: any) => void = () => {/**/};
|
||||
@@ -14,18 +16,22 @@ export class ValueAccessor implements ControlValueAccessor {
|
||||
setIonicClasses(this.el);
|
||||
}
|
||||
|
||||
handleChangeEvent(value: any) {
|
||||
if (value !== this.lastValue) {
|
||||
this.lastValue = value;
|
||||
this.onChange(value);
|
||||
handleChangeEvent(el: HTMLElement, value: any) {
|
||||
if (el === this.el.nativeElement) {
|
||||
if (value !== this.lastValue) {
|
||||
this.lastValue = value;
|
||||
this.onChange(value);
|
||||
}
|
||||
setIonicClasses(this.el);
|
||||
}
|
||||
setIonicClasses(this.el);
|
||||
}
|
||||
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
setIonicClasses(this.el);
|
||||
@HostListener('ionBlur', ['$event.target'])
|
||||
_handleBlurEvent(el: any) {
|
||||
if (el === this.el.nativeElement) {
|
||||
this.onTouched();
|
||||
setIonicClasses(this.el);
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
@@ -41,8 +47,8 @@ export class ValueAccessor implements ControlValueAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
export function setIonicClasses(element: ElementRef) {
|
||||
requestAnimationFrame(() => {
|
||||
export const setIonicClasses = (element: ElementRef) => {
|
||||
raf(() => {
|
||||
const input = element.nativeElement as HTMLElement;
|
||||
const classes = getClasses(input);
|
||||
setClasses(input, classes);
|
||||
@@ -52,9 +58,9 @@ export function setIonicClasses(element: ElementRef) {
|
||||
setClasses(item, classes);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getClasses(element: HTMLElement) {
|
||||
const getClasses = (element: HTMLElement) => {
|
||||
const classList = element.classList;
|
||||
const classes = [];
|
||||
for (let i = 0; i < classList.length; i++) {
|
||||
@@ -64,22 +70,22 @@ function getClasses(element: HTMLElement) {
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
};
|
||||
|
||||
function setClasses(element: HTMLElement, classes: string[]) {
|
||||
const setClasses = (element: HTMLElement, classes: string[]) => {
|
||||
const classList = element.classList;
|
||||
|
||||
classList.remove(
|
||||
[
|
||||
'ion-valid',
|
||||
'ion-invalid',
|
||||
'ion-touched',
|
||||
'ion-untouched',
|
||||
'ion-dirty',
|
||||
'ion-pristine'
|
||||
);
|
||||
classList.add(...classes);
|
||||
}
|
||||
].forEach(c => classList.remove(c));
|
||||
|
||||
function startsWith(input: string, search: string): boolean {
|
||||
classes.forEach(c => classList.add(c));
|
||||
};
|
||||
|
||||
const startsWith = (input: string, search: string): boolean => {
|
||||
return input.substr(0, search.length) === search;
|
||||
}
|
||||
};
|
||||
|
||||
134
angular/src/directives/css-utils-deprecations.ts
Normal file
134
angular/src/directives/css-utils-deprecations.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { Directive, ElementRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[align-self-start], [align-self-end], [align-self-center], [align-self-stretch], [align-self-baseline], [align-self-auto], [wrap-reverse], [justify-content-start], [justify-content-center], [justify-content-end], [justify-content-around], [justify-content-between], [justify-content-evenly], [align-items-start], [align-items-center], [align-items-end], [align-items-stretch], [align-items-baseline], [float-left], [float-right], [float-start], [float-end], [float-sm-left], [float-sm-right], [float-sm-start], [float-sm-end], [float-md-left], [float-md-right], [float-md-start], [float-md-end], [float-lg-left], [float-lg-right], [float-lg-start], [float-lg-end], [float-xl-left], [float-xl-right], [float-xl-start], [float-xl-end], [text-center], [text-justify], [text-start], [text-end], [text-left], [text-right], [text-nowrap], [text-wrap], [text-sm-center], [text-sm-justify], [text-sm-start], [text-sm-end], [text-sm-left], [text-sm-right], [text-sm-nowrap], [text-sm-wrap], [text-md-center], [text-md-justify], [text-md-start], [text-md-end], [text-md-left], [text-md-right], [text-md-nowrap], [text-md-wrap], [text-lg-center], [text-lg-justify], [text-lg-start], [text-lg-end], [text-lg-left], [text-lg-right], [text-lg-nowrap], [text-lg-wrap], [text-xl-center], [text-xl-justify], [text-xl-start], [text-xl-end], [text-xl-left], [text-xl-right], [text-xl-nowrap], [text-xl-wrap], [text-uppercase], [text-lowercase], [text-capitalize], [text-sm-uppercase], [text-sm-lowercase], [text-sm-capitalize], [text-md-uppercase], [text-md-lowercase], [text-md-capitalize], [text-lg-uppercase], [text-lg-lowercase], [text-lg-capitalize], [text-xl-uppercase], [text-xl-lowercase], [text-xl-capitalize], [no-padding], [padding], [padding-top], [padding-bottom], [padding-start], [padding-end], [padding-vertical], [padding-horizontal], [no-margin], [margin], [margin-top], [margin-bottom], [margin-start], [margin-end], [margin-vertical], [margin-horizontal]',
|
||||
})
|
||||
export class CssUtilsDeprecations {
|
||||
constructor(ref: ElementRef) {
|
||||
const el = (ref.nativeElement as HTMLElement);
|
||||
const attributes = Array.from(el.attributes)
|
||||
.map(a => a.name)
|
||||
.filter(n => DEPRECATED_ATTRIBUTES.includes(n));
|
||||
|
||||
if (attributes.length > 0) {
|
||||
console.warn(`[DEPRECATED][CSS] Ionic CSS attributes are deprecated.
|
||||
Replace:
|
||||
'<${el.tagName.toLowerCase()} ${attributes.map(n => `${n}`).join(' ')}>'
|
||||
|
||||
With:
|
||||
'<${el.tagName.toLowerCase()} class="${attributes.map(n => `ion-${n}`).join(' ')}">'
|
||||
`);
|
||||
}
|
||||
}
|
||||
}
|
||||
const DEPRECATED_ATTRIBUTES = [
|
||||
'align-self-start',
|
||||
'align-self-end',
|
||||
'align-self-center',
|
||||
'align-self-stretch',
|
||||
'align-self-baseline',
|
||||
'align-self-auto',
|
||||
'wrap-reverse',
|
||||
'justify-content-start',
|
||||
'justify-content-center',
|
||||
'justify-content-end',
|
||||
'justify-content-around',
|
||||
'justify-content-between',
|
||||
'justify-content-evenly',
|
||||
'align-items-start',
|
||||
'align-items-center',
|
||||
'align-items-end',
|
||||
'align-items-stretch',
|
||||
'align-items-baseline',
|
||||
'float-left',
|
||||
'float-right',
|
||||
'float-start',
|
||||
'float-end',
|
||||
'float-sm-left',
|
||||
'float-sm-right',
|
||||
'float-sm-start',
|
||||
'float-sm-end',
|
||||
'float-md-left',
|
||||
'float-md-right',
|
||||
'float-md-start',
|
||||
'float-md-end',
|
||||
'float-lg-left',
|
||||
'float-lg-right',
|
||||
'float-lg-start',
|
||||
'float-lg-end',
|
||||
'float-xl-left',
|
||||
'float-xl-right',
|
||||
'float-xl-start',
|
||||
'float-xl-end',
|
||||
'text-center',
|
||||
'text-justify',
|
||||
'text-start',
|
||||
'text-end',
|
||||
'text-left',
|
||||
'text-right',
|
||||
'text-nowrap',
|
||||
'text-wrap',
|
||||
'text-sm-center',
|
||||
'text-sm-justify',
|
||||
'text-sm-start',
|
||||
'text-sm-end',
|
||||
'text-sm-left',
|
||||
'text-sm-right',
|
||||
'text-sm-nowrap',
|
||||
'text-sm-wrap',
|
||||
'text-md-center',
|
||||
'text-md-justify',
|
||||
'text-md-start',
|
||||
'text-md-end',
|
||||
'text-md-left',
|
||||
'text-md-right',
|
||||
'text-md-nowrap',
|
||||
'text-md-wrap',
|
||||
'text-lg-center',
|
||||
'text-lg-justify',
|
||||
'text-lg-start',
|
||||
'text-lg-end',
|
||||
'text-lg-left',
|
||||
'text-lg-right',
|
||||
'text-lg-nowrap',
|
||||
'text-lg-wrap',
|
||||
'text-xl-center',
|
||||
'text-xl-justify',
|
||||
'text-xl-start',
|
||||
'text-xl-end',
|
||||
'text-xl-left',
|
||||
'text-xl-right',
|
||||
'text-xl-nowrap',
|
||||
'text-xl-wrap',
|
||||
'text-uppercase',
|
||||
'text-lowercase',
|
||||
'text-capitalize',
|
||||
'text-sm-uppercase',
|
||||
'text-sm-lowercase',
|
||||
'text-sm-capitalize',
|
||||
'text-md-uppercase',
|
||||
'text-md-lowercase',
|
||||
'text-md-capitalize',
|
||||
'text-lg-uppercase',
|
||||
'text-lg-lowercase',
|
||||
'text-lg-capitalize',
|
||||
'text-xl-uppercase',
|
||||
'text-xl-lowercase',
|
||||
'text-xl-capitalize',
|
||||
'no-padding',
|
||||
'padding',
|
||||
'padding-top',
|
||||
'padding-bottom',
|
||||
'padding-start',
|
||||
'padding-end',
|
||||
'padding-vertical',
|
||||
'padding-horizontal',
|
||||
'no-margin',
|
||||
'margin',
|
||||
'margin-top',
|
||||
'margin-bottom',
|
||||
'margin-start',
|
||||
'margin-end',
|
||||
'margin-vertical',
|
||||
'margin-horizontal'
|
||||
];
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Location } from '@angular/common';
|
||||
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core';
|
||||
import { Attribute, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core';
|
||||
import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET, Router } from '@angular/router';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
|
||||
@@ -57,7 +57,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
private resolver: ComponentFactoryResolver,
|
||||
@Attribute('name') name: string,
|
||||
@Optional() @Attribute('tabs') tabs: string,
|
||||
private changeDetector: ChangeDetectorRef,
|
||||
private config: Config,
|
||||
private navCtrl: NavController,
|
||||
commonLocation: Location,
|
||||
@@ -210,8 +209,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
// Store references to the proxy by component
|
||||
this.proxyMap.set(cmpRef.instance, activatedRouteProxy);
|
||||
this.currentActivatedRoute$.next({ component: cmpRef.instance, activatedRoute });
|
||||
|
||||
this.changeDetector.markForCheck();
|
||||
}
|
||||
|
||||
this.activatedView = enteringView;
|
||||
|
||||
@@ -31,7 +31,7 @@ export class StackController {
|
||||
createView(ref: ComponentRef<any>, activatedRoute: ActivatedRoute): RouteView {
|
||||
const url = getUrl(this.router, activatedRoute);
|
||||
const element = (ref && ref.location && ref.location.nativeElement) as HTMLElement;
|
||||
const unlistenEvents = bindLifecycleEvents(ref.instance, element);
|
||||
const unlistenEvents = bindLifecycleEvents(this.zone, ref.instance, element);
|
||||
return {
|
||||
id: this.nextId++,
|
||||
stackId: computeStackId(this.tabsPrefix, url),
|
||||
@@ -59,6 +59,7 @@ export class StackController {
|
||||
direction = 'back';
|
||||
animation = undefined;
|
||||
}
|
||||
|
||||
const viewsSnapshot = this.views.slice();
|
||||
|
||||
let currentNavigation;
|
||||
@@ -94,16 +95,36 @@ export class StackController {
|
||||
}
|
||||
}
|
||||
|
||||
const reused = this.views.includes(enteringView);
|
||||
const views = this.insertView(enteringView, direction);
|
||||
return this.wait(async () => {
|
||||
await this.transition(enteringView, leavingView, animation, this.canGoBack(1), false);
|
||||
await cleanupAsync(enteringView, views, viewsSnapshot, this.location);
|
||||
return {
|
||||
enteringView,
|
||||
direction,
|
||||
animation,
|
||||
tabSwitch
|
||||
};
|
||||
|
||||
// Trigger change detection before transition starts
|
||||
// This will call ngOnInit() the first time too, just after the view
|
||||
// was attached to the dom, but BEFORE the transition starts
|
||||
if (!reused) {
|
||||
enteringView.ref.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
// Wait until previous transitions finish
|
||||
return this.zone.runOutsideAngular(() => {
|
||||
return this.wait(() => {
|
||||
// disconnect leaving page from change detection to
|
||||
// reduce jank during the page transition
|
||||
if (leavingView) {
|
||||
leavingView.ref.changeDetectorRef.detach();
|
||||
}
|
||||
// In case the enteringView is the same as the leavingPage we need to reattach()
|
||||
enteringView.ref.changeDetectorRef.reattach();
|
||||
|
||||
return this.transition(enteringView, leavingView, animation, this.canGoBack(1), false)
|
||||
.then(() => cleanupAsync(enteringView, views, viewsSnapshot, this.location))
|
||||
.then(() => ({
|
||||
enteringView,
|
||||
direction,
|
||||
animation,
|
||||
tabSwitch
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -138,28 +159,30 @@ export class StackController {
|
||||
});
|
||||
}
|
||||
|
||||
async startBackTransition() {
|
||||
startBackTransition() {
|
||||
const leavingView = this.activeView;
|
||||
if (leavingView) {
|
||||
const views = this.getStack(leavingView.stackId);
|
||||
const enteringView = views[views.length - 2];
|
||||
enteringView.ref.changeDetectorRef.reattach();
|
||||
await this.wait(() => {
|
||||
return this.wait(() => {
|
||||
return this.transition(
|
||||
enteringView, // entering view
|
||||
leavingView, // leaving view
|
||||
'back',
|
||||
true,
|
||||
this.canGoBack(2),
|
||||
true
|
||||
);
|
||||
});
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
endBackTransition(shouldComplete: boolean) {
|
||||
if (shouldComplete) {
|
||||
this.skipTransition = true;
|
||||
this.pop(1);
|
||||
} else if (this.activeView) {
|
||||
cleanup(this.activeView, this.views, this.views, this.location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +212,7 @@ export class StackController {
|
||||
return this.views.slice();
|
||||
}
|
||||
|
||||
private async transition(
|
||||
private transition(
|
||||
enteringView: RouteView | undefined,
|
||||
leavingView: RouteView | undefined,
|
||||
direction: 'forward' | 'back' | undefined,
|
||||
@@ -198,26 +221,32 @@ export class StackController {
|
||||
) {
|
||||
if (this.skipTransition) {
|
||||
this.skipTransition = false;
|
||||
return;
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
if (leavingView === enteringView) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
const enteringEl = enteringView ? enteringView.element : undefined;
|
||||
const leavingEl = leavingView ? leavingView.element : undefined;
|
||||
const containerEl = this.containerEl;
|
||||
if (enteringEl && enteringEl !== leavingEl) {
|
||||
enteringEl.classList.add('ion-page', 'ion-page-invisible');
|
||||
enteringEl.classList.add('ion-page');
|
||||
enteringEl.classList.add('ion-page-invisible');
|
||||
if (enteringEl.parentElement !== containerEl) {
|
||||
containerEl.appendChild(enteringEl);
|
||||
}
|
||||
|
||||
await containerEl.componentOnReady();
|
||||
await containerEl.commit(enteringEl, leavingEl, {
|
||||
deepWait: true,
|
||||
duration: direction === undefined ? 0 : undefined,
|
||||
direction,
|
||||
showGoBack,
|
||||
progressAnimation
|
||||
});
|
||||
if ((containerEl as any).commit) {
|
||||
return containerEl.commit(enteringEl, leavingEl, {
|
||||
deepWait: true,
|
||||
duration: direction === undefined ? 0 : undefined,
|
||||
direction,
|
||||
showGoBack,
|
||||
progressAnimation
|
||||
});
|
||||
}
|
||||
}
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
private async wait<T>(task: () => Promise<T>): Promise<T> {
|
||||
@@ -230,22 +259,24 @@ export class StackController {
|
||||
}
|
||||
}
|
||||
|
||||
function cleanupAsync(activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) {
|
||||
return new Promise(resolve => {
|
||||
requestAnimationFrame(() => {
|
||||
cleanup(activeRoute, views, viewsSnapshot, location);
|
||||
resolve();
|
||||
const cleanupAsync = (activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) => {
|
||||
if (typeof (requestAnimationFrame as any) === 'function') {
|
||||
return new Promise<any>(resolve => {
|
||||
requestAnimationFrame(() => {
|
||||
cleanup(activeRoute, views, viewsSnapshot, location);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
function cleanup(activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) {
|
||||
const cleanup = (activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) => {
|
||||
viewsSnapshot
|
||||
.filter(view => !views.includes(view))
|
||||
.forEach(destroyView);
|
||||
|
||||
views.forEach(view => {
|
||||
|
||||
/**
|
||||
* In the event that a user navigated multiple
|
||||
* times in rapid succession, we want to make sure
|
||||
@@ -265,4 +296,4 @@ function cleanup(activeRoute: RouteView, views: RouteView[], viewsSnapshot: Rout
|
||||
view.ref.changeDetectorRef.detach();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ComponentRef } from '@angular/core';
|
||||
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
|
||||
import { NavDirection, RouterDirection } from '@ionic/core';
|
||||
|
||||
export function insertView(views: RouteView[], view: RouteView, direction: RouterDirection) {
|
||||
export const insertView = (views: RouteView[], view: RouteView, direction: RouterDirection) => {
|
||||
if (direction === 'root') {
|
||||
return setRoot(views, view);
|
||||
} else if (direction === 'forward') {
|
||||
@@ -10,15 +10,15 @@ export function insertView(views: RouteView[], view: RouteView, direction: Route
|
||||
} else {
|
||||
return setBack(views, view);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function setRoot(views: RouteView[], view: RouteView) {
|
||||
const setRoot = (views: RouteView[], view: RouteView) => {
|
||||
views = views.filter(v => v.stackId !== view.stackId);
|
||||
views.push(view);
|
||||
return views;
|
||||
}
|
||||
};
|
||||
|
||||
function setForward(views: RouteView[], view: RouteView) {
|
||||
const setForward = (views: RouteView[], view: RouteView) => {
|
||||
const index = views.indexOf(view);
|
||||
if (index >= 0) {
|
||||
views = views.filter(v => v.stackId !== view.stackId || v.id <= view.id);
|
||||
@@ -26,30 +26,30 @@ function setForward(views: RouteView[], view: RouteView) {
|
||||
views.push(view);
|
||||
}
|
||||
return views;
|
||||
}
|
||||
};
|
||||
|
||||
function setBack(views: RouteView[], view: RouteView) {
|
||||
const setBack = (views: RouteView[], view: RouteView) => {
|
||||
const index = views.indexOf(view);
|
||||
if (index >= 0) {
|
||||
return views.filter(v => v.stackId !== view.stackId || v.id <= view.id);
|
||||
} else {
|
||||
return setRoot(views, view);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export function getUrl(router: Router, activatedRoute: ActivatedRoute) {
|
||||
export const getUrl = (router: Router, activatedRoute: ActivatedRoute) => {
|
||||
const urlTree = router.createUrlTree(['.'], { relativeTo: activatedRoute });
|
||||
return router.serializeUrl(urlTree);
|
||||
}
|
||||
};
|
||||
|
||||
export function isTabSwitch(enteringView: RouteView, leavingView: RouteView | undefined) {
|
||||
export const isTabSwitch = (enteringView: RouteView, leavingView: RouteView | undefined) => {
|
||||
if (!leavingView) {
|
||||
return true;
|
||||
}
|
||||
return enteringView.stackId !== leavingView.stackId;
|
||||
}
|
||||
};
|
||||
|
||||
export function computeStackId(prefixUrl: string[] | undefined, url: string) {
|
||||
export const computeStackId = (prefixUrl: string[] | undefined, url: string) => {
|
||||
if (!prefixUrl) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -63,22 +63,22 @@ export function computeStackId(prefixUrl: string[] | undefined, url: string) {
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export function toSegments(path: string): string[] {
|
||||
export const toSegments = (path: string) => {
|
||||
return path
|
||||
.split('/')
|
||||
.map(s => s.trim())
|
||||
.filter(s => s !== '');
|
||||
}
|
||||
};
|
||||
|
||||
export function destroyView(view: RouteView | undefined) {
|
||||
export const destroyView = (view: RouteView | undefined) => {
|
||||
if (view) {
|
||||
// TODO lifecycle event
|
||||
view.ref.destroy();
|
||||
view.unlistenEvents();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export interface StackEvent {
|
||||
enteringView: RouteView;
|
||||
|
||||
@@ -43,6 +43,7 @@ d.IonApp,
|
||||
d.IonMenuButton,
|
||||
d.IonMenuToggle,
|
||||
d.IonNav,
|
||||
d.IonNavLink,
|
||||
d.IonNavPop,
|
||||
d.IonNavPush,
|
||||
d.IonNavSetRoot,
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
/* tslint:disable */
|
||||
import { fromEvent } from 'rxjs';
|
||||
|
||||
export function proxyInputs(Cmp: any, inputs: string[]) {
|
||||
export const proxyInputs = (Cmp: any, inputs: string[]) => {
|
||||
const Prototype = Cmp.prototype;
|
||||
inputs.forEach(item => {
|
||||
Object.defineProperty(Prototype, item, {
|
||||
get() { return this.el[item]; },
|
||||
set(val: any) { this.el[item] = val; },
|
||||
set(val: any) {
|
||||
this.z.runOutsideAngular(() => this.el[item] = val);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export function proxyMethods(Cmp: any, methods: string[]) {
|
||||
export const proxyMethods = (Cmp: any, methods: string[]) => {
|
||||
const Prototype = Cmp.prototype;
|
||||
methods.forEach(methodName => {
|
||||
Prototype[methodName] = function() {
|
||||
const args = arguments;
|
||||
return this.el.componentOnReady().then((el: any) => el[methodName].apply(el, args));
|
||||
return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args));
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export function proxyOutputs(instance: any, el: any, events: string[]) {
|
||||
export const proxyOutputs = (instance: any, el: any, events: string[]) => {
|
||||
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
/* tslint:disable */
|
||||
/* auto-generated angular directive proxies */
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
|
||||
import { proxyInputs, proxyMethods, proxyOutputs } from './proxies-utils';
|
||||
|
||||
import { Components } from '@ionic/core'
|
||||
import { Components } from '@ionic/core';
|
||||
|
||||
export declare interface IonApp extends Components.IonApp {}
|
||||
@Component({ selector: 'ion-app', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
export class IonApp {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ export declare interface IonAvatar extends Components.IonAvatar {}
|
||||
@Component({ selector: 'ion-avatar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
export class IonAvatar {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -29,7 +29,7 @@ export declare interface IonBackButton extends Components.IonBackButton {}
|
||||
@Component({ selector: 'ion-back-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'defaultHref', 'disabled', 'icon', 'mode', 'text', 'type'] })
|
||||
export class IonBackButton {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ export declare interface IonBackdrop extends Components.IonBackdrop {}
|
||||
export class IonBackdrop {
|
||||
ionBackdropTap!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionBackdropTap']);
|
||||
@@ -53,7 +53,7 @@ export declare interface IonBadge extends Components.IonBadge {}
|
||||
@Component({ selector: 'ion-badge', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class IonBadge {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ export class IonButton {
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionFocus', 'ionBlur']);
|
||||
@@ -75,20 +75,21 @@ export class IonButton {
|
||||
proxyInputs(IonButton, ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'href', 'mode', 'rel', 'routerDirection', 'shape', 'size', 'strong', 'target', 'type']);
|
||||
|
||||
export declare interface IonButtons extends Components.IonButtons {}
|
||||
@Component({ selector: 'ion-buttons', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
@Component({ selector: 'ion-buttons', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['collapse'] })
|
||||
export class IonButtons {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
}
|
||||
proxyInputs(IonButtons, ['collapse']);
|
||||
|
||||
export declare interface IonCard extends Components.IonCard {}
|
||||
@Component({ selector: 'ion-card', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['button', 'color', 'disabled', 'download', 'href', 'mode', 'rel', 'routerDirection', 'target', 'type'] })
|
||||
export class IonCard {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -99,7 +100,7 @@ export declare interface IonCardContent extends Components.IonCardContent {}
|
||||
@Component({ selector: 'ion-card-content', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['mode'] })
|
||||
export class IonCardContent {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -110,7 +111,7 @@ export declare interface IonCardHeader extends Components.IonCardHeader {}
|
||||
@Component({ selector: 'ion-card-header', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'translucent'] })
|
||||
export class IonCardHeader {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -121,7 +122,7 @@ export declare interface IonCardSubtitle extends Components.IonCardSubtitle {}
|
||||
@Component({ selector: 'ion-card-subtitle', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class IonCardSubtitle {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -132,7 +133,7 @@ export declare interface IonCardTitle extends Components.IonCardTitle {}
|
||||
@Component({ selector: 'ion-card-title', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class IonCardTitle {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -146,7 +147,7 @@ export class IonCheckbox {
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
|
||||
@@ -158,7 +159,7 @@ export declare interface IonChip extends Components.IonChip {}
|
||||
@Component({ selector: 'ion-chip', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'outline'] })
|
||||
export class IonChip {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -169,7 +170,7 @@ export declare interface IonCol extends Components.IonCol {}
|
||||
@Component({ selector: 'ion-col', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['offset', 'offsetLg', 'offsetMd', 'offsetSm', 'offsetXl', 'offsetXs', 'pull', 'pullLg', 'pullMd', 'pullSm', 'pullXl', 'pullXs', 'push', 'pushLg', 'pushMd', 'pushSm', 'pushXl', 'pushXs', 'size', 'sizeLg', 'sizeMd', 'sizeSm', 'sizeXl', 'sizeXs'] })
|
||||
export class IonCol {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -183,7 +184,7 @@ export class IonContent {
|
||||
ionScroll!: EventEmitter<CustomEvent>;
|
||||
ionScrollEnd!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionScrollStart', 'ionScroll', 'ionScrollEnd']);
|
||||
@@ -200,7 +201,7 @@ export class IonDatetime {
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionCancel', 'ionChange', 'ionFocus', 'ionBlur']);
|
||||
@@ -213,7 +214,7 @@ export declare interface IonFab extends Components.IonFab {}
|
||||
@Component({ selector: 'ion-fab', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['activated', 'edge', 'horizontal', 'vertical'] })
|
||||
export class IonFab {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -227,7 +228,7 @@ export class IonFabButton {
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionFocus', 'ionBlur']);
|
||||
@@ -239,7 +240,7 @@ export declare interface IonFabList extends Components.IonFabList {}
|
||||
@Component({ selector: 'ion-fab-list', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['activated', 'side'] })
|
||||
export class IonFabList {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -250,7 +251,7 @@ export declare interface IonFooter extends Components.IonFooter {}
|
||||
@Component({ selector: 'ion-footer', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['mode', 'translucent'] })
|
||||
export class IonFooter {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -261,7 +262,7 @@ export declare interface IonGrid extends Components.IonGrid {}
|
||||
@Component({ selector: 'ion-grid', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['fixed'] })
|
||||
export class IonGrid {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -269,21 +270,21 @@ export class IonGrid {
|
||||
proxyInputs(IonGrid, ['fixed']);
|
||||
|
||||
export declare interface IonHeader extends Components.IonHeader {}
|
||||
@Component({ selector: 'ion-header', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['mode', 'translucent'] })
|
||||
@Component({ selector: 'ion-header', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['collapse', 'mode', 'translucent'] })
|
||||
export class IonHeader {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
}
|
||||
proxyInputs(IonHeader, ['mode', 'translucent']);
|
||||
proxyInputs(IonHeader, ['collapse', 'mode', 'translucent']);
|
||||
|
||||
export declare interface IonIcon extends Components.IonIcon {}
|
||||
@Component({ selector: 'ion-icon', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['ariaLabel', 'color', 'flipRtl', 'icon', 'ios', 'lazy', 'md', 'mode', 'name', 'size', 'src'] })
|
||||
export class IonIcon {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -297,7 +298,7 @@ export class IonImg {
|
||||
ionImgDidLoad!: EventEmitter<CustomEvent>;
|
||||
ionError!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionImgWillLoad', 'ionImgDidLoad', 'ionError']);
|
||||
@@ -310,7 +311,7 @@ export declare interface IonInfiniteScroll extends Components.IonInfiniteScroll
|
||||
export class IonInfiniteScroll {
|
||||
ionInfinite!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionInfinite']);
|
||||
@@ -323,7 +324,7 @@ export declare interface IonInfiniteScrollContent extends Components.IonInfinite
|
||||
@Component({ selector: 'ion-infinite-scroll-content', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['loadingSpinner', 'loadingText'] })
|
||||
export class IonInfiniteScrollContent {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -338,7 +339,7 @@ export class IonInput {
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionInput', 'ionChange', 'ionBlur', 'ionFocus']);
|
||||
@@ -351,7 +352,7 @@ export declare interface IonItem extends Components.IonItem {}
|
||||
@Component({ selector: 'ion-item', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['button', 'color', 'detail', 'detailIcon', 'disabled', 'download', 'href', 'lines', 'mode', 'rel', 'routerDirection', 'target', 'type'] })
|
||||
export class IonItem {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -362,7 +363,7 @@ export declare interface IonItemDivider extends Components.IonItemDivider {}
|
||||
@Component({ selector: 'ion-item-divider', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'sticky'] })
|
||||
export class IonItemDivider {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -373,7 +374,7 @@ export declare interface IonItemGroup extends Components.IonItemGroup {}
|
||||
@Component({ selector: 'ion-item-group', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
export class IonItemGroup {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -383,7 +384,7 @@ export declare interface IonItemOption extends Components.IonItemOption {}
|
||||
@Component({ selector: 'ion-item-option', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'disabled', 'download', 'expandable', 'href', 'mode', 'rel', 'target', 'type'] })
|
||||
export class IonItemOption {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -395,7 +396,7 @@ export declare interface IonItemOptions extends Components.IonItemOptions {}
|
||||
export class IonItemOptions {
|
||||
ionSwipe!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionSwipe']);
|
||||
@@ -408,7 +409,7 @@ export declare interface IonItemSliding extends Components.IonItemSliding {}
|
||||
export class IonItemSliding {
|
||||
ionDrag!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionDrag']);
|
||||
@@ -421,7 +422,7 @@ export declare interface IonLabel extends Components.IonLabel {}
|
||||
@Component({ selector: 'ion-label', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'position'] })
|
||||
export class IonLabel {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -432,7 +433,7 @@ export declare interface IonList extends Components.IonList {}
|
||||
@Component({ selector: 'ion-list', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['inset', 'lines', 'mode'] })
|
||||
export class IonList {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -444,7 +445,7 @@ export declare interface IonListHeader extends Components.IonListHeader {}
|
||||
@Component({ selector: 'ion-list-header', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class IonListHeader {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -459,7 +460,7 @@ export class IonMenu {
|
||||
ionDidOpen!: EventEmitter<CustomEvent>;
|
||||
ionDidClose!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionWillOpen', 'ionWillClose', 'ionDidOpen', 'ionDidClose']);
|
||||
@@ -472,7 +473,7 @@ export declare interface IonMenuButton extends Components.IonMenuButton {}
|
||||
@Component({ selector: 'ion-menu-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['autoHide', 'color', 'disabled', 'menu', 'type'] })
|
||||
export class IonMenuButton {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -483,7 +484,7 @@ export declare interface IonMenuToggle extends Components.IonMenuToggle {}
|
||||
@Component({ selector: 'ion-menu-toggle', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['autoHide', 'menu'] })
|
||||
export class IonMenuToggle {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -496,7 +497,7 @@ export class IonNav {
|
||||
ionNavWillChange!: EventEmitter<CustomEvent>;
|
||||
ionNavDidChange!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionNavWillChange', 'ionNavDidChange']);
|
||||
@@ -505,11 +506,22 @@ export class IonNav {
|
||||
proxyMethods(IonNav, ['push', 'insert', 'insertPages', 'pop', 'popTo', 'popToRoot', 'removeIndex', 'setRoot', 'setPages', 'getActive', 'getByIndex', 'canGoBack', 'getPrevious']);
|
||||
proxyInputs(IonNav, ['animated', 'animation', 'root', 'rootParams', 'swipeGesture']);
|
||||
|
||||
export declare interface IonNavLink extends Components.IonNavLink {}
|
||||
@Component({ selector: 'ion-nav-link', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps', 'routerDirection'] })
|
||||
export class IonNavLink {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
}
|
||||
proxyInputs(IonNavLink, ['component', 'componentProps', 'routerDirection']);
|
||||
|
||||
export declare interface IonNavPop extends Components.IonNavPop {}
|
||||
@Component({ selector: 'ion-nav-pop', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
export class IonNavPop {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -519,7 +531,7 @@ export declare interface IonNavPush extends Components.IonNavPush {}
|
||||
@Component({ selector: 'ion-nav-push', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps'] })
|
||||
export class IonNavPush {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -530,7 +542,7 @@ export declare interface IonNavSetRoot extends Components.IonNavSetRoot {}
|
||||
@Component({ selector: 'ion-nav-set-root', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps'] })
|
||||
export class IonNavSetRoot {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -541,7 +553,7 @@ export declare interface IonNote extends Components.IonNote {}
|
||||
@Component({ selector: 'ion-note', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class IonNote {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -552,7 +564,7 @@ export declare interface IonProgressBar extends Components.IonProgressBar {}
|
||||
@Component({ selector: 'ion-progress-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['buffer', 'color', 'mode', 'reversed', 'type', 'value'] })
|
||||
export class IonProgressBar {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -566,7 +578,7 @@ export class IonRadio {
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionSelect', 'ionFocus', 'ionBlur']);
|
||||
@@ -579,7 +591,7 @@ export declare interface IonRadioGroup extends Components.IonRadioGroup {}
|
||||
export class IonRadioGroup {
|
||||
ionChange!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionChange']);
|
||||
@@ -594,7 +606,7 @@ export class IonRange {
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
|
||||
@@ -609,7 +621,7 @@ export class IonRefresher {
|
||||
ionPull!: EventEmitter<CustomEvent>;
|
||||
ionStart!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionRefresh', 'ionPull', 'ionStart']);
|
||||
@@ -622,7 +634,7 @@ export declare interface IonRefresherContent extends Components.IonRefresherCont
|
||||
@Component({ selector: 'ion-refresher-content', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['pullingIcon', 'pullingText', 'refreshingSpinner', 'refreshingText'] })
|
||||
export class IonRefresherContent {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -633,7 +645,7 @@ export declare interface IonReorder extends Components.IonReorder {}
|
||||
@Component({ selector: 'ion-reorder', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
export class IonReorder {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -644,7 +656,7 @@ export declare interface IonReorderGroup extends Components.IonReorderGroup {}
|
||||
export class IonReorderGroup {
|
||||
ionItemReorder!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionItemReorder']);
|
||||
@@ -657,7 +669,7 @@ export declare interface IonRippleEffect extends Components.IonRippleEffect {}
|
||||
@Component({ selector: 'ion-ripple-effect', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['type'] })
|
||||
export class IonRippleEffect {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -669,14 +681,14 @@ export declare interface IonRow extends Components.IonRow {}
|
||||
@Component({ selector: 'ion-row', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
export class IonRow {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface IonSearchbar extends Components.IonSearchbar {}
|
||||
@Component({ selector: 'ion-searchbar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value'] })
|
||||
@Component({ selector: 'ion-searchbar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'inputmode', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value'] })
|
||||
export class IonSearchbar {
|
||||
ionInput!: EventEmitter<CustomEvent>;
|
||||
ionChange!: EventEmitter<CustomEvent>;
|
||||
@@ -685,25 +697,24 @@ export class IonSearchbar {
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionInput', 'ionChange', 'ionCancel', 'ionClear', 'ionBlur', 'ionFocus']);
|
||||
}
|
||||
}
|
||||
proxyMethods(IonSearchbar, ['setFocus', 'getInputElement']);
|
||||
proxyInputs(IonSearchbar, ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value']);
|
||||
proxyInputs(IonSearchbar, ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'inputmode', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value']);
|
||||
|
||||
export declare interface IonSegment extends Components.IonSegment {}
|
||||
@Component({ selector: 'ion-segment', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'disabled', 'mode', 'scrollable', 'value'] })
|
||||
export class IonSegment {
|
||||
ionChange!: EventEmitter<CustomEvent>;
|
||||
ionStyle!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionChange', 'ionStyle']);
|
||||
proxyOutputs(this, this.el, ['ionChange']);
|
||||
}
|
||||
}
|
||||
proxyInputs(IonSegment, ['color', 'disabled', 'mode', 'scrollable', 'value']);
|
||||
@@ -713,7 +724,7 @@ export declare interface IonSegmentButton extends Components.IonSegmentButton {}
|
||||
export class IonSegmentButton {
|
||||
ionSelect!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionSelect']);
|
||||
@@ -729,7 +740,7 @@ export class IonSelect {
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionChange', 'ionCancel', 'ionFocus', 'ionBlur']);
|
||||
@@ -742,7 +753,7 @@ export declare interface IonSelectOption extends Components.IonSelectOption {}
|
||||
@Component({ selector: 'ion-select-option', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['disabled', 'selected', 'value'] })
|
||||
export class IonSelectOption {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -753,7 +764,7 @@ export declare interface IonSkeletonText extends Components.IonSkeletonText {}
|
||||
@Component({ selector: 'ion-skeleton-text', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['animated', 'width'] })
|
||||
export class IonSkeletonText {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -764,7 +775,7 @@ export declare interface IonSlide extends Components.IonSlide {}
|
||||
@Component({ selector: 'ion-slide', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
export class IonSlide {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -790,20 +801,20 @@ export class IonSlides {
|
||||
ionSlideTouchStart!: EventEmitter<CustomEvent>;
|
||||
ionSlideTouchEnd!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionSlidesDidLoad', 'ionSlideTap', 'ionSlideDoubleTap', 'ionSlideWillChange', 'ionSlideDidChange', 'ionSlideNextStart', 'ionSlidePrevStart', 'ionSlideNextEnd', 'ionSlidePrevEnd', 'ionSlideTransitionStart', 'ionSlideTransitionEnd', 'ionSlideDrag', 'ionSlideReachStart', 'ionSlideReachEnd', 'ionSlideTouchStart', 'ionSlideTouchEnd']);
|
||||
}
|
||||
}
|
||||
proxyMethods(IonSlides, ['update', 'updateAutoHeight', 'slideTo', 'slideNext', 'slidePrev', 'getActiveIndex', 'getPreviousIndex', 'length', 'isEnd', 'isBeginning', 'startAutoplay', 'stopAutoplay', 'lockSwipeToNext', 'lockSwipeToPrev', 'lockSwipes']);
|
||||
proxyMethods(IonSlides, ['update', 'updateAutoHeight', 'slideTo', 'slideNext', 'slidePrev', 'getActiveIndex', 'getPreviousIndex', 'length', 'isEnd', 'isBeginning', 'startAutoplay', 'stopAutoplay', 'lockSwipeToNext', 'lockSwipeToPrev', 'lockSwipes', 'getSwiper']);
|
||||
proxyInputs(IonSlides, ['mode', 'options', 'pager', 'scrollbar']);
|
||||
|
||||
export declare interface IonSpinner extends Components.IonSpinner {}
|
||||
@Component({ selector: 'ion-spinner', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'duration', 'name', 'paused'] })
|
||||
export class IonSpinner {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -815,7 +826,7 @@ export declare interface IonSplitPane extends Components.IonSplitPane {}
|
||||
export class IonSplitPane {
|
||||
ionSplitPaneVisible!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionSplitPaneVisible']);
|
||||
@@ -827,7 +838,7 @@ export declare interface IonTabBar extends Components.IonTabBar {}
|
||||
@Component({ selector: 'ion-tab-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'selectedTab', 'translucent'] })
|
||||
export class IonTabBar {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -838,7 +849,7 @@ export declare interface IonTabButton extends Components.IonTabButton {}
|
||||
@Component({ selector: 'ion-tab-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['disabled', 'download', 'href', 'layout', 'mode', 'rel', 'selected', 'tab', 'target'] })
|
||||
export class IonTabButton {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -849,7 +860,7 @@ export declare interface IonText extends Components.IonText {}
|
||||
@Component({ selector: 'ion-text', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class IonText {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
@@ -864,7 +875,7 @@ export class IonTextarea {
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionChange', 'ionInput', 'ionBlur', 'ionFocus']);
|
||||
@@ -877,22 +888,22 @@ export declare interface IonThumbnail extends Components.IonThumbnail {}
|
||||
@Component({ selector: 'ion-thumbnail', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
|
||||
export class IonThumbnail {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface IonTitle extends Components.IonTitle {}
|
||||
@Component({ selector: 'ion-title', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color'] })
|
||||
@Component({ selector: 'ion-title', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'size'] })
|
||||
export class IonTitle {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
}
|
||||
proxyInputs(IonTitle, ['color']);
|
||||
proxyInputs(IonTitle, ['color', 'size']);
|
||||
|
||||
export declare interface IonToggle extends Components.IonToggle {}
|
||||
@Component({ selector: 'ion-toggle', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['checked', 'color', 'disabled', 'mode', 'name', 'value'] })
|
||||
@@ -901,7 +912,7 @@ export class IonToggle {
|
||||
ionFocus!: EventEmitter<CustomEvent>;
|
||||
ionBlur!: EventEmitter<CustomEvent>;
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
|
||||
@@ -913,7 +924,7 @@ export declare interface IonToolbar extends Components.IonToolbar {}
|
||||
@Component({ selector: 'ion-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class IonToolbar {
|
||||
protected el: HTMLElement;
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
||||
c.detach();
|
||||
this.el = r.nativeElement;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EmbeddedViewRef, IterableDiffer, IterableDiffers, NgZone, SimpleChanges, TrackByFunction } from '@angular/core';
|
||||
import { Cell, CellType, HeaderFn, ItemHeightFn } from '@ionic/core';
|
||||
import { Cell, CellType, FooterHeightFn, HeaderFn, HeaderHeightFn, ItemHeightFn } from '@ionic/core';
|
||||
|
||||
import { proxyInputs, proxyMethods } from '../proxies-utils';
|
||||
|
||||
@@ -75,7 +75,7 @@ export declare interface IonVirtualScroll {
|
||||
|
||||
/**
|
||||
* An optional function that maps each item within their height.
|
||||
* When this function is provides, heavy optimizations and fast path can be taked by
|
||||
* When this function is provided, heavy optimizations and fast path can be taked by
|
||||
* `ion-virtual-scroll` leading to massive performance improvements.
|
||||
*
|
||||
* This function allows to skip all DOM reads, which can be Doing so leads
|
||||
@@ -83,6 +83,16 @@ export declare interface IonVirtualScroll {
|
||||
*/
|
||||
itemHeight?: ItemHeightFn;
|
||||
|
||||
/**
|
||||
* An optional function that maps each item header within their height.
|
||||
*/
|
||||
headerHeight?: HeaderHeightFn;
|
||||
|
||||
/**
|
||||
* An optional function that maps each item footer within their height.
|
||||
*/
|
||||
footerHeight?: FooterHeightFn;
|
||||
|
||||
/**
|
||||
* Same as `ngForTrackBy` which can be used on `ngFor`.
|
||||
*/
|
||||
@@ -114,6 +124,8 @@ export declare interface IonVirtualScroll {
|
||||
'footerFn',
|
||||
'items',
|
||||
'itemHeight',
|
||||
'headerHeight',
|
||||
'footerHeight',
|
||||
'trackBy'
|
||||
]
|
||||
})
|
||||
@@ -128,7 +140,7 @@ export class IonVirtualScroll {
|
||||
@ContentChild(VirtualFooter) ftrTmp!: VirtualFooter;
|
||||
|
||||
constructor(
|
||||
private zone: NgZone,
|
||||
private z: NgZone,
|
||||
private iterableDiffers: IterableDiffers,
|
||||
elementRef: ElementRef,
|
||||
) {
|
||||
@@ -162,7 +174,7 @@ export class IonVirtualScroll {
|
||||
}
|
||||
|
||||
private nodeRender(el: HTMLElement | null, cell: Cell, index: number): HTMLElement {
|
||||
return this.zone.run(() => {
|
||||
return this.z.run(() => {
|
||||
let node: EmbeddedViewRef<VirtualContext>;
|
||||
if (!el) {
|
||||
node = this.itmTmp.viewContainer.createEmbeddedView(
|
||||
@@ -194,7 +206,7 @@ export class IonVirtualScroll {
|
||||
}
|
||||
}
|
||||
|
||||
function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement {
|
||||
const getElement = (view: EmbeddedViewRef<VirtualContext>): HTMLElement => {
|
||||
const rootNodes = view.rootNodes;
|
||||
for (let i = 0; i < rootNodes.length; i++) {
|
||||
if (rootNodes[i].nodeType === 1) {
|
||||
@@ -202,7 +214,7 @@ function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement {
|
||||
}
|
||||
}
|
||||
throw new Error('virtual element was not created');
|
||||
}
|
||||
};
|
||||
|
||||
proxyInputs(IonVirtualScroll, [
|
||||
'approxItemHeight',
|
||||
@@ -211,7 +223,9 @@ proxyInputs(IonVirtualScroll, [
|
||||
'headerFn',
|
||||
'footerFn',
|
||||
'items',
|
||||
'itemHeight'
|
||||
'itemHeight',
|
||||
'headerHeight',
|
||||
'footerHeight'
|
||||
]);
|
||||
|
||||
proxyMethods(IonVirtualScroll, [
|
||||
|
||||
@@ -14,6 +14,7 @@ export { IonVirtualScroll } from './directives/virtual-scroll/virtual-scroll';
|
||||
export { VirtualItem } from './directives/virtual-scroll/virtual-item';
|
||||
export { VirtualHeader } from './directives/virtual-scroll/virtual-header';
|
||||
export { VirtualFooter } from './directives/virtual-scroll/virtual-footer';
|
||||
export { CssUtilsDeprecations } from './directives/css-utils-deprecations';
|
||||
export * from './directives/proxies';
|
||||
|
||||
// PROVIDERS
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CommonModule, DOCUMENT } from '@angular/common';
|
||||
import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { APP_INITIALIZER, ModuleWithProviders, NgModule, NgZone } from '@angular/core';
|
||||
import { IonicConfig } from '@ionic/core';
|
||||
|
||||
import { appInitialize } from './app-initialize';
|
||||
@@ -8,12 +8,13 @@ import { NumericValueAccessor } from './directives/control-value-accessors/numer
|
||||
import { RadioValueAccessor } from './directives/control-value-accessors/radio-value-accessor';
|
||||
import { SelectValueAccessor } from './directives/control-value-accessors/select-value-accessor';
|
||||
import { TextValueAccessor } from './directives/control-value-accessors/text-value-accessor';
|
||||
import { CssUtilsDeprecations } from './directives/css-utils-deprecations';
|
||||
import { IonBackButtonDelegate } from './directives/navigation/ion-back-button';
|
||||
import { IonRouterOutlet } from './directives/navigation/ion-router-outlet';
|
||||
import { IonTabs } from './directives/navigation/ion-tabs';
|
||||
import { NavDelegate } from './directives/navigation/nav-delegate';
|
||||
import { RouterLinkDelegate } from './directives/navigation/router-link-delegate';
|
||||
import { IonApp, IonAvatar, IonBackButton, IonBackdrop, IonBadge, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCheckbox, IonChip, IonCol, IonContent, IonDatetime, IonFab, IonFabButton, IonFabList, IonFooter, IonGrid, IonHeader, IonIcon, IonImg, IonInfiniteScroll, IonInfiniteScrollContent, IonInput, IonItem, IonItemDivider, IonItemGroup, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonList, IonListHeader, IonMenu, IonMenuButton, IonMenuToggle, IonNav, IonNavPop, IonNavPush, IonNavSetRoot, IonNote, IonProgressBar, IonRadio, IonRadioGroup, IonRange, IonRefresher, IonRefresherContent, IonReorder, IonReorderGroup, IonRippleEffect, IonRow, IonSearchbar, IonSegment, IonSegmentButton, IonSelect, IonSelectOption, IonSkeletonText, IonSlide, IonSlides, IonSpinner, IonSplitPane, IonTabBar, IonTabButton, IonText, IonTextarea, IonThumbnail, IonTitle, IonToggle, IonToolbar } from './directives/proxies';
|
||||
import { IonApp, IonAvatar, IonBackButton, IonBackdrop, IonBadge, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCheckbox, IonChip, IonCol, IonContent, IonDatetime, IonFab, IonFabButton, IonFabList, IonFooter, IonGrid, IonHeader, IonIcon, IonImg, IonInfiniteScroll, IonInfiniteScrollContent, IonInput, IonItem, IonItemDivider, IonItemGroup, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonList, IonListHeader, IonMenu, IonMenuButton, IonMenuToggle, IonNav, IonNavLink, IonNavPop, IonNavPush, IonNavSetRoot, IonNote, IonProgressBar, IonRadio, IonRadioGroup, IonRange, IonRefresher, IonRefresherContent, IonReorder, IonReorderGroup, IonRippleEffect, IonRow, IonSearchbar, IonSegment, IonSegmentButton, IonSelect, IonSelectOption, IonSkeletonText, IonSlide, IonSlides, IonSpinner, IonSplitPane, IonTabBar, IonTabButton, IonText, IonTextarea, IonThumbnail, IonTitle, IonToggle, IonToolbar } from './directives/proxies';
|
||||
import { VirtualFooter } from './directives/virtual-scroll/virtual-footer';
|
||||
import { VirtualHeader } from './directives/virtual-scroll/virtual-header';
|
||||
import { VirtualItem } from './directives/virtual-scroll/virtual-item';
|
||||
@@ -66,6 +67,7 @@ const DECLARATIONS = [
|
||||
IonMenuButton,
|
||||
IonMenuToggle,
|
||||
IonNav,
|
||||
IonNavLink,
|
||||
IonNavPop,
|
||||
IonNavPush,
|
||||
IonNavSetRoot,
|
||||
@@ -118,7 +120,10 @@ const DECLARATIONS = [
|
||||
VirtualFooter,
|
||||
VirtualHeader,
|
||||
VirtualItem,
|
||||
IonVirtualScroll
|
||||
IonVirtualScroll,
|
||||
|
||||
// Deprecations
|
||||
CssUtilsDeprecations
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
@@ -142,7 +147,8 @@ export class IonicModule {
|
||||
multi: true,
|
||||
deps: [
|
||||
ConfigToken,
|
||||
DOCUMENT
|
||||
DOCUMENT,
|
||||
NgZone
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -34,10 +34,10 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
) {}
|
||||
|
||||
attachViewToDom(container: any, component: any, params?: any, cssClasses?: string[]): Promise<any> {
|
||||
return new Promise(resolve => {
|
||||
this.zone.run(() => {
|
||||
return this.zone.run(() => {
|
||||
return new Promise(resolve => {
|
||||
const el = attachView(
|
||||
this.resolver, this.injector, this.location, this.appRef,
|
||||
this.zone, this.resolver, this.injector, this.location, this.appRef,
|
||||
this.elRefMap, this.elEventsMap,
|
||||
container, component, params, cssClasses
|
||||
);
|
||||
@@ -47,8 +47,8 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
}
|
||||
|
||||
removeViewFromDom(_container: any, component: any): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.zone.run(() => {
|
||||
return this.zone.run(() => {
|
||||
return new Promise(resolve => {
|
||||
const componentRef = this.elRefMap.get(component);
|
||||
if (componentRef) {
|
||||
componentRef.destroy();
|
||||
@@ -65,7 +65,8 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
export function attachView(
|
||||
export const attachView = (
|
||||
zone: NgZone,
|
||||
resolver: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
location: ViewContainerRef | undefined,
|
||||
@@ -73,7 +74,7 @@ export function attachView(
|
||||
elRefMap: WeakMap<HTMLElement, any>,
|
||||
elEventsMap: WeakMap<HTMLElement, () => void>,
|
||||
container: any, component: any, params: any, cssClasses: string[] | undefined
|
||||
) {
|
||||
) => {
|
||||
const factory = resolver.resolveComponentFactory(component);
|
||||
const childInjector = Injector.create({
|
||||
providers: getProviders(params),
|
||||
@@ -93,7 +94,7 @@ export function attachView(
|
||||
hostElement.classList.add(clazz);
|
||||
}
|
||||
}
|
||||
const unbindEvents = bindLifecycleEvents(instance, hostElement);
|
||||
const unbindEvents = bindLifecycleEvents(zone, instance, hostElement);
|
||||
container.appendChild(hostElement);
|
||||
|
||||
if (!location) {
|
||||
@@ -103,7 +104,7 @@ export function attachView(
|
||||
elRefMap.set(hostElement, componentRef);
|
||||
elEventsMap.set(hostElement, unbindEvents);
|
||||
return hostElement;
|
||||
}
|
||||
};
|
||||
|
||||
const LIFECYCLES = [
|
||||
LIFECYCLE_WILL_ENTER,
|
||||
@@ -113,26 +114,22 @@ const LIFECYCLES = [
|
||||
LIFECYCLE_WILL_UNLOAD
|
||||
];
|
||||
|
||||
export function bindLifecycleEvents(instance: any, element: HTMLElement) {
|
||||
const unregisters = LIFECYCLES.map(eventName => {
|
||||
const handler = (ev: any) => {
|
||||
if (typeof instance[eventName] === 'function') {
|
||||
instance[eventName](ev.detail);
|
||||
}
|
||||
};
|
||||
element.addEventListener(eventName, handler);
|
||||
return () => {
|
||||
element.removeEventListener(eventName, handler);
|
||||
};
|
||||
export const bindLifecycleEvents = (zone: NgZone, instance: any, element: HTMLElement) => {
|
||||
return zone.run(() => {
|
||||
const unregisters = LIFECYCLES
|
||||
.filter(eventName => typeof instance[eventName] === 'function')
|
||||
.map(eventName => {
|
||||
const handler = (ev: any) => instance[eventName](ev.detail);
|
||||
element.addEventListener(eventName, handler);
|
||||
return () => element.removeEventListener(eventName, handler);
|
||||
});
|
||||
return () => unregisters.forEach(fn => fn());
|
||||
});
|
||||
return () => {
|
||||
unregisters.forEach(fn => fn());
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const NavParamsToken = new InjectionToken<any>('NavParamsToken');
|
||||
|
||||
function getProviders(params: {[key: string]: any}) {
|
||||
const getProviders = (params: {[key: string]: any}) => {
|
||||
return [
|
||||
{
|
||||
provide: NavParamsToken, useValue: params
|
||||
@@ -141,8 +138,8 @@ function getProviders(params: {[key: string]: any}) {
|
||||
provide: NavParams, useFactory: provideNavParamsInjectable, deps: [NavParamsToken]
|
||||
}
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
function provideNavParamsInjectable(params: {[key: string]: any}) {
|
||||
const provideNavParamsInjectable = (params: {[key: string]: any}) => {
|
||||
return new NavParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,6 +33,7 @@ export class Config {
|
||||
}
|
||||
|
||||
set(key: keyof IonicConfig, value?: any) {
|
||||
console.warn(`[DEPRECATION][Config]: The Config.set() method is deprecated and will be removed in Ionic Framework 6.0. Please see https://ionicframework.com/docs/angular/config for alternatives.`);
|
||||
const c = getConfig();
|
||||
if (c) {
|
||||
c.set(key, value);
|
||||
@@ -42,12 +43,12 @@ export class Config {
|
||||
|
||||
export const ConfigToken = new InjectionToken<any>('USERCONFIG');
|
||||
|
||||
function getConfig(): CoreConfig | null {
|
||||
const getConfig = (): CoreConfig | null => {
|
||||
if (typeof (window as any) !== 'undefined') {
|
||||
const Ionic = (window as IonicWindow).Ionic;
|
||||
const Ionic = (window as any as IonicWindow).Ionic;
|
||||
if (Ionic && Ionic.config) {
|
||||
return Ionic.config;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ export class DomController {
|
||||
}
|
||||
}
|
||||
|
||||
function getQueue() {
|
||||
const getQueue = () => {
|
||||
const win = typeof (window as any) !== 'undefined' ? window : null as any;
|
||||
|
||||
if (win != null) {
|
||||
@@ -41,6 +41,6 @@ function getQueue() {
|
||||
read: (cb: any) => cb(),
|
||||
write: (cb: any) => cb()
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export type RafCallback = (timeStamp?: number) => void;
|
||||
|
||||
@@ -7,6 +7,11 @@ export type EventHandler = (...args: any[]) => any;
|
||||
export class Events {
|
||||
private c = new Map<string, EventHandler[]>();
|
||||
|
||||
constructor() {
|
||||
console.warn(`[DEPRECATION][Events]: The Events provider is deprecated and it will be removed in the next major release.
|
||||
- Use "Observables" for a similar pub/sub architecture: https://angular.io/guide/observables
|
||||
- Use "Redux" for advanced state management: https://ngrx.io`);
|
||||
}
|
||||
/**
|
||||
* Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
|
||||
*
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { menuController } from '@ionic/core';
|
||||
|
||||
import { proxyMethod } from '../util/util';
|
||||
|
||||
const CTRL = 'ion-menu-controller';
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class MenuController {
|
||||
|
||||
constructor(@Inject(DOCUMENT) private doc: any) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Programmatically open the Menu.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu is fully opened
|
||||
*/
|
||||
open(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, this.doc, 'open', menuId);
|
||||
open(menuId?: string) {
|
||||
return menuController.open(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,8 +22,8 @@ export class MenuController {
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu is fully closed
|
||||
*/
|
||||
close(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, this.doc, 'close', menuId);
|
||||
close(menuId?: string) {
|
||||
return menuController.close(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,8 +32,8 @@ export class MenuController {
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu has been toggled
|
||||
*/
|
||||
toggle(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, this.doc, 'toggle', menuId);
|
||||
toggle(menuId?: string) {
|
||||
return menuController.toggle(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,8 +44,20 @@ export class MenuController {
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu, which is useful for chaining.
|
||||
*/
|
||||
enable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, this.doc, 'enable', shouldEnable, menuId);
|
||||
enable(shouldEnable: boolean, menuId?: string) {
|
||||
return menuController.enable(shouldEnable, menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to enable or disable the ability to swipe open the menu.
|
||||
* @param shouldEnable True if it should be swipe-able, false if not.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu, which is useful for chaining.
|
||||
* @deprecated Use swipeGesture() instead.
|
||||
*/
|
||||
swipeEnable(shouldEnable: boolean, menuId?: string) {
|
||||
console.warn('[DEPRECATED][ion-menu-controller] swipeEnable() is deprecated. Use MenuController.swipeGesture() instead');
|
||||
return this.swipeGesture(shouldEnable, menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,8 +66,8 @@ export class MenuController {
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu, which is useful for chaining.
|
||||
*/
|
||||
swipeEnable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, this.doc, 'swipeEnable', shouldEnable, menuId);
|
||||
swipeGesture(shouldEnable: boolean, menuId?: string) {
|
||||
return menuController.swipeGesture(shouldEnable, menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,16 +75,16 @@ export class MenuController {
|
||||
* @return Returns true if the specified menu is currently open, otherwise false.
|
||||
* If the menuId is not specified, it returns true if ANY menu is currenly open.
|
||||
*/
|
||||
isOpen(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, this.doc, 'isOpen', menuId);
|
||||
isOpen(menuId?: string) {
|
||||
return menuController.isOpen(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns true if the menu is currently enabled, otherwise false.
|
||||
*/
|
||||
isEnabled(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, this.doc, 'isEnabled', menuId);
|
||||
isEnabled(menuId?: string) {
|
||||
return menuController.isEnabled(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,21 +96,21 @@ export class MenuController {
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu if found, otherwise `null`.
|
||||
*/
|
||||
get(menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, this.doc, 'get', menuId);
|
||||
get(menuId?: string) {
|
||||
return menuController.get(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the instance of the menu already opened, otherwise `null`.
|
||||
*/
|
||||
getOpen(): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, this.doc, 'getOpen');
|
||||
getOpen() {
|
||||
return menuController.getOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns an array of all menu instances.
|
||||
*/
|
||||
getMenus(): Promise<HTMLIonMenuElement[]> {
|
||||
return proxyMethod(CTRL, this.doc, 'getMenus');
|
||||
getMenus() {
|
||||
return menuController.getMenus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,12 +50,12 @@ export class NavController {
|
||||
|
||||
/**
|
||||
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
|
||||
* it's equivalent to call `this.router.navigateByUrl()`, but it's explicit about the **direction** of the transition.
|
||||
* it's equivalent to calling `this.router.navigateByUrl()`, but it's explicit about the **direction** of the transition.
|
||||
*
|
||||
* Going **forward** means that a new page it's going to be pushed to the stack of the outlet (ion-router-outlet),
|
||||
* Going **forward** means that a new page is going to be pushed to the stack of the outlet (ion-router-outlet),
|
||||
* and that it will show a "forward" animation by default.
|
||||
*
|
||||
* Navigating forward can also be trigger in a declarative manner by using the `[routerDirection]` directive:
|
||||
* Navigating forward can also be triggered in a declarative manner by using the `[routerDirection]` directive:
|
||||
*
|
||||
* ```html
|
||||
* <a routerLink="/path/to/page" routerDirection="forward">Link</a>
|
||||
@@ -68,17 +68,17 @@ export class NavController {
|
||||
|
||||
/**
|
||||
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
|
||||
* it's equivalent to call:
|
||||
* it's equivalent to calling:
|
||||
*
|
||||
* ```ts
|
||||
* this.navController.setDirection('back');
|
||||
* this.router.navigateByUrl(path);
|
||||
* ```
|
||||
*
|
||||
* Going **back** means that all the pages in the stack until the navigated page is found will be pop,
|
||||
* Going **back** means that all the pages in the stack until the navigated page is found will be popped,
|
||||
* and that it will show a "back" animation by default.
|
||||
*
|
||||
* Navigating back can also be trigger in a declarative manner by using the `[routerDirection]` directive:
|
||||
* Navigating back can also be triggered in a declarative manner by using the `[routerDirection]` directive:
|
||||
*
|
||||
* ```html
|
||||
* <a routerLink="/path/to/page" routerDirection="back">Link</a>
|
||||
@@ -91,7 +91,7 @@ export class NavController {
|
||||
|
||||
/**
|
||||
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
|
||||
* it's equivalent to call:
|
||||
* it's equivalent to calling:
|
||||
*
|
||||
* ```ts
|
||||
* this.navController.setDirection('root');
|
||||
@@ -101,7 +101,7 @@ export class NavController {
|
||||
* Going **root** means that all existing pages in the stack will be removed,
|
||||
* and the navigated page will become the single page in the stack.
|
||||
*
|
||||
* Navigating root can also be trigger in a declarative manner by using the `[routerDirection]` directive:
|
||||
* Navigating root can also be triggered in a declarative manner by using the `[routerDirection]` directive:
|
||||
*
|
||||
* ```html
|
||||
* <a routerLink="/path/to/page" routerDirection="root">Link</a>
|
||||
@@ -114,7 +114,8 @@ export class NavController {
|
||||
|
||||
/**
|
||||
* Same as [Location](https://angular.io/api/common/Location)'s back() method.
|
||||
* It will use the standard `window.history.back()` under the hood, but featuring a `back` animation.
|
||||
* It will use the standard `window.history.back()` under the hood, but featuring a `back` animation
|
||||
* by default.
|
||||
*/
|
||||
back(options: AnimationOptions = { animated: true, animationDirection: 'back' }) {
|
||||
this.setDirection('back', options.animated, options.animationDirection);
|
||||
@@ -122,9 +123,9 @@ export class NavController {
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods goes back in the context of ionic's stack navigation.
|
||||
* This methods goes back in the context of Ionic's stack navigation.
|
||||
*
|
||||
* It recursivelly finds the top active `ion-router-outlet` and calls `pop()`.
|
||||
* It recursively finds the top active `ion-router-outlet` and calls `pop()`.
|
||||
* This is the recommended way to go back when you are using `ion-router-outlet`.
|
||||
*/
|
||||
async pop() {
|
||||
@@ -140,11 +141,11 @@ export class NavController {
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods specifies the direction of the next navigation performed by the angular router.
|
||||
* This methods specifies the direction of the next navigation performed by the Angular router.
|
||||
*
|
||||
* `setDirection()` does not trigger any transition, it just sets a set of flags to be consumed by `ion-router-outlet`.
|
||||
* `setDirection()` does not trigger any transition, it just sets some flags to be consumed by `ion-router-outlet`.
|
||||
*
|
||||
* It's recommended to use `navigateForward()`, `navigateBack()` and `navigateBack()` instead of `setDirection()`.
|
||||
* It's recommended to use `navigateForward()`, `navigateBack()` and `navigateRoot()` instead of `setDirection()`.
|
||||
*/
|
||||
setDirection(direction: RouterDirection, animated?: boolean, animationDirection?: 'forward' | 'back') {
|
||||
this.direction = direction;
|
||||
@@ -212,7 +213,7 @@ export class NavController {
|
||||
}
|
||||
}
|
||||
|
||||
function getAnimation(direction: RouterDirection, animated: boolean | undefined, animationDirection: 'forward' | 'back' | undefined): NavDirection | undefined {
|
||||
const getAnimation = (direction: RouterDirection, animated: boolean | undefined, animationDirection: 'forward' | 'back' | undefined): NavDirection | undefined => {
|
||||
if (animated === false) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -225,7 +226,7 @@ function getAnimation(direction: RouterDirection, animated: boolean | undefined,
|
||||
return 'forward';
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const DEFAULT_DIRECTION = 'auto';
|
||||
const DEFAULT_ANIMATED = undefined;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Inject, Injectable, NgZone } from '@angular/core';
|
||||
import { BackButtonEventDetail, Platforms, getPlatforms, isPlatform } from '@ionic/core';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
|
||||
@@ -42,29 +42,30 @@ export class Platform {
|
||||
*/
|
||||
resize = new Subject<void>();
|
||||
|
||||
constructor(@Inject(DOCUMENT) private doc: any) {
|
||||
this.win = doc.defaultView;
|
||||
constructor(@Inject(DOCUMENT) private doc: any, zone: NgZone) {
|
||||
zone.run(() => {
|
||||
this.win = doc.defaultView;
|
||||
this.backButton.subscribeWithPriority = function(priority, callback) {
|
||||
return this.subscribe(ev => (
|
||||
ev.register(priority, () => zone.run(callback))
|
||||
));
|
||||
};
|
||||
|
||||
this.backButton.subscribeWithPriority = function(priority, callback) {
|
||||
return this.subscribe(ev => {
|
||||
ev.register(priority, callback);
|
||||
});
|
||||
};
|
||||
proxyEvent(this.pause, doc, 'pause');
|
||||
proxyEvent(this.resume, doc, 'resume');
|
||||
proxyEvent(this.backButton, doc, 'ionBackButton');
|
||||
proxyEvent(this.resize, this.win, 'resize');
|
||||
|
||||
proxyEvent(this.pause, doc, 'pause');
|
||||
proxyEvent(this.resume, doc, 'resume');
|
||||
proxyEvent(this.backButton, doc, 'ionBackButton');
|
||||
proxyEvent(this.resize, this.win, 'resize');
|
||||
|
||||
let readyResolve: (value: string) => void;
|
||||
this._readyPromise = new Promise(res => { readyResolve = res; });
|
||||
if (this.win && this.win['cordova']) {
|
||||
doc.addEventListener('deviceready', () => {
|
||||
readyResolve('cordova');
|
||||
}, { once: true });
|
||||
} else {
|
||||
readyResolve!('dom');
|
||||
}
|
||||
let readyResolve: (value: string) => void;
|
||||
this._readyPromise = new Promise(res => { readyResolve = res; });
|
||||
if (this.win && this.win['cordova']) {
|
||||
doc.addEventListener('deviceready', () => {
|
||||
readyResolve('cordova');
|
||||
}, { once: true });
|
||||
} else {
|
||||
readyResolve!('dom');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,9 +25,6 @@ export class IonicRouteStrategy implements RouteReuseStrategy {
|
||||
if (future.routeConfig !== curr.routeConfig) {
|
||||
return false;
|
||||
}
|
||||
if (future.component !== curr.component) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// checking router params
|
||||
const futureParams = future.params;
|
||||
|
||||
@@ -11,8 +11,9 @@ export class OverlayBaseController<Opts, Overlay> implements ControllerShape<Opt
|
||||
/**
|
||||
* Creates a new overlay
|
||||
*/
|
||||
create(opts: Opts) {
|
||||
return this.ctrl.create(opts);
|
||||
create(opts?: Opts) {
|
||||
// TODO: next major release opts is not optional
|
||||
return this.ctrl.create((opts || {}) as any);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import { HTMLStencilElement } from '../types/interfaces';
|
||||
|
||||
export function proxyMethod(ctrlName: string, doc: Document, methodName: string, ...args: any[]) {
|
||||
const controller = ensureElementInBody(ctrlName, doc);
|
||||
return controller.componentOnReady()
|
||||
.then(() => (controller as any)[methodName].apply(controller, args));
|
||||
}
|
||||
declare const __zone_symbol__requestAnimationFrame: any;
|
||||
declare const requestAnimationFrame: any;
|
||||
|
||||
export function ensureElementInBody(elementName: string, doc: Document) {
|
||||
let element = doc.querySelector(elementName);
|
||||
if (!element) {
|
||||
element = doc.createElement(elementName);
|
||||
doc.body.appendChild(element);
|
||||
export const raf = (h: any) => {
|
||||
if (typeof __zone_symbol__requestAnimationFrame === 'function') {
|
||||
return __zone_symbol__requestAnimationFrame(h);
|
||||
}
|
||||
return element as HTMLStencilElement;
|
||||
}
|
||||
if (typeof requestAnimationFrame === 'function') {
|
||||
return requestAnimationFrame(h);
|
||||
}
|
||||
return setTimeout(h);
|
||||
};
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/test-app",
|
||||
"outputPath": "dist/browser",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
{
|
||||
@@ -31,9 +31,7 @@
|
||||
"output": "./svg"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"styles": ["src/styles.css"],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
@@ -86,37 +84,13 @@
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"karmaConfig": "src/karma.conf.js",
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"styles": ["src/styles.css"],
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
]
|
||||
"assets": ["src/favicon.ico", "src/assets"]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"test-app-e2e": {
|
||||
"root": "e2e/",
|
||||
"projectType": "application",
|
||||
"prefix": "",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
@@ -126,20 +100,39 @@
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "test-app:serve:production"
|
||||
},
|
||||
"ci": {
|
||||
"devServerTarget": "test-app:serve:ci"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
"tsConfig": ["tsconfig.app.json", "tsconfig.spec.json"],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"builder": "@angular-devkit/build-angular:server",
|
||||
"options": {
|
||||
"outputPath": "dist/server",
|
||||
"main": "src/main.server.ts",
|
||||
"tsConfig": "tsconfig.server.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"src": "src/environments/environment.ts",
|
||||
"replaceWith": "src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "test-app"
|
||||
}
|
||||
}
|
||||
|
||||
12
angular/test/test-app/browserslist
Normal file
12
angular/test/test-app/browserslist
Normal file
@@ -0,0 +1,12 @@
|
||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||
# For additional information regarding the format and rule options, please see:
|
||||
# https://github.com/browserslist/browserslist#queries
|
||||
|
||||
# You can see what browsers were selected by your queries by running:
|
||||
# npx browserslist
|
||||
|
||||
> 0.5%
|
||||
last 2 versions
|
||||
Firefox ESR
|
||||
not dead
|
||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
||||
@@ -1,32 +1,35 @@
|
||||
// @ts-check
|
||||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
|
||||
/**
|
||||
* @type { import("protractor").Config }
|
||||
*/
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./**/*.e2e-spec.ts'
|
||||
'./src/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
browserName: 'chrome',
|
||||
|
||||
chromeOptions: {
|
||||
args: [ "--headless", "--disable-gpu", "--window-size=400,1000", "--start-maximized" ]
|
||||
}
|
||||
'browserName': 'chrome'
|
||||
},
|
||||
chromeOptions: {
|
||||
args: [ "--headless", "--disable-gpu", "--window-size=400,1000", "--start-maximized" ]
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
defaultTimeoutInterval: 70000,
|
||||
print: function() {}
|
||||
},
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: require('path').join(__dirname, './tsconfig.e2e.json')
|
||||
project: require('path').join(__dirname, './tsconfig.json')
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import { handleErrorMessages, setProperty, getText, waitTime } from './utils';
|
||||
describe('form', () => {
|
||||
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
describe('change', () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ describe('inputs', () => {
|
||||
await waitTime(30);
|
||||
});
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
it('should have default value', async () => {
|
||||
@@ -60,4 +60,10 @@ describe('inputs', () => {
|
||||
expect(await element(by.css('#select-note')).getText()).toEqual('playstation');
|
||||
expect(await element(by.css('#range-note')).getText()).toEqual('20');
|
||||
});
|
||||
|
||||
it('nested components should not interfere with NgModel', async () => {
|
||||
expect(await element(by.css('#range-note')).getText()).toEqual('10');
|
||||
await element(by.css('#nested-toggle')).click();
|
||||
expect(await element(by.css('#range-note')).getText()).toEqual('10');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ describe('modals', () => {
|
||||
await waitTime(30);
|
||||
});
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
it('should open standalone modal and close', async () => {
|
||||
|
||||
@@ -4,9 +4,44 @@ import { handleErrorMessages, waitTime, testStack } from './utils';
|
||||
describe('navigation', () => {
|
||||
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
// TODO: Fix flaky tests
|
||||
xit ('should swipe and abort', async () => {
|
||||
await browser.get('/router-link?ionic:mode=ios');
|
||||
await waitTime(500);
|
||||
await element(by.css('#routerLink')).click();
|
||||
await waitTime(500);
|
||||
await swipeLeft(5);
|
||||
await waitTime(500);
|
||||
|
||||
const pageHidden = element(by.css('app-router-link'));
|
||||
expect(await pageHidden.getAttribute('aria-hidden')).toEqual('true');
|
||||
expect(await pageHidden.getAttribute('class')).toEqual('ion-page ion-page-hidden');
|
||||
|
||||
const pageVisible = element(by.css('app-router-link-page'));
|
||||
expect(await pageVisible.getAttribute('aria-hidden')).toEqual(null);
|
||||
expect(await pageVisible.getAttribute('class')).toEqual('ion-page can-go-back');
|
||||
});
|
||||
|
||||
xit ('should swipe and go back', async () => {
|
||||
await browser.get('/router-link?ionic:mode=ios');
|
||||
await waitTime(500);
|
||||
await element(by.css('#routerLink')).click();
|
||||
await waitTime(500);
|
||||
await testStack('ion-router-outlet', ['app-router-link', 'app-router-link-page']);
|
||||
|
||||
await swipeLeft(300);
|
||||
|
||||
await waitTime(1000);
|
||||
await testStack('ion-router-outlet', ['app-router-link']);
|
||||
|
||||
const page = element(by.css('app-router-link'));
|
||||
expect(await page.getAttribute('aria-hidden')).toEqual(null);
|
||||
expect(await page.getAttribute('class')).toEqual('ion-page');
|
||||
})
|
||||
|
||||
it('should navigate correctly', async () => {
|
||||
await browser.get('/navigation/page1');
|
||||
await waitTime(2000);
|
||||
@@ -22,3 +57,17 @@ describe('navigation', () => {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function swipeLeft(end: number) {
|
||||
return browser.driver.touchActions()
|
||||
.tapAndHold({x: 5, y: 1})
|
||||
.move({x: 6, y: 1})
|
||||
.move({x: 7, y: 1})
|
||||
.move({x: 8, y: 1})
|
||||
.move({x: 30, y: 1})
|
||||
.move({x: 300, y: 1})
|
||||
.move({x: end, y: 1})
|
||||
.move({x: end, y: 1})
|
||||
.release({x: end, y: 1})
|
||||
.perform();
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { waitTime, handleErrorMessages, goBack } from './utils';
|
||||
describe('nested-outlet', () => {
|
||||
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
it('should navigate correctly', async () => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { handleErrorMessages, waitTime } from './utils';
|
||||
describe('providers', () => {
|
||||
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
it('should load all providers', async () => {
|
||||
@@ -12,6 +12,9 @@ describe('providers', () => {
|
||||
|
||||
expect(await element(by.css('#is-loaded')).getText()).toEqual('true');
|
||||
expect(await element(by.css('#is-ready')).getText()).toEqual('true');
|
||||
expect(await element(by.css('#is-paused')).getText()).toEqual('true');
|
||||
expect(await element(by.css('#is-resumed')).getText()).toEqual('true');
|
||||
expect(await element(by.css('#is-resized')).getText()).toEqual('true');
|
||||
expect(await element(by.css('#is-testing')).getText()).toEqual('false');
|
||||
expect(await element(by.css('#is-desktop')).getText()).toEqual('true');
|
||||
expect(await element(by.css('#is-mobile')).getText()).toEqual('false');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { browser, element, by, protractor } from 'protractor';
|
||||
import { waitTime, testStack, testLifeCycle, handleErrorMessages } from './utils';
|
||||
import { waitTime, testStack, testLifeCycle, handleErrorMessages, getText } from './utils';
|
||||
|
||||
const EC = protractor.ExpectedConditions;
|
||||
|
||||
@@ -9,7 +9,7 @@ describe('router-link params and fragments', () => {
|
||||
const id = 'MyPageID==';
|
||||
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
it('should go to a page with properly encoded values', async () => {
|
||||
@@ -23,12 +23,13 @@ describe('router-link params and fragments', () => {
|
||||
|
||||
it('should return to a page with preserved query param and fragment', async () => {
|
||||
await browser.get('/router-link?ionic:_testing=true');
|
||||
await waitTime(30);
|
||||
await element(by.css('#queryParamsFragment')).click();
|
||||
await waitTime(200);
|
||||
await waitTime(400);
|
||||
await element(by.css('#goToPage3')).click();
|
||||
|
||||
browser.wait(EC.urlContains('router-link-page3'), 5000);
|
||||
await waitTime(200);
|
||||
await waitTime(400);
|
||||
|
||||
await element(by.css('#goBackFromPage3')).click();
|
||||
|
||||
@@ -38,6 +39,7 @@ describe('router-link params and fragments', () => {
|
||||
|
||||
it('should preserve query param and fragment with defaultHref string', async () => {
|
||||
await browser.get('/router-link-page3?ionic:_testing=true');
|
||||
await waitTime(30);
|
||||
|
||||
await element(by.css('#goBackFromPage3')).click();
|
||||
|
||||
@@ -53,7 +55,7 @@ describe('router-link', () => {
|
||||
await waitTime(30);
|
||||
});
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
|
||||
@@ -71,18 +73,6 @@ describe('router-link', () => {
|
||||
it('should go forward with ion-button[routerLink]', async () => {
|
||||
await element(by.css('#routerLink')).click();
|
||||
await testForward();
|
||||
|
||||
// test go back
|
||||
await element(by.css('ion-back-button')).click();
|
||||
await waitTime(500);
|
||||
|
||||
await testStack('ion-router-outlet', ['app-router-link']);
|
||||
await testLifeCycle('app-router-link', {
|
||||
ionViewWillEnter: 2,
|
||||
ionViewDidEnter: 2,
|
||||
ionViewWillLeave: 1,
|
||||
ionViewDidLeave: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it('should go forward with a[routerLink]', async () => {
|
||||
@@ -123,7 +113,6 @@ describe('router-link', () => {
|
||||
|
||||
it('should go back with ion-button[routerLink][routerDirection=back]', async () => {
|
||||
await element(by.css('#routerLink-back')).click();
|
||||
await testBack();
|
||||
});
|
||||
|
||||
it('should go back with a[routerLink][routerDirection=back]', async () => {
|
||||
@@ -139,21 +128,25 @@ describe('router-link', () => {
|
||||
});
|
||||
|
||||
async function testForward() {
|
||||
await waitTime(500);
|
||||
await waitTime(2500);
|
||||
await testStack('ion-router-outlet', ['app-router-link', 'app-router-link-page']);
|
||||
await testLifeCycle('app-router-link', {
|
||||
ionViewWillEnter: 1,
|
||||
ionViewDidEnter: 1,
|
||||
ionViewWillLeave: 1,
|
||||
ionViewDidLeave: 1,
|
||||
});
|
||||
await testLifeCycle('app-router-link-page', {
|
||||
ionViewWillEnter: 1,
|
||||
ionViewDidEnter: 1,
|
||||
ionViewWillLeave: 0,
|
||||
ionViewDidLeave: 0,
|
||||
});
|
||||
expect(await getText(`app-router-link-page #canGoBack`)).toEqual('true');
|
||||
|
||||
await browser.navigate().back();
|
||||
await waitTime(100);
|
||||
await testStack('ion-router-outlet', ['app-router-link']);
|
||||
await testLifeCycle('app-router-link', {
|
||||
ionViewWillEnter: 2,
|
||||
ionViewDidEnter: 2,
|
||||
ionViewWillLeave: 1,
|
||||
ionViewDidLeave: 1,
|
||||
});
|
||||
}
|
||||
|
||||
async function testRoot() {
|
||||
@@ -165,6 +158,17 @@ async function testRoot() {
|
||||
ionViewWillLeave: 0,
|
||||
ionViewDidLeave: 0,
|
||||
});
|
||||
expect(await getText(`app-router-link-page #canGoBack`)).toEqual('false');
|
||||
|
||||
await browser.navigate().back();
|
||||
await waitTime(100);
|
||||
await testStack('ion-router-outlet', ['app-router-link']);
|
||||
await testLifeCycle('app-router-link', {
|
||||
ionViewWillEnter: 1,
|
||||
ionViewDidEnter: 1,
|
||||
ionViewWillLeave: 0,
|
||||
ionViewDidLeave: 0,
|
||||
});
|
||||
}
|
||||
|
||||
async function testBack() {
|
||||
@@ -176,4 +180,15 @@ async function testBack() {
|
||||
ionViewWillLeave: 0,
|
||||
ionViewDidLeave: 0,
|
||||
});
|
||||
expect(await getText(`app-router-link-page #canGoBack`)).toEqual('false');
|
||||
|
||||
await browser.navigate().back();
|
||||
await waitTime(100);
|
||||
await testStack('ion-router-outlet', ['app-router-link']);
|
||||
await testLifeCycle('app-router-link', {
|
||||
ionViewWillEnter: 1,
|
||||
ionViewDidEnter: 1,
|
||||
ionViewWillLeave: 0,
|
||||
ionViewDidLeave: 0,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ describe('slides', () => {
|
||||
await waitTime(30);
|
||||
});
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
it('should change index on slide change', async () => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { waitTime, testStack, handleErrorMessages } from './utils';
|
||||
|
||||
describe('tabs', () => {
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
describe('entry url - /tabs', () => {
|
||||
beforeEach(async () => {
|
||||
@@ -17,10 +17,19 @@ describe('tabs', () => {
|
||||
await testState(1, 'account');
|
||||
});
|
||||
|
||||
it('should navigate between tabs and ionChange events should be dispatched ', async () => {
|
||||
let tab = await testTabTitle('Tab 1 - Page 1');
|
||||
expect(await tab.$('.segment-changed').getText()).toEqual('false');
|
||||
|
||||
await element(by.css('#tab-button-contact')).click();
|
||||
tab = await testTabTitle('Tab 2 - Page 1');
|
||||
expect(await tab.$('.segment-changed').getText()).toEqual('false');
|
||||
});
|
||||
|
||||
it('should simulate stack + double tab click', async () => {
|
||||
let tab = await getSelectedTab() as ElementFinder;
|
||||
await tab.$('#goto-tab1-page2').click();
|
||||
await testTabTitle('Tab 1 - Page 2');
|
||||
await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab1-nested']);
|
||||
await testState(1, 'account');
|
||||
expect(await tab.$('ion-back-button').isDisplayed()).toBe(true);
|
||||
@@ -31,7 +40,7 @@ describe('tabs', () => {
|
||||
await testState(2, 'contact');
|
||||
|
||||
await element(by.css('#tab-button-account')).click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2');
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab1-nested', 'app-tabs-tab2']);
|
||||
await testState(3, 'account');
|
||||
expect(await tab.$('ion-back-button').isDisplayed()).toBe(true);
|
||||
@@ -45,7 +54,7 @@ describe('tabs', () => {
|
||||
it('should simulate stack + back button click', async () => {
|
||||
const tab = await getSelectedTab();
|
||||
await tab.$('#goto-tab1-page2').click();
|
||||
await testTabTitle('Tab 1 - Page 2');
|
||||
await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
await testState(1, 'account');
|
||||
|
||||
await element(by.css('#tab-button-contact')).click();
|
||||
@@ -53,7 +62,7 @@ describe('tabs', () => {
|
||||
await testState(2, 'contact');
|
||||
|
||||
await element(by.css('#tab-button-account')).click();
|
||||
await testTabTitle('Tab 1 - Page 2');
|
||||
await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
await testState(3, 'account');
|
||||
|
||||
await element(by.css('ion-back-button')).click();
|
||||
@@ -62,6 +71,33 @@ describe('tabs', () => {
|
||||
await testState(3, 'account');
|
||||
});
|
||||
|
||||
it('should navigate deep then go home', async () => {
|
||||
let tab = await getSelectedTab();
|
||||
await tab.$('#goto-tab1-page2').click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
|
||||
await tab.$('#goto-next').click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (2)');
|
||||
|
||||
await element(by.css('#tab-button-contact')).click();
|
||||
tab = await testTabTitle('Tab 2 - Page 1');
|
||||
|
||||
await element(by.css('#tab-button-account')).click();
|
||||
await testTabTitle('Tab 1 - Page 2 (2)');
|
||||
await testStack('ion-tabs ion-router-outlet', [
|
||||
'app-tabs-tab1',
|
||||
'app-tabs-tab1-nested',
|
||||
'app-tabs-tab1-nested',
|
||||
'app-tabs-tab2'
|
||||
]);
|
||||
await element(by.css('#tab-button-account')).click();
|
||||
await testTabTitle('Tab 1 - Page 1');
|
||||
await testStack('ion-tabs ion-router-outlet', [
|
||||
'app-tabs-tab1',
|
||||
'app-tabs-tab2'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should switch tabs and go back', async () => {
|
||||
await element(by.css('#tab-button-contact')).click();
|
||||
const tab = await testTabTitle('Tab 2 - Page 1');
|
||||
@@ -76,7 +112,7 @@ describe('tabs', () => {
|
||||
const tab = await testTabTitle('Tab 2 - Page 1');
|
||||
|
||||
await tab.$('#goto-tab1-page2').click();
|
||||
await testTabTitle('Tab 1 - Page 2');
|
||||
await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab2', 'app-tabs-tab1-nested']);
|
||||
});
|
||||
|
||||
@@ -97,14 +133,14 @@ describe('tabs', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('entry url - /tabs/account/nested/12', () => {
|
||||
describe('entry url - /tabs/account/nested/1', () => {
|
||||
beforeEach(async () => {
|
||||
await browser.get('/tabs/account/nested/12');
|
||||
await browser.get('/tabs/account/nested/1');
|
||||
await waitTime(30);
|
||||
});
|
||||
|
||||
it('should only display the back-button when there is a page in the stack', async () => {
|
||||
let tab = await testTabTitle('Tab 1 - Page 2') as ElementFinder;
|
||||
let tab = await testTabTitle('Tab 1 - Page 2 (1)') as ElementFinder;
|
||||
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1-nested']);
|
||||
expect(await tab.$('ion-back-button').isDisplayed()).toBe(false);
|
||||
|
||||
@@ -112,9 +148,32 @@ describe('tabs', () => {
|
||||
tab = await testTabTitle('Tab 1 - Page 1');
|
||||
|
||||
await tab.$('#goto-tab1-page2').click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2');
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
expect(await tab.$('ion-back-button').isDisplayed()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not reuse the same page', async () => {
|
||||
let tab = await testTabTitle('Tab 1 - Page 2 (1)') as ElementFinder;
|
||||
await tab.$('#goto-next').click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (2)');
|
||||
await tab.$('#goto-next').click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (3)');
|
||||
|
||||
await testStack('ion-tabs ion-router-outlet',[
|
||||
'app-tabs-tab1-nested',
|
||||
'app-tabs-tab1-nested',
|
||||
'app-tabs-tab1-nested'
|
||||
]);
|
||||
|
||||
await tab.$('ion-back-button').click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (2)');
|
||||
await tab.$('ion-back-button').click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
|
||||
expect(await tab.$('ion-back-button').isDisplayed()).toBe(false);
|
||||
|
||||
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1-nested']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('entry url - /tabs/lazy', () => {
|
||||
@@ -128,7 +187,7 @@ describe('tabs', () => {
|
||||
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab3']);
|
||||
|
||||
await tab.$('#goto-tab1-page2').click();
|
||||
tab = await testTabTitle('Tab 1 - Page 2');
|
||||
tab = await testTabTitle('Tab 1 - Page 2 (1)');
|
||||
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab3', 'app-tabs-tab1-nested']);
|
||||
expect(await tab.$('ion-back-button').isDisplayed()).toBe(false);
|
||||
});
|
||||
|
||||
@@ -37,29 +37,30 @@ export interface LifeCycleCount {
|
||||
}
|
||||
|
||||
export function handleErrorMessages() {
|
||||
browser.manage().logs().get('browser').then(function(browserLog) {
|
||||
let severWarnings = false;
|
||||
|
||||
for (let i; i <= browserLog.length - 1; i++) {
|
||||
if (browserLog[i].level.name === 'SEVERE') {
|
||||
console.log('\n' + browserLog[i].level.name);
|
||||
console.log('(Possibly exception) \n' + browserLog[i].message);
|
||||
|
||||
severWarnings = true;
|
||||
}
|
||||
return browser.manage().logs().get('browser').then(function (browserLog) {
|
||||
for (let i = 0; i <= browserLog.length - 1; i++) {
|
||||
if (browserLog[i].level.name_ === 'SEVERE') {
|
||||
fail(browserLog[i].message);
|
||||
}
|
||||
}
|
||||
|
||||
expect(severWarnings).toBe(false);
|
||||
});
|
||||
}
|
||||
|
||||
export async function testLifeCycle(selector: string, expected: LifeCycleCount) {
|
||||
await waitTime(50);
|
||||
expect(await getText(`${selector} #ngOnInit`)).toEqual('1');
|
||||
expect(await getText(`${selector} #ionViewWillEnter`)).toEqual(expected.ionViewWillEnter.toString());
|
||||
expect(await getText(`${selector} #ionViewDidEnter`)).toEqual(expected.ionViewDidEnter.toString());
|
||||
expect(await getText(`${selector} #ionViewWillLeave`)).toEqual(expected.ionViewWillLeave.toString());
|
||||
expect(await getText(`${selector} #ionViewDidLeave`)).toEqual(expected.ionViewDidLeave.toString());
|
||||
const results = await Promise.all([
|
||||
getText(`${selector} #ngOnInit`),
|
||||
getText(`${selector} #ionViewWillEnter`),
|
||||
getText(`${selector} #ionViewDidEnter`),
|
||||
getText(`${selector} #ionViewWillLeave`),
|
||||
getText(`${selector} #ionViewDidLeave`),
|
||||
]);
|
||||
|
||||
expect(results[0]).toEqual('1');
|
||||
expect(results[1]).toEqual(expected.ionViewWillEnter.toString());
|
||||
expect(results[2]).toEqual(expected.ionViewDidEnter.toString());
|
||||
expect(results[3]).toEqual(expected.ionViewWillLeave.toString());
|
||||
expect(results[4]).toEqual(expected.ionViewDidLeave.toString());
|
||||
}
|
||||
|
||||
export async function testStack(selector: string, expected: string[]) {
|
||||
|
||||
@@ -8,7 +8,7 @@ describe('view-child', () => {
|
||||
await waitTime(30);
|
||||
});
|
||||
afterEach(() => {
|
||||
handleErrorMessages();
|
||||
return handleErrorMessages();
|
||||
});
|
||||
|
||||
it('should get a reference to all children', async () => {
|
||||
|
||||
18
angular/test/test-app/e2e/src/virtual-scroll.e2e-spec.ts
Normal file
18
angular/test/test-app/e2e/src/virtual-scroll.e2e-spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { browser, element, by } from 'protractor';
|
||||
import { waitTime, handleErrorMessages } from './utils';
|
||||
|
||||
describe('virtual-scroll', () => {
|
||||
afterEach(() => {
|
||||
return handleErrorMessages();
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await browser.get('/virtual-scroll');
|
||||
await waitTime(30);
|
||||
});
|
||||
|
||||
it('should open virtual-scroll', () => {
|
||||
const virtualElements = element.all(by.css('ion-virtual-scroll > *'));
|
||||
expect(virtualElements.count()).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -8,8 +8,6 @@ module.exports = function (config) {
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
11146
angular/test/test-app/package-lock.json
generated
11146
angular/test/test-app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,51 +1,60 @@
|
||||
{
|
||||
"name": "test-app",
|
||||
"name": "ionic-angular-test-app",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "npm run sync && ng serve",
|
||||
"sync:build": "sh scripts/build-ionic.sh",
|
||||
"sync": "sh scripts/sync.sh",
|
||||
"build": "ng build --prod --no-progress",
|
||||
"build": "npm run sync && ng build --prod --no-progress",
|
||||
"test": "ng e2e --prod",
|
||||
"test.dev": "npm run sync && ng e2e",
|
||||
"lint": "ng lint",
|
||||
"postinstall": "npm run sync"
|
||||
"postinstall": "npm run sync",
|
||||
"compile:server": "webpack --config webpack.server.config.js --progress --colors",
|
||||
"serve:ssr": "node dist/server",
|
||||
"build:ssr": "npm run build:client-and-server-bundles && npm run compile:server",
|
||||
"build:client-and-server-bundles": "npm run build && ng run test-app:server:production --bundleDependencies all"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~7.2.1",
|
||||
"@angular/common": "~7.2.1",
|
||||
"@angular/compiler": "~7.2.1",
|
||||
"@angular/core": "~7.2.1",
|
||||
"@angular/forms": "~7.2.1",
|
||||
"@angular/platform-browser": "~7.2.1",
|
||||
"@angular/platform-browser-dynamic": "~7.2.1",
|
||||
"@angular/router": "~7.2.1",
|
||||
"@ionic/angular": "^4.0.0-rc.1",
|
||||
"@angular/animations": "^8.2.8",
|
||||
"@angular/common": "^8.2.8",
|
||||
"@angular/compiler": "^8.2.8",
|
||||
"@angular/core": "^8.2.8",
|
||||
"@angular/forms": "^8.2.8",
|
||||
"@angular/platform-browser": "^8.2.8",
|
||||
"@angular/platform-browser-dynamic": "^8.2.8",
|
||||
"@angular/platform-server": "^8.2.8",
|
||||
"@angular/router": "^8.2.8",
|
||||
"@ionic/angular": "^4.7.0",
|
||||
"@ionic/angular-server": "^0.0.2",
|
||||
"@nguniversal/express-engine": "~8.1.1",
|
||||
"@nguniversal/module-map-ngfactory-loader": "~8.1.1",
|
||||
"core-js": "^2.6.2",
|
||||
"rxjs": "~6.3.3",
|
||||
"express": "^4.15.2",
|
||||
"rxjs": "^6.5.3",
|
||||
"tslib": "^1.9.0",
|
||||
"zone.js": "~0.8.26"
|
||||
"zone.js": "~0.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.12.2",
|
||||
"@angular/cli": "~7.2.1",
|
||||
"@angular/compiler-cli": "~7.2.1",
|
||||
"@angular/language-service": "~7.2.1",
|
||||
"@types/jasmine": "~2.8.8",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "~8.9.4",
|
||||
"codelyzer": "~4.5.0",
|
||||
"jasmine-core": "~2.99.1",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"karma": "~3.1.4",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "~2.0.1",
|
||||
"karma-jasmine": "~1.1.2",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "~5.4.2",
|
||||
"ts-node": "~7.0.0",
|
||||
"tslint": "~5.12.1",
|
||||
"typescript": "~3.2.4"
|
||||
"@angular-devkit/build-angular": "^0.803.6",
|
||||
"@angular/cli": "^8.3.6",
|
||||
"@angular/compiler-cli": "^8.2.8",
|
||||
"@angular/language-service": "^8.2.8",
|
||||
"@types/jasmine": "3.4.1",
|
||||
"@types/node": "12.7.8",
|
||||
"codelyzer": "^5.1.2",
|
||||
"jasmine-core": "3.5.0",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"karma": "4.3.0",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-jasmine": "2.0.1",
|
||||
"protractor": "5.4.2",
|
||||
"ts-loader": "^6.1.2",
|
||||
"ts-node": "8.4.1",
|
||||
"tslint": "~5.18.0",
|
||||
"typescript": "~3.5.3",
|
||||
"webpack-cli": "^3.3.9"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,14 @@ popd
|
||||
pushd angular
|
||||
npm link @ionic/core
|
||||
npm run build
|
||||
npm link
|
||||
popd
|
||||
|
||||
# Build angular-server
|
||||
pushd packages/angular-server
|
||||
npm link @ionic/core
|
||||
npm link @ionic/angular
|
||||
npm run build
|
||||
popd
|
||||
|
||||
popd
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
# Copy angular dist
|
||||
rm -rf node_modules/@ionic/angular/dist
|
||||
rm -rf node_modules/@ionic/angular
|
||||
mkdir node_modules/@ionic/angular
|
||||
cp -a ../../dist node_modules/@ionic/angular/dist
|
||||
cp -a ../../css node_modules/@ionic/angular/css
|
||||
cp -a ../../package.json node_modules/@ionic/angular/package.json
|
||||
|
||||
# Copy core dist
|
||||
rm -rf node_modules/@ionic/core/dist
|
||||
rm -rf node_modules/@ionic/core/loader
|
||||
# Copy angular server
|
||||
rm -rf node_modules/@ionic/angular-server
|
||||
mkdir node_modules/@ionic/angular-server
|
||||
cp -a ../../../packages/angular-server/dist node_modules/@ionic/angular-server/dist
|
||||
cp -a ../../../packages/angular-server/package.json node_modules/@ionic/angular-server/package.json
|
||||
|
||||
# # Copy core dist
|
||||
rm -rf node_modules/@ionic/core
|
||||
mkdir node_modules/@ionic/core
|
||||
cp -a ../../../core/css node_modules/@ionic/core/css
|
||||
cp -a ../../../core/dist node_modules/@ionic/core/dist
|
||||
cp -a ../../../core/hydrate node_modules/@ionic/core/hydrate
|
||||
cp -a ../../../core/loader node_modules/@ionic/core/loader
|
||||
cp -a ../../../core/package.json node_modules/@ionic/core/package.json
|
||||
|
||||
# Copy ionicons
|
||||
# # Copy ionicons
|
||||
rm -rf node_modules/ionicons
|
||||
cp -a ../../../core/node_modules/ionicons node_modules/ionicons
|
||||
|
||||
58
angular/test/test-app/server.ts
Normal file
58
angular/test/test-app/server.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* *** NOTE ON IMPORTING FROM ANGULAR AND NGUNIVERSAL IN THIS FILE ***
|
||||
*
|
||||
* If your application uses third-party dependencies, you'll need to
|
||||
* either use Webpack or the Angular CLI's `bundleDependencies` feature
|
||||
* in order to adequately package them for use on the server without a
|
||||
* node_modules directory.
|
||||
*
|
||||
* However, due to the nature of the CLI's `bundleDependencies`, importing
|
||||
* Angular in this file will create a different instance of Angular than
|
||||
* the version in the compiled application code. This leads to unavoidable
|
||||
* conflicts. Therefore, please do not explicitly import from @angular or
|
||||
* @nguniversal in this file. You can export any needed resources
|
||||
* from your application's main.server.ts file, as seen below with the
|
||||
* import for `ngExpressEngine`.
|
||||
*/
|
||||
|
||||
import 'zone.js/dist/zone-node';
|
||||
|
||||
import * as express from 'express';
|
||||
import {join} from 'path';
|
||||
|
||||
// Express server
|
||||
const app = express();
|
||||
|
||||
const PORT = process.env.PORT || 4000;
|
||||
const DIST_FOLDER = join(process.cwd(), 'dist/browser');
|
||||
|
||||
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
|
||||
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');
|
||||
|
||||
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
|
||||
app.engine('html', ngExpressEngine({
|
||||
bootstrap: AppServerModuleNgFactory,
|
||||
providers: [
|
||||
provideModuleMap(LAZY_MODULE_MAP)
|
||||
]
|
||||
}));
|
||||
|
||||
app.set('view engine', 'html');
|
||||
app.set('views', DIST_FOLDER);
|
||||
|
||||
// Example Express Rest API endpoints
|
||||
// app.get('/api/**', (req, res) => { });
|
||||
// Serve static files from /browser
|
||||
app.get('*.*', express.static(DIST_FOLDER, {
|
||||
maxAge: '1y'
|
||||
}));
|
||||
|
||||
// All regular routes use the Universal engine
|
||||
app.get('*', (req, res) => {
|
||||
res.render('index', { req });
|
||||
});
|
||||
|
||||
// Start up the Node server
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Node Express server listening on http://localhost:${PORT}`);
|
||||
});
|
||||
@@ -1,10 +1,10 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Modal test
|
||||
Alert test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-button (click)="openAlert()" id="action-button">Open Alert</ion-button>
|
||||
<ion-content>
|
||||
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
|
||||
</ion-content>
|
||||
|
||||
@@ -8,14 +8,31 @@ import { NavComponent } from '../nav/nav.component';
|
||||
})
|
||||
export class AlertComponent {
|
||||
|
||||
changes = 0;
|
||||
|
||||
constructor(
|
||||
private alertCtrl: AlertController
|
||||
) { }
|
||||
|
||||
counter() {
|
||||
this.changes++;
|
||||
return Math.floor(this.changes / 2);
|
||||
}
|
||||
|
||||
async openAlert() {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: 'Hello',
|
||||
message: 'Some text'
|
||||
message: 'Some text',
|
||||
buttons: [
|
||||
{
|
||||
role: 'cancel',
|
||||
text: 'Cancel',
|
||||
handler: () => {
|
||||
console.log(NgZone.isInAngularZone());
|
||||
NgZone.assertInAngularZone();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
await alert.present();
|
||||
}
|
||||
|
||||
@@ -7,10 +7,6 @@ import { RouterLinkPageComponent } from './router-link-page/router-link-page.com
|
||||
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from './home-page/home-page.component';
|
||||
import { TabsComponent } from './tabs/tabs.component';
|
||||
import { TabsTab1Component } from './tabs-tab1/tabs-tab1.component';
|
||||
import { TabsTab1NestedComponent } from './tabs-tab1-nested/tabs-tab1-nested.component';
|
||||
import { TabsTab2Component } from './tabs-tab2/tabs-tab2.component';
|
||||
import { VirtualScrollComponent } from './virtual-scroll/virtual-scroll.component';
|
||||
import { VirtualScrollDetailComponent } from './virtual-scroll-detail/virtual-scroll-detail.component';
|
||||
import { NestedOutletComponent } from './nested-outlet/nested-outlet.component';
|
||||
@@ -51,40 +47,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
component: TabsComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'account',
|
||||
children: [
|
||||
{
|
||||
path: 'nested/:id',
|
||||
component: TabsTab1NestedComponent
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: TabsTab1Component
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'contact',
|
||||
children: [
|
||||
{
|
||||
path: 'one',
|
||||
component: TabsTab2Component
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'one',
|
||||
pathMatch: 'full'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'lazy',
|
||||
loadChildren: './tabs-lazy/tabs-lazy.module#TabsLazyModule'
|
||||
}
|
||||
]
|
||||
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
|
||||
},
|
||||
{
|
||||
path: 'nested-outlet',
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouteReuseStrategy } from '@angular/router';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { InputsComponent } from './inputs/inputs.component';
|
||||
import { ModalComponent } from './modal/modal.component';
|
||||
@@ -14,10 +15,6 @@ import { RouterLinkPageComponent } from './router-link-page/router-link-page.com
|
||||
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from './home-page/home-page.component';
|
||||
import { TabsComponent } from './tabs/tabs.component';
|
||||
import { TabsTab1Component } from './tabs-tab1/tabs-tab1.component';
|
||||
import { TabsTab2Component } from './tabs-tab2/tabs-tab2.component';
|
||||
import { TabsTab1NestedComponent } from './tabs-tab1-nested/tabs-tab1-nested.component';
|
||||
import { VirtualScrollComponent } from './virtual-scroll/virtual-scroll.component';
|
||||
import { VirtualScrollDetailComponent } from './virtual-scroll-detail/virtual-scroll-detail.component';
|
||||
import { VirtualScrollInnerComponent } from './virtual-scroll-inner/virtual-scroll-inner.component';
|
||||
@@ -45,10 +42,6 @@ import { AlertComponent } from './alert/alert.component';
|
||||
RouterLinkPage2Component,
|
||||
RouterLinkPage3Component,
|
||||
HomePageComponent,
|
||||
TabsComponent,
|
||||
TabsTab1Component,
|
||||
TabsTab2Component,
|
||||
TabsTab1NestedComponent,
|
||||
VirtualScrollComponent,
|
||||
VirtualScrollDetailComponent,
|
||||
VirtualScrollInnerComponent,
|
||||
@@ -66,7 +59,7 @@ import { AlertComponent } from './alert/alert.component';
|
||||
AlertComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||
AppRoutingModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
@@ -76,7 +69,9 @@ import { AlertComponent } from './alert/alert.component';
|
||||
ModalExampleComponent,
|
||||
NavComponent
|
||||
],
|
||||
providers: [],
|
||||
providers: [
|
||||
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
19
angular/test/test-app/src/app/app.server.module.ts
Normal file
19
angular/test/test-app/src/app/app.server.module.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ServerModule } from '@angular/platform-server';
|
||||
|
||||
import { IonicServerModule } from '@ionic/angular-server';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
AppModule,
|
||||
ServerModule,
|
||||
ModuleMapLoaderModule,
|
||||
IonicServerModule
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppServerModule {}
|
||||
@@ -20,7 +20,9 @@ export class FormComponent {
|
||||
input2: ['Default Value'],
|
||||
checkbox: [false],
|
||||
range: [5, Validators.min(10)],
|
||||
}, {updateOn: window.location.hash === '#blur' ? 'blur' : 'change'});
|
||||
}, {
|
||||
updateOn: typeof (window as any) !== 'undefined' && window.location.hash === '#blur' ? 'blur' : 'change'
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit(_ev) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
|
||||
<ion-list>
|
||||
|
||||
<ion-item>
|
||||
@@ -89,10 +90,12 @@
|
||||
<ion-range [(ngModel)]="range"></ion-range>
|
||||
<ion-note slot="end" id="range-note">{{range}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
|
||||
<ion-item color="dark">
|
||||
<ion-label>Range Mirror</ion-label>
|
||||
<ion-range [(ngModel)]="range"></ion-range>
|
||||
<ion-range [(ngModel)]="range">
|
||||
<ion-toggle slot="start" id="nested-toggle" [(ngModel)]="toggle"></ion-toggle>
|
||||
</ion-range>
|
||||
<ion-note slot="end">{{range}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ export class InputsComponent {
|
||||
toggle = true;
|
||||
select = 'nes';
|
||||
range = 10;
|
||||
changes = 0;
|
||||
|
||||
setValues() {
|
||||
console.log('set values');
|
||||
@@ -32,4 +33,8 @@ export class InputsComponent {
|
||||
this.select = undefined;
|
||||
this.range = undefined;
|
||||
}
|
||||
counter() {
|
||||
this.changes++;
|
||||
return Math.floor(this.changes / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Value</h1>
|
||||
<h2>{{value}}</h2>
|
||||
<h3>{{valueFromParams}}</h3>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button (click)="openModal()" id="action-button">Open Modal</ion-button>
|
||||
<ion-button (click)="openNav()" id="action-button-2">Open Nav in Modal</ion-button>
|
||||
<p>
|
||||
|
||||
@@ -5,13 +5,22 @@
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<p>
|
||||
isLoaded: <span id="is-loaded">{{isLoaded}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isReady: <span id="is-ready">{{isReady}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isResumed: <span id="is-resumed">{{isResumed}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isPaused: <span id="is-paused">{{isPaused}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isResized: <span id="is-resized">{{isResized}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isTesting: <span id="is-testing">{{isTesting}}</span>
|
||||
</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
import {
|
||||
Platform, ModalController, AlertController, ActionSheetController,
|
||||
PopoverController, ToastController, Events, PickerController, MenuController,
|
||||
@@ -14,6 +14,9 @@ export class ProvidersComponent {
|
||||
isLoaded = false;
|
||||
isReady = false;
|
||||
isEvent = false;
|
||||
isResumed = false;
|
||||
isPaused = false;
|
||||
isResized = false;
|
||||
isTesting: boolean = undefined;
|
||||
isDesktop: boolean = undefined;
|
||||
isMobile: boolean = undefined;
|
||||
@@ -32,7 +35,8 @@ export class ProvidersComponent {
|
||||
toastCtrl: ToastController,
|
||||
navCtrl: NavController,
|
||||
domCtrl: DomController,
|
||||
config: Config
|
||||
config: Config,
|
||||
zone: NgZone
|
||||
) {
|
||||
// test all providers load
|
||||
if (
|
||||
@@ -44,15 +48,31 @@ export class ProvidersComponent {
|
||||
|
||||
// test platform ready()
|
||||
platform.ready().then(() => {
|
||||
NgZone.assertInAngularZone();
|
||||
this.isReady = true;
|
||||
});
|
||||
|
||||
platform.resume.subscribe(() => {
|
||||
console.log('platform:resume');
|
||||
NgZone.assertInAngularZone();
|
||||
this.isResumed = true;
|
||||
});
|
||||
platform.pause.subscribe(() => {
|
||||
console.log('platform:pause');
|
||||
NgZone.assertInAngularZone();
|
||||
this.isPaused = true;
|
||||
});
|
||||
platform.resize.subscribe(() => {
|
||||
console.log('platform:resize');
|
||||
NgZone.assertInAngularZone();
|
||||
this.isResized = true;
|
||||
});
|
||||
this.isDesktop = platform.is('desktop');
|
||||
this.isMobile = platform.is('mobile');
|
||||
|
||||
// test events
|
||||
events.subscribe('topic', () => {
|
||||
this.isEvent = true;
|
||||
NgZone.assertInAngularZone();
|
||||
});
|
||||
events.publish('topic');
|
||||
|
||||
@@ -60,5 +80,11 @@ export class ProvidersComponent {
|
||||
this.isTesting = config.getBoolean('_testing');
|
||||
config.set('keyboardHeight', 12345);
|
||||
this.keyboardHeight = config.getNumber('keyboardHeight');
|
||||
|
||||
zone.runOutsideAngular(() => {
|
||||
document.dispatchEvent(new CustomEvent('pause'));
|
||||
document.dispatchEvent(new CustomEvent('resume'));
|
||||
window.dispatchEvent(new CustomEvent('resize'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
|
||||
<p>canGoBack: <span id="canGoBack">{{canGoBack}}</span></p>
|
||||
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
|
||||
<p>ionViewDidEnter: <span id="ionViewDidEnter">{{didEnter}}</span></p>
|
||||
<p>ionViewWillLeave: <span id="ionViewWillLeave">{{willLeave}}</span></p>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, OnInit, NgZone } from '@angular/core';
|
||||
import { IonRouterOutlet } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-router-link-page',
|
||||
@@ -11,9 +12,15 @@ export class RouterLinkPageComponent implements OnInit {
|
||||
didEnter = 0;
|
||||
willLeave = 0;
|
||||
didLeave = 0;
|
||||
canGoBack: boolean = null;
|
||||
|
||||
constructor(
|
||||
private ionRouterOutlet: IonRouterOutlet
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.canGoBack = this.ionRouterOutlet.canGoBack();
|
||||
this.onInit++;
|
||||
}
|
||||
|
||||
@@ -21,10 +28,16 @@ export class RouterLinkPageComponent implements OnInit {
|
||||
if (this.onInit !== 1) {
|
||||
throw new Error('ngOnInit was not called');
|
||||
}
|
||||
if (this.canGoBack !== this.ionRouterOutlet.canGoBack()) {
|
||||
throw new Error('canGoBack() changed');
|
||||
}
|
||||
NgZone.assertInAngularZone();
|
||||
this.willEnter++;
|
||||
}
|
||||
ionViewDidEnter() {
|
||||
if (this.canGoBack !== this.ionRouterOutlet.canGoBack()) {
|
||||
throw new Error('canGoBack() changed');
|
||||
}
|
||||
NgZone.assertInAngularZone();
|
||||
this.didEnter++;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button routerLink="/router-link-page3" id="goToPage3">Go to Page 3</ion-button>
|
||||
</ion-content>
|
||||
@@ -7,6 +7,6 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
Page 3
|
||||
</ion-content>
|
||||
@@ -5,12 +5,13 @@
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
|
||||
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
|
||||
<p>ionViewDidEnter: <span id="ionViewDidEnter">{{didEnter}}</span></p>
|
||||
<p>ionViewWillLeave: <span id="ionViewWillLeave">{{willLeave}}</span></p>
|
||||
<p>ionViewDidLeave: <span id="ionViewDidLeave">{{didLeave}}</span></p>
|
||||
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
|
||||
|
||||
<p>
|
||||
<ion-button routerLink="/router-link-page" expand="block" color="dark" id="routerLink">ion-button[routerLink]</ion-button>
|
||||
@@ -26,7 +27,7 @@
|
||||
<p><button (click)="navigateForward()" id="button-forward">navigateForward</button></p>
|
||||
<p><button (click)="navigateRoot()" id="button-root">navigateForward</button></p>
|
||||
<p><button (click)="navigateBack()" id="button-back">navigateBack</button></p>
|
||||
|
||||
|
||||
<p><button id="queryParamsFragment" routerLink="/router-link-page2/MyPageID==" [queryParams]="{ token: 'A&=#Y' }" fragment="myDiv1">Query Params and Fragment</button></p>
|
||||
|
||||
|
||||
</ion-content>
|
||||
|
||||
@@ -13,6 +13,7 @@ export class RouterLinkComponent implements OnInit {
|
||||
didEnter = 0;
|
||||
willLeave = 0;
|
||||
didLeave = 0;
|
||||
changes = 0;
|
||||
|
||||
constructor(
|
||||
private navCtrl: NavController,
|
||||
@@ -35,6 +36,11 @@ export class RouterLinkComponent implements OnInit {
|
||||
this.navCtrl.navigateRoot('/router-link-page');
|
||||
}
|
||||
|
||||
counter() {
|
||||
this.changes++;
|
||||
return Math.floor(this.changes / 2);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.onInit++;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||
import { AfterViewInit, Component, ViewChild } from '@angular/core';
|
||||
import { IonSlides } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
@@ -6,7 +6,7 @@ import { IonSlides } from '@ionic/angular';
|
||||
templateUrl: './slides.component.html',
|
||||
})
|
||||
export class SlidesComponent implements AfterViewInit {
|
||||
@ViewChild(IonSlides) slides: IonSlides;
|
||||
@ViewChild(IonSlides, { static: true }) slides: IonSlides;
|
||||
|
||||
slideIndex = 0;
|
||||
slideIndex2 = 0;
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>LAZY LOADED TAB</h1>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
<ion-button routerLink="/tabs/lazy/nested" id="goto-tab3-page2">Go to Tab 3 - Page 2</ion-button>
|
||||
|
||||
</p>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab 1 - Page 2</ion-title>
|
||||
<ion-title>Tab 1 - Page 2 ({{id}})</ion-title>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<h1>Welcome to NESTED PAGE</h1>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Welcome to NESTED PAGE {{id}}</h1>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/contact" id="goto-tab2-page1">Go to Tab 2 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/{{next()}}" id="goto-next">Go to Next</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs-tab1-nested',
|
||||
templateUrl: './tabs-tab1-nested.component.html',
|
||||
})
|
||||
export class TabsTab1NestedComponent { }
|
||||
export class TabsTab1NestedComponent {
|
||||
id = '';
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.id = this.route.snapshot.paramMap.get('id');
|
||||
}
|
||||
|
||||
next() {
|
||||
return parseInt(this.id, 10) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab 1 - Page 1</ion-title>
|
||||
<ion-title>{{title}}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Welcome to Tab1</h1>
|
||||
<ion-segment [(ngModel)]="segment" (ionChange)="segmentChanged($event)">
|
||||
<ion-segment-button value="one">One</ion-segment-button>
|
||||
<ion-segment-button value="two">Two</ion-segment-button>
|
||||
</ion-segment>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Page 2</ion-button>
|
||||
Segment changed: <span class="segment-changed">{{changed}}</span>
|
||||
</p>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Page 2</ion-button>
|
||||
<ion-button routerLink="/tabs/lazy/nested" id="goto-tab3-page2">Go to Tab 3 - Page 2</ion-button>
|
||||
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
|
||||
</p>
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs-tab1',
|
||||
templateUrl: './tabs-tab1.component.html',
|
||||
})
|
||||
export class TabsTab1Component { }
|
||||
export class TabsTab1Component {
|
||||
title = 'ERROR';
|
||||
segment = 'one';
|
||||
changed = 'false';
|
||||
|
||||
ionViewWillEnter() {
|
||||
NgZone.assertInAngularZone();
|
||||
setTimeout(() => {
|
||||
NgZone.assertInAngularZone();
|
||||
this.title = 'Tab 1 - Page 1';
|
||||
});
|
||||
}
|
||||
|
||||
segmentChanged(ev: any) {
|
||||
console.log('Segment changed', ev);
|
||||
this.changed = 'true';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab 2 - Page 1</ion-title>
|
||||
<ion-title>{{title}}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Welcome to Tab 2</h1>
|
||||
<ion-segment [(ngModel)]="segment" (ionChange)="segmentChanged($event)">
|
||||
<ion-segment-button value="one">One</ion-segment-button>
|
||||
<ion-segment-button value="two">Two</ion-segment-button>
|
||||
</ion-segment>
|
||||
<p>
|
||||
Segment changed: <span class="segment-changed">{{changed}}</span>
|
||||
</p>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs-tab2',
|
||||
templateUrl: './tabs-tab2.component.html',
|
||||
})
|
||||
export class TabsTab2Component { }
|
||||
export class TabsTab2Component {
|
||||
title = 'ERROR';
|
||||
segment = 'two';
|
||||
changed = 'false';
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
setTimeout(() => {
|
||||
NgZone.assertInAngularZone();
|
||||
this.title = 'Tab 2 - Page 1';
|
||||
});
|
||||
}
|
||||
|
||||
segmentChanged(ev: any) {
|
||||
console.log('Segment changed', ev);
|
||||
this.changed = 'true';
|
||||
}
|
||||
}
|
||||
|
||||
27
angular/test/test-app/src/app/tabs/tabs.module.ts
Executable file
27
angular/test/test-app/src/app/tabs/tabs.module.ts
Executable file
@@ -0,0 +1,27 @@
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { TabsPageRoutingModule } from './tabs.router.module';
|
||||
import { TabsComponent } from './tabs.component';
|
||||
import { TabsTab1Component } from '../tabs-tab1/tabs-tab1.component';
|
||||
import { TabsTab2Component } from '../tabs-tab2/tabs-tab2.component';
|
||||
import { TabsTab1NestedComponent } from '../tabs-tab1-nested/tabs-tab1-nested.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
TabsPageRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
TabsComponent,
|
||||
TabsTab1Component,
|
||||
TabsTab2Component,
|
||||
TabsTab1NestedComponent
|
||||
]
|
||||
})
|
||||
export class TabsPageModule {}
|
||||
52
angular/test/test-app/src/app/tabs/tabs.router.module.ts
Executable file
52
angular/test/test-app/src/app/tabs/tabs.router.module.ts
Executable file
@@ -0,0 +1,52 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { TabsComponent } from './tabs.component';
|
||||
import { TabsTab1NestedComponent } from '../tabs-tab1-nested/tabs-tab1-nested.component';
|
||||
import { TabsTab1Component } from '../tabs-tab1/tabs-tab1.component';
|
||||
import { TabsTab2Component } from '../tabs-tab2/tabs-tab2.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: TabsComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'account',
|
||||
children: [
|
||||
{
|
||||
path: 'nested/:id',
|
||||
component: TabsTab1NestedComponent
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: TabsTab1Component
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'contact',
|
||||
children: [
|
||||
{
|
||||
path: 'one',
|
||||
component: TabsTab2Component
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'one',
|
||||
pathMatch: 'full'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'lazy',
|
||||
loadChildren: () => import('../tabs-lazy/tabs-lazy.module').then(m => m.TabsLazyModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class TabsPageRoutingModule {}
|
||||
@@ -5,7 +5,7 @@
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-slides>
|
||||
<ion-slide #slide>
|
||||
<ion-button id="color-button">Hello! it's a button</ion-button>
|
||||
|
||||
@@ -7,11 +7,11 @@ import { IonTabs, IonButton, IonSlides, IonSlide } from '@ionic/angular';
|
||||
})
|
||||
export class ViewChildComponent implements AfterViewInit {
|
||||
|
||||
@ViewChild(IonSlides) slides: IonSlides;
|
||||
@ViewChild(IonButton) button: IonButton;
|
||||
@ViewChild(IonTabs) tabs: IonTabs;
|
||||
@ViewChild('div') div: ElementRef;
|
||||
@ViewChild('slide') slide: IonSlide;
|
||||
@ViewChild(IonSlides, { static: true }) slides: IonSlides;
|
||||
@ViewChild(IonButton, { static: true }) button: IonButton;
|
||||
@ViewChild(IonTabs, { static: true }) tabs: IonTabs;
|
||||
@ViewChild('div', { static: true }) div: ElementRef;
|
||||
@ViewChild('slide', { static: true }) slide: IonSlide;
|
||||
|
||||
ngAfterViewInit() {
|
||||
const loaded = !!(this.slides && this.button && this.tabs && this.div && this.slide);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Item {{itemNu}}</h1>
|
||||
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
|
||||
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user