mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
296 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75cf887f91 | ||
|
|
32c5bed546 | ||
|
|
4f3e91bdfa | ||
|
|
236e7f8393 | ||
|
|
ea710044ef | ||
|
|
efd6605f98 | ||
|
|
aaa3cac917 | ||
|
|
4cc54eeb5d | ||
|
|
cfdba88754 | ||
|
|
7c583938a2 | ||
|
|
d659676ba2 | ||
|
|
e555eae1f5 | ||
|
|
5742540a36 | ||
|
|
6978bb551f | ||
|
|
e7ac15f9be | ||
|
|
2ab8385ee0 | ||
|
|
616786b387 | ||
|
|
6b5f9f113f | ||
|
|
2bba548253 | ||
|
|
1497d83a0e | ||
|
|
7f7f60ede5 | ||
|
|
73f6a82446 | ||
|
|
893ef725e9 | ||
|
|
4ea843440b | ||
|
|
f2946e77e6 | ||
|
|
ebdf22d2d3 | ||
|
|
dd66f9a7a9 | ||
|
|
6b848a04b3 | ||
|
|
af363581da | ||
|
|
33960f1a5a | ||
|
|
e5df0625b2 | ||
|
|
22747e3588 | ||
|
|
dc280b4199 | ||
|
|
fae5365b12 | ||
|
|
ecde0ae70f | ||
|
|
c8be8e254c | ||
|
|
356240883e | ||
|
|
c4e9b5d343 | ||
|
|
9f17b388d2 | ||
|
|
49e0c3701a | ||
|
|
ee766e1de8 | ||
|
|
74c5871ac4 | ||
|
|
8ec70ee02a | ||
|
|
ae4be669bb | ||
|
|
c91223bfb2 | ||
|
|
b1803510e3 | ||
|
|
70809caa8d | ||
|
|
88b2e8316d | ||
|
|
199cb00444 | ||
|
|
9bfd286dfa | ||
|
|
ac4dd6fea2 | ||
|
|
2646ebedf1 | ||
|
|
a77bb2c1d5 | ||
|
|
c963745888 | ||
|
|
2bd89feb0f | ||
|
|
c38cc28c5f | ||
|
|
9d4c94a7ac | ||
|
|
ad8d8ed2c3 | ||
|
|
0ba33d943f | ||
|
|
e0c830962c | ||
|
|
dac887092e | ||
|
|
e5b3eb7c8b | ||
|
|
c60588a290 | ||
|
|
77fcaef436 | ||
|
|
9c2181b8f9 | ||
|
|
4db20a648c | ||
|
|
f6d6596912 | ||
|
|
39e7da3840 | ||
|
|
9b3fb78a68 | ||
|
|
559f4d3bd5 | ||
|
|
f1a676e4c2 | ||
|
|
1573043f4e | ||
|
|
0a49648fe8 | ||
|
|
599bf3df5e | ||
|
|
fce5d8a04f | ||
|
|
108fc0fc3f | ||
|
|
521402b548 | ||
|
|
921ccbb79e | ||
|
|
c08de08d5f | ||
|
|
4199accdc2 | ||
|
|
70ab2a4e74 | ||
|
|
eacc5d4f23 | ||
|
|
112d4f5490 | ||
|
|
f42e81b02b | ||
|
|
9b5c0e035b | ||
|
|
4e56458b5c | ||
|
|
b5bfda2c42 | ||
|
|
200fa935b8 | ||
|
|
66faa1d959 | ||
|
|
b248eb7508 | ||
|
|
c7b2b186ec | ||
|
|
86210750d5 | ||
|
|
794d88d455 | ||
|
|
a48d02a966 | ||
|
|
d028a29d0e | ||
|
|
288c00a641 | ||
|
|
3b5c34c801 | ||
|
|
f2dc8b24b1 | ||
|
|
547ab8d8ef | ||
|
|
e2b3d753a7 | ||
|
|
3fb0371927 | ||
|
|
59f97e780d | ||
|
|
468dcd32fa | ||
|
|
cfd9e3b3a9 | ||
|
|
86e2742d58 | ||
|
|
8c207e827e | ||
|
|
fdacbbf1d0 | ||
|
|
ac04710b8a | ||
|
|
d0cad6b31e | ||
|
|
f5ef1ca552 | ||
|
|
830f885a06 | ||
|
|
318737535f | ||
|
|
04fe92cd58 | ||
|
|
b809665944 | ||
|
|
4d786b30ba | ||
|
|
4f49f27824 | ||
|
|
7e8bd5a8fe | ||
|
|
f4539aacc9 | ||
|
|
4911d9f01a | ||
|
|
6e64b8d915 | ||
|
|
e3216da03e | ||
|
|
bd0c265978 | ||
|
|
846eb09991 | ||
|
|
ac4a043314 | ||
|
|
106950533c | ||
|
|
295fe783b0 | ||
|
|
0a6bb3bb21 | ||
|
|
1b9c3daef1 | ||
|
|
54cdf00454 | ||
|
|
5bb3e73296 | ||
|
|
ae94f5ecea | ||
|
|
b87d212829 | ||
|
|
26b09f1d49 | ||
|
|
1e9539b9df | ||
|
|
17b3a39f0d | ||
|
|
475b722c7d | ||
|
|
50beafae6a | ||
|
|
f605f0a74c | ||
|
|
e401997a42 | ||
|
|
16f2ebe241 | ||
|
|
584afd040f | ||
|
|
de0f9d5f28 | ||
|
|
4596dbe5c0 | ||
|
|
400aa549d4 | ||
|
|
add0c4ecfe | ||
|
|
519d657e6e | ||
|
|
a8ceee467b | ||
|
|
97f9522110 | ||
|
|
961bfc3ebb | ||
|
|
5b9fe5e81a | ||
|
|
c4e7552b56 | ||
|
|
cec718c6c7 | ||
|
|
ab511c4744 | ||
|
|
2d49e10da4 | ||
|
|
ce46c24413 | ||
|
|
f7fce5fa16 | ||
|
|
d23b9f7d49 | ||
|
|
4c13535416 | ||
|
|
889b49f372 | ||
|
|
acb6facc7b | ||
|
|
2153940de8 | ||
|
|
6d8da0ae32 | ||
|
|
347c260950 | ||
|
|
9ffc52b582 | ||
|
|
08be9dc58b | ||
|
|
ad25cd1cd7 | ||
|
|
693c1c56d1 | ||
|
|
b5aa304e7e | ||
|
|
3e3a00b2fb | ||
|
|
923e3b2e26 | ||
|
|
e079f7777f | ||
|
|
5a4b351794 | ||
|
|
d22d77b485 | ||
|
|
efd54750bf | ||
|
|
eb830d4202 | ||
|
|
3f39e14f76 | ||
|
|
fce4422ab1 | ||
|
|
04e78d8c22 | ||
|
|
48b3243689 | ||
|
|
486bff036d | ||
|
|
a7e5fa7ea7 | ||
|
|
5771543c3b | ||
|
|
048af1b329 | ||
|
|
a92d805e89 | ||
|
|
8dc08f9c1f | ||
|
|
bc7bb21f1a | ||
|
|
016b90da47 | ||
|
|
0f5c47db15 | ||
|
|
86495e111d | ||
|
|
fba6ff0638 | ||
|
|
30f69c8a16 | ||
|
|
1beef75c80 | ||
|
|
58e1d79518 | ||
|
|
0480f73f8e | ||
|
|
f39c3811c5 | ||
|
|
6f7acdbddf | ||
|
|
bcc85d9144 | ||
|
|
00fbded168 | ||
|
|
5cad96570f | ||
|
|
e3a8d27ec1 | ||
|
|
d8b65da6ac | ||
|
|
70b5b6b5e5 | ||
|
|
5094feec89 | ||
|
|
1ca7df75ed | ||
|
|
877d8211d5 | ||
|
|
a8731dfc98 | ||
|
|
7803998542 | ||
|
|
8bd2f24d06 | ||
|
|
63f728f517 | ||
|
|
61935602a1 | ||
|
|
1a4aacf8be | ||
|
|
5a5da39a1e | ||
|
|
c7645ee59d | ||
|
|
2743c63537 | ||
|
|
7a1342caa1 | ||
|
|
3564bcfe1b | ||
|
|
f149c5ee95 | ||
|
|
2791c40c29 | ||
|
|
54ac2e393f | ||
|
|
dc958c3e2c | ||
|
|
9f86e10f46 | ||
|
|
8041eedf22 | ||
|
|
ef85ba6c1f | ||
|
|
6dee17b89b | ||
|
|
c10f72b1e2 | ||
|
|
47e3c70bf3 | ||
|
|
a91a68e198 | ||
|
|
3e0d43e7dc | ||
|
|
d0847aabdb | ||
|
|
63b0f0aaf6 | ||
|
|
10f4df42d0 | ||
|
|
f4452b5d33 | ||
|
|
20c9dd7e64 | ||
|
|
6db8c147a6 | ||
|
|
3c046b413b | ||
|
|
30dc247404 | ||
|
|
ac52d3b724 | ||
|
|
435f5c4db0 | ||
|
|
30047f004e | ||
|
|
75bfbad21e | ||
|
|
2273fb5d47 | ||
|
|
bb574743d9 | ||
|
|
d0ae810bae | ||
|
|
344589a00e | ||
|
|
dc6c5863fb | ||
|
|
f7ac32bbf1 | ||
|
|
c0033f512a | ||
|
|
305c306b14 | ||
|
|
9aedc9dc52 | ||
|
|
fe751f7ac3 | ||
|
|
5d2974f2d2 | ||
|
|
133a0f9379 | ||
|
|
bb966e5a31 | ||
|
|
f0c6948ef8 | ||
|
|
ad40b3b86b | ||
|
|
cb5d505d64 | ||
|
|
2cffb44187 | ||
|
|
35a0e228de | ||
|
|
7d8696c050 | ||
|
|
1c25acbb1f | ||
|
|
64cac79da6 | ||
|
|
59a1e3def1 | ||
|
|
e3c60c5de4 | ||
|
|
f5bbdcd32e | ||
|
|
6322134994 | ||
|
|
dd6de0d625 | ||
|
|
c9cb9ae15a | ||
|
|
6256b0fa66 | ||
|
|
a40b872975 | ||
|
|
57dc22d173 | ||
|
|
0f4ed1c7f8 | ||
|
|
1c76cde986 | ||
|
|
76a9454285 | ||
|
|
0570e3e262 | ||
|
|
4c57326dc4 | ||
|
|
0624a77afe | ||
|
|
7af93d23b8 | ||
|
|
42d29f4331 | ||
|
|
ecc4e4a530 | ||
|
|
18517660d4 | ||
|
|
117003e9e4 | ||
|
|
041689b5f5 | ||
|
|
e354f21936 | ||
|
|
73ab06e360 | ||
|
|
d4fce8995b | ||
|
|
2afb936536 | ||
|
|
e526ce1da5 | ||
|
|
39909d0f68 | ||
|
|
261bc4d5f4 | ||
|
|
f14d7d6524 | ||
|
|
2edb085d4d | ||
|
|
638ab70309 | ||
|
|
556745191f | ||
|
|
3de6d24a40 | ||
|
|
8ba1fcac45 | ||
|
|
4a56cbba29 |
18
.github/CONTRIBUTING.md
vendored
18
.github/CONTRIBUTING.md
vendored
@@ -5,7 +5,7 @@ Thanks for your interest in contributing to the Ionic Framework! :tada:
|
||||
|
||||
## Contributing Etiquette
|
||||
|
||||
Please see our [Contributor Code of Conduct](https://github.com/driftyco/ionic/blob/master/CODE_OF_CONDUCT.md) for information on our rules of conduct.
|
||||
Please see our [Contributor Code of Conduct](https://github.com/ionic-team/ionic/blob/master/CODE_OF_CONDUCT.md) for information on our rules of conduct.
|
||||
|
||||
|
||||
## Creating an Issue
|
||||
@@ -18,16 +18,16 @@ Please see our [Contributor Code of Conduct](https://github.com/driftyco/ionic/b
|
||||
|
||||
* Issues with no clear steps to reproduce will not be triaged. If an issue is labeled with "needs reply" and receives no further replies from the author of the issue for more than 5 days, it will be closed.
|
||||
|
||||
* If you think you have found a bug, or have a new feature idea, please start by making sure it hasn't already been [reported](https://github.com/driftyco/ionic/issues?utf8=%E2%9C%93&q=is%3Aissue). You can search through existing issues to see if there is a similar one reported. Include closed issues as it may have been closed with a solution.
|
||||
* If you think you have found a bug, or have a new feature idea, please start by making sure it hasn't already been [reported](https://github.com/ionic-team/ionic/issues?utf8=%E2%9C%93&q=is%3Aissue). You can search through existing issues to see if there is a similar one reported. Include closed issues as it may have been closed with a solution.
|
||||
|
||||
* Next, [create a new issue](https://github.com/driftyco/ionic/issues/new) that thoroughly explains the problem. Please fill out the populated issue form before submitting the issue.
|
||||
* Next, [create a new issue](https://github.com/ionic-team/ionic/issues/new) that thoroughly explains the problem. Please fill out the populated issue form before submitting the issue.
|
||||
|
||||
|
||||
## Creating a Pull Request
|
||||
|
||||
* We appreciate you taking the time to contribute! Before submitting a pull request, we ask that you please [create an issue](#creating-an-issue) that explains the bug or feature request and let us know that you plan on creating a pull request for it. If an issue already exists, please comment on that issue letting us know you would like to submit a pull request for it. This helps us to keep track of the pull request and make sure there isn't duplicated effort.
|
||||
|
||||
* Looking for an issue to fix? Make sure to look through our issues with the [help wanted](https://github.com/driftyco/ionic/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) label!
|
||||
* Looking for an issue to fix? Make sure to look through our issues with the [help wanted](https://github.com/ionic-team/ionic/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) label!
|
||||
|
||||
### Setup
|
||||
|
||||
@@ -85,9 +85,9 @@ Please see our [Contributor Code of Conduct](https://github.com/driftyco/ionic/b
|
||||
```
|
||||
|
||||
where `@name` is the Class name, `@description` is the description displayed on the documentation page, `@see` links to any related pages, and `@demo` links to the API demo located in the `demos` folder.
|
||||
2. In order to run API documentation locally, you will need to clone the `ionic-site` repo as a sibling to the `ionic` repo and then run it: https://github.com/driftyco/ionic-site#local-build
|
||||
2. In order to run API documentation locally, you will need to clone the `ionic-site` repo as a sibling to the `ionic` repo and then run it: https://github.com/ionic-team/ionic-site#local-build
|
||||
3. Then, run `gulp docs` in the `ionic` repo every time you make a change and the site will update.
|
||||
4. If the change affects the component documentation, create an issue on the `ionic-site` repo: https://github.com/driftyco/ionic-site/issues
|
||||
4. If the change affects the component documentation, create an issue on the `ionic-site` repo: https://github.com/ionic-team/ionic-site/issues
|
||||
|
||||
|
||||
#### Adding Demos
|
||||
@@ -106,12 +106,12 @@ Please see our [Contributor Code of Conduct](https://github.com/driftyco/ionic/b
|
||||
```
|
||||
3. Run `gulp watch.demos` to watch for changes to the demo
|
||||
4. Navigate to `http://localhost:8000/dist/demos/` and then to your component's demo to view it.
|
||||
5. If the change affects the component demos, create an issue on the `ionic-site` repo: https://github.com/driftyco/ionic-site/issues
|
||||
5. If the change affects the component demos, create an issue on the `ionic-site` repo: https://github.com/ionic-team/ionic-site/issues
|
||||
|
||||
|
||||
## Commit Message Format
|
||||
|
||||
We have very precise rules over how our git commit messages should be formatted. This leads to readable messages that are easy to follow when looking through the project history. We also use the git commit messages to generate our [changelog](https://github.com/driftyco/ionic/blob/master/CHANGELOG.md). (Ok you got us, it's basically Angular's commit message format).
|
||||
We have very precise rules over how our git commit messages should be formatted. This leads to readable messages that are easy to follow when looking through the project history. We also use the git commit messages to generate our [changelog](https://github.com/ionic-team/ionic/blob/master/CHANGELOG.md). (Ok you got us, it's basically Angular's commit message format).
|
||||
|
||||
`type(scope): subject`
|
||||
|
||||
@@ -143,4 +143,4 @@ The subject contains succinct description of the change:
|
||||
|
||||
## License
|
||||
|
||||
By contributing your code to the driftyco/ionic GitHub Repository, you agree to license your contribution under the MIT license.
|
||||
By contributing your code to the ionic-team/ionic GitHub Repository, you agree to license your contribution under the MIT license.
|
||||
|
||||
29
.github/ISSUE_TEMPLATE.md
vendored
29
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,12 +1,18 @@
|
||||
<!-- Before submitting an issue, please consult our troubleshooting guide (http://ionicframework.com/docs/troubleshooting/) and developer resources (http://ionicframework.com/docs/developer-resources/) -->
|
||||
|
||||
<!-- Please make sure you are posting an issue pertaining to the Ionic Framework. If you are having an issue with the Ionic Pro services (Ionic View, Ionic Deploy, etc.) please consult the Ionic Pro support portal (http://support.ionicjs.com) -->
|
||||
|
||||
**Ionic version:** (check one with "x")
|
||||
[ ] **1.x** (For Ionic 1.x issues, please use https://github.com/driftyco/ionic-v1)
|
||||
(For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
|
||||
[ ] **2.x**
|
||||
[ ] **3.x**
|
||||
[ ] **4.x**
|
||||
|
||||
**I'm submitting a ...** (check one with "x")
|
||||
[ ] bug report
|
||||
[ ] feature request
|
||||
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
|
||||
|
||||
Please do not submit support requests or "How to" questions here. Instead, please use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
|
||||
|
||||
**Current behavior:**
|
||||
<!-- Describe how the bug manifests. -->
|
||||
@@ -15,17 +21,22 @@
|
||||
<!-- Describe what the behavior would be without the bug. -->
|
||||
|
||||
**Steps to reproduce:**
|
||||
<!-- If you are able to illustrate the bug or feature request with an example, please provide steps to reproduce and if possible a demo using one of the following templates:
|
||||
|
||||
For Ionic V1 issues - http://plnkr.co/edit/Xo1QyAUx35ny1Xf9ODHx?p=preview
|
||||
|
||||
For Ionic issues - http://plnkr.co/edit/z0DzVL?p=preview
|
||||
-->
|
||||
<!-- Please explain the steps required to duplicate the issue, especially if you are able to provide a sample application. -->
|
||||
|
||||
**Related code:**
|
||||
|
||||
<!-- If you are able to illustrate the bug or feature request with an example, please provide a sample application via one of the following means:
|
||||
|
||||
A sample application via GitHub
|
||||
|
||||
StackBlitz (https://stackblitz.com)
|
||||
|
||||
Plunker (http://plnkr.co/edit/cpeRJs?p=preview)
|
||||
|
||||
-->
|
||||
|
||||
```
|
||||
insert any relevant code here
|
||||
insert short code snippets here
|
||||
```
|
||||
|
||||
**Other information:**
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,6 +9,7 @@ log.txt
|
||||
*.sublime-workspace
|
||||
|
||||
.idea/
|
||||
.sourcemaps/
|
||||
.vscode/
|
||||
.sass-cache/
|
||||
.versions/
|
||||
|
||||
@@ -2,12 +2,9 @@
|
||||
|
||||
# See config at https://github.com/brigade/scss-lint/blob/master/config/default.yml
|
||||
|
||||
plugin_directories: ['.scss-linters']
|
||||
|
||||
exclude:
|
||||
- 'src/components/item/item.ios.scss'
|
||||
- 'src/components/item/item.md.scss'
|
||||
- 'src/components/list/list.ios.scss'
|
||||
- 'src/components/show-hide-when/**'
|
||||
- 'src/components/slides/**'
|
||||
- 'src/themes/ionic.mixins.scss'
|
||||
- 'src/themes/license.scss'
|
||||
- 'src/themes/util.scss'
|
||||
@@ -19,6 +16,9 @@ linters:
|
||||
ColorVariable:
|
||||
enabled: false
|
||||
|
||||
DefaultRule:
|
||||
enabled: true
|
||||
|
||||
DuplicateProperty:
|
||||
enabled: false
|
||||
|
||||
@@ -56,11 +56,6 @@ linters:
|
||||
- justify-content
|
||||
- order
|
||||
-
|
||||
- margin-top
|
||||
- margin-bottom
|
||||
- padding-top
|
||||
- padding-bottom
|
||||
-
|
||||
- width
|
||||
- min-width
|
||||
- max-width
|
||||
@@ -140,7 +135,6 @@ linters:
|
||||
- background-color
|
||||
- background-image
|
||||
- background-repeat
|
||||
- background-position
|
||||
- background-size
|
||||
|
||||
# Other
|
||||
@@ -163,7 +157,6 @@ linters:
|
||||
|
||||
- transform
|
||||
- transform-box
|
||||
- transform-origin
|
||||
- transform-style
|
||||
|
||||
- transition
|
||||
@@ -188,27 +181,33 @@ linters:
|
||||
enabled: true
|
||||
style: double_quotes
|
||||
|
||||
SelectorDepth:
|
||||
enabled: true
|
||||
max_depth: 5
|
||||
|
||||
PropertySpelling:
|
||||
extra_properties:
|
||||
- contain
|
||||
disabled_properties:
|
||||
- background-position
|
||||
- direction
|
||||
- right
|
||||
- left
|
||||
|
||||
- float
|
||||
|
||||
- padding
|
||||
- padding-left
|
||||
- padding-right
|
||||
|
||||
- padding-top
|
||||
- padding-bottom
|
||||
- margin
|
||||
- margin-left
|
||||
- margin-right
|
||||
|
||||
- margin-top
|
||||
- margin-bottom
|
||||
- border-radius
|
||||
- border-top-left-radius
|
||||
- border-top-right-radius
|
||||
- border-bottom-right-radius
|
||||
- border-bottom-left-radius
|
||||
|
||||
- text-align
|
||||
- transform-origin
|
||||
18
.scss-linters/default_rule.rb
Normal file
18
.scss-linters/default_rule.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
module SCSSLint
|
||||
# Reports the use of !default at the end of variable declarations.
|
||||
class Linter::DefaultRule < Linter
|
||||
include LinterRegistry
|
||||
|
||||
def visit_function(node)
|
||||
return true
|
||||
end
|
||||
|
||||
def visit_variable(node)
|
||||
return if source_from_range(node.source_range).include?('!default')
|
||||
|
||||
return unless node_ancestor(node, 2).nil?
|
||||
|
||||
add_lint(node, '!default should be used')
|
||||
end
|
||||
end
|
||||
end
|
||||
1958
CHANGELOG.md
1958
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
2
LICENSE
2
LICENSE
@@ -20,4 +20,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
12
README.md
12
README.md
@@ -1,5 +1,5 @@
|
||||
[](https://badge.fury.io/js/ionic-angular)
|
||||
[](https://circleci.com/gh/driftyco/ionic)
|
||||
[](https://circleci.com/gh/ionic-team/ionic)
|
||||
|
||||
# Ionic
|
||||
|
||||
@@ -17,21 +17,21 @@ started using Ionic.
|
||||
|
||||
Start a new project by following our quick [Getting Started guide](https://ionicframework.com/getting-started/).
|
||||
We would love to hear from you! If you have any feedback or run into issues using our framework, please file
|
||||
an [issue](https://github.com/driftyco/ionic/issues/new) on this repository.
|
||||
an [issue](https://github.com/ionic-team/ionic/issues/new) on this repository.
|
||||
|
||||
### Contributing
|
||||
|
||||
Thanks for your interest in contributing! Read up on our guidelines for
|
||||
[contributing](https://github.com/driftyco/ionic/blob/master/.github/CONTRIBUTING.md)
|
||||
and then look through our issues with a [help wanted](https://github.com/driftyco/ionic/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
[contributing](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md)
|
||||
and then look through our issues with a [help wanted](https://github.com/ionic-team/ionic/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
label.
|
||||
|
||||
### Examples
|
||||
|
||||
The [Ionic Conference App](https://github.com/driftyco/ionic-conference-app) is a full featured Ionic app.
|
||||
The [Ionic Conference App](https://github.com/ionic-team/ionic-conference-app) is a full featured Ionic app.
|
||||
It is the perfect starting point for learning and building your own app.
|
||||
|
||||
### Ionic V1
|
||||
|
||||
The source code for Ionic V1 has been moved to [driftyco/ionic-v1](https://github.com/driftyco/ionic-v1).
|
||||
The source code for Ionic V1 has been moved to [ionic-team/ionic-v1](https://github.com/ionic-team/ionic-v1).
|
||||
Please open any issues and pull requests related to Ionic V1 on that repository.
|
||||
|
||||
@@ -4,6 +4,10 @@ jobs:
|
||||
working_directory: ~/ionic/
|
||||
docker:
|
||||
- image: node:7
|
||||
branches:
|
||||
ignore:
|
||||
- mono-refactor
|
||||
- core
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
|
||||
@@ -58,13 +58,13 @@ export class PageOne {
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
handler: (data) => {
|
||||
handler: () => {
|
||||
console.log('Cancel clicked');
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Save',
|
||||
handler: (data) => {
|
||||
handler: () => {
|
||||
console.log('Saved clicked');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,12 +39,12 @@
|
||||
|
||||
<h4>Icons</h4>
|
||||
|
||||
<button ion-button icon-left color="dark">
|
||||
<button ion-button icon-start color="dark">
|
||||
<ion-icon name="star"></ion-icon>
|
||||
Left Icon
|
||||
</button>
|
||||
|
||||
<button ion-button icon-right color="dark">
|
||||
<button ion-button icon-end color="dark">
|
||||
Right Icon
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</button>
|
||||
|
||||
@@ -26,7 +26,7 @@ export class AppComponent {
|
||||
this.listenToLoginEvents();
|
||||
}
|
||||
|
||||
openPage(menu: any, page: any) {
|
||||
openPage(_: any, page: any) {
|
||||
// find the nav component and set what the root page should be
|
||||
// reset the nav to remove previous pages and only have this page
|
||||
// we wouldn't want the back button to show in this scenario
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<ion-icon name="trash"></ion-icon>
|
||||
</button>
|
||||
</ion-item-options>
|
||||
<ion-item-options (ionSwipe)="download(item)" icon-left>
|
||||
<ion-item-options (ionSwipe)="download(item)" icon-start>
|
||||
<button ion-button color="dark" (click)="more(item)">
|
||||
<ion-icon name="volume-off"></ion-icon>
|
||||
Mute
|
||||
@@ -85,7 +85,7 @@
|
||||
</ion-content>
|
||||
|
||||
<style>
|
||||
/* TODO: spinner is dropping classes so we have to use ids: https://github.com/driftyco/ionic/issues/7087 */
|
||||
/* TODO: spinner is dropping classes so we have to use ids: https://github.com/ionic-team/ionic/issues/7087 */
|
||||
#archive-spinner,
|
||||
#download-spinner,
|
||||
.archiving .expand-hide,
|
||||
@@ -93,7 +93,7 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* TODO: spinner doesn't have a good way to do this yet: https://github.com/driftyco/ionic/issues/7087 */
|
||||
/* TODO: spinner doesn't have a good way to do this yet: https://github.com/ionic-team/ionic/issues/7087 */
|
||||
#archive-spinner.spinner-ios line,
|
||||
#archive-spinner.spinner-crescent circle {
|
||||
stroke: #fff;
|
||||
|
||||
@@ -71,7 +71,7 @@ export class PageOne {
|
||||
this.expandAction(item, 'downloading', 'Login was downloaded.');
|
||||
}
|
||||
|
||||
expandAction(item: ItemSliding, action: string, text: string) {
|
||||
expandAction(item: ItemSliding, _: any, text: string) {
|
||||
// TODO item.setElementClass(action, true);
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
<ion-toolbar>
|
||||
<ion-buttons end>
|
||||
<button ion-button icon-right (click)="goToPage2()">
|
||||
<button ion-button icon-end (click)="goToPage2()">
|
||||
Show Loading and Navigate
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
</button>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</ion-buttons>
|
||||
<ion-title>Solid</ion-title>
|
||||
<ion-buttons end>
|
||||
<button ion-button icon-right solid color="secondary">
|
||||
<button ion-button icon-end solid color="secondary">
|
||||
Help
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
</button>
|
||||
@@ -69,7 +69,7 @@
|
||||
</button>
|
||||
</ion-buttons>
|
||||
<ion-buttons end>
|
||||
<button ion-button icon-right outline color="secondary">
|
||||
<button ion-button icon-end outline color="secondary">
|
||||
Help
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
</button>
|
||||
|
||||
@@ -16,7 +16,7 @@ export class PageOne {
|
||||
|
||||
filterItems(ev: any) {
|
||||
this.setItems();
|
||||
let val = ev.value;
|
||||
let val = ev.target.value;
|
||||
|
||||
if (val && val.trim() !== '') {
|
||||
this.items = this.items.filter(function(item) {
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Hair Color</ion-label>
|
||||
<ion-select [(ngModel)]="hairColor" okText="Okay" cancelText="Dismiss" [compareWith]="compareFn">
|
||||
<ion-option *ngFor="let o of hairColorData" [value]="o">{{o.text}}</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Gaming</ion-label>
|
||||
<ion-select [(ngModel)]="gaming" okText="Okay" cancelText="Dismiss">
|
||||
@@ -147,6 +154,13 @@
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Skittles</ion-label>
|
||||
<ion-select [(ngModel)]="skittles" multiple="true" okText="Okay" cancelText="Dismiss" [compareWith]="compareFn">
|
||||
<ion-option *ngFor="let o of skittlesData" [value]="o">{{o.text}}</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Disabled</ion-label>
|
||||
<ion-select multiple disabled="true">
|
||||
|
||||
@@ -10,6 +10,10 @@ export class PageOne {
|
||||
petAlertOpts: any;
|
||||
petData: any;
|
||||
pets: Array<string>;
|
||||
hairColorData: any;
|
||||
hairColor: any;
|
||||
skittlesData: any;
|
||||
skittles: Array<any>;
|
||||
notifications: string = 'mute_1';
|
||||
rating: number = 2;
|
||||
|
||||
@@ -31,9 +35,37 @@ export class PageOne {
|
||||
{ text: 'Honey Badger', value: 'honeybadger' },
|
||||
];
|
||||
|
||||
this.hairColorData = [
|
||||
{ text: 'Brown', value: 'brown' },
|
||||
{ text: 'Blonde', value: 'blonde' },
|
||||
{ text: 'Black', value: 'black' },
|
||||
{ text: 'Red', value: 'red' }
|
||||
];
|
||||
|
||||
// Pre-selected object with different object reference
|
||||
this.hairColor = { text: 'Brown', value: 'brown' };
|
||||
|
||||
this.skittlesData = [
|
||||
{ text: 'Red', value: 'red' },
|
||||
{ text: 'Orange', value: 'orange' },
|
||||
{ text: 'Yellow', value: 'yellow' },
|
||||
{ text: 'Green', value: 'green' },
|
||||
{ text: 'Purple', value: 'purple' }
|
||||
];
|
||||
|
||||
// Pre-selected object with different object reference
|
||||
this.skittles = [
|
||||
{ text: 'Red', value: 'red' },
|
||||
{ text: 'Purple', value: 'purple' }
|
||||
];
|
||||
|
||||
this.pets = ['cat', 'dog'];
|
||||
}
|
||||
|
||||
compareFn(option1: any, option2: any) {
|
||||
return option1.value === option2.value;
|
||||
}
|
||||
|
||||
monthChange(val: any) {
|
||||
console.log('Month Change:', val);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
|
||||
<!-- Icons right of text -->
|
||||
<ion-tabs tabs-only tabsLayout="icon-right" selectedIndex="0" color="light">
|
||||
<ion-tabs tabs-only tabsLayout="icon-end" selectedIndex="0" color="light">
|
||||
<ion-tab tabTitle="Recents" tabIcon="call" [root]="root"></ion-tab>
|
||||
<ion-tab tabTitle="Favorites" tabIcon="heart" [root]="root"></ion-tab>
|
||||
<ion-tab tabTitle="Settings" tabIcon="settings" [root]="root" tabBadge="4" tabBadgeStyle="secondary"></ion-tab>
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
|
||||
<!-- Icons left of text -->
|
||||
<ion-tabs tabs-only tabsLayout="icon-left" color="dark">
|
||||
<ion-tabs tabs-only tabsLayout="icon-start" color="dark">
|
||||
<ion-tab tabTitle="Recents" tabIcon="call" [root]="root" tabBadge="1" tabBadgeStyle="danger"></ion-tab>
|
||||
<ion-tab tabTitle="Favorites" tabIcon="heart" [root]="root"></ion-tab>
|
||||
<ion-tab tabTitle="Settings" tabIcon="settings" [root]="root"></ion-tab>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</ion-buttons>
|
||||
<ion-title>Solid</ion-title>
|
||||
<ion-buttons end>
|
||||
<button ion-button icon-right solid color="secondary">
|
||||
<button ion-button icon-end solid color="secondary">
|
||||
Help
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
</button>
|
||||
@@ -69,7 +69,7 @@
|
||||
</button>
|
||||
</ion-buttons>
|
||||
<ion-buttons end>
|
||||
<button ion-button icon-right outline color="secondary">
|
||||
<button ion-button icon-end outline color="secondary">
|
||||
Help
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
</button>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</ion-buttons>
|
||||
<ion-title>Solid</ion-title>
|
||||
<ion-buttons end>
|
||||
<button ion-button icon-right solid color="secondary">
|
||||
<button ion-button icon-end solid color="secondary">
|
||||
Help
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
</button>
|
||||
@@ -69,7 +69,7 @@
|
||||
</button>
|
||||
</ion-buttons>
|
||||
<ion-buttons end>
|
||||
<button ion-button icon-right outline color="secondary">
|
||||
<button ion-button icon-end outline color="secondary">
|
||||
Help
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
</button>
|
||||
|
||||
15015
package-lock.json
generated
Normal file
15015
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
47
package.json
47
package.json
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "ionic2",
|
||||
"version": "3.2.1",
|
||||
"description": "A powerful framework for building mobile and progressive web apps with JavaScript and Angular 2",
|
||||
"version": "3.8.0",
|
||||
"description": "A powerful framework for building mobile and progressive web apps with JavaScript and Angular",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
"framework",
|
||||
@@ -17,28 +17,29 @@
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/driftyco/ionic.git"
|
||||
"url": "https://github.com/ionic-team/ionic.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "gulp validate",
|
||||
"test:generators": "jasmine-node ./tooling/spec",
|
||||
"link": "gulp release.prepareReleasePackage && cd dist/ionic-angular && npm link"
|
||||
"link": "gulp release.prepareReleasePackage && cd dist/ionic-angular && npm link",
|
||||
"tsc": "tsc --outdir .tmp"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/common": "4.1.2",
|
||||
"@angular/compiler": "4.1.2",
|
||||
"@angular/compiler-cli": "4.1.2",
|
||||
"@angular/core": "4.1.2",
|
||||
"@angular/forms": "4.1.2",
|
||||
"@angular/http": "4.1.2",
|
||||
"@angular/platform-browser": "4.1.2",
|
||||
"@angular/platform-browser-dynamic": "4.1.2",
|
||||
"@angular/common": "4.4.6",
|
||||
"@angular/compiler": "4.4.6",
|
||||
"@angular/compiler-cli": "4.4.6",
|
||||
"@angular/core": "4.4.6",
|
||||
"@angular/forms": "4.4.6",
|
||||
"@angular/http": "4.4.6",
|
||||
"@angular/platform-browser": "4.4.6",
|
||||
"@angular/platform-browser-dynamic": "4.4.6",
|
||||
"ionicons": "~3.0.0",
|
||||
"rxjs": "5.1.1",
|
||||
"zone.js": "^0.8.10"
|
||||
"rxjs": "5.5.2",
|
||||
"zone.js": "0.8.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/app-scripts": "1.3.7",
|
||||
"@ionic/app-scripts": "nightly",
|
||||
"@ionic/commit-hooks": "1.0.3",
|
||||
"@types/connect": "3.4.30",
|
||||
"@types/del": "2.2.31",
|
||||
@@ -51,7 +52,7 @@
|
||||
"@types/lodash": "4.14.35",
|
||||
"@types/merge2": "0.3.29",
|
||||
"@types/mkdirp": "0.3.29",
|
||||
"@types/node": "^6.0.34",
|
||||
"@types/node": "^6.0.88",
|
||||
"@types/protractor": "^4.0.0",
|
||||
"@types/run-sequence": "0.0.28",
|
||||
"@types/semver": "5.3.30",
|
||||
@@ -63,8 +64,9 @@
|
||||
"canonical-path": "0.0.2",
|
||||
"connect": "3.5.0",
|
||||
"conventional-changelog": "1.1.0",
|
||||
"core-js": "2.4.1",
|
||||
"core-js": "2.5.1",
|
||||
"cpr": "2.0.0",
|
||||
"cross-spawn": "^5.1.0",
|
||||
"del": "2.2.2",
|
||||
"dgeni": "^0.4.7",
|
||||
"dgeni-packages": "^0.16.10",
|
||||
@@ -91,7 +93,7 @@
|
||||
"gulp-scss-lint": "0.4.0",
|
||||
"gulp-shell": "0.5.2",
|
||||
"gulp-strip-debug": "1.1.0",
|
||||
"gulp-tslint": "6.1.1",
|
||||
"gulp-tslint": "^8.1.1",
|
||||
"gulp-typescript": "2.13.6",
|
||||
"gulp-uglify": "2.0.0",
|
||||
"gulp-util": "3.0.7",
|
||||
@@ -129,12 +131,11 @@
|
||||
"sw-toolbox": "3.4.0",
|
||||
"systemjs": "0.19.38",
|
||||
"through2": "2.0.1",
|
||||
"ts-node": "1.3.0",
|
||||
"tslint": "3.15.1",
|
||||
"tslint-ionic-rules": "0.0.7",
|
||||
"typescript": "~2.3.2",
|
||||
"ts-node": "3.3.0",
|
||||
"tslint": "^5.4.3",
|
||||
"tslint-ionic-rules": "0.0.11",
|
||||
"typescript": "~2.4.2",
|
||||
"vinyl": "1.2.0",
|
||||
"webpack": "^2.1.0-beta.27",
|
||||
"yargs": "5.0.0"
|
||||
},
|
||||
"config": {
|
||||
|
||||
@@ -7,7 +7,7 @@ All of these commands require you to run `npm install` first. To see a full list
|
||||
|
||||
### Committing
|
||||
|
||||
Please follow the commit message format in [CONTRIBUTING.md](https://github.com/driftyco/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format).
|
||||
Please follow the commit message format in [CONTRIBUTING.md](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format).
|
||||
|
||||
|
||||
### Installing Nightly Version
|
||||
@@ -110,6 +110,12 @@ It does not work for windows, linux, or non retina macs.
|
||||
|
||||
- `--dev` runs a dev build when building the e2e tests. This build takes much less time than a production build, so it is advisable to use this when doing quick validation.
|
||||
|
||||
#### Errors
|
||||
|
||||
If you are having getting an error running snapshot such as `SessionNotCreatedError: session not created exception` or `UnknownError: Connection refused` the solution is to download the chromedriver from here: http://chromedriver.storage.googleapis.com/index.html?path=2.24/ and then move it into your `protractor/selenium` folder
|
||||
|
||||
Running `webdriver-manager help` should show you what directory the webdriver is at under the options. For example, yours may be at `/usr/local/lib/node_modules/protractor/selenium` or if you use nvm `/Users/{username}/.nvm/versions/node/v7.5.0/lib/node_modules/protractor/selenium`.
|
||||
|
||||
### Running Tests
|
||||
|
||||
1. `gulp validate`
|
||||
@@ -119,7 +125,7 @@ It does not work for windows, linux, or non retina macs.
|
||||
|
||||
**Requires Ruby. Skip this step entirely if you are unable to install Ruby.**
|
||||
|
||||
1. See the [Sass Guidelines](https://github.com/driftyco/ionic/blob/master/.github/CONTRIBUTING.md#sass-changes) for editing the Sass.
|
||||
1. See the [Sass Guidelines](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#sass-changes) for editing the Sass.
|
||||
2. Install the linter: `gem install scss_lint`
|
||||
3. Run `gulp lint.sass` and fix any linter errors.
|
||||
|
||||
@@ -160,13 +166,13 @@ It does not work for windows, linux, or non retina macs.
|
||||
|
||||
### Releasing Component Demos
|
||||
|
||||
Ionic Component demos are automatically compiled and deployed to the [ionic staging site](http://ionic-site-staging.herokuapp.com/) on every commit in [ionic-preview-app](https://github.com/driftyco/ionic-preview-app). No action is necessary.
|
||||
Ionic Component demos are automatically compiled and deployed to the [ionic staging site](http://ionic-site-staging.herokuapp.com/) on every commit in [ionic-preview-app](https://github.com/ionic-team/ionic-preview-app). No action is necessary.
|
||||
|
||||
If you'd like to manually update the demos, follow the steps on the preview app for [running locally on the site](https://github.com/driftyco/ionic-preview-app#running-locally-on-the-site).
|
||||
If you'd like to manually update the demos, follow the steps on the preview app for [running locally on the site](https://github.com/ionic-team/ionic-preview-app#running-locally-on-the-site).
|
||||
|
||||
|
||||
### Releasing API Demos
|
||||
|
||||
Ionic API demos are automatically compiled and deployed to the [ionic staging site](http://ionic-site-staging.herokuapp.com/) on every commit. No action is necessary.
|
||||
|
||||
If you'd like to manually update the demos, clone the [`ionic-site`](https://github.com/driftyco/ionic-site) repo as a sibling of `ionic`. From `ionic` run `gulp demos` and then `gulp docs`, and it'll compile and copy the demos to the `ionic-site` repo, ready for testing.
|
||||
If you'd like to manually update the demos, clone the [`ionic-site`](https://github.com/ionic-team/ionic-site) repo as a sibling of `ionic`. From `ionic` run `gulp demos` and then `gulp docs`, and it'll compile and copy the demos to the `ionic-site` repo, ready for testing.
|
||||
|
||||
@@ -4,7 +4,7 @@ var path = require('path');
|
||||
module.exports = {
|
||||
copyAssets: {
|
||||
src: [path.join(path.dirname(process.env.IONIC_APP_ENTRY_POINT), '..', 'assets', '**', '*')],
|
||||
dest: '{{WWW}}/assets'
|
||||
dest: path.join('{{WWW}}', 'assets')
|
||||
},
|
||||
copyIndexContent: {
|
||||
src: [path.join(process.cwd(), 'scripts', 'demos', 'index.html')],
|
||||
@@ -12,7 +12,7 @@ module.exports = {
|
||||
},
|
||||
copyFonts: {
|
||||
src: [`${process.cwd()}/node_modules/ionicons/dist/fonts/**/*`, `${process.cwd()}/src/fonts/**/*`],
|
||||
dest: '{{WWW}}/assets/fonts'
|
||||
dest: path.join('{{WWW}}', 'assets', 'fonts')
|
||||
},
|
||||
copyPolyfills: {
|
||||
src: [path.join(process.cwd(), 'dist', 'demos', 'polyfills', 'polyfills.js')],
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<ion-app></ion-app>
|
||||
|
||||
<script src="./build/polyfills.js"></script>
|
||||
<script src="./build/vendor.js"></script>
|
||||
<script src="./build/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var path = require('path');
|
||||
|
||||
var watch = require('../../node_modules/@ionic/app-scripts/dist/watch');
|
||||
var watch = require(path.join('..', '..', 'node_modules', '@ionic', 'app-scripts', 'dist', 'watch'));
|
||||
|
||||
var entryPointDirectory = path.dirname(process.env.IONIC_APP_ENTRY_POINT)
|
||||
|
||||
@@ -9,7 +9,7 @@ module.exports = {
|
||||
paths: [path.join(entryPointDirectory, '..', '**', '*.(ts|html|s(c|a)ss)')],
|
||||
options: { ignored: [path.join(entryPointDirectory, '..', '**', '*.spec.ts'),
|
||||
path.join(entryPointDirectory, '..', '**', '*.e2e.ts'),
|
||||
'**/*.DS_Store'] },
|
||||
path.join('**', '*.DS_Store')] },
|
||||
callback: watch.buildUpdate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,10 +63,10 @@ function run {
|
||||
# if no changes, don't commit
|
||||
if [[ "$CHANGES" == "" ]]; then
|
||||
echo "-- No changes detected for the following commit, docs not updated."
|
||||
echo "https://github.com/driftyco/$CIRCLE_PROJECT_REPONAME/commit/$CIRCLE_SHA1"
|
||||
echo "https://github.com/ionic-team/$CIRCLE_PROJECT_REPONAME/commit/$CIRCLE_SHA1"
|
||||
else
|
||||
git add -A
|
||||
git commit -am "Automated build of ionic v$VERSION driftyco/$CIRCLE_PROJECT_REPONAME@$CIRCLE_SHA1"
|
||||
git commit -am "Automated build of ionic v$VERSION ionic-team/$CIRCLE_PROJECT_REPONAME@$CIRCLE_SHA1"
|
||||
# in case a different commit was pushed to ionic-site during doc/demo gen,
|
||||
# try to rebase around it before pushing
|
||||
git fetch
|
||||
|
||||
@@ -87,8 +87,8 @@ module.exports = function(gulp, flags) {
|
||||
}));
|
||||
callback();
|
||||
}).on('end', function() {
|
||||
gutil.log("Writing to file at", gutil.colors.cyan("/driftyco/ionic/" + outputFile));
|
||||
gutil.log("Place this file in", gutil.colors.cyan("/driftyco/ionic-site/" + config.v2DocsDir + "/theming/overriding-ionic-variables/"), "in order to update the docs");
|
||||
gutil.log("Writing to file at", gutil.colors.cyan("/ionic-team/ionic/" + outputFile));
|
||||
gutil.log("Place this file in", gutil.colors.cyan("/ionic-team/ionic-site/" + config.v2DocsDir + "/theming/overriding-ionic-variables/"), "in order to update the docs");
|
||||
mkdirp.sync('tmp');
|
||||
fs.writeFileSync(outputFile, JSON.stringify(variables));
|
||||
}));
|
||||
|
||||
@@ -29,6 +29,14 @@ module.exports = function jekyll(renderDocsProcessor) {
|
||||
if (docs[i].href) {
|
||||
docs[i].href = doc.href.replace('content/', '');
|
||||
}
|
||||
if (docs[i].description) {
|
||||
docs[i].description = docs[i].description.replace(/(\#\#\#).+/g, (section) => {
|
||||
const title = section.replace(/^(\#+\s?)/, '');
|
||||
const segment = title.replace(/[^a-zA-Z0-9]+/g, '-').toLowerCase();
|
||||
|
||||
return `\n<h3><a class="anchor" name="${segment}" href="#${segment}">${title}</a></h3>\n`;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
docs.push({
|
||||
|
||||
@@ -7,7 +7,7 @@ path: ""
|
||||
category: api
|
||||
id: api
|
||||
title: Javascript
|
||||
header_sub_title: Extend Ionic even further with the power of AngularJS
|
||||
header_sub_title: Extend Ionic even further with the power of Angular
|
||||
searchable: false
|
||||
---
|
||||
|
||||
@@ -15,9 +15,6 @@ searchable: false
|
||||
|
||||
<img class="section-header" src="/img/docs/api-intro-header.png" />
|
||||
|
||||
|
||||
Ionic takes everything you know and loved about Ionic V1, and builds on top of it to provide a much more flexible framework.
|
||||
|
||||
In the API docs, you'll find two kinds of doc pages: Component and Service APIs.
|
||||
|
||||
The Component APIs include classes like `Checkbox`, `Toggle` or `Item` and show you how to use them, in addition to listing their selectors, available properties and events.
|
||||
|
||||
25
scripts/docs/templates/common.template.html
vendored
25
scripts/docs/templates/common.template.html
vendored
@@ -225,7 +225,7 @@ Delegate: <$ doc.delegate $>
|
||||
|
||||
</h1>
|
||||
|
||||
<a class="improve-v2-docs" href="http://github.com/driftyco/ionic/edit/master/<$ doc.fileInfo.projectRelativePath $>#L<$ doc.location.start.line $>">
|
||||
<a class="improve-v2-docs" href="http://github.com/ionic-team/ionic/edit/master/<$ doc.fileInfo.projectRelativePath $>#L<$ doc.location.start.line $>">
|
||||
Improve this doc
|
||||
</a>
|
||||
|
||||
@@ -242,7 +242,7 @@ Improve this doc
|
||||
|
||||
<!-- @usage tag -->
|
||||
<@ if doc.usage @>
|
||||
<h2><a class="anchor" name="usage" href="#usage"></a>Usage</h2>
|
||||
<h2><a class="anchor" name="usage" href="#usage">Usage</a></h2>
|
||||
<@ block usage @>
|
||||
<$ doc.usage | marked $>
|
||||
<@ endblock @>
|
||||
@@ -250,7 +250,7 @@ Improve this doc
|
||||
|
||||
<!-- @property tags -->
|
||||
<@ if doc.properties @>
|
||||
<h2><a class="anchor" name="attributes" href="#attributes"></a>Attributes:</h2>
|
||||
<h2><a class="anchor" name="attributes" href="#attributes">Attributes</a></h2>
|
||||
<table class="table" style="margin:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -293,10 +293,10 @@ Improve this doc
|
||||
|
||||
|
||||
<@- if doc.statics.length -@>
|
||||
<h2><a class="anchor" name="static-members" href="#static-members"></a>Static Members</h2>
|
||||
<h2><a class="anchor" name="static-members" href="#static-members">Static Members</a></h2>
|
||||
<@- for method in doc.statics @><@ if not method.internal @>
|
||||
<div id="<$ method.name $>"></div>
|
||||
<h3><a class="anchor" name="<$ method.name $>" href="#<$ method.name $>"></a><$ functionSyntax(method) $></h3>
|
||||
<h3><a class="anchor" name="<$ method.name $>" href="#<$ method.name $>"><$ functionSyntax(method) $></a></h3>
|
||||
|
||||
<$ method.description $>
|
||||
|
||||
@@ -327,14 +327,15 @@ Improve this doc
|
||||
<!-- instance methods on the class -->
|
||||
<@- if doc.members and doc.members.length @>
|
||||
|
||||
<h2><a class="anchor" name="instance-members" href="#instance-members"></a>Instance Members</h2>
|
||||
<h2><a class="anchor" name="instance-members" href="#instance-members">Instance Members</a></h2>
|
||||
<@- for method in doc.members @>
|
||||
|
||||
<div id="<$ method.name $>"></div>
|
||||
|
||||
<h3>
|
||||
<a class="anchor" name="<$ method.name $>" href="#<$ method.name $>"></a>
|
||||
<a class="anchor" name="<$ method.name $>" href="#<$ method.name $>">
|
||||
<$ functionSyntax(method) $>
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<$ method.description $>
|
||||
@@ -366,26 +367,26 @@ Improve this doc
|
||||
|
||||
<@- if doc.inputs and doc.inputs.length @>
|
||||
<!-- input methods on the class -->
|
||||
<h2><a class="anchor" name="input-properties" href="#input-properties"></a>Input Properties</h2>
|
||||
<h2><a class="anchor" name="input-properties" href="#input-properties">Input Properties</a></h2>
|
||||
<$ inputTable(doc.inputs) $>
|
||||
<@- endif -@>
|
||||
|
||||
<@- if doc.outputs and doc.outputs.length @>
|
||||
<!-- output events on the class -->
|
||||
<h2><a class="anchor" name="output-events" href="#output-events"></a>Output Events</h2>
|
||||
<h2><a class="anchor" name="output-events" href="#output-events">Output Events</a></h2>
|
||||
<$ outputTable(doc.outputs) $>
|
||||
<@- endif -@>
|
||||
|
||||
|
||||
<@ block advanced @>
|
||||
<@- if doc.advanced -@>
|
||||
<h2><a class="anchor" name="advanced" href="#advanced"></a>Advanced</h2>
|
||||
<h2><a class="anchor" name="advanced" href="#advanced">Advanced</a></h2>
|
||||
<$ doc.advanced | marked $>
|
||||
<@- endif -@>
|
||||
<@ endblock @>
|
||||
|
||||
<@ if doc.sassVariables @>
|
||||
<h2 id="sass-variable-header"><a class="anchor" name="sass-variables" href="#sass-variables"></a>Sass Variables</h2>
|
||||
<h2 id="sass-variable-header"><a class="anchor" name="sass-variables" href="#sass-variables">Sass Variables</a></h2>
|
||||
<$ sassTable(doc.sassVariables) $>
|
||||
<@ endif @>
|
||||
|
||||
@@ -393,7 +394,7 @@ Improve this doc
|
||||
<!-- related link -->
|
||||
<@- if doc.see @>
|
||||
|
||||
<h2><a class="anchor" name="related" href="#related"></a>Related</h2>
|
||||
<h2><a class="anchor" name="related" href="#related">Related</a></h2>
|
||||
<@ for s in doc.see @>
|
||||
<$ s | safe $> <@- if not loop.last @>,<@- endif -@>
|
||||
<@- endfor -@>
|
||||
|
||||
@@ -4,15 +4,15 @@ var path = require('path');
|
||||
module.exports = {
|
||||
copyAssets: {
|
||||
src: [path.join(path.dirname(process.env.IONIC_APP_ENTRY_POINT), '..', 'assets', '**', '*')],
|
||||
dest: '{{WWW}}/assets'
|
||||
dest: path.join('{{WWW}}', 'assets')
|
||||
},
|
||||
copyIndexContent: {
|
||||
src: [path.join(process.cwd(), 'scripts', 'e2e', 'index.html')],
|
||||
dest: '{{WWW}}'
|
||||
},
|
||||
copyFonts: {
|
||||
src: [`${process.cwd()}/node_modules/ionicons/dist/fonts/**/*`, `${process.cwd()}/src/fonts/**/*`],
|
||||
dest: '{{WWW}}/assets/fonts'
|
||||
src: [path.join(process.cwd(), 'node_modules', 'ionicons', 'dist', 'fonts', '**', '*'), path.join(process.cwd(), 'src', 'fonts', '**', '*')],
|
||||
dest: path.join('{{WWW}}', 'assets', 'fonts')
|
||||
},
|
||||
copyPolyfills: {
|
||||
src: [path.join(process.cwd(), 'dist', 'e2e', 'polyfills', 'polyfills.ng.js')],
|
||||
|
||||
@@ -4,7 +4,7 @@ module.exports = function(options) {
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var request = require('request');
|
||||
var inputDir = path.join(__dirname, '../../dist/e2e/tests');
|
||||
var inputDir = path.join(__dirname, '..', '..' , 'dist', 'e2e', 'tests');
|
||||
var uploadQueue = [];
|
||||
|
||||
var ignoreFiles = /(\/test\/|\/ts\/|\/q\/|\/ionic-site\/|\/docs\/|\/examples\/|\/inquirer\/|\/lodash\/|\/tooling\/|\/colors\/|\/bin\/|\.ts$|\.bin|\.map$|\.md$|\.git|\.scss$|\.yml$|\.yaml$|\.dart$|\.txt|\.npm|bower|DS_Store|LICENSE)/i;
|
||||
@@ -13,15 +13,15 @@ module.exports = function(options) {
|
||||
fs.readdir(dir, function(err, list) {
|
||||
|
||||
list.forEach(function(file) {
|
||||
var url = urlPath + '/' + file;
|
||||
var url = path.join(urlPath, file);
|
||||
|
||||
|
||||
fs.stat(dir + '/' + file, function(err, stat) {
|
||||
fs.stat(path.join(dir, file), function(err, stat) {
|
||||
if (stat && stat.isDirectory()) {
|
||||
uploadFiles(dir + '/' + file, urlPath + '/' + file);
|
||||
uploadFiles(path.join(dir, file), path.join(urlPath, file);
|
||||
} else {
|
||||
if ( shouldProcessPath (url) ){
|
||||
uploadFile(url, dir + '/' + file);
|
||||
uploadFile(url, path.join(dir, file));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
}
|
||||
</script>
|
||||
<script src="./build/polyfills.ng.js"></script>
|
||||
<script src="./build/vendor.js"></script>
|
||||
<script src="./build/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -31,7 +31,15 @@ $colors: (
|
||||
light: #f4f4f4,
|
||||
dark: #222,
|
||||
vibrant: rebeccapurple,
|
||||
bright: #ffc125
|
||||
bright: #ffc125,
|
||||
greyYellow: (
|
||||
base:#49606e,
|
||||
contrast:#fbb636
|
||||
),
|
||||
greyWhite: (
|
||||
base:#49606e,
|
||||
contrast:#fff
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ function run {
|
||||
git config --global user.email "hi@ionicframework.com"
|
||||
git config --global user.name "Ionitron"
|
||||
|
||||
git clone git@github.com:driftyco/$REPOSITORY.git $DIRECTORY $ARGS
|
||||
git clone git@github.com:ionic-team/$REPOSITORY.git $DIRECTORY $ARGS
|
||||
cd $DIRECTORY
|
||||
git fetch origin --tags
|
||||
cd ../
|
||||
|
||||
@@ -20,7 +20,7 @@ export const BUNDLES = 'bundles';
|
||||
export const SITE_NAME = 'ionic-site';
|
||||
|
||||
// File Paths
|
||||
export const PROJECT_ROOT = join(__dirname, '../..');
|
||||
export const PROJECT_ROOT = join(__dirname, '..', '..');
|
||||
export const DEMOS_ROOT = join(PROJECT_ROOT, DEMOS_NAME);
|
||||
export const DEMOS_SRC_ROOT = join(DEMOS_ROOT, SRC_NAME);
|
||||
export const DIST_ROOT = join(PROJECT_ROOT, DIST_NAME);
|
||||
@@ -45,7 +45,7 @@ export const WORKERS_SRC = join(SCRIPTS_ROOT, 'workers');
|
||||
|
||||
// NPM
|
||||
export const NPM_VENDOR_FILES = [
|
||||
'@angular', 'core-js/client', 'rxjs', 'systemjs/dist', 'zone.js/dist'
|
||||
'@angular', join('core-js', 'client'), 'rxjs', join('systemjs', 'dist'), join('zone.js', 'dist')
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { task } from 'gulp';
|
||||
import { DIST_BUILD_ROOT, DIST_BUILD_ES2015_ROOT, DIST_BUILD_UMD_ROOT, ES5, ES_2015, PROJECT_ROOT, UMD_MODULE } from '../constants';
|
||||
import { join } from 'path';
|
||||
import { DIST_BUILD_ES2015_ROOT, DIST_BUILD_ROOT, DIST_BUILD_UMD_ROOT, ES5, ES_2015, PROJECT_ROOT, UMD_MODULE } from '../constants';
|
||||
import { copySourceToDest, createTempTsConfig, deleteFiles, runNgc, runTsc } from '../util';
|
||||
|
||||
|
||||
@@ -7,8 +8,8 @@ export function buildIonicAngularUmd(excludeSpec: boolean, stripDebug: boolean,
|
||||
const stream = copySourceToDest(DIST_BUILD_UMD_ROOT, excludeSpec, true, stripDebug);
|
||||
stream.on('end', () => {
|
||||
// the source files are copied, copy over a tsconfig from
|
||||
createTempTsConfig(['./**/*.ts'], ES5, UMD_MODULE, `${PROJECT_ROOT}/tsconfig.json`, `${DIST_BUILD_UMD_ROOT}/tsconfig.json`);
|
||||
runNgc(`${DIST_BUILD_UMD_ROOT}/tsconfig.json`, (err) => {
|
||||
createTempTsConfig([join('.', '**', '*.ts')], ES5, UMD_MODULE, join(PROJECT_ROOT, 'tsconfig.json'), join(DIST_BUILD_UMD_ROOT, 'tsconfig.json'));
|
||||
runNgc(join(DIST_BUILD_UMD_ROOT, 'tsconfig.json'), (err) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
@@ -27,8 +28,8 @@ export function buildIonicAngularUmdTsc(excludeSpec: boolean, stripDebug: boolea
|
||||
const stream = copySourceToDest(DIST_BUILD_UMD_ROOT, excludeSpec, true, stripDebug);
|
||||
stream.on('end', () => {
|
||||
// the source files are copied, copy over a tsconfig from
|
||||
createTempTsConfig(['./**/*.ts'], ES5, UMD_MODULE, `${PROJECT_ROOT}/tsconfig.json`, `${DIST_BUILD_UMD_ROOT}/tsconfig.json`);
|
||||
runTsc(`${DIST_BUILD_UMD_ROOT}/tsconfig.json`, (err) => {
|
||||
createTempTsConfig([join('.', '**', '*.ts')], ES5, UMD_MODULE, join(PROJECT_ROOT, 'tsconfig.json'), join(DIST_BUILD_UMD_ROOT, 'tsconfig.json'));
|
||||
runTsc(join(DIST_BUILD_UMD_ROOT, 'tsconfig.json'), (err) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
@@ -48,8 +49,8 @@ export function buildIonicAngularEsm(stripDebug: boolean, done: Function) {
|
||||
const stream = copySourceToDest(DIST_BUILD_ROOT, true, true, stripDebug);
|
||||
stream.on('end', () => {
|
||||
// the source files are copied, copy over a tsconfig from
|
||||
createTempTsConfig(['./**/*.ts'], ES5, ES_2015, `${PROJECT_ROOT}/tsconfig.json`, `${DIST_BUILD_ROOT}/tsconfig.json`);
|
||||
runNgc(`${DIST_BUILD_ROOT}/tsconfig.json`, (err) => {
|
||||
createTempTsConfig([join('.', '**', '*.ts')], ES5, ES_2015, join(PROJECT_ROOT, 'tsconfig.json'), join(DIST_BUILD_ROOT, 'tsconfig.json'));
|
||||
runNgc(join(DIST_BUILD_ROOT, 'tsconfig.json'), (err) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
@@ -67,8 +68,8 @@ export function buildIonicPureEs6(stripDebug: boolean, done: Function) {
|
||||
const stream = copySourceToDest(DIST_BUILD_ES2015_ROOT, true, true, stripDebug);
|
||||
stream.on('end', () => {
|
||||
// the source files are copied, copy over a tsconfig from
|
||||
createTempTsConfig(['./**/*.ts'], ES_2015, ES_2015, `${PROJECT_ROOT}/tsconfig.json`, `${DIST_BUILD_ES2015_ROOT}/tsconfig.json`);
|
||||
runNgc(`${DIST_BUILD_ES2015_ROOT}/tsconfig.json`, (err) => {
|
||||
createTempTsConfig([join('.', '**', '*.ts')], ES_2015, ES_2015, join(PROJECT_ROOT, 'tsconfig.json'), join(DIST_BUILD_ES2015_ROOT, 'tsconfig.json'));
|
||||
runNgc(join(DIST_BUILD_ES2015_ROOT, 'tsconfig.json'), (err) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
|
||||
@@ -11,14 +11,14 @@ task('demos.watch', ['demos.prepare'], (done: Function) => {
|
||||
done(new Error(`Usage: gulp e2e.watch --folder modal`));
|
||||
}
|
||||
|
||||
serveDemo(folderInfo.componentName).then(() => {
|
||||
serveDemo(folderInfo.componentName, folderInfo.devApp).then(() => {
|
||||
done();
|
||||
}).catch((err: Error) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
function serveDemo(folderName: any) {
|
||||
function serveDemo(folderName: any, devApp: boolean) {
|
||||
|
||||
const ionicAngularDir = join(PROJECT_ROOT, 'src');
|
||||
const srcTestRoot = join(DEMOS_ROOT, 'src', folderName);
|
||||
@@ -40,5 +40,5 @@ function serveDemo(folderName: any) {
|
||||
const appNgModulePath = join(srcTestRoot, 'app', 'app.module.ts');
|
||||
const distDir = join(distDemoRoot, 'www');
|
||||
|
||||
return runAppScriptsServe(folderName, appEntryPoint, appNgModulePath, ionicAngularDir, distDir, pathToWriteFile, ionicAngularDir, sassConfigPath, copyConfigPath, watchConfigPath);
|
||||
return runAppScriptsServe(folderName, appEntryPoint, appNgModulePath, ionicAngularDir, distDir, pathToWriteFile, ionicAngularDir, sassConfigPath, copyConfigPath, watchConfigPath, devApp);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as s3 from 's3';
|
||||
import { argv } from 'yargs';
|
||||
|
||||
|
||||
import { DEMOS_SRC_ROOT, ES_2015, PROJECT_ROOT } from '../constants';
|
||||
import { DEMOS_SRC_ROOT, ES_2015, ES5, PROJECT_ROOT } from '../constants';
|
||||
import { createTempTsConfig, getFolderInfo, runAppScriptsBuild, writePolyfills } from '../util';
|
||||
|
||||
import * as pAll from 'p-all';
|
||||
@@ -59,9 +59,9 @@ function getDemosEntryPoints() {
|
||||
|
||||
|
||||
function buildDemos(filePaths: string[]) {
|
||||
var batches = chunkArrayInGroups(filePaths, argv.batches || 1);
|
||||
var batch = argv.batch || 0;
|
||||
if(batch >= batches.length) {
|
||||
const batches = chunkArrayInGroups(filePaths, argv.batches || 1);
|
||||
const batch = argv.batch || 0;
|
||||
if (batch >= batches.length) {
|
||||
throw new Error(`Batch number higher than total number of batches.`);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ function buildDemo(filePath: string) {
|
||||
const pathToWriteFile = join(distTestRoot, 'tsconfig.json');
|
||||
const pathToReadFile = join(PROJECT_ROOT, 'tsconfig.json');
|
||||
|
||||
createTempTsConfig(includeGlob, ES_2015, ES_2015, pathToReadFile, pathToWriteFile, { removeComments: true});
|
||||
createTempTsConfig(includeGlob, ES5, ES_2015, pathToReadFile, pathToWriteFile, { removeComments: true});
|
||||
|
||||
const sassConfigPath = join('scripts', 'demos', 'sass.config.js');
|
||||
const copyConfigPath = join('scripts', 'demos', 'copy.config.js');
|
||||
@@ -99,15 +99,23 @@ function buildDemo(filePath: string) {
|
||||
const appNgModulePath = join(dirname(filePath), 'app.module.ts');
|
||||
const distDir = join(distTestRoot, 'www');
|
||||
|
||||
const minifyCss = argv.noMinifyCss ? false : true;
|
||||
const minifyJs = argv.noMinifyJs ? false : true;
|
||||
const optimizeJs = argv.noOptimizeJs ? false : true;
|
||||
|
||||
return runAppScriptsBuild(
|
||||
appEntryPoint,
|
||||
appNgModulePath,
|
||||
ionicAngularDir,
|
||||
distDir,
|
||||
pathToWriteFile,
|
||||
ionicAngularDir,
|
||||
sassConfigPath,
|
||||
copyConfigPath
|
||||
appEntryPoint,
|
||||
appNgModulePath,
|
||||
ionicAngularDir,
|
||||
distDir,
|
||||
pathToWriteFile,
|
||||
ionicAngularDir,
|
||||
sassConfigPath,
|
||||
copyConfigPath,
|
||||
false,
|
||||
minifyCss,
|
||||
minifyJs,
|
||||
optimizeJs
|
||||
).then(() => {
|
||||
const end = Date.now();
|
||||
console.log(`${filePath} took a total of ${(end - start) / 1000} seconds to build`);
|
||||
@@ -116,8 +124,8 @@ function buildDemo(filePath: string) {
|
||||
}
|
||||
|
||||
function chunkArrayInGroups(arr, size) {
|
||||
var result = [];
|
||||
for(var i = 0; i < arr.length; i++) {
|
||||
const result = [];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (!Array.isArray(result[i % size])) {
|
||||
result[i % size] = [];
|
||||
}
|
||||
@@ -129,7 +137,7 @@ function chunkArrayInGroups(arr, size) {
|
||||
function uploadToS3(path) {
|
||||
// fail silently if envars not present
|
||||
if (!process.env.AWS_KEY || !process.env.AWS_SECRET) {
|
||||
return new Promise((resolve) => {resolve();});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
let client = s3.createClient({
|
||||
@@ -143,23 +151,23 @@ function uploadToS3(path) {
|
||||
let demo = path.split('/')[path.split('/').length - 2];
|
||||
|
||||
let params = {
|
||||
localDir: path.replace('tsconfig.json',''),
|
||||
deleteRemoved: true,
|
||||
localDir: path.replace('tsconfig.json', ''),
|
||||
deleteRemoved: true,
|
||||
s3Params: {
|
||||
Bucket: "ionic-demos",
|
||||
Bucket: 'ionic-demos',
|
||||
Prefix: demo,
|
||||
},
|
||||
};
|
||||
|
||||
var uploader = client.uploadDir(params);
|
||||
const uploader = client.uploadDir(params);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uploader.on('error', function(err) {
|
||||
console.error("s3 Upload Error:", err.stack);
|
||||
console.error('s3 Upload Error:', err.stack);
|
||||
reject();
|
||||
});
|
||||
uploader.on('end', function() {
|
||||
console.log(demo, " demo uploaded to s3");
|
||||
console.log(demo, ' demo uploaded to s3');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@@ -167,7 +175,7 @@ function uploadToS3(path) {
|
||||
|
||||
task('demos.download', (done: Function) => {
|
||||
if (!process.env.AWS_KEY || !process.env.AWS_SECRET) {
|
||||
return new Promise((resolve) => {resolve();});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
let client = s3.createClient({
|
||||
@@ -180,23 +188,23 @@ task('demos.download', (done: Function) => {
|
||||
let params = {
|
||||
localDir: join(process.cwd(), 'dist', 'demos', 'src'),
|
||||
s3Params: {
|
||||
Bucket: "ionic-demos",
|
||||
Bucket: 'ionic-demos',
|
||||
},
|
||||
};
|
||||
|
||||
let uploader = client.downloadDir(params);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uploader.on('error', function(err) {
|
||||
console.error("s3 Download Error:", err.stack);
|
||||
console.error('s3 Download Error:', err.stack);
|
||||
reject();
|
||||
});
|
||||
uploader.on('end', function() {
|
||||
console.log("Demos downloaded from s3");
|
||||
console.log('Demos downloaded from s3');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
task('demos.clean', (done: Function) => {
|
||||
// this is a super hack, but it works for now
|
||||
|
||||
@@ -22,34 +22,10 @@ task('demos.polyfill', (done: Function) => {
|
||||
});
|
||||
});
|
||||
|
||||
task('demos.copyAndCompile', (done: (err: any) => void) => {
|
||||
runSequence(
|
||||
'demos.copySource',
|
||||
'demos.compileTests',
|
||||
'demos.bundle',
|
||||
done);
|
||||
});
|
||||
|
||||
task('demos.copyExternalDependencies', () => {
|
||||
src([`${SCRIPTS_ROOT}/${DEMOS_NAME}/*.css`]).pipe(dest(`${DIST_DEMOS_ROOT}/css`));
|
||||
});
|
||||
|
||||
task('demos.sass', () => {
|
||||
// ensure there is a version.scss file
|
||||
setSassIonicVersion(`E2E-${createTimestamp()}`);
|
||||
return compileSass(`${DIST_DEMOS_ROOT}/css`);
|
||||
});
|
||||
|
||||
task('demos.fonts', () => {
|
||||
return copyFonts(`${DIST_DEMOS_ROOT}/fonts`);
|
||||
});
|
||||
|
||||
task('demos.serve', function() {
|
||||
connect.server({
|
||||
root: './',
|
||||
port: LOCAL_SERVER_PORT,
|
||||
livereload: {
|
||||
port: 35700
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -132,8 +132,8 @@ task('docs.sassVariables', () => {
|
||||
callback();
|
||||
}).on('end', () => {
|
||||
const config = require('../../config.json');
|
||||
console.log(`Writing to file at /driftyco/ionic/${outputFile}`);
|
||||
console.log(`Place this file in /driftyco/ionic-site/${config.v2DocsDir}/theming/overriding-ionic-variables in order to update the docs`);
|
||||
console.log(`Writing to file at /ionic-team/ionic/${outputFile}`);
|
||||
console.log(`Place this file in /ionic-team/ionic-site/${config.v2DocsDir}/theming/overriding-ionic-variables in order to update the docs`);
|
||||
mkdirp.sync('tmp');
|
||||
writeFileSync(outputFile, JSON.stringify(variables));
|
||||
}));
|
||||
|
||||
@@ -13,14 +13,14 @@ task('e2e.watch', ['e2e.prepare'], (done: Function) => {
|
||||
return;
|
||||
}
|
||||
|
||||
serveTest(folderInfo).then(() => {
|
||||
serveTest(folderInfo, folderInfo.devApp).then(() => {
|
||||
done();
|
||||
}).catch((err: Error) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
function serveTest(folderInfo: any) {
|
||||
function serveTest(folderInfo: any, devApp: boolean) {
|
||||
|
||||
const ionicAngularDir = join(PROJECT_ROOT, 'src');
|
||||
const srcTestRoot = join(PROJECT_ROOT, 'src', 'components', folderInfo.componentName, 'test', folderInfo.componentTest);
|
||||
@@ -47,5 +47,5 @@ function serveTest(folderInfo: any) {
|
||||
const appNgModulePath = join(dirname(appEntryPoint), 'app.module.ts');
|
||||
const distDir = join(distTestRoot, 'www');
|
||||
|
||||
return runAppScriptsServe(folderInfo.componentName + '/' + folderInfo.componentTest, appEntryPoint, appNgModulePath, ionicAngularDir, distDir, pathToWriteFile, ionicAngularDir, sassConfigPath, copyConfigPath, null);
|
||||
return runAppScriptsServe(join(folderInfo.componentName, folderInfo.componentTest), appEntryPoint, appNgModulePath, ionicAngularDir, distDir, pathToWriteFile, ionicAngularDir, sassConfigPath, copyConfigPath, null, devApp);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ task('e2e.prepare', (done: Function) => {
|
||||
|
||||
task('e2e.prepareSass', (done: Function) => {
|
||||
const version = `E2E-${createTimestamp()}`;
|
||||
writeFileSync(join(SRC_ROOT, 'themes/version.scss'), `$ionic-version: "${version}";`);
|
||||
writeFileSync(join(SRC_ROOT, 'themes', 'version.scss'), `$ionic-version: "${version}";`);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -41,7 +41,7 @@ task('e2e.prod', ['e2e.prepare'], (done: Function) => {
|
||||
});
|
||||
|
||||
function e2eComponentExists(folderInfo: any): boolean {
|
||||
let componentPath = `${SRC_COMPONENTS_ROOT}/${folderInfo.componentName}/test/${folderInfo.componentTest}/app`;
|
||||
let componentPath = join(SRC_COMPONENTS_ROOT, folderInfo.componentName, 'test', folderInfo.componentTest, 'app');
|
||||
|
||||
try {
|
||||
accessSync(componentPath);
|
||||
@@ -62,11 +62,11 @@ function filterE2eTestfiles() {
|
||||
const folderInfo = getFolderInfo();
|
||||
if (folderInfo && folderInfo.componentName && folderInfo.componentTest) {
|
||||
if (!e2eComponentExists(folderInfo)) {
|
||||
console.log(`Can't find E2E test "${folderInfo.componentName}/test/${folderInfo.componentTest}". Make sure that the test exists and you are passing the correct folder.`);
|
||||
console.log('Cannot find E2E test ', join(folderInfo.componentName, 'test', folderInfo.componentTest), '. Make sure that the test exists and you are passing the correct folder.');
|
||||
return [];
|
||||
}
|
||||
const filtered = entryPoints.filter(entryPoint => {
|
||||
return entryPoint.indexOf(`${folderInfo.componentName}/test/${folderInfo.componentTest}`) >= 0;
|
||||
return entryPoint.indexOf(join(folderInfo.componentName, 'test', folderInfo.componentTest)) >= 0;
|
||||
});
|
||||
return filtered;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ function buildTest(filePath: string) {
|
||||
const relativePathFromComponents = relative(dirname(SRC_COMPONENTS_ROOT), srcTestRoot);
|
||||
const distTestRoot = join(process.cwd(), 'dist', 'e2e', relativePathFromComponents);
|
||||
|
||||
const includeGlob = [ join(ionicAngularDir, '**', '*.ts')];
|
||||
const includeGlob = [join(ionicAngularDir, '**', '*.ts')];
|
||||
const pathToWriteFile = join(distTestRoot, 'tsconfig.json');
|
||||
const pathToReadFile = join(PROJECT_ROOT, 'tsconfig.json');
|
||||
|
||||
@@ -133,7 +133,11 @@ function buildTest(filePath: string) {
|
||||
const appNgModulePath = join(dirname(appEntryPoint), 'app.module.ts');
|
||||
const distDir = join(distTestRoot, 'www');
|
||||
|
||||
return runAppScriptsBuild(appEntryPoint, appNgModulePath, ionicAngularDir, distDir, pathToWriteFile, ionicAngularDir, sassConfigPath, copyConfigPath, argv.dev).then(() => {
|
||||
const minifyCss = argv.minifyCss ? true : false;
|
||||
const minifyJs = argv.minifyJs ? true : false;
|
||||
const optimizeJs = argv.optimizeJs ? true : false;
|
||||
|
||||
return runAppScriptsBuild(appEntryPoint, appNgModulePath, ionicAngularDir, distDir, pathToWriteFile, ionicAngularDir, sassConfigPath, copyConfigPath, argv.dev, minifyCss, minifyJs, optimizeJs).then(() => {
|
||||
const end = Date.now();
|
||||
console.log(`${filePath} took a total of ${(end - start) / 1000} seconds to build`);
|
||||
}).catch((err) => {
|
||||
@@ -154,7 +158,7 @@ function copyProtractorTestContent(filePaths: string[]): Promise<any> {
|
||||
}
|
||||
|
||||
function applyTemplate(filePathContent: Map<string, string>) {
|
||||
const buildConfig = require('../../build/config');
|
||||
const buildConfig = require(join('..', '..', 'build', 'config'));
|
||||
const templateFileContent = readFileSync(join(SCRIPTS_ROOT, 'e2e', 'e2e.template.js'));
|
||||
const templater = template(templateFileContent.toString());
|
||||
const modifiedMap = new Map<string, string>();
|
||||
@@ -235,7 +239,7 @@ task('e2e.polyfill', (done: Function) => {
|
||||
return done();
|
||||
}
|
||||
|
||||
writePolyfills('dist/e2e/polyfills').then(() => {
|
||||
writePolyfills(join('dist', 'e2e', 'polyfills')).then(() => {
|
||||
done();
|
||||
}).catch(err => {
|
||||
done(err);
|
||||
@@ -249,9 +253,8 @@ task('e2e.openProd', (done: Function) => {
|
||||
task('e2e.open', (done: Function) => {
|
||||
const folderInfo = getFolderInfo();
|
||||
if (folderInfo && folderInfo.componentName && folderInfo.componentTest) {
|
||||
const filePath = `${folderInfo.componentName}/test/${folderInfo.componentTest}/www/index.html`;
|
||||
const fullPath = join(DIST_E2E_COMPONENTS_ROOT, filePath);
|
||||
const spawnedCommand = spawn('open', [fullPath]);
|
||||
const filePath = join(DIST_E2E_COMPONENTS_ROOT, folderInfo.componentName, 'test', folderInfo.componentTest, 'www', 'index.html');
|
||||
const spawnedCommand = spawn('open', [filePath]);
|
||||
|
||||
spawnedCommand.on('close', (code: number) => {
|
||||
done();
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { task } from 'gulp';
|
||||
import { writePolyfills } from '../util';
|
||||
import { join } from 'path';
|
||||
|
||||
|
||||
task('src.polyfill', (done: Function) => {
|
||||
writePolyfills('scripts/polyfill').then(() => {
|
||||
writePolyfills(join('scripts', 'polyfills')).then(() => {
|
||||
done();
|
||||
}).catch(err => {
|
||||
done(err);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { task, src, dest } from 'gulp';
|
||||
import { writePolyfills } from '../util';
|
||||
import { dest, src, task } from 'gulp';
|
||||
import { readFileAsync, writeFileAsync, writePolyfills } from '../util';
|
||||
import { join } from 'path';
|
||||
|
||||
task('polyfill', ['polyfill.copy-readme', 'polyfill.write']);
|
||||
|
||||
task('polyfill.write', (done: Function) => {
|
||||
writePolyfills('dist/ionic-angular/polyfills').then(() => {
|
||||
writePolyfills(join('dist', 'ionic-angular', 'polyfills')).then(() => {
|
||||
done();
|
||||
}).catch(err => {
|
||||
done(err);
|
||||
@@ -12,6 +13,9 @@ task('polyfill.write', (done: Function) => {
|
||||
});
|
||||
|
||||
task('polyfill.copy-readme', (done: Function) => {
|
||||
return src('scripts/polyfill/readme.md')
|
||||
.pipe(dest('dist/ionic-angular/polyfills/'), done);
|
||||
return readFileAsync(join('scripts', 'polyfill', 'readme.md')).then((fileContent: string) => {
|
||||
return writeFileAsync(join('dist', 'ionic-angular', 'polyfills', 'readme.md'), fileContent);
|
||||
}).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { exec, spawnSync, spawn } from 'child_process';
|
||||
import { exec, spawnSync } from 'child_process';
|
||||
import { spawn } from 'cross-spawn';
|
||||
import { writeFileSync } from 'fs';
|
||||
import * as changelog from 'conventional-changelog';
|
||||
import * as GithubApi from 'github';
|
||||
@@ -11,7 +12,7 @@ import * as runSequence from 'run-sequence';
|
||||
import * as semver from 'semver';
|
||||
import { obj } from 'through2';
|
||||
|
||||
import { DIST_BUILD_UMD_BUNDLE_ENTRYPOINT, DIST_BUILD_ROOT, DIST_BUNDLE_ROOT, PROJECT_ROOT, SCRIPTS_ROOT, SRC_ROOT } from '../constants';
|
||||
import { DIST_BUILD_ROOT, DIST_BUILD_UMD_BUNDLE_ENTRYPOINT, DIST_BUNDLE_ROOT, PROJECT_ROOT, SCRIPTS_ROOT, SRC_ROOT } from '../constants';
|
||||
import { compileSass, copyFonts, createTimestamp, setSassIonicVersion, writePolyfills } from '../util';
|
||||
|
||||
var promptAnswers;
|
||||
@@ -84,9 +85,9 @@ task('release.publishGithubRelease', (done: Function) => {
|
||||
return changelog({
|
||||
preset: 'angular'
|
||||
})
|
||||
.pipe(obj(function(file, enc, cb){
|
||||
.pipe(obj(function(file, enc, cb) {
|
||||
github.releases.createRelease({
|
||||
owner: 'driftyco',
|
||||
owner: 'ionic-team',
|
||||
repo: 'ionic',
|
||||
target_commitish: 'master',
|
||||
tag_name: 'v' + packageJSON.version,
|
||||
|
||||
@@ -77,7 +77,9 @@ function protractor(callback, args, testId: string) {
|
||||
|
||||
console.log(`Serving ${process.cwd()} on http://localhost:${buildConfig.protractorPort}`);
|
||||
|
||||
const child = spawn('protractor', args, {
|
||||
let spawnCommand = process.platform === 'win32' ? 'protractor.cmd' : 'protractor';
|
||||
|
||||
const child = spawn(spawnCommand, args, {
|
||||
stdio: [process.stdin, process.stdout, 'pipe']
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { spawn } from 'child_process';
|
||||
import { spawn } from 'cross-spawn';
|
||||
import { NODE_MODULES_ROOT, SRC_ROOT } from './constants';
|
||||
import { src, dest } from 'gulp';
|
||||
import { dirname, join } from 'path';
|
||||
import { ensureDirSync, readdirSync, readFile, readFileSync, statSync, writeFile, writeFileSync } from 'fs-extra';
|
||||
import { dest, src } from 'gulp';
|
||||
import { dirname, join, resolve } from 'path';
|
||||
import { ensureDirSync, readFile, readFileSync, readdirSync, statSync, writeFile, writeFileSync } from 'fs-extra';
|
||||
import { rollup } from 'rollup';
|
||||
import { Replacer } from 'strip-function';
|
||||
import * as commonjs from 'rollup-plugin-commonjs';
|
||||
@@ -25,10 +25,10 @@ export function mergeObjects(obj1: any, obj2: any ) {
|
||||
obj2 = {};
|
||||
}
|
||||
var obj3 = {};
|
||||
for (var attrname in obj1) {
|
||||
for (let attrname in obj1) {
|
||||
(<any>obj3)[attrname] = obj1[attrname];
|
||||
}
|
||||
for (var attrname in obj2) {
|
||||
for (let attrname in obj2) {
|
||||
(<any>obj3)[attrname] = obj2[attrname];
|
||||
}
|
||||
return obj3;
|
||||
@@ -50,6 +50,15 @@ export function createTempTsConfig(includeGlob: string[], target: string, module
|
||||
if (config.compilerOptions && config.compilerOptions.outDir) {
|
||||
delete config.compilerOptions.outDir;
|
||||
}
|
||||
|
||||
// remove linting checks that we do not want in dist
|
||||
if (config.compilerOptions.noUnusedLocals) {
|
||||
delete config.compilerOptions.noUnusedLocals;
|
||||
}
|
||||
if (config.compilerOptions.noUnusedParameters) {
|
||||
delete config.compilerOptions.noUnusedParameters;
|
||||
}
|
||||
|
||||
if (config.compilerOptions) {
|
||||
config.compilerOptions.module = moduleType;
|
||||
config.compilerOptions.target = target;
|
||||
@@ -60,7 +69,9 @@ export function createTempTsConfig(includeGlob: string[], target: string, module
|
||||
config.compilerOptions = Object.assign(config.compilerOptions, overrideCompileOptions);
|
||||
}
|
||||
|
||||
// TS represents paths internally with '/' and expects the tsconfig path to be in this format
|
||||
let json = JSON.stringify(config, null, 2);
|
||||
json = json.replace(/\\\\/g, '/');
|
||||
|
||||
const dirToCreate = dirname(pathToWriteFile);
|
||||
ensureDirSync(dirToCreate);
|
||||
@@ -188,7 +199,7 @@ export function runWebpack(pathToWebpackConfig: string, done: Function) {
|
||||
});
|
||||
}
|
||||
|
||||
export function runAppScriptsServe(testOrDemoName: string, appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, watchConfigPath: string) {
|
||||
export function runAppScriptsServe(testOrDemoName: string, appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, watchConfigPath: string, devApp: boolean) {
|
||||
console.log('Running ionic-app-scripts serve with', testOrDemoName);
|
||||
const deepLinksDir = dirname(dirname(appNgModulePath));
|
||||
let scriptArgs = [
|
||||
@@ -203,8 +214,12 @@ export function runAppScriptsServe(testOrDemoName: string, appEntryPoint: string
|
||||
'--ionicAngularDir', ionicAngularDir,
|
||||
'--sass', sassConfigPath,
|
||||
'--copy', copyConfigPath,
|
||||
'--enableLint', 'false'
|
||||
'--enableLint', 'false',
|
||||
'--skipIonicAngularVersion', 'true'
|
||||
];
|
||||
if (devApp) {
|
||||
scriptArgs.push('--bonjour');
|
||||
}
|
||||
|
||||
if (watchConfigPath) {
|
||||
scriptArgs.push('--watch');
|
||||
@@ -217,9 +232,11 @@ export function runAppScriptsServe(testOrDemoName: string, appEntryPoint: string
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const args = ['./node_modules/.bin/ionic-app-scripts'].concat(scriptArgs);
|
||||
console.log(`node ${args.join(' ')}`);
|
||||
const spawnedCommand = spawn('node', args, {stdio: 'inherit'});
|
||||
let pathToAppScripts = join(NODE_MODULES_ROOT, '.bin', 'ionic-app-scripts');
|
||||
pathToAppScripts = process.platform === 'win32' ? pathToAppScripts + '.cmd' : pathToAppScripts;
|
||||
|
||||
const spawnedCommand = spawn(pathToAppScripts, scriptArgs, {stdio: 'inherit'});
|
||||
console.log(`${pathToAppScripts} ${scriptArgs.join(' ')}`);
|
||||
|
||||
spawnedCommand.on('close', (code: number) => {
|
||||
if (code === 0) {
|
||||
@@ -230,10 +247,10 @@ export function runAppScriptsServe(testOrDemoName: string, appEntryPoint: string
|
||||
});
|
||||
}
|
||||
|
||||
export function runAppScriptsBuild(appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, isDev: boolean = false) {
|
||||
export function runAppScriptsBuild(appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, isDev: boolean = false, minifyCss: boolean = true, minifyJs: boolean = true, optimizeJs: boolean = true) {
|
||||
const pathToAppScripts = join(NODE_MODULES_ROOT, '.bin', 'ionic-app-scripts');
|
||||
const debug: boolean = argv.debug;
|
||||
return runWorker(pathToAppScripts, debug, appEntryPoint, appNgModulePath, srcDir, distDir, tsConfig, ionicAngularDir, sassConfigPath, copyConfigPath, isDev);
|
||||
return runWorker(pathToAppScripts, debug, appEntryPoint, appNgModulePath, srcDir, distDir, tsConfig, ionicAngularDir, sassConfigPath, copyConfigPath, isDev, minifyCss, minifyJs, optimizeJs);
|
||||
}
|
||||
|
||||
/** Resolves the path for a node package executable. */
|
||||
@@ -309,7 +326,7 @@ export function writePolyfills(outputDirectory: string) {
|
||||
promises.push(bundlePolyfill(NG_ENTRIES, join(outputDirectory, 'polyfills.ng.js')));
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
}
|
||||
|
||||
function bundlePolyfill(pathsToIncludeInPolyfill: string[], outputPath: string) {
|
||||
return rollup({
|
||||
@@ -333,6 +350,8 @@ function bundlePolyfill(pathsToIncludeInPolyfill: string[], outputPath: string)
|
||||
moduleName: 'MyBundle',
|
||||
dest: outputPath
|
||||
});
|
||||
}).catch(err => {
|
||||
console.log('caught rollup error: ', err);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -345,9 +364,11 @@ export function getFolderInfo() {
|
||||
componentName = folderSplit[0];
|
||||
componentTest = (folderSplit.length > 1 ? folderSplit[1] : 'basic');
|
||||
}
|
||||
const devApp = argv.devapp !== undefined;
|
||||
return {
|
||||
componentName: componentName,
|
||||
componentTest: componentTest
|
||||
componentTest: componentTest,
|
||||
devApp: devApp
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { dirname, join } from 'path';
|
||||
|
||||
import { MessageToWorker, WorkerProcess } from './interfaces';
|
||||
|
||||
export function runWorker(pathToAppScripts: string, debug: boolean, appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, isDev: boolean) {
|
||||
export function runWorker(pathToAppScripts: string, debug: boolean, appEntryPoint: string, appNgModulePath: string, srcDir: string, distDir: string, tsConfig: string, ionicAngularDir: string, sassConfigPath: string, copyConfigPath: string, isDev: boolean, minifyCss: boolean, minifyJs: boolean, optimizeJs: boolean) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const msgToWorker: MessageToWorker = {
|
||||
@@ -17,7 +17,10 @@ export function runWorker(pathToAppScripts: string, debug: boolean, appEntryPoin
|
||||
ionicAngularDir: ionicAngularDir,
|
||||
sassConfigPath: sassConfigPath,
|
||||
copyConfigPath: copyConfigPath,
|
||||
isDev: isDev
|
||||
isDev: isDev,
|
||||
minifyCss: minifyCss,
|
||||
minifyJs: minifyJs,
|
||||
optimizeJs: optimizeJs
|
||||
};
|
||||
|
||||
const worker = <ChildProcess>createWorker(msgToWorker);
|
||||
@@ -73,6 +76,7 @@ export function createWorker(msg: MessageToWorker): any {
|
||||
'--sass', msg.sassConfigPath,
|
||||
'--copy', msg.copyConfigPath,
|
||||
'--enableLint', 'false',
|
||||
'--skipIonicAngularVersion', 'true'
|
||||
];
|
||||
|
||||
// TODO, use prod once we're a little more settled
|
||||
@@ -84,6 +88,18 @@ export function createWorker(msg: MessageToWorker): any {
|
||||
scriptArgs.push('--debug');
|
||||
}
|
||||
|
||||
if (msg.minifyJs) {
|
||||
scriptArgs.push('--minifyJs');
|
||||
}
|
||||
|
||||
if (msg.minifyCss) {
|
||||
scriptArgs.push('--minifyCss');
|
||||
}
|
||||
|
||||
if (msg.optimizeJs) {
|
||||
scriptArgs.push('--optimizeJs');
|
||||
}
|
||||
|
||||
const workerModule = join(process.cwd(), 'node_modules', '@ionic', 'app-scripts', 'bin', 'ionic-app-scripts.js');
|
||||
const worker = fork(workerModule, scriptArgs, {
|
||||
env: {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
export interface WorkerProcess {
|
||||
appEntryPoint: string;
|
||||
worker: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface MessageToWorker {
|
||||
pathToAppScripts: string;
|
||||
@@ -16,4 +16,8 @@ export interface MessageToWorker {
|
||||
sassConfigPath: string;
|
||||
copyConfigPath: string;
|
||||
isDev: boolean;
|
||||
};
|
||||
minifyJs: boolean;
|
||||
minifyCss: boolean;
|
||||
optimizeJs: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ export function config(config) {
|
||||
'dist/ionic-angular/umd/**/!(*spec).js': ['coverage'],
|
||||
'dist/ionic-angular/**/*.js': ['sourcemap']
|
||||
},
|
||||
reporters: ['dots', 'coverage', 'spec'],
|
||||
reporters: ['coverage', 'spec'],
|
||||
specReporter: {
|
||||
maxLogLines: 5, // limit number of lines logged per test
|
||||
suppressErrorSummary: true, // do not print error summary
|
||||
@@ -95,4 +95,4 @@ export function config(config) {
|
||||
singleRun: true
|
||||
});
|
||||
|
||||
};
|
||||
};
|
||||
@@ -5,22 +5,12 @@
|
||||
"keywords": [],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/driftyco/ionic.git"
|
||||
"url": "https://github.com/ionic-team/ionic.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "umd/index.js",
|
||||
"module": "index.js",
|
||||
"es2015": "es2015/index.js",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "",
|
||||
"@angular/compiler": "",
|
||||
"@angular/compiler-cli": "",
|
||||
"@angular/core": "",
|
||||
"@angular/forms": "",
|
||||
"@angular/http": "",
|
||||
"@angular/platform-browser": "",
|
||||
"@angular/platform-browser-dynamic": "",
|
||||
"rxjs": "",
|
||||
"zone.js": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ weak maps / weak sets
|
||||
|
||||
## polyfills.ng.js
|
||||
|
||||
Only the required polyfill for Angular 2. This does not come with any ES6 polyfills. Note that all polyfill files listed here included the required polyfills for Angular 2 to work correctly.
|
||||
Only the required polyfill for Angular. This does not come with any ES6 polyfills. Note that all polyfill files listed here included the required polyfills for Angular to work correctly.
|
||||
|
||||
### Targets:
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from 'ionic-angular';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { $CLASSNAME } from './$FILENAME';
|
||||
|
||||
@NgModule({
|
||||
@@ -7,7 +7,7 @@ import { $CLASSNAME } from './$FILENAME';
|
||||
$CLASSNAME,
|
||||
],
|
||||
imports: [
|
||||
IonicPageModule.forChild($CLASSNAME),
|
||||
IonicModule,
|
||||
],
|
||||
exports: [
|
||||
$CLASSNAME
|
||||
|
||||
@@ -3,8 +3,8 @@ import { Component } from '@angular/core';
|
||||
/**
|
||||
* Generated class for the $CLASSNAME component.
|
||||
*
|
||||
* See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html
|
||||
* for more info on Angular Components.
|
||||
* See https://angular.io/api/core/Component for more info on Angular
|
||||
* Components.
|
||||
*/
|
||||
@Component({
|
||||
selector: '$FILENAME',
|
||||
|
||||
@@ -3,8 +3,8 @@ import { Directive } from '@angular/core';
|
||||
/**
|
||||
* Generated class for the $CLASSNAME directive.
|
||||
*
|
||||
* See https://angular.io/docs/ts/latest/api/core/index/DirectiveMetadata-class.html
|
||||
* for more info on Angular Directives.
|
||||
* See https://angular.io/api/core/Directive for more info on Angular
|
||||
* Directives.
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[$FILENAME]' // Attribute selector
|
||||
|
||||
@@ -9,8 +9,5 @@ import { $CLASSNAME } from './$FILENAME';
|
||||
imports: [
|
||||
IonicPageModule.forChild($CLASSNAME),
|
||||
],
|
||||
exports: [
|
||||
$CLASSNAME
|
||||
]
|
||||
})
|
||||
export class $CLASSNAMEModule {}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams } from 'ionic-angular';
|
||||
$IMPORTSTATEMENT
|
||||
|
||||
/**
|
||||
* Generated class for the $CLASSNAME page.
|
||||
*
|
||||
* See http://ionicframework.com/docs/components/#navigation for more info
|
||||
* on Ionic pages and navigation.
|
||||
* See https://ionicframework.com/docs/components/#navigation for more info on
|
||||
* Ionic pages and navigation.
|
||||
*/
|
||||
@IonicPage()
|
||||
$IONICPAGE
|
||||
@Component({
|
||||
selector: 'page-$FILENAME',
|
||||
templateUrl: '$FILENAME.html',
|
||||
|
||||
@@ -3,11 +3,10 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||
/**
|
||||
* Generated class for the $CLASSNAME pipe.
|
||||
*
|
||||
* See https://angular.io/docs/ts/latest/guide/pipes.html for more info on
|
||||
* Angular Pipes.
|
||||
* See https://angular.io/api/core/Pipe for more info on Angular Pipes.
|
||||
*/
|
||||
@Pipe({
|
||||
name: '$FILENAME',
|
||||
name: '$PIPENAME',
|
||||
})
|
||||
export class $CLASSNAME implements PipeTransform {
|
||||
/**
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
/*
|
||||
Generated class for the $CLASSNAME provider.
|
||||
|
||||
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
|
||||
for more info on providers and Angular 2 DI.
|
||||
See https://angular.io/guide/dependency-injection for more info on providers
|
||||
and Angular DI.
|
||||
*/
|
||||
@Injectable()
|
||||
export class $CLASSNAME {
|
||||
|
||||
constructor(public http: Http) {
|
||||
constructor(public http: HttpClient) {
|
||||
console.log('Hello $CLASSNAME Provider');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage, NavController } from 'ionic-angular';
|
||||
$TABS_IMPORTSTATEMENT
|
||||
|
||||
/**
|
||||
* Generated class for the $CLASSNAME tabs.
|
||||
*
|
||||
* See https://angular.io/docs/ts/latest/guide/dependency-injection.html for
|
||||
* more info on providers and Angular DI.
|
||||
* See https://ionicframework.com/docs/components/#navigation for more info on
|
||||
* Ionic pages and navigation.
|
||||
*/
|
||||
$IONICPAGE
|
||||
@Component({
|
||||
selector: 'page-$FILENAME',
|
||||
templateUrl: '$FILENAME.html'
|
||||
})
|
||||
@IonicPage()
|
||||
export class $CLASSNAME {
|
||||
|
||||
$TAB_VARIABLES
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { isDefined, assert } from '../util/util';
|
||||
import { assert, isDefined } from '../util/util';
|
||||
import { Platform } from '../platform/platform';
|
||||
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@@ -48,12 +47,12 @@ export class Animation {
|
||||
if (ele) {
|
||||
if (typeof ele === 'string') {
|
||||
ele = this.plt.doc().querySelectorAll(ele);
|
||||
for (var i = 0; i < ele.length; i++) {
|
||||
for (let i = 0; i < ele.length; i++) {
|
||||
this._addEle(ele[i]);
|
||||
}
|
||||
|
||||
} else if (ele.length) {
|
||||
for (var i = 0; i < ele.length; i++) {
|
||||
for (let i = 0; i < ele.length; i++) {
|
||||
this._addEle(ele[i]);
|
||||
}
|
||||
|
||||
@@ -194,7 +193,7 @@ export class Animation {
|
||||
|
||||
if (!fxProp) {
|
||||
// first time we've see this EffectProperty
|
||||
var shouldTrans = (ANIMATION_TRANSFORMS[prop] === 1);
|
||||
const shouldTrans = (ANIMATION_TRANSFORMS[prop] === 1);
|
||||
fxProp = {
|
||||
name: prop,
|
||||
trans: shouldTrans,
|
||||
@@ -262,7 +261,7 @@ export class Animation {
|
||||
*/
|
||||
beforeClearStyles(propertyNames: string[]): Animation {
|
||||
this._bfSty = this._bfSty || {};
|
||||
for (var i = 0; i < propertyNames.length; i++) {
|
||||
for (let i = 0; i < propertyNames.length; i++) {
|
||||
this._bfSty[propertyNames[i]] = '';
|
||||
}
|
||||
return this;
|
||||
@@ -319,7 +318,7 @@ export class Animation {
|
||||
*/
|
||||
afterClearStyles(propertyNames: string[]): Animation {
|
||||
this._afSty = this._afSty || {};
|
||||
for (var i = 0; i < propertyNames.length; i++) {
|
||||
for (let i = 0; i < propertyNames.length; i++) {
|
||||
this._afSty[propertyNames[i]] = '';
|
||||
}
|
||||
return this;
|
||||
@@ -386,7 +385,7 @@ export class Animation {
|
||||
this._hasDur = (this.getDuration(opts) > ANIMATION_DURATION_MIN);
|
||||
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
children[i]._playInit(opts);
|
||||
}
|
||||
@@ -441,7 +440,7 @@ export class Animation {
|
||||
*/
|
||||
_playProgress(opts: PlayOptions) {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
children[i]._playProgress(opts);
|
||||
}
|
||||
@@ -474,7 +473,7 @@ export class Animation {
|
||||
*/
|
||||
_playToStep(stepValue: number) {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
children[i]._playToStep(stepValue);
|
||||
}
|
||||
@@ -546,7 +545,7 @@ export class Animation {
|
||||
*/
|
||||
_playEnd(stepValue?: number) {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
children[i]._playEnd(stepValue);
|
||||
}
|
||||
@@ -583,7 +582,7 @@ export class Animation {
|
||||
}
|
||||
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
if (children[i]._hasDuration(opts)) {
|
||||
return true;
|
||||
}
|
||||
@@ -602,7 +601,7 @@ export class Animation {
|
||||
}
|
||||
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
if (children[i]._hasDomReads()) {
|
||||
return true;
|
||||
}
|
||||
@@ -650,16 +649,16 @@ export class Animation {
|
||||
if (this._rv) {
|
||||
stepValue = ((stepValue * -1) + 1);
|
||||
}
|
||||
var i: number, j: number;
|
||||
var finalTransform: string = '';
|
||||
var elements = this._e;
|
||||
let i: number, j: number;
|
||||
let finalTransform: string = '';
|
||||
const elements = this._e;
|
||||
for (i = 0; i < effects.length; i++) {
|
||||
var fx = effects[i];
|
||||
const fx = effects[i];
|
||||
|
||||
if (fx.from && fx.to) {
|
||||
var fromNum = fx.from.num;
|
||||
var toNum = fx.to.num;
|
||||
var tweenEffect = (fromNum !== toNum);
|
||||
const fromNum = fx.from.num;
|
||||
const toNum = fx.to.num;
|
||||
const tweenEffect = (fromNum !== toNum);
|
||||
|
||||
assert(tweenEffect || !this._isAsync, 'in async animations to != from value');
|
||||
if (tweenEffect) {
|
||||
@@ -676,8 +675,8 @@ export class Animation {
|
||||
|
||||
} else if (tweenEffect) {
|
||||
// EVERYTHING IN BETWEEN
|
||||
var valNum = (((toNum - fromNum) * stepValue) + fromNum);
|
||||
var unit = fx.to.unit;
|
||||
let valNum = (((toNum - fromNum) * stepValue) + fromNum);
|
||||
const unit = fx.to.unit;
|
||||
if (unit === 'px') {
|
||||
valNum = Math.round(valNum);
|
||||
}
|
||||
@@ -685,7 +684,7 @@ export class Animation {
|
||||
}
|
||||
|
||||
if (val !== null) {
|
||||
var prop = fx.name;
|
||||
const prop = fx.name;
|
||||
if (fx.trans) {
|
||||
finalTransform += prop + '(' + val + ') ';
|
||||
|
||||
@@ -705,7 +704,7 @@ export class Animation {
|
||||
finalTransform += 'translateZ(0px)';
|
||||
}
|
||||
|
||||
var cssTransform = this.plt.Css.transform;
|
||||
const cssTransform = this.plt.Css.transform;
|
||||
for (i = 0; i < elements.length; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
(<any>elements[i].style)[cssTransform] = finalTransform;
|
||||
@@ -734,7 +733,7 @@ export class Animation {
|
||||
const cssTransitionTimingFn = Css.transitionTimingFn;
|
||||
|
||||
let eleStyle: any;
|
||||
for (var i = 0; i < this._eL; i++) {
|
||||
for (let i = 0; i < this._eL; i++) {
|
||||
eleStyle = elements[i].style;
|
||||
if (dur > 0) {
|
||||
// ******** DOM WRITE ****************
|
||||
@@ -836,14 +835,14 @@ export class Animation {
|
||||
*/
|
||||
_fireBeforeReadFunc() {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM READ ****************
|
||||
children[i]._fireBeforeReadFunc();
|
||||
}
|
||||
|
||||
const readFunctions = this._rdFn;
|
||||
if (readFunctions) {
|
||||
for (var i = 0; i < readFunctions.length; i++) {
|
||||
for (let i = 0; i < readFunctions.length; i++) {
|
||||
// ******** DOM READ ****************
|
||||
readFunctions[i]();
|
||||
}
|
||||
@@ -857,14 +856,14 @@ export class Animation {
|
||||
*/
|
||||
_fireBeforeWriteFunc() {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
children[i]._fireBeforeWriteFunc();
|
||||
}
|
||||
|
||||
const writeFunctions = this._wrFn;
|
||||
if (this._wrFn) {
|
||||
for (var i = 0; i < writeFunctions.length; i++) {
|
||||
for (let i = 0; i < writeFunctions.length; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
writeFunctions[i]();
|
||||
}
|
||||
@@ -909,7 +908,7 @@ export class Animation {
|
||||
|
||||
// inline styles that were added before the animation should be removed
|
||||
if (this._bfSty) {
|
||||
for (var prop in this._bfSty) {
|
||||
for (const prop in this._bfSty) {
|
||||
// ******** DOM WRITE ****************
|
||||
(<any>ele).style[prop] = '';
|
||||
}
|
||||
@@ -936,7 +935,7 @@ export class Animation {
|
||||
|
||||
// inline styles to add after the animation
|
||||
if (this._afSty) {
|
||||
for (var prop in this._afSty) {
|
||||
for (const prop in this._afSty) {
|
||||
// ******** DOM WRITE ****************
|
||||
(<any>ele).style[prop] = this._afSty[prop];
|
||||
}
|
||||
@@ -956,8 +955,8 @@ export class Animation {
|
||||
let willChange: string;
|
||||
if (addWillChange && effects) {
|
||||
wc = [];
|
||||
for (var i = 0; i < effects.length; i++) {
|
||||
var propWC = effects[i].wc;
|
||||
for (let i = 0; i < effects.length; i++) {
|
||||
const propWC = effects[i].wc;
|
||||
if (propWC === 'webkitTransform') {
|
||||
wc.push('transform', '-webkit-transform');
|
||||
|
||||
@@ -969,7 +968,7 @@ export class Animation {
|
||||
} else {
|
||||
willChange = '';
|
||||
}
|
||||
for (var i = 0; i < this._eL; i++) {
|
||||
for (let i = 0; i < this._eL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
(<any>this._e[i]).style.willChange = willChange;
|
||||
}
|
||||
@@ -996,7 +995,7 @@ export class Animation {
|
||||
*/
|
||||
_progressStart() {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
children[i]._progressStart();
|
||||
}
|
||||
@@ -1017,7 +1016,7 @@ export class Animation {
|
||||
stepValue = Math.min(1, Math.max(0, stepValue));
|
||||
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
children[i].progressStep(stepValue);
|
||||
}
|
||||
@@ -1076,7 +1075,7 @@ export class Animation {
|
||||
*/
|
||||
_progressEnd(shouldComplete: boolean, stepValue: number, dur: number, isAsync: boolean) {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
// ******** DOM WRITE ****************
|
||||
children[i]._progressEnd(shouldComplete, stepValue, dur, isAsync);
|
||||
}
|
||||
@@ -1127,7 +1126,7 @@ export class Animation {
|
||||
*/
|
||||
_didFinishAll(hasCompleted: boolean, finishAsyncAnimations: boolean, finishNoDurationAnimations: boolean) {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
children[i]._didFinishAll(hasCompleted, finishAsyncAnimations, finishNoDurationAnimations);
|
||||
}
|
||||
|
||||
@@ -1146,14 +1145,14 @@ export class Animation {
|
||||
|
||||
if (this._fFn) {
|
||||
// run all finish callbacks
|
||||
for (var i = 0; i < this._fFn.length; i++) {
|
||||
for (let i = 0; i < this._fFn.length; i++) {
|
||||
this._fFn[i](this);
|
||||
}
|
||||
}
|
||||
|
||||
if (this._fOneFn) {
|
||||
// run all "onetime" finish callbacks
|
||||
for (var i = 0; i < this._fOneFn.length; i++) {
|
||||
for (let i = 0; i < this._fOneFn.length; i++) {
|
||||
this._fOneFn[i](this);
|
||||
}
|
||||
this._fOneFn.length = 0;
|
||||
@@ -1165,7 +1164,7 @@ export class Animation {
|
||||
*/
|
||||
reverse(shouldReverse: boolean = true): Animation {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
children[i].reverse(shouldReverse);
|
||||
}
|
||||
this._rv = shouldReverse;
|
||||
@@ -1177,7 +1176,7 @@ export class Animation {
|
||||
*/
|
||||
destroy() {
|
||||
const children = this._c;
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
children[i].destroy();
|
||||
}
|
||||
|
||||
@@ -1202,9 +1201,9 @@ export class Animation {
|
||||
*/
|
||||
_transEl(): HTMLElement {
|
||||
// get the lowest level element that has an Animation
|
||||
var targetEl: HTMLElement;
|
||||
let targetEl: HTMLElement;
|
||||
|
||||
for (var i = 0; i < this._cL; i++) {
|
||||
for (let i = 0; i < this._cL; i++) {
|
||||
targetEl = this._c[i]._transEl();
|
||||
if (targetEl) {
|
||||
return targetEl;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Component, ElementRef, HostListener, Renderer, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
import { ActionSheetOptions, ActionSheetButton } from './action-sheet-options';
|
||||
import { ActionSheetButton, ActionSheetOptions } from './action-sheet-options';
|
||||
import { assert } from '../../util/util';
|
||||
import { BlockerDelegate, GestureController, BLOCK_ALL } from '../../gestures/gesture-controller';
|
||||
import { BLOCK_ALL, BlockerDelegate, GestureController } from '../../gestures/gesture-controller';
|
||||
import { Config } from '../../config/config';
|
||||
import { KEY_ESCAPE } from '../../platform/key';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import { NavParams } from '../../navigation/nav-params';
|
||||
import { NavOptions } from '../../navigation/nav-util';
|
||||
import { ViewController } from '../../navigation/view-controller';
|
||||
@@ -22,13 +21,13 @@ import { ViewController } from '../../navigation/view-controller';
|
||||
'<div class="action-sheet-group">' +
|
||||
'<div class="action-sheet-title" id="{{hdrId}}" *ngIf="d.title">{{d.title}}</div>' +
|
||||
'<div class="action-sheet-sub-title" id="{{descId}}" *ngIf="d.subTitle">{{d.subTitle}}</div>' +
|
||||
'<button ion-button="action-sheet-button" (click)="click(b)" *ngFor="let b of d.buttons" class="disable-hover" [attr.icon-left]="b.icon ? \'\' : null" [ngClass]="b.cssClass">' +
|
||||
'<button ion-button="action-sheet-button" (click)="click(b)" *ngFor="let b of d.buttons" class="disable-hover" [attr.icon-start]="b.icon ? \'\' : null" [ngClass]="b.cssClass">' +
|
||||
'<ion-icon [name]="b.icon" *ngIf="b.icon" class="action-sheet-icon"></ion-icon>' +
|
||||
'{{b.text}}' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'<div class="action-sheet-group" *ngIf="cancelButton">' +
|
||||
'<button ion-button="action-sheet-button" (click)="click(cancelButton)" class="action-sheet-cancel disable-hover" [attr.icon-left]="cancelButton.icon ? \'\' : null" [ngClass]="cancelButton.cssClass">' +
|
||||
'<div class="action-sheet-group action-sheet-group-cancel" *ngIf="cancelButton">' +
|
||||
'<button ion-button="action-sheet-button" (click)="click(cancelButton)" class="action-sheet-cancel disable-hover" [attr.icon-start]="cancelButton.icon ? \'\' : null" [ngClass]="cancelButton.cssClass">' +
|
||||
'<ion-icon [name]="cancelButton.icon" *ngIf="cancelButton.icon" class="action-sheet-icon"></ion-icon>' +
|
||||
'{{cancelButton.text}}' +
|
||||
'</button>' +
|
||||
@@ -57,7 +56,6 @@ export class ActionSheetCmp {
|
||||
constructor(
|
||||
private _viewCtrl: ViewController,
|
||||
config: Config,
|
||||
private _plt: Platform,
|
||||
private _elementRef: ElementRef,
|
||||
gestureCtrl: GestureController,
|
||||
params: NavParams,
|
||||
@@ -117,8 +115,6 @@ export class ActionSheetCmp {
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this._plt.focusOutActiveElement();
|
||||
|
||||
const focusableEle = this._elementRef.nativeElement.querySelector('button');
|
||||
if (focusableEle) {
|
||||
focusableEle.focus();
|
||||
|
||||
@@ -39,10 +39,10 @@ import { Config } from '../../config/config';
|
||||
*
|
||||
* export class MyClass{
|
||||
*
|
||||
* constructor(public actionSheetCtrl: ActionSheetController) {}
|
||||
* constructor(public actionSheetCtrl: ActionSheetController) { }
|
||||
*
|
||||
* presentActionSheet() {
|
||||
* let actionSheet = this.actionSheetCtrl.create({
|
||||
* const actionSheet = this.actionSheetCtrl.create({
|
||||
* title: 'Modify your album',
|
||||
* buttons: [
|
||||
* {
|
||||
@@ -115,7 +115,7 @@ import { Config } from '../../config/config';
|
||||
* out first, *then* start the next transition.
|
||||
*
|
||||
* ```ts
|
||||
* let actionSheet = this.actionSheetCtrl.create({
|
||||
* const actionSheet = this.actionSheetCtrl.create({
|
||||
* title: 'Hello',
|
||||
* buttons: [{
|
||||
* text: 'Ok',
|
||||
|
||||
@@ -13,4 +13,4 @@ export interface ActionSheetButton {
|
||||
icon?: string;
|
||||
cssClass?: string;
|
||||
handler?: () => boolean|void;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ $action-sheet-ios-padding-bottom: $action-sheet-ios-paddin
|
||||
/// @prop - Padding start of the action sheet
|
||||
$action-sheet-ios-padding-start: $action-sheet-ios-padding-end !default;
|
||||
|
||||
/// @prop - Top margin of the action sheet button group
|
||||
$action-sheet-ios-group-margin-top: 10px !default;
|
||||
|
||||
/// @prop - Bottom margin of the action sheet button group
|
||||
$action-sheet-ios-group-margin-bottom: 10px !default;
|
||||
|
||||
@@ -89,6 +92,11 @@ $action-sheet-ios-button-cancel-font-weight: 600 !default;
|
||||
@include text-align($action-sheet-ios-text-align);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-wrapper {
|
||||
@include margin(constant(safe-area-inset-top), auto, constant(safe-area-inset-bottom), auto);
|
||||
@include margin(env(safe-area-inset-top), auto, env(safe-area-inset-bottom), auto);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-container {
|
||||
@include deprecated-variable(padding, $action-sheet-ios-padding) {
|
||||
@include padding($action-sheet-ios-padding-top, $action-sheet-ios-padding-end, $action-sheet-ios-padding-bottom, $action-sheet-ios-padding-start);
|
||||
@@ -97,16 +105,22 @@ $action-sheet-ios-button-cancel-font-weight: 600 !default;
|
||||
|
||||
.action-sheet-ios .action-sheet-group {
|
||||
@include border-radius($action-sheet-ios-border-radius);
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
margin-bottom: $action-sheet-ios-group-margin-bottom - 2;
|
||||
@include margin(null, null, $action-sheet-ios-group-margin-bottom - 2, null);
|
||||
|
||||
background: $action-sheet-ios-background;
|
||||
|
||||
// scss-lint:disable VendorPrefix
|
||||
-webkit-overflow-scrolling: touch;
|
||||
// Prevents borders from going outside of the container
|
||||
-webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-group:first-child {
|
||||
@include margin($action-sheet-ios-group-margin-top, null, null, null);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-group:last-child {
|
||||
margin-bottom: $action-sheet-ios-group-margin-bottom;
|
||||
@include margin(null, null, $action-sheet-ios-group-margin-bottom, null);
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-title {
|
||||
@@ -137,7 +151,7 @@ $action-sheet-ios-button-cancel-font-weight: 600 !default;
|
||||
}
|
||||
|
||||
.action-sheet-ios .action-sheet-button.activated {
|
||||
margin-top: -$action-sheet-ios-button-border-width;
|
||||
@include margin(-$action-sheet-ios-button-border-width, null, null, null);
|
||||
|
||||
border-top: $action-sheet-ios-button-border-width $action-sheet-ios-button-border-style $action-sheet-ios-button-background-activated;
|
||||
border-bottom-color: $action-sheet-ios-button-background-activated;
|
||||
|
||||
@@ -9,8 +9,11 @@ $action-sheet-md-text-align: start !default;
|
||||
/// @prop - Background color of the action sheet
|
||||
$action-sheet-md-background: #fafafa !default;
|
||||
|
||||
/// @prop - Bottom margin of the action sheet button group
|
||||
$action-sheet-md-group-margin-bottom: 8px !default;
|
||||
/// @prop - Padding top of the action sheet
|
||||
$action-sheet-md-padding-top: .8rem !default;
|
||||
|
||||
/// @prop - Padding bottom of the action sheet
|
||||
$action-sheet-md-padding-bottom: .8rem !default;
|
||||
|
||||
/// @prop - Color of the action sheet title
|
||||
$action-sheet-md-title-color: #757575 !default;
|
||||
@@ -90,11 +93,6 @@ $action-sheet-md-icon-margin-bottom: 0 !default;
|
||||
/// @prop - Margin start of the icon in the action sheet button
|
||||
$action-sheet-md-icon-margin-start: 0 !default;
|
||||
|
||||
.action-sheet-md .action-sheet-container {
|
||||
@include padding(.8rem, 0);
|
||||
|
||||
background: $action-sheet-md-background;
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-title {
|
||||
@include text-align($action-sheet-md-text-align);
|
||||
@@ -144,7 +142,15 @@ $action-sheet-md-icon-margin-start: 0 !default;
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-group {
|
||||
overflow: hidden;
|
||||
background: $action-sheet-md-background;
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-group:first-child {
|
||||
@include padding($action-sheet-md-padding-top, null, null, null);
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-group:last-child {
|
||||
@include padding(null, null, $action-sheet-md-padding-bottom, null);
|
||||
}
|
||||
|
||||
.action-sheet-md .action-sheet-group .button-inner {
|
||||
|
||||
@@ -22,8 +22,9 @@ ion-action-sheet {
|
||||
}
|
||||
|
||||
.action-sheet-wrapper {
|
||||
@include position(null, 0, 0, 0);
|
||||
@include position(0, 0, 0, 0);
|
||||
@include margin(auto);
|
||||
@include transform(translate3d(0, 100%, 0));
|
||||
|
||||
position: absolute;
|
||||
z-index: $z-index-overlay-wrapper;
|
||||
@@ -32,9 +33,34 @@ ion-action-sheet {
|
||||
width: $action-sheet-width;
|
||||
max-width: $action-sheet-max-width;
|
||||
|
||||
transform: translate3d(0, 100%, 0);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.action-sheet-button {
|
||||
width: $action-sheet-width;
|
||||
}
|
||||
|
||||
.action-sheet-container {
|
||||
display: flex;
|
||||
|
||||
flex-flow: column;
|
||||
|
||||
justify-content: flex-end;
|
||||
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.action-sheet-group {
|
||||
overflow: scroll;
|
||||
|
||||
flex-shrink: 2;
|
||||
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.action-sheet-group-cancel {
|
||||
overflow: hidden;
|
||||
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ActionSheetCmp } from './action-sheet-component';
|
||||
import { ActionSheetOptions, ActionSheetButton } from './action-sheet-options';
|
||||
import { ActionSheetSlideIn, ActionSheetMdSlideIn, ActionSheetSlideOut, ActionSheetMdSlideOut, ActionSheetWpSlideIn, ActionSheetWpSlideOut } from './action-sheet-transitions';
|
||||
import { ActionSheetButton, ActionSheetOptions } from './action-sheet-options';
|
||||
import { ActionSheetMdSlideIn, ActionSheetMdSlideOut, ActionSheetSlideIn, ActionSheetSlideOut, ActionSheetWpSlideIn, ActionSheetWpSlideOut } from './action-sheet-transitions';
|
||||
import { App } from '../app/app';
|
||||
import { Config } from '../../config/config';
|
||||
import { isPresent } from '../../util/util';
|
||||
|
||||
@@ -9,6 +9,12 @@ $action-sheet-wp-text-align: start !default;
|
||||
/// @prop - Background color of the action sheet
|
||||
$action-sheet-wp-background: #fff !default;
|
||||
|
||||
/// @prop - Padding top of the action sheet
|
||||
$action-sheet-wp-padding-top: .8rem !default;
|
||||
|
||||
/// @prop - Padding bottom of the action sheet
|
||||
$action-sheet-wp-padding-bottom: .8rem !default;
|
||||
|
||||
/// @prop - Box shadow color of the action sheet
|
||||
$action-sheet-wp-box-shadow-color: rgba(0, 0, 0, .2) !default;
|
||||
|
||||
@@ -100,10 +106,6 @@ $action-sheet-wp-icon-margin-bottom: 0 !default;
|
||||
$action-sheet-wp-icon-margin-start: 0 !default;
|
||||
|
||||
|
||||
.action-sheet-wp .action-sheet-wrapper {
|
||||
box-shadow: $action-sheet-wp-box-shadow;
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-title {
|
||||
@include text-align($action-sheet-wp-title-text-align);
|
||||
|
||||
@@ -147,12 +149,20 @@ $action-sheet-wp-icon-margin-start: 0 !default;
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-container {
|
||||
@include padding(.8rem, 0);
|
||||
|
||||
.action-sheet-wp .action-sheet-group {
|
||||
background: $action-sheet-wp-background;
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-group:first-child {
|
||||
@include padding($action-sheet-wp-padding-top, null, null, null);
|
||||
|
||||
box-shadow: $action-sheet-wp-box-shadow;
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-group:last-child {
|
||||
@include padding(null, null, $action-sheet-wp-padding-bottom, null);
|
||||
}
|
||||
|
||||
.action-sheet-wp .action-sheet-group .button-inner {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,12 @@
|
||||
|
||||
<ion-content padding>
|
||||
|
||||
<button ion-button block class="e2eOpenActionSheet" (click)="presentActionSheet1()">Present Action Sheet 1</button>
|
||||
<button ion-button block (click)="presentActionSheet2()">Present Action Sheet 2</button>
|
||||
<button ion-button block (click)="presentActionSheet3()">Present Action Sheet 3</button>
|
||||
<button ion-button block class="e2eOpenActionSheet" (click)="presentBasic()">Basic</button>
|
||||
<button ion-button block (click)="presentNoBackdropDismiss()">No Backdrop Dismiss</button>
|
||||
<button ion-button block (click)="presentAlert()">Alert from Action Sheet</button>
|
||||
<button ion-button block (click)="presentScroll()">Scrollable Options</button>
|
||||
<button ion-button block (click)="presentScrollNoCancel()">Scroll Without Cancel</button>
|
||||
<button ion-button block (click)="presentCancelOnly()">Cancel Only</button>
|
||||
|
||||
<pre>
|
||||
Result: {{result}}
|
||||
|
||||
@@ -12,7 +12,7 @@ export class PageOne {
|
||||
|
||||
constructor(public actionSheetCtrl: ActionSheetController, public alertCtrl: AlertController, public modalCtrl: ModalController, public plt: Platform) {}
|
||||
|
||||
presentActionSheet1() {
|
||||
presentBasic() {
|
||||
this.result = '';
|
||||
|
||||
this.actionSheetCtrl.create()
|
||||
@@ -66,7 +66,7 @@ export class PageOne {
|
||||
.present();
|
||||
}
|
||||
|
||||
presentActionSheet2() {
|
||||
presentNoBackdropDismiss() {
|
||||
this.result = '';
|
||||
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
@@ -102,7 +102,7 @@ export class PageOne {
|
||||
actionSheet.present(actionSheet);
|
||||
}
|
||||
|
||||
presentActionSheet3() {
|
||||
presentAlert() {
|
||||
this.result = '';
|
||||
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
@@ -150,4 +150,168 @@ export class PageOne {
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
presentScroll() {
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Add Reaction',
|
||||
handler: () => {
|
||||
console.log('Add Reaction clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Text',
|
||||
handler: () => {
|
||||
console.log('Copy Text clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Share Text',
|
||||
handler: () => {
|
||||
console.log('Share Text clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Link to Message',
|
||||
handler: () => {
|
||||
console.log('Copy Link to Message clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Remind Me',
|
||||
handler: () => {
|
||||
console.log('Remind Me clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Pin File',
|
||||
handler: () => {
|
||||
console.log('Pin File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Star File',
|
||||
handler: () => {
|
||||
console.log('Star File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Mark Unread',
|
||||
handler: () => {
|
||||
console.log('Mark Unread clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Edit Title',
|
||||
handler: () => {
|
||||
console.log('Edit Title clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Save Image',
|
||||
handler: () => {
|
||||
console.log('Save Image clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Image',
|
||||
handler: () => {
|
||||
console.log('Copy Image clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Delete File',
|
||||
role: 'destructive',
|
||||
handler: () => {
|
||||
console.log('Delete File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Cancel',
|
||||
role: 'cancel', // will always sort to be on the bottom
|
||||
handler: () => {
|
||||
console.log('Cancel clicked');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
presentScrollNoCancel() {
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Add Reaction',
|
||||
handler: () => {
|
||||
console.log('Add Reaction clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Text',
|
||||
handler: () => {
|
||||
console.log('Copy Text clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Share Text',
|
||||
handler: () => {
|
||||
console.log('Share Text clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Link to Message',
|
||||
handler: () => {
|
||||
console.log('Copy Link to Message clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Remind Me',
|
||||
handler: () => {
|
||||
console.log('Remind Me clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Pin File',
|
||||
handler: () => {
|
||||
console.log('Pin File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Star File',
|
||||
handler: () => {
|
||||
console.log('Star File clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Mark Unread',
|
||||
handler: () => {
|
||||
console.log('Mark Unread clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Edit Title',
|
||||
handler: () => {
|
||||
console.log('Edit Title clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Save Image',
|
||||
handler: () => {
|
||||
console.log('Save Image clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Image',
|
||||
handler: () => {
|
||||
console.log('Copy Image clicked');
|
||||
}
|
||||
}, {
|
||||
text: 'Delete File',
|
||||
role: 'destructive',
|
||||
handler: () => {
|
||||
console.log('Delete File clicked');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
presentCancelOnly() {
|
||||
let actionSheet = this.actionSheetCtrl.create({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel', // will always sort to be on the bottom
|
||||
handler: () => {
|
||||
console.log('Cancel clicked');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ import { Component, ElementRef, HostListener, Renderer, ViewEncapsulation } from
|
||||
|
||||
import { Config } from '../../config/config';
|
||||
import { NON_TEXT_INPUT_REGEX } from '../../util/dom';
|
||||
import { GestureController, BlockerDelegate, BLOCK_ALL } from '../../gestures/gesture-controller';
|
||||
import { isPresent, assert } from '../../util/util';
|
||||
import { BLOCK_ALL, BlockerDelegate, GestureController } from '../../gestures/gesture-controller';
|
||||
import { assert, isPresent } from '../../util/util';
|
||||
import { KEY_ENTER, KEY_ESCAPE } from '../../platform/key';
|
||||
import { NavParams } from '../../navigation/nav-params';
|
||||
import { NavOptions } from '../../navigation/nav-util';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import { ViewController } from '../../navigation/view-controller';
|
||||
import { AlertInputOptions, AlertOptions, AlertButton } from './alert-options';
|
||||
import { AlertButton, AlertInputOptions, AlertOptions } from './alert-options';
|
||||
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ import { AlertInputOptions, AlertOptions, AlertButton } from './alert-options';
|
||||
'<ng-template ngSwitchDefault>' +
|
||||
'<div class="alert-input-group">' +
|
||||
'<div *ngFor="let i of d.inputs" class="alert-input-wrapper">' +
|
||||
'<input [placeholder]="i.placeholder" [(ngModel)]="i.value" [type]="i.type" [min]="i.min" [max]="i.max" [attr.id]="i.id" class="alert-input">' +
|
||||
'<input [placeholder]="i.placeholder" [(ngModel)]="i.value" [type]="i.type" dir="auto" [min]="i.min" [max]="i.max" [attr.id]="i.id" class="alert-input">' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</ng-template>' +
|
||||
@@ -84,6 +84,7 @@ export class AlertCmp {
|
||||
msgId: string;
|
||||
subHdrId: string;
|
||||
mode: string;
|
||||
keyboardResizes: boolean;
|
||||
gestureBlocker: BlockerDelegate;
|
||||
|
||||
constructor(
|
||||
@@ -99,6 +100,7 @@ export class AlertCmp {
|
||||
this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
|
||||
this.d = params.data;
|
||||
this.mode = this.d.mode || config.get('mode');
|
||||
this.keyboardResizes = config.getBoolean('keyboardResizes', false);
|
||||
_renderer.setElementClass(_elementRef.nativeElement, `alert-${this.mode}`, true);
|
||||
|
||||
if (this.d.cssClass) {
|
||||
@@ -178,7 +180,7 @@ export class AlertCmp {
|
||||
}
|
||||
|
||||
const hasTextInput = (this.d.inputs.length && this.d.inputs.some(i => !(NON_TEXT_INPUT_REGEX.test(i.type))));
|
||||
if (hasTextInput && this._plt.is('mobile')) {
|
||||
if (!this.keyboardResizes && hasTextInput && this._plt.is('mobile')) {
|
||||
// this alert has a text input and it's on a mobile device so we should align
|
||||
// the alert up high because we need to leave space for the virtual keboard
|
||||
// this also helps prevent the layout getting all messed up from
|
||||
@@ -192,25 +194,17 @@ export class AlertCmp {
|
||||
}
|
||||
|
||||
ionViewDidLeave() {
|
||||
this._plt.focusOutActiveElement();
|
||||
this.gestureBlocker.unblock();
|
||||
}
|
||||
|
||||
ionViewWillLeave() {
|
||||
this._plt.focusOutActiveElement();
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
// focus out of the active element
|
||||
this._plt.focusOutActiveElement();
|
||||
|
||||
// set focus on the first input or button in the alert
|
||||
// note that this does not always work and bring up the keyboard on
|
||||
// devices since the focus command must come from the user's touch event
|
||||
// and ionViewDidEnter is not in the same callstack as the touch event :(
|
||||
const focusableEle = this._elementRef.nativeElement.querySelector('input,button');
|
||||
if (focusableEle) {
|
||||
focusableEle.focus();
|
||||
setTimeout(() => focusableEle.focus());
|
||||
}
|
||||
this.enabled = true;
|
||||
}
|
||||
@@ -316,6 +310,11 @@ export class AlertCmp {
|
||||
return this.d.inputs.filter(i => i.checked).map(i => i.value);
|
||||
}
|
||||
|
||||
if (this.d.inputs.length === 0) {
|
||||
// this is an alert without any options/inputs at all
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// this is an alert with text inputs
|
||||
// return an object of all the values with the input name as the key
|
||||
const values: {[k: string]: string} = {};
|
||||
|
||||
@@ -51,12 +51,10 @@ import { Config } from '../../config/config';
|
||||
* ```ts
|
||||
* import { AlertController } from 'ionic-angular';
|
||||
*
|
||||
* constructor(private alertCtrl: AlertController) {
|
||||
*
|
||||
* }
|
||||
* constructor(public alertCtrl: AlertController) { }
|
||||
*
|
||||
* presentAlert() {
|
||||
* let alert = this.alertCtrl.create({
|
||||
* const alert = this.alertCtrl.create({
|
||||
* title: 'Low battery',
|
||||
* subTitle: '10% of battery remaining',
|
||||
* buttons: ['Dismiss']
|
||||
@@ -65,7 +63,7 @@ import { Config } from '../../config/config';
|
||||
* }
|
||||
*
|
||||
* presentConfirm() {
|
||||
* let alert = this.alertCtrl.create({
|
||||
* const alert = this.alertCtrl.create({
|
||||
* title: 'Confirm purchase',
|
||||
* message: 'Do you want to buy this book?',
|
||||
* buttons: [
|
||||
@@ -88,7 +86,7 @@ import { Config } from '../../config/config';
|
||||
* }
|
||||
*
|
||||
* presentPrompt() {
|
||||
* let alert = this.alertCtrl.create({
|
||||
* const alert = this.alertCtrl.create({
|
||||
* title: 'Login',
|
||||
* inputs: [
|
||||
* {
|
||||
@@ -181,14 +179,14 @@ import { Config } from '../../config/config';
|
||||
* out first, *then* start the next transition.
|
||||
*
|
||||
* ```ts
|
||||
* let alert = this.alertCtrl.create({
|
||||
* const alert = this.alertCtrl.create({
|
||||
* title: 'Hello',
|
||||
* buttons: [{
|
||||
* text: 'Ok',
|
||||
* handler: () => {
|
||||
* // user has clicked the alert button
|
||||
* // begin the alert's dismiss transition
|
||||
* let navTransition = alert.dismiss();
|
||||
* const navTransition = alert.dismiss();
|
||||
*
|
||||
* // start some async method
|
||||
* someAsyncOperation().then(() => {
|
||||
|
||||
@@ -29,4 +29,4 @@ export interface AlertButton {
|
||||
role?: string;
|
||||
cssClass?: string;
|
||||
handler?: (value: any) => boolean|void;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -193,8 +193,10 @@ $alert-ios-radio-min-width: 30px !default;
|
||||
/// @prop - Top of the icon in the radio alert
|
||||
$alert-ios-radio-icon-top: -7px !default;
|
||||
|
||||
/// @prop - Left of the icon in the radio alert
|
||||
// deprecated
|
||||
$alert-ios-radio-icon-left: 7px !default;
|
||||
/// @prop - Start of the icon in the radio alert
|
||||
$alert-ios-radio-icon-start: $alert-ios-radio-icon-left !default;
|
||||
|
||||
/// @prop - Width of the icon in the radio alert
|
||||
$alert-ios-radio-icon-width: 6px !default;
|
||||
@@ -277,8 +279,10 @@ $alert-ios-checkbox-background-color-on: color($colors-ios, primary) !def
|
||||
/// @prop - Top of the icon in the checkbox alert
|
||||
$alert-ios-checkbox-icon-top: 4px !default;
|
||||
|
||||
/// @prop - Left of the icon in the checkbox alert
|
||||
// deprecated
|
||||
$alert-ios-checkbox-icon-left: 7px !default;
|
||||
/// @prop - Start of the icon in the checkbox alert
|
||||
$alert-ios-checkbox-icon-start: $alert-ios-checkbox-icon-left !default;
|
||||
|
||||
/// @prop - Width of the icon in the checkbox alert
|
||||
$alert-ios-checkbox-icon-width: 4px !default;
|
||||
@@ -324,7 +328,7 @@ $alert-ios-checkbox-icon-transform: rotate(45deg) !default;
|
||||
}
|
||||
|
||||
.alert-ios .alert-title {
|
||||
margin-top: $alert-ios-title-margin-top;
|
||||
@include margin($alert-ios-title-margin-top, null, null, null);
|
||||
|
||||
font-size: $alert-ios-title-font-size;
|
||||
font-weight: $alert-ios-title-font-weight;
|
||||
@@ -446,7 +450,7 @@ $alert-ios-checkbox-icon-transform: rotate(45deg) !default;
|
||||
// -----------------------------------------
|
||||
|
||||
.alert-ios [aria-checked=true] .alert-radio-inner {
|
||||
@include position($alert-ios-radio-icon-top, null, null, $alert-ios-radio-icon-left);
|
||||
@include position($alert-ios-radio-icon-top, null, null, $alert-ios-radio-icon-start);
|
||||
|
||||
position: absolute;
|
||||
|
||||
@@ -519,7 +523,7 @@ $alert-ios-checkbox-icon-transform: rotate(45deg) !default;
|
||||
// -----------------------------------------
|
||||
|
||||
.alert-ios [aria-checked=true] .alert-checkbox-inner {
|
||||
@include position($alert-ios-checkbox-icon-top, null, null, $alert-ios-checkbox-icon-left);
|
||||
@include position($alert-ios-checkbox-icon-top, null, null, $alert-ios-checkbox-icon-start);
|
||||
|
||||
position: absolute;
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ $alert-md-input-margin-bottom: 5px !default;
|
||||
// deprecated
|
||||
$alert-md-input-margin-left: 0 !default;
|
||||
/// @prop - Margin start of the alert input
|
||||
$alert-md-input-margin-start: $alert-md-input-margin-left;
|
||||
$alert-md-input-margin-start: $alert-md-input-margin-left !default;
|
||||
|
||||
/// @prop - Flex wrap of the alert button group
|
||||
$alert-md-button-group-flex-wrap: wrap-reverse !default;
|
||||
@@ -249,8 +249,10 @@ $alert-md-radio-border-color-on: $alert-md-button-text-color !defau
|
||||
/// @prop - Top of the icon in the alert radio
|
||||
$alert-md-radio-icon-top: 2px !default;
|
||||
|
||||
/// @prop - Left of the icon in the alert radio
|
||||
// deprecated
|
||||
$alert-md-radio-icon-left: 2px !default;
|
||||
/// @prop - Start of the icon in the radio alert
|
||||
$alert-md-radio-icon-start: $alert-md-radio-icon-left !default;
|
||||
|
||||
/// @prop - Width of the icon in the alert radio
|
||||
$alert-md-radio-icon-width: 8px !default;
|
||||
@@ -323,8 +325,10 @@ $alert-md-checkbox-border-color-on: $alert-md-button-text-color !defau
|
||||
/// @prop - Top of the icon in the checkbox alert
|
||||
$alert-md-checkbox-icon-top: 0 !default;
|
||||
|
||||
/// @prop - Left of the icon in the checkbox alert
|
||||
// deprecated
|
||||
$alert-md-checkbox-icon-left: 3px !default;
|
||||
/// @prop - Start of the icon in the checkbox alert
|
||||
$alert-md-checkbox-icon-start: $alert-md-checkbox-icon-left !default;
|
||||
|
||||
/// @prop - Width of the icon in the checkbox alert
|
||||
$alert-md-checkbox-icon-width: 6px !default;
|
||||
@@ -410,7 +414,7 @@ $alert-md-checkbox-icon-transform: rotate(45deg) !default;
|
||||
}
|
||||
|
||||
.alert-md .alert-input:focus {
|
||||
margin-bottom: $alert-md-input-margin-bottom - 1;
|
||||
@include margin(null, null, $alert-md-input-margin-bottom - 1, null);
|
||||
|
||||
border-bottom: $alert-md-input-border-width-focused $alert-md-input-border-style-focused $alert-md-input-border-color-focused;
|
||||
}
|
||||
@@ -481,7 +485,7 @@ $alert-md-checkbox-icon-transform: rotate(45deg) !default;
|
||||
// ---------------------------------------------------
|
||||
|
||||
.alert-md .alert-radio-inner {
|
||||
@include position($alert-md-radio-icon-top, null, null, $alert-md-radio-icon-left);
|
||||
@include position($alert-md-radio-icon-top, null, null, $alert-md-radio-icon-start);
|
||||
@include border-radius($alert-md-radio-icon-border-radius);
|
||||
|
||||
position: absolute;
|
||||
@@ -559,7 +563,7 @@ $alert-md-checkbox-icon-transform: rotate(45deg) !default;
|
||||
}
|
||||
|
||||
.alert-md [aria-checked=true] .alert-checkbox-inner {
|
||||
@include position($alert-md-checkbox-icon-top, null, null, $alert-md-checkbox-icon-left);
|
||||
@include position($alert-md-checkbox-icon-top, null, null, $alert-md-checkbox-icon-start);
|
||||
|
||||
position: absolute;
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ ion-alert {
|
||||
}
|
||||
|
||||
ion-alert.alert-top {
|
||||
align-items: flex-start;
|
||||
@include padding(50px, null, null, null);
|
||||
|
||||
padding-top: 50px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
ion-alert input {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { App } from '../app/app';
|
||||
import { AlertCmp } from './alert-component';
|
||||
import { AlertOptions, AlertInputOptions, AlertButton } from './alert-options';
|
||||
import { AlertPopIn, AlertPopOut, AlertMdPopIn, AlertMdPopOut, AlertWpPopIn, AlertWpPopOut } from './alert-transitions';
|
||||
import { AlertButton, AlertInputOptions, AlertOptions } from './alert-options';
|
||||
import { AlertMdPopIn, AlertMdPopOut, AlertPopIn, AlertPopOut, AlertWpPopIn, AlertWpPopOut } from './alert-transitions';
|
||||
import { Config } from '../../config/config';
|
||||
import { isPresent } from '../../util/util';
|
||||
import { NavOptions } from '../../navigation/nav-util';
|
||||
|
||||
@@ -262,8 +262,10 @@ $alert-wp-radio-border-color: $input-wp-border-color !default;
|
||||
/// @prop - Top of the icon in the radio alert
|
||||
$alert-wp-radio-icon-top: 2px !default;
|
||||
|
||||
/// @prop - Left of the icon in the radio alert
|
||||
// deprecated
|
||||
$alert-wp-radio-icon-left: 2px !default;
|
||||
/// @prop - Start of the icon in the radio alert
|
||||
$alert-wp-radio-icon-start: $alert-wp-radio-icon-left !default;
|
||||
|
||||
/// @prop - Width of the icon in the radio alert
|
||||
$alert-wp-radio-icon-width: 8px !default;
|
||||
@@ -328,8 +330,10 @@ $alert-wp-checkbox-background-on: color($colors-wp, primary) !defau
|
||||
/// @prop - Top of the icon in the checkbox alert
|
||||
$alert-wp-checkbox-icon-top: -2px !default;
|
||||
|
||||
/// @prop - Left of the icon in the checkbox alert
|
||||
// deprecated
|
||||
$alert-wp-checkbox-icon-left: 3px !default;
|
||||
/// @prop - Start of the icon in the checkbox alert
|
||||
$alert-wp-checkbox-icon-start: $alert-wp-checkbox-icon-left !default;
|
||||
|
||||
/// @prop - Width of the icon in the checkbox alert
|
||||
$alert-wp-checkbox-icon-width: 6px !default;
|
||||
@@ -495,7 +499,7 @@ $alert-wp-checkbox-icon-transform: rotate(45deg) !default;
|
||||
// ---------------------------------------------------
|
||||
|
||||
.alert-wp .alert-radio-inner {
|
||||
@include position($alert-wp-radio-icon-top, null, null, $alert-wp-radio-icon-left);
|
||||
@include position($alert-wp-radio-icon-top, null, null, $alert-wp-radio-icon-start);
|
||||
@include border-radius($alert-wp-radio-icon-border-radius);
|
||||
|
||||
position: absolute;
|
||||
@@ -575,7 +579,7 @@ $alert-wp-checkbox-icon-transform: rotate(45deg) !default;
|
||||
// --------------------------------------------------
|
||||
|
||||
.alert-wp [aria-checked=true] .alert-checkbox-inner {
|
||||
@include position($alert-wp-checkbox-icon-top, null, null, $alert-wp-checkbox-icon-left);
|
||||
@include position($alert-wp-checkbox-icon-top, null, null, $alert-wp-checkbox-icon-start);
|
||||
|
||||
position: absolute;
|
||||
|
||||
@@ -604,7 +608,7 @@ $alert-wp-checkbox-icon-transform: rotate(45deg) !default;
|
||||
}
|
||||
|
||||
.alert-wp .alert-button-group-vertical .alert-button {
|
||||
margin-top: $alert-wp-button-group-vertical-margin-top;
|
||||
@include margin($alert-wp-button-group-vertical-margin-top, null, null, null);
|
||||
|
||||
width: $alert-wp-button-group-vertical-width;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { IonicApp, IonicModule, AlertController, LoadingController, NavController } from '../../../..';
|
||||
import { AlertController, IonicApp, IonicModule, LoadingController, NavController } from '../../../..';
|
||||
import { FormBuilder, Validators } from '@angular/forms';
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, ComponentFactoryResolver, ElementRef, Inject, OnInit, OpaqueToken, Renderer, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
import { Component, ComponentFactoryResolver, ElementRef, Inject, InjectionToken, OnInit, Renderer, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
|
||||
import { App } from './app';
|
||||
import { assert } from '../../util/util';
|
||||
@@ -8,7 +8,7 @@ import { OverlayPortal } from './overlay-portal';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import * as Constants from './app-constants';
|
||||
|
||||
export const AppRootToken = new OpaqueToken('USERROOT');
|
||||
export const AppRootToken = new InjectionToken<any>('USERROOT');
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
|
||||
@@ -145,8 +145,7 @@ h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin-top: 1.6rem;
|
||||
margin-bottom: 1rem;
|
||||
@include margin(1.6rem, null, 1rem, null);
|
||||
|
||||
font-weight: $headings-font-weight;
|
||||
line-height: $headings-line-height;
|
||||
@@ -160,7 +159,7 @@ h6 {
|
||||
h5,
|
||||
h6 {
|
||||
&:first-child {
|
||||
margin-top: -.3rem;
|
||||
@include margin(-.3rem, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,17 +167,17 @@ h6 {
|
||||
h1 + h2,
|
||||
h1 + h3,
|
||||
h2 + h3 {
|
||||
margin-top: -.3rem;
|
||||
@include margin(-.3rem, null, null, null);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 2rem;
|
||||
@include margin(2rem, null, null, null);
|
||||
|
||||
font-size: $h1-font-size;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 1.8rem;
|
||||
@include margin(1.8rem, null, null, null);
|
||||
|
||||
font-size: $h2-font-size;
|
||||
}
|
||||
@@ -412,31 +411,19 @@ ion-footer {
|
||||
// Provide `[float-{bp}]` attributes for floating the element based
|
||||
// on the breakpoint
|
||||
[float#{$infix}-left] {
|
||||
// scss-lint:disable ImportantRule, PropertySpelling
|
||||
float: left !important;
|
||||
@include float(left, !important);
|
||||
}
|
||||
|
||||
[float#{$infix}-right] {
|
||||
// scss-lint:disable ImportantRule, PropertySpelling
|
||||
float: right !important;
|
||||
@include float(right, !important);
|
||||
}
|
||||
|
||||
[float#{$infix}-start] {
|
||||
// scss-lint:disable ImportantRule, PropertySpelling
|
||||
float: left !important;
|
||||
|
||||
@include rtl() {
|
||||
float: right !important;
|
||||
}
|
||||
@include float(start, !important);
|
||||
}
|
||||
|
||||
[float#{$infix}-end] {
|
||||
// scss-lint:disable ImportantRule, PropertySpelling
|
||||
float: right !important;
|
||||
|
||||
@include rtl() {
|
||||
float: left !important;
|
||||
}
|
||||
@include float(end, !important);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { EventEmitter, Injectable, Optional } from '@angular/core';
|
||||
import { Title, DOCUMENT } from '@angular/platform-browser';
|
||||
import { DOCUMENT, Title } from '@angular/platform-browser';
|
||||
|
||||
import { IonicApp } from './app-root';
|
||||
import * as Constants from './app-constants';
|
||||
import { ClickBlock } from './click-block';
|
||||
import { runInDev, assert } from '../../util/util';
|
||||
import { assert, runInDev } from '../../util/util';
|
||||
import { Config } from '../../config/config';
|
||||
import { isNav, NavOptions, DIRECTION_FORWARD, DIRECTION_BACK } from '../../navigation/nav-util';
|
||||
import { DIRECTION_BACK, DIRECTION_FORWARD, NavOptions, isTabs } from '../../navigation/nav-util';
|
||||
import { MenuController } from './menu-controller';
|
||||
import { NavController } from '../../navigation/nav-controller';
|
||||
import { NavigationContainer } from '../../navigation/navigation-container';
|
||||
import { NavControllerBase } from '../../navigation/nav-controller-base';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import { ViewController } from '../../navigation/view-controller';
|
||||
import { IOSTransition } from '../../transitions/transition-ios';
|
||||
@@ -28,8 +29,9 @@ export class App {
|
||||
private _scrollTime: number = 0;
|
||||
private _title: string = '';
|
||||
private _titleSrv: Title = new Title(DOCUMENT);
|
||||
private _rootNav: NavController = null;
|
||||
private _rootNavs = new Map<string, NavigationContainer>();
|
||||
private _disableScrollAssist: boolean;
|
||||
private _didScroll = false;
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
@@ -87,6 +89,11 @@ export class App {
|
||||
_plt.registerBackButtonAction(this.goBack.bind(this));
|
||||
this._disableScrollAssist = _config.getBoolean('disableScrollAssist', false);
|
||||
|
||||
const blurring = _config.getBoolean('inputBlurring', false);
|
||||
if (blurring) {
|
||||
this._enableInputBlurring();
|
||||
}
|
||||
|
||||
runInDev(() => {
|
||||
// During developement, navPop can be triggered by calling
|
||||
const win = <any>_plt.win();
|
||||
@@ -179,6 +186,7 @@ export class App {
|
||||
*/
|
||||
setScrolling() {
|
||||
this._scrollTime = Date.now() + ACTIVE_SCROLLING_TIME;
|
||||
this._didScroll = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,28 +206,89 @@ export class App {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {NavController} Returns the active NavController. Using this method is preferred when we need access to the top-level navigation controller while on the outside views and handlers like `registerBackButtonAction()`
|
||||
* @return {NavController} Returns the first Active Nav Controller from the list. This method is deprecated
|
||||
*/
|
||||
getActiveNav(): NavController {
|
||||
getActiveNav(): NavControllerBase {
|
||||
console.warn('(getActiveNav) is deprecated and will be removed in the next major release. Use getActiveNavs instead.');
|
||||
const navs = this.getActiveNavs();
|
||||
if (navs && navs.length) {
|
||||
return navs[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {NavController[]} Returns the active NavControllers. Using this method is preferred when we need access to the top-level navigation controller while on the outside views and handlers like `registerBackButtonAction()`
|
||||
*/
|
||||
getActiveNavs(rootNavId?: string): NavControllerBase[] {
|
||||
const portal = this._appRoot._getPortal(Constants.PORTAL_MODAL);
|
||||
if (portal.length() > 0) {
|
||||
return findTopNav(portal);
|
||||
return <NavControllerBase[]> findTopNavs(portal);
|
||||
}
|
||||
return findTopNav(this._rootNav || null);
|
||||
if (!this._rootNavs || !this._rootNavs.size) {
|
||||
return [];
|
||||
}
|
||||
if (this._rootNavs.size === 1) {
|
||||
return <NavControllerBase[]> findTopNavs(this._rootNavs.values().next().value);
|
||||
}
|
||||
if (rootNavId) {
|
||||
return <NavControllerBase[]> findTopNavs(this._rootNavs.get(rootNavId));
|
||||
}
|
||||
// fallback to just using all root names
|
||||
let activeNavs: NavigationContainer[] = [];
|
||||
this._rootNavs.forEach(nav => {
|
||||
const topNavs = findTopNavs(nav);
|
||||
activeNavs = activeNavs.concat(topNavs);
|
||||
});
|
||||
return <NavControllerBase[]> activeNavs;
|
||||
}
|
||||
|
||||
getRootNav(): any {
|
||||
console.warn('(getRootNav) is deprecated and will be removed in the next major release. Use getRootNavById instead.');
|
||||
const rootNavs = this.getRootNavs();
|
||||
if (rootNavs.length === 0) {
|
||||
return null;
|
||||
} else if (rootNavs.length > 1) {
|
||||
console.warn('(getRootNav) there are multiple root navs, use getRootNavs instead');
|
||||
}
|
||||
return rootNavs[0];
|
||||
}
|
||||
|
||||
getRootNavs(): any[] {
|
||||
const navs: NavigationContainer[] = [];
|
||||
this._rootNavs.forEach(nav => navs.push(nav));
|
||||
return navs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {NavController} Returns the root NavController
|
||||
*/
|
||||
getRootNav(): NavController {
|
||||
return this._rootNav;
|
||||
getRootNavById(navId: string): NavigationContainer {
|
||||
return this._rootNavs.get(navId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
_setRootNav(nav: any) {
|
||||
this._rootNav = nav;
|
||||
registerRootNav(nav: NavigationContainer) {
|
||||
this._rootNavs.set(nav.id, nav);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
unregisterRootNav(nav: NavigationContainer) {
|
||||
this._rootNavs.delete(nav.id);
|
||||
}
|
||||
|
||||
|
||||
getActiveNavContainers(): NavigationContainer[] {
|
||||
// for each root nav container, get it's active nav
|
||||
let list: NavigationContainer[] = [];
|
||||
this._rootNavs.forEach((container: NavigationContainer) => {
|
||||
list = list.concat(findTopNavs(container));
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,7 +303,6 @@ export class App {
|
||||
// TODO: move _setNav() to the earlier stages of NavController. _queueTrns()
|
||||
enteringView._setNav(portal);
|
||||
|
||||
opts.keyboardClose = false;
|
||||
opts.direction = DIRECTION_FORWARD;
|
||||
|
||||
if (!opts.animation) {
|
||||
@@ -242,7 +310,7 @@ export class App {
|
||||
}
|
||||
|
||||
enteringView.setLeavingOpts({
|
||||
keyboardClose: false,
|
||||
keyboardClose: opts.keyboardClose,
|
||||
direction: DIRECTION_BACK,
|
||||
animation: enteringView.getTransitionName(DIRECTION_BACK),
|
||||
ev: opts.ev
|
||||
@@ -260,7 +328,7 @@ export class App {
|
||||
}
|
||||
|
||||
const navPromise = this.navPop();
|
||||
if (navPromise === null) {
|
||||
if (!navPromise) {
|
||||
// no views to go back to
|
||||
// let's exit the app
|
||||
if (this._config.getBoolean('navExitApp', true)) {
|
||||
@@ -275,7 +343,7 @@ export class App {
|
||||
* @hidden
|
||||
*/
|
||||
navPop(): Promise<any> {
|
||||
if (!this._rootNav || !this.isEnabled()) {
|
||||
if (!this._rootNavs || this._rootNavs.size === 0 || !this.isEnabled()) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -284,43 +352,140 @@ export class App {
|
||||
if (portal.length() > 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
// next get the active nav, check itself and climb up all
|
||||
// of its parent navs until it finds a nav that can pop
|
||||
return recursivePop(this.getActiveNav());
|
||||
|
||||
let navToPop: NavControllerBase = null;
|
||||
let mostRecentVC: ViewController = null;
|
||||
this._rootNavs.forEach((navContainer: NavigationContainer) => {
|
||||
const activeNavs = this.getActiveNavs(navContainer.id);
|
||||
const poppableNavs = activeNavs.map(activeNav => getPoppableNav(activeNav)).filter(nav => !!nav);
|
||||
poppableNavs.forEach(poppable => {
|
||||
const topViewController = poppable.last();
|
||||
if (poppable._isPortal || (topViewController && poppable.length() > 1 && (!mostRecentVC || topViewController._ts >= mostRecentVC._ts))) {
|
||||
mostRecentVC = topViewController;
|
||||
navToPop = poppable;
|
||||
}
|
||||
});
|
||||
});
|
||||
if (navToPop) {
|
||||
return navToPop.pop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
_enableInputBlurring() {
|
||||
console.debug('App: _enableInputBlurring');
|
||||
let focused = true;
|
||||
const self = this;
|
||||
const platform = this._plt;
|
||||
|
||||
platform.registerListener(platform.doc(), 'focusin', onFocusin, { capture: true, zone: false, passive: true });
|
||||
platform.registerListener(platform.doc(), 'touchend', onTouchend, { capture: false, zone: false, passive: true });
|
||||
|
||||
function onFocusin() {
|
||||
focused = true;
|
||||
}
|
||||
|
||||
function onTouchend(ev: any) {
|
||||
// if app did scroll return early
|
||||
if (self._didScroll) {
|
||||
self._didScroll = false;
|
||||
return;
|
||||
}
|
||||
const active = <HTMLElement> self._plt.getActiveElement();
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
// only blur if the active element is a text-input or a textarea
|
||||
if (SKIP_BLURRING.indexOf(active.tagName) === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the selected target is the active element, do not blur
|
||||
const tapped = ev.target;
|
||||
if (tapped === active) {
|
||||
return;
|
||||
}
|
||||
if (SKIP_BLURRING.indexOf(tapped.tagName) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// skip if div is a cover
|
||||
if (tapped.classList.contains('input-cover')) {
|
||||
return;
|
||||
}
|
||||
|
||||
focused = false;
|
||||
// TODO: find a better way, why 50ms?
|
||||
platform.timeout(() => {
|
||||
if (!focused) {
|
||||
active.blur();
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
|
||||
getNavByIdOrName(id: string) {
|
||||
const navs = Array.from(this._rootNavs.values());
|
||||
for (const navContainer of navs) {
|
||||
const match = getNavByIdOrName(navContainer, id);
|
||||
if (match) {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function recursivePop(nav: any): Promise<any> {
|
||||
export function getNavByIdOrName(nav: NavigationContainer, id: string): NavigationContainer {
|
||||
if (nav.id === id || nav.name === id) {
|
||||
return nav;
|
||||
}
|
||||
for (const child of nav.getAllChildNavs()) {
|
||||
const tmp = getNavByIdOrName(child, id);
|
||||
if (tmp) {
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getPoppableNav(nav: NavControllerBase): NavControllerBase {
|
||||
if (!nav) {
|
||||
return null;
|
||||
}
|
||||
if (isNav(nav)) {
|
||||
var len = nav.length();
|
||||
if (len > 1 || (nav._isPortal && len > 0)) {
|
||||
// this nav controller has more than one view
|
||||
// pop the current view on this nav and we're done here
|
||||
console.debug('app, goBack pop nav');
|
||||
return nav.pop();
|
||||
}
|
||||
|
||||
if (isTabs(nav)) {
|
||||
// tabs aren't a nav, so just call this function again immediately on the parent on tabs
|
||||
return getPoppableNav(nav.parent);
|
||||
}
|
||||
const len = nav.length();
|
||||
if (len > 1 || (nav._isPortal && len > 0)) {
|
||||
// this nav controller has more than one view
|
||||
// use this nav!
|
||||
return nav;
|
||||
}
|
||||
// try again using the parent nav (if there is one)
|
||||
return recursivePop(nav.parent);
|
||||
return getPoppableNav(nav.parent);
|
||||
}
|
||||
|
||||
function findTopNav(nav: NavController) {
|
||||
var activeChildNav: any;
|
||||
|
||||
while (nav) {
|
||||
activeChildNav = nav.getActiveChildNav();
|
||||
if (!activeChildNav) {
|
||||
break;
|
||||
}
|
||||
nav = activeChildNav;
|
||||
export function findTopNavs(nav: NavigationContainer): NavigationContainer[] {
|
||||
let containers: NavigationContainer[] = [];
|
||||
const childNavs = nav.getActiveChildNavs();
|
||||
if (!childNavs || !childNavs.length) {
|
||||
containers.push(nav);
|
||||
} else {
|
||||
childNavs.forEach(childNav => {
|
||||
const topNavs = findTopNavs(childNav);
|
||||
containers = containers.concat(topNavs);
|
||||
});
|
||||
}
|
||||
|
||||
return nav;
|
||||
return containers;
|
||||
}
|
||||
|
||||
|
||||
const SKIP_BLURRING = ['INPUT', 'TEXTAREA', 'ION-INPUT', 'ION-TEXTAREA'];
|
||||
const ACTIVE_SCROLLING_TIME = 100;
|
||||
const CLICK_BLOCK_BUFFER_IN_MILLIS = 64;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Directive, ElementRef, forwardRef, Inject, Renderer } from '@angular/core';
|
||||
import { Directive, ElementRef, Inject, Renderer, forwardRef } from '@angular/core';
|
||||
|
||||
import { App } from '../app/app';
|
||||
import { Config } from '../../config/config';
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Menu, MenuType } from './menu-interface';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import { removeArrayItem, assert } from '../../util/util';
|
||||
import { assert, removeArrayItem } from '../../util/util';
|
||||
|
||||
|
||||
/**
|
||||
* @name MenuController
|
||||
* @description
|
||||
* The MenuController is a provider which makes it easy to control a [Menu](../Menu).
|
||||
* The MenuController is a provider which makes it easy to control a [Menu](../../Menu/Menu/).
|
||||
* Its methods can be used to display the menu, enable the menu, toggle the menu, and more.
|
||||
* The controller will grab a reference to the menu by the `side`, `id`, or, if neither
|
||||
* of these are passed to it, it will grab the first menu it finds.
|
||||
@@ -14,7 +14,7 @@ import { removeArrayItem, assert } from '../../util/util';
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* Add a basic menu component to start with. See the [Menu](../Menu) API docs
|
||||
* Add a basic menu component to start with. See the [Menu](../../Menu/Menu/) API docs
|
||||
* for more information on adding menu components.
|
||||
*
|
||||
* ```html
|
||||
|
||||
@@ -27,7 +27,7 @@ export interface Menu {
|
||||
getBackdropElement(): HTMLElement;
|
||||
_canOpen(): boolean;
|
||||
persistent: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface MenuType {
|
||||
ani: Animation;
|
||||
@@ -37,4 +37,4 @@ export interface MenuType {
|
||||
setProgessStep(stepValue: number): void;
|
||||
setProgressEnd(shouldComplete: boolean, currentStepValue: number, velocity: number, done: Function): void;
|
||||
destroy(): void;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, ErrorHandler, forwardRef, Inject, Input, NgZone, Optional, Renderer, ViewContainerRef } from '@angular/core';
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, ErrorHandler, Inject, Input, NgZone, Optional, Renderer, ViewContainerRef, forwardRef } from '@angular/core';
|
||||
|
||||
import { App } from './app';
|
||||
import { Config } from '../../config/config';
|
||||
import { DeepLinker } from '../../navigation/deep-linker';
|
||||
import { DomController } from '../../platform/dom-controller';
|
||||
import { GestureController } from '../../gestures/gesture-controller';
|
||||
import { Keyboard } from '../../platform/keyboard';
|
||||
import { NavControllerBase } from '../../navigation/nav-controller-base';
|
||||
import { NavigationContainer } from '../../navigation/navigation-container';
|
||||
import { Platform } from '../../platform/platform';
|
||||
import { TransitionController } from '../../transitions/transition-controller';
|
||||
import { ViewController } from '../../navigation/view-controller';
|
||||
@@ -17,12 +17,11 @@ import { ViewController } from '../../navigation/view-controller';
|
||||
@Directive({
|
||||
selector: '[overlay-portal]',
|
||||
})
|
||||
export class OverlayPortal extends NavControllerBase {
|
||||
export class OverlayPortal extends NavControllerBase implements NavigationContainer {
|
||||
constructor(
|
||||
@Inject(forwardRef(() => App)) app: App,
|
||||
config: Config,
|
||||
plt: Platform,
|
||||
keyboard: Keyboard,
|
||||
elementRef: ElementRef,
|
||||
zone: NgZone,
|
||||
renderer: Renderer,
|
||||
@@ -34,7 +33,7 @@ export class OverlayPortal extends NavControllerBase {
|
||||
domCtrl: DomController,
|
||||
errHandler: ErrorHandler
|
||||
) {
|
||||
super(null, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
|
||||
super(null, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
|
||||
this._isPortal = true;
|
||||
this._init = true;
|
||||
this.setViewport(viewPort);
|
||||
@@ -57,4 +56,17 @@ export class OverlayPortal extends NavControllerBase {
|
||||
this.destroy();
|
||||
}
|
||||
|
||||
/*
|
||||
* @private
|
||||
*/
|
||||
getType() {
|
||||
return 'portal';
|
||||
}
|
||||
|
||||
/*
|
||||
* @private
|
||||
*/
|
||||
getSecondaryIdentifier(): string {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { App } from '../app';
|
||||
import { ClickBlock } from '../click-block';
|
||||
import { Config } from '../../../config/config';
|
||||
import { mockApp, mockConfig, mockElementRef, mockNavController, mockPlatform, MockPlatform, mockRenderer, mockTab, mockTabs, mockView, mockViews } from '../../../util/mock-providers';
|
||||
import { MockPlatform, mockApp, mockConfig, mockElementRef, mockNavController, mockPlatform, mockRenderer, mockTab, mockTabs, mockView, mockViews } from '../../../util/mock-providers';
|
||||
import { OverlayPortal } from '../overlay-portal';
|
||||
import { PORTAL_MODAL } from '../app-constants';
|
||||
|
||||
@@ -10,105 +10,115 @@ describe('App', () => {
|
||||
|
||||
describe('goBack', () => {
|
||||
|
||||
it('should not select the previous tab', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
it('should not select the previous tab', (done: Function) => {
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
let tabs = mockTabs();
|
||||
let tab1 = mockTab(tabs);
|
||||
let tab2 = mockTab(tabs);
|
||||
const tabs = mockTabs();
|
||||
const tab1 = mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
|
||||
tab1.root = 'Page1';
|
||||
tab2.root = 'Page2';
|
||||
|
||||
nav.registerChildNav(tabs);
|
||||
|
||||
tabs.select(tab1);
|
||||
tabs.select(tab2);
|
||||
|
||||
expect(tabs._selectHistory).toEqual([tab1.id, tab2.id]);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(tabs, 'select');
|
||||
spyOn(tab1, 'pop');
|
||||
spyOn(tab2, 'pop');
|
||||
spyOn(portal, 'pop');
|
||||
|
||||
app.goBack();
|
||||
|
||||
expect(tabs.select).not.toHaveBeenCalled();
|
||||
expect(tab1.pop).not.toHaveBeenCalled();
|
||||
expect(tab2.pop).not.toHaveBeenCalled();
|
||||
expect(portal.pop).not.toHaveBeenCalled();
|
||||
expect(plt.exitApp).toHaveBeenCalled();
|
||||
tabs.select(tab1).then(() => {
|
||||
return tabs.select(tab2);
|
||||
}).then(() => {
|
||||
expect(tabs._selectHistory).toEqual([tab1.id, tab2.id]);
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(tabs, 'select');
|
||||
spyOn(tab1, 'pop');
|
||||
spyOn(tab2, 'pop');
|
||||
spyOn(portal, 'pop');
|
||||
return app.goBack();
|
||||
}).then(() => {
|
||||
expect(tabs.select).not.toHaveBeenCalled();
|
||||
expect(tab1.pop).not.toHaveBeenCalled();
|
||||
expect(tab2.pop).not.toHaveBeenCalled();
|
||||
expect(portal.pop).not.toHaveBeenCalled();
|
||||
expect(plt.exitApp).toHaveBeenCalled();
|
||||
done();
|
||||
}).catch((err: Error) => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should pop from the active tab, when tabs is nested is the root nav', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
let tabs = mockTabs();
|
||||
mockTab(tabs);
|
||||
let tab2 = mockTab(tabs);
|
||||
const tabs = mockTabs();
|
||||
mockTab(tabs);
|
||||
nav.registerChildNav(tabs);
|
||||
|
||||
const tab1 = mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
|
||||
tab2.setSelected(true);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(tab2, 'pop');
|
||||
spyOn(tab1, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(tab2, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(portal, 'pop');
|
||||
|
||||
let view1 = mockView();
|
||||
let view2 = mockView();
|
||||
const view1 = mockView();
|
||||
const view2 = mockView();
|
||||
tab2._views = [view1, view2];
|
||||
tab1._views = [mockView()];
|
||||
|
||||
app.goBack();
|
||||
|
||||
expect(tab1.pop).not.toHaveBeenCalled();
|
||||
expect(tab2.pop).toHaveBeenCalled();
|
||||
expect(portal.pop).not.toHaveBeenCalled();
|
||||
expect(plt.exitApp).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should pop from the active tab, when tabs is the root', () => {
|
||||
let tabs = mockTabs();
|
||||
const tabs = mockTabs();
|
||||
mockTab(tabs);
|
||||
let tab2 = mockTab(tabs);
|
||||
mockTab(tabs);
|
||||
app._setRootNav(tabs);
|
||||
app.registerRootNav(tabs);
|
||||
|
||||
const tab1 = mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
|
||||
tab2.setSelected(true);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(tab2, 'pop');
|
||||
spyOn(tab1, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(tab2, 'pop').and.returnValue(Promise.resolve());
|
||||
|
||||
let view1 = mockView();
|
||||
let view2 = mockView();
|
||||
const view1 = mockView();
|
||||
const view2 = mockView();
|
||||
tab2._views = [view1, view2];
|
||||
|
||||
app.goBack();
|
||||
|
||||
expect(tab1.pop).not.toHaveBeenCalled();
|
||||
expect(tab2.pop).toHaveBeenCalled();
|
||||
expect(plt.exitApp).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should pop the root nav when nested nav has less than 2 views', () => {
|
||||
let rootNav = mockNavController();
|
||||
let nestedNav = mockNavController();
|
||||
rootNav.registerChildNav(nestedNav);
|
||||
const rootNav = mockNavController();
|
||||
app.registerRootNav(rootNav);
|
||||
|
||||
const nestedNav = mockNavController();
|
||||
nestedNav.parent = rootNav;
|
||||
app._setRootNav(rootNav);
|
||||
rootNav.registerChildNav(nestedNav);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(rootNav, 'pop');
|
||||
spyOn(nestedNav, 'pop');
|
||||
spyOn(portal, 'pop');
|
||||
spyOn(rootNav, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(nestedNav, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(portal, 'pop').and.returnValue(Promise.resolve());
|
||||
|
||||
let rootView1 = mockView();
|
||||
let rootView2 = mockView();
|
||||
const rootView1 = mockView();
|
||||
const rootView2 = mockView();
|
||||
mockViews(rootNav, [rootView1, rootView2]);
|
||||
|
||||
let nestedView1 = mockView();
|
||||
const nestedView1 = mockView();
|
||||
mockViews(nestedNav, [nestedView1]);
|
||||
|
||||
app.goBack();
|
||||
@@ -120,22 +130,22 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should pop a view from the nested nav that has more than 1 view', () => {
|
||||
let rootNav = mockNavController();
|
||||
let nestedNav = mockNavController();
|
||||
app._setRootNav(rootNav);
|
||||
const rootNav = mockNavController();
|
||||
const nestedNav = mockNavController();
|
||||
app.registerRootNav(rootNav);
|
||||
rootNav.registerChildNav(nestedNav);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(rootNav, 'pop');
|
||||
spyOn(nestedNav, 'pop');
|
||||
spyOn(nestedNav, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(portal, 'pop');
|
||||
|
||||
let rootView1 = mockView();
|
||||
let rootView2 = mockView();
|
||||
const rootView1 = mockView();
|
||||
const rootView2 = mockView();
|
||||
mockViews(rootNav, [rootView1, rootView2]);
|
||||
|
||||
let nestedView1 = mockView();
|
||||
let nestedView2 = mockView();
|
||||
const nestedView1 = mockView();
|
||||
const nestedView2 = mockView();
|
||||
mockViews(nestedNav, [nestedView1, nestedView2]);
|
||||
|
||||
app.goBack();
|
||||
@@ -147,18 +157,18 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should pop the overlay in the portal of the root nav', (done: Function) => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(nav, 'pop');
|
||||
spyOn(portal, 'pop').and.returnValue(Promise.resolve());
|
||||
|
||||
let view1 = mockView();
|
||||
let view2 = mockView();
|
||||
const view1 = mockView();
|
||||
const view2 = mockView();
|
||||
mockViews(nav, [view1, view2]);
|
||||
|
||||
let overlay1 = mockView();
|
||||
const overlay1 = mockView();
|
||||
mockViews(portal, [overlay1]);
|
||||
|
||||
app.goBack().then(() => {
|
||||
@@ -173,15 +183,15 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should pop the second view in the root nav', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(nav, 'pop');
|
||||
spyOn(nav, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(portal, 'pop');
|
||||
|
||||
let view1 = mockView();
|
||||
let view2 = mockView();
|
||||
const view1 = mockView();
|
||||
const view2 = mockView();
|
||||
mockViews(nav, [view1, view2]);
|
||||
|
||||
app.goBack();
|
||||
@@ -192,17 +202,17 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should exit app when only one view in the root nav', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(nav, 'pop');
|
||||
spyOn(portal, 'pop');
|
||||
|
||||
let view1 = mockView();
|
||||
const view1 = mockView();
|
||||
mockViews(nav, [view1]);
|
||||
|
||||
expect(app.getActiveNav()).toBe(nav);
|
||||
expect(app.getActiveNavs(nav.id)[0]).toBe(nav);
|
||||
expect(nav.first()).toBe(view1);
|
||||
|
||||
app.goBack();
|
||||
@@ -213,8 +223,8 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should not exit app when only one view in the root nav, but navExitApp config set', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(nav, 'pop');
|
||||
@@ -222,10 +232,10 @@ describe('App', () => {
|
||||
|
||||
config.set('navExitApp', false);
|
||||
|
||||
let view1 = mockView();
|
||||
const view1 = mockView();
|
||||
mockViews(nav, [view1]);
|
||||
|
||||
expect(app.getActiveNav()).toBe(nav);
|
||||
expect(app.getActiveNavs(nav.id)[0]).toBe(nav);
|
||||
expect(nav.first()).toBe(view1);
|
||||
|
||||
app.goBack();
|
||||
@@ -236,14 +246,14 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should not go back if app is not enabled', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(nav, 'pop');
|
||||
spyOn(portal, 'pop');
|
||||
|
||||
let view1 = mockView();
|
||||
const view1 = mockView();
|
||||
mockViews(nav, [view1]);
|
||||
|
||||
app.setEnabled(false, 10000);
|
||||
@@ -263,38 +273,273 @@ describe('App', () => {
|
||||
expect(plt.exitApp).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should first pop the from the nav controller with the most recent view, then pop subsequent views, and eventually exit the app when there isnt anything left to pop', () => {
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
const navTwo = mockNavController();
|
||||
app.registerRootNav(navTwo);
|
||||
|
||||
spyOn(plt, 'exitApp');
|
||||
spyOn(nav, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(navTwo, 'pop').and.returnValue(Promise.resolve());
|
||||
spyOn(portal, 'pop');
|
||||
|
||||
const view1 = mockView();
|
||||
const view2 = mockView();
|
||||
mockViews(nav, [view1, view2]);
|
||||
|
||||
const view3 = mockView();
|
||||
view3._ts = view3._ts + 1000;
|
||||
const view4 = mockView();
|
||||
view4._ts = view4._ts + 1000;
|
||||
mockViews(navTwo, [view3, view4]);
|
||||
|
||||
app.goBack();
|
||||
|
||||
mockViews(navTwo, [view3]);
|
||||
|
||||
expect(portal.pop).not.toHaveBeenCalled();
|
||||
expect(nav.pop).not.toHaveBeenCalled();
|
||||
expect(navTwo.pop).toHaveBeenCalled();
|
||||
expect(plt.exitApp).not.toHaveBeenCalled();
|
||||
|
||||
app.goBack();
|
||||
expect(nav.pop).toHaveBeenCalled();
|
||||
|
||||
mockViews(nav, [view1]);
|
||||
|
||||
app.goBack();
|
||||
expect(plt.exitApp).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getActiveNav', () => {
|
||||
describe('getActiveNavs', () => {
|
||||
|
||||
it('should get active NavController when using tabs with nested nav', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
let tabs = mockTabs();
|
||||
let tab1 = mockTab(tabs);
|
||||
let tab2 = mockTab(tabs);
|
||||
const tabs = mockTabs();
|
||||
const tab1 = mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
nav.registerChildNav(tabs);
|
||||
|
||||
tab2.setSelected(true);
|
||||
let nav2 = mockNavController();
|
||||
let nav3 = mockNavController();
|
||||
let nav4 = mockNavController();
|
||||
const nav2 = mockNavController();
|
||||
nav2.name = 'nav2';
|
||||
const nav3 = mockNavController();
|
||||
nav3.name = 'nav3';
|
||||
const nav4 = mockNavController();
|
||||
nav4.name = 'nav4';
|
||||
|
||||
tab1.registerChildNav(nav4);
|
||||
// tab 2 registers two child navs!!
|
||||
tab2.registerChildNav(nav2);
|
||||
tab2.registerChildNav(nav3);
|
||||
|
||||
expect(app.getActiveNav()).toBe(nav3);
|
||||
const activeNavs = app.getActiveNavs(nav.id);
|
||||
expect(activeNavs.length).toEqual(2);
|
||||
expect(activeNavs[0]).toEqual(nav2);
|
||||
expect(activeNavs[1]).toEqual(nav3);
|
||||
|
||||
const activeNavsTwo = app.getActiveNavs();
|
||||
expect(activeNavsTwo.length).toEqual(2);
|
||||
expect(activeNavsTwo[0]).toEqual(nav2);
|
||||
expect(activeNavsTwo[1]).toEqual(nav3);
|
||||
});
|
||||
|
||||
it('should get active NavController when using tabs, nested in a root nav', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
let tabs = mockTabs();
|
||||
const tabs = mockTabs();
|
||||
mockTab(tabs);
|
||||
let tab2 = mockTab(tabs);
|
||||
let tab3 = mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
const tab3 = mockTab(tabs);
|
||||
nav.registerChildNav(tabs);
|
||||
|
||||
tab2.setSelected(true);
|
||||
|
||||
expect(app.getActiveNavs(nav.id)[0]).toBe(tab2);
|
||||
expect(app.getActiveNavs()[0]).toBe(tab2);
|
||||
|
||||
tab2.setSelected(false);
|
||||
tab3.setSelected(true);
|
||||
expect(app.getActiveNavs(nav.id)[0]).toBe(tab3);
|
||||
expect(app.getActiveNavs()[0]).toBe(tab3);
|
||||
});
|
||||
|
||||
it('should get active tab NavController when using tabs, and tabs is the root', () => {
|
||||
const tabs = mockTabs();
|
||||
mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
const tab3 = mockTab(tabs);
|
||||
app.registerRootNav(tabs);
|
||||
|
||||
tab2.setSelected(true);
|
||||
|
||||
expect(app.getActiveNavs(tabs.id)[0]).toBe(tab2);
|
||||
expect(app.getActiveNavs()[0]).toBe(tab2);
|
||||
|
||||
tab2.setSelected(false);
|
||||
tab3.setSelected(true);
|
||||
expect(app.getActiveNavs(tabs.id)[0]).toBe(tab3);
|
||||
expect(app.getActiveNavs()[0]).toBe(tab3);
|
||||
});
|
||||
|
||||
it('should get active NavController when nested 3 deep', () => {
|
||||
const nav1 = mockNavController();
|
||||
const nav2 = mockNavController();
|
||||
const nav3 = mockNavController();
|
||||
app.registerRootNav(nav1);
|
||||
|
||||
nav1.registerChildNav(nav2);
|
||||
nav2.registerChildNav(nav3);
|
||||
|
||||
expect(app.getActiveNavs(nav1.id)[0]).toBe(nav3);
|
||||
expect(app.getActiveNavs()[0]).toBe(nav3);
|
||||
expect(app.getActiveNavs().length).toBe(1);
|
||||
});
|
||||
|
||||
it('should get active NavController when nested 2 deep', () => {
|
||||
const nav1 = mockNavController();
|
||||
const nav2 = mockNavController();
|
||||
app.registerRootNav(nav1);
|
||||
|
||||
nav1.registerChildNav(nav2);
|
||||
|
||||
const activeNav = app.getActiveNavs(nav1.id)[0];
|
||||
|
||||
expect(activeNav).toBe(nav2);
|
||||
|
||||
expect(app.getActiveNavs()[0]).toBe(nav2);
|
||||
});
|
||||
|
||||
it('should get active NavController when only one nav controller', () => {
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
expect(app.getActiveNavs(nav.id)[0]).toBe(nav);
|
||||
expect(app.getActiveNavs()[0]).toBe(nav);
|
||||
});
|
||||
|
||||
it('should set/get the root nav controller', () => {
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
expect(app.getRootNavById(nav.id)).toBe(nav);
|
||||
});
|
||||
|
||||
it('should not get an active NavController if there is not root set', () => {
|
||||
const activeNavs = app.getActiveNavs();
|
||||
const rootNav = app.getRootNavById('');
|
||||
expect(activeNavs.length).toEqual(0);
|
||||
expect(rootNav).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should just work when there are multiple active navs', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
const rootNavTwo = mockNavController();
|
||||
|
||||
app.registerRootNav(rootNavOne);
|
||||
app.registerRootNav(rootNavTwo);
|
||||
|
||||
const childNavOne = mockNavController();
|
||||
const childNavTwo = mockNavController();
|
||||
|
||||
rootNavOne.registerChildNav(childNavOne);
|
||||
rootNavTwo.registerChildNav(childNavTwo);
|
||||
|
||||
const activeNavOne = app.getActiveNavs(rootNavOne.id)[0];
|
||||
const activeNavTwo = app.getActiveNavs(rootNavTwo.id)[0];
|
||||
|
||||
expect(activeNavOne).toBe(childNavOne);
|
||||
expect(activeNavTwo).toBe(childNavTwo);
|
||||
|
||||
expect(app.getActiveNavs()[0]).toBe(childNavOne);
|
||||
expect(app.getActiveNavs()[1]).toBe(childNavTwo);
|
||||
});
|
||||
|
||||
it('should get the active nav when no id is provided assuming there is one nav', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
app.registerRootNav(rootNavOne);
|
||||
|
||||
const childNavOne = mockNavController();
|
||||
rootNavOne.registerChildNav(childNavOne);
|
||||
|
||||
const result = app.getActiveNavs()[0];
|
||||
|
||||
expect(result).toEqual(childNavOne);
|
||||
});
|
||||
|
||||
it('should return the all the active navs when there is not an id passed', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
app.registerRootNav(rootNavOne);
|
||||
|
||||
const rootNavTwo = mockNavController();
|
||||
app.registerRootNav(rootNavTwo);
|
||||
|
||||
const childNavOne = mockNavController();
|
||||
rootNavOne.registerChildNav(childNavOne);
|
||||
|
||||
const childChildNavOne = mockNavController();
|
||||
childNavOne.registerChildNav(childChildNavOne);
|
||||
|
||||
const childNavTwo = mockNavController();
|
||||
rootNavTwo.registerChildNav(childNavTwo);
|
||||
|
||||
const childChildNavTwo = mockNavController();
|
||||
childNavTwo.registerChildNav(childChildNavTwo);
|
||||
|
||||
const results = app.getActiveNavs();
|
||||
expect(results.length).toEqual(2);
|
||||
expect(results[0]).toEqual(childChildNavOne);
|
||||
expect(results[1]).toEqual(childChildNavTwo);
|
||||
|
||||
const withIdResultsOne = app.getActiveNavs(rootNavOne.id);
|
||||
expect(withIdResultsOne.length).toEqual(1);
|
||||
expect(withIdResultsOne[0]).toEqual(childChildNavOne);
|
||||
|
||||
const withIdResultsTwo = app.getActiveNavs(rootNavTwo.id);
|
||||
expect(withIdResultsTwo.length).toEqual(1);
|
||||
expect(withIdResultsTwo[0]).toEqual(childChildNavTwo);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getActiveNav', () => {
|
||||
it('should get active NavController when using tabs with nested nav', () => {
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
const tabs = mockTabs();
|
||||
const tab1 = mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
nav.registerChildNav(tabs);
|
||||
|
||||
tab2.setSelected(true);
|
||||
const nav2 = mockNavController();
|
||||
nav2.name = 'nav2';
|
||||
const nav3 = mockNavController();
|
||||
nav3.name = 'nav3';
|
||||
const nav4 = mockNavController();
|
||||
nav4.name = 'nav4';
|
||||
|
||||
tab1.registerChildNav(nav4);
|
||||
// tab 2 registers two child navs!!
|
||||
tab2.registerChildNav(nav2);
|
||||
tab2.registerChildNav(nav3);
|
||||
|
||||
const activeNav = app.getActiveNav();
|
||||
expect(activeNav).toEqual(nav2);
|
||||
});
|
||||
|
||||
it('should get active NavController when using tabs, nested in a root nav', () => {
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
|
||||
const tabs = mockTabs();
|
||||
mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
const tab3 = mockTab(tabs);
|
||||
nav.registerChildNav(tabs);
|
||||
|
||||
tab2.setSelected(true);
|
||||
@@ -307,11 +552,11 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should get active tab NavController when using tabs, and tabs is the root', () => {
|
||||
let tabs = mockTabs();
|
||||
const tabs = mockTabs();
|
||||
mockTab(tabs);
|
||||
let tab2 = mockTab(tabs);
|
||||
let tab3 = mockTab(tabs);
|
||||
app._setRootNav(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
const tab3 = mockTab(tabs);
|
||||
app.registerRootNav(tabs);
|
||||
|
||||
tab2.setSelected(true);
|
||||
|
||||
@@ -323,10 +568,10 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should get active NavController when nested 3 deep', () => {
|
||||
let nav1 = mockNavController();
|
||||
let nav2 = mockNavController();
|
||||
let nav3 = mockNavController();
|
||||
app._setRootNav(nav1);
|
||||
const nav1 = mockNavController();
|
||||
const nav2 = mockNavController();
|
||||
const nav3 = mockNavController();
|
||||
app.registerRootNav(nav1);
|
||||
|
||||
nav1.registerChildNav(nav2);
|
||||
nav2.registerChildNav(nav3);
|
||||
@@ -335,29 +580,87 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('should get active NavController when nested 2 deep', () => {
|
||||
let nav1 = mockNavController();
|
||||
let nav2 = mockNavController();
|
||||
app._setRootNav(nav1);
|
||||
const nav1 = mockNavController();
|
||||
const nav2 = mockNavController();
|
||||
app.registerRootNav(nav1);
|
||||
|
||||
nav1.registerChildNav(nav2);
|
||||
expect(app.getActiveNav()).toBe(nav2);
|
||||
|
||||
const activeNav = app.getActiveNav();
|
||||
|
||||
expect(activeNav).toBe(nav2);
|
||||
});
|
||||
|
||||
it('should get active NavController when only one nav controller', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
expect(app.getActiveNav()).toBe(nav);
|
||||
});
|
||||
|
||||
it('should set/get the root nav controller', () => {
|
||||
let nav = mockNavController();
|
||||
app._setRootNav(nav);
|
||||
expect(app.getRootNav()).toBe(nav);
|
||||
it('should not get an active NavController if there is not root set', () => {
|
||||
const activeNav = app.getActiveNav();
|
||||
expect(activeNav).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not get an active NavController if there is not root set', () => {
|
||||
expect(app.getActiveNav()).toBeNull();
|
||||
expect(app.getRootNav()).toBeNull();
|
||||
it('should just work when there are multiple active navs', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
const rootNavTwo = mockNavController();
|
||||
|
||||
app.registerRootNav(rootNavOne);
|
||||
app.registerRootNav(rootNavTwo);
|
||||
|
||||
const childNavOne = mockNavController();
|
||||
const childNavTwo = mockNavController();
|
||||
|
||||
rootNavOne.registerChildNav(childNavOne);
|
||||
rootNavTwo.registerChildNav(childNavTwo);
|
||||
|
||||
const activeNavOne = app.getActiveNav();
|
||||
|
||||
expect(activeNavOne).toBe(childNavOne);
|
||||
});
|
||||
|
||||
it('should get the active nav when no id is provided assuming there is one nav', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
app.registerRootNav(rootNavOne);
|
||||
|
||||
const childNavOne = mockNavController();
|
||||
rootNavOne.registerChildNav(childNavOne);
|
||||
|
||||
const result = app.getActiveNav();
|
||||
|
||||
expect(result).toEqual(childNavOne);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRootNavs', () => {
|
||||
it('should return an array of navs', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
app.registerRootNav(rootNavOne);
|
||||
const rootNavTwo = mockNavController();
|
||||
app.registerRootNav(rootNavTwo);
|
||||
|
||||
const results = app.getRootNavs();
|
||||
expect(results.length).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRootNav', () => {
|
||||
it('should return the single root nav', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
app.registerRootNav(rootNavOne);
|
||||
const result = app.getRootNav();
|
||||
expect(result).toEqual(rootNavOne);
|
||||
});
|
||||
|
||||
it('should return the first nav in the list for backwards compatibility', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
app.registerRootNav(rootNavOne);
|
||||
const rootNavTwo = mockNavController();
|
||||
app.registerRootNav(rootNavTwo);
|
||||
|
||||
const result = app.getRootNav();
|
||||
expect(result).toEqual(rootNavOne);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -381,7 +684,7 @@ describe('App', () => {
|
||||
|
||||
it('should enable click block when false is passed with duration', () => {
|
||||
// arrange
|
||||
let mockClickBlock: any = {
|
||||
const mockClickBlock: any = {
|
||||
activate: () => {}
|
||||
};
|
||||
|
||||
@@ -398,7 +701,7 @@ describe('App', () => {
|
||||
|
||||
it('should enable click block when false is passed w/o duration', () => {
|
||||
// arrange
|
||||
let mockClickBlock: any = {
|
||||
const mockClickBlock: any = {
|
||||
activate: () => {}
|
||||
};
|
||||
|
||||
@@ -416,7 +719,7 @@ describe('App', () => {
|
||||
|
||||
it('should enable click block when false is passed with a duration of 0 and with a minDuration', () => {
|
||||
// arrange
|
||||
let mockClickBlock: any = {
|
||||
const mockClickBlock: any = {
|
||||
activate: () => {}
|
||||
};
|
||||
|
||||
@@ -433,7 +736,7 @@ describe('App', () => {
|
||||
|
||||
it('should enable click block when false is passed with a null duration and a minDuration', () => {
|
||||
// arrange
|
||||
let mockClickBlock: any = {
|
||||
const mockClickBlock: any = {
|
||||
activate: () => {}
|
||||
};
|
||||
|
||||
@@ -450,7 +753,7 @@ describe('App', () => {
|
||||
|
||||
it('should enable click block when false is passed with a duration and a minDuration', () => {
|
||||
// arrange
|
||||
let mockClickBlock: any = {
|
||||
const mockClickBlock: any = {
|
||||
activate: () => {}
|
||||
};
|
||||
|
||||
@@ -466,10 +769,153 @@ describe('App', () => {
|
||||
});
|
||||
});
|
||||
|
||||
var app: App;
|
||||
var config: Config;
|
||||
var plt: MockPlatform;
|
||||
var portal: OverlayPortal;
|
||||
describe('getNavByIdOrName', () => {
|
||||
it('should return a basic root nav', () => {
|
||||
const nav = mockNavController();
|
||||
app.registerRootNav(nav);
|
||||
const result = app.getNavByIdOrName(nav.id);
|
||||
expect(result).toEqual(nav);
|
||||
});
|
||||
|
||||
it('should return a child nav', () => {
|
||||
const rootNav = mockNavController();
|
||||
app.registerRootNav(rootNav);
|
||||
|
||||
const childNav = mockNavController();
|
||||
childNav.parent = rootNav;
|
||||
rootNav.registerChildNav(childNav);
|
||||
|
||||
const childChildNav = mockNavController();
|
||||
childChildNav.parent = childNav;
|
||||
childNav.registerChildNav(childChildNav);
|
||||
|
||||
|
||||
const expectedChildNav = app.getNavByIdOrName(childNav.id);
|
||||
expect(expectedChildNav).toEqual(childNav);
|
||||
|
||||
const expectedChildChildNav = app.getNavByIdOrName(childChildNav.id);
|
||||
expect(expectedChildChildNav).toEqual(childChildNav);
|
||||
});
|
||||
|
||||
it('should return a child nav when there is a tabs in there', () => {
|
||||
const rootNav = mockNavController();
|
||||
app.registerRootNav(rootNav);
|
||||
|
||||
const tabs = mockTabs();
|
||||
tabs.parent = rootNav;
|
||||
rootNav.registerChildNav(tabs);
|
||||
|
||||
const tab1 = mockTab(tabs);
|
||||
const tab2 = mockTab(tabs);
|
||||
const tab3 = mockTab(tabs);
|
||||
|
||||
const tabChildNav = mockNavController();
|
||||
tabChildNav.parent = tab2;
|
||||
tab2.registerChildNav(tabChildNav);
|
||||
|
||||
const tabChildChildNav = mockNavController();
|
||||
tabChildChildNav.parent = tabChildNav;
|
||||
tabChildNav.registerChildNav(tabChildChildNav);
|
||||
|
||||
const expectedTab1 = app.getNavByIdOrName(tab1.id);
|
||||
expect(expectedTab1).toEqual(tab1);
|
||||
|
||||
const expectedTab2 = app.getNavByIdOrName(tab2.id);
|
||||
expect(expectedTab2).toEqual(tab2);
|
||||
|
||||
const expectedTab3 = app.getNavByIdOrName(tab3.id);
|
||||
expect(expectedTab3).toEqual(tab3);
|
||||
|
||||
const expectedTabChildNav = app.getNavByIdOrName(tabChildNav.id);
|
||||
expect(expectedTabChildNav).toEqual(tabChildNav);
|
||||
|
||||
const expectedTabChildChildNav = app.getNavByIdOrName(tabChildChildNav.id);
|
||||
expect(expectedTabChildChildNav).toEqual(tabChildChildNav);
|
||||
});
|
||||
|
||||
it('should return a basic root nav when the are multiple root navs', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
const rootNavTwo = mockNavController();
|
||||
const rootNavThree = mockNavController();
|
||||
app.registerRootNav(rootNavOne);
|
||||
app.registerRootNav(rootNavTwo);
|
||||
app.registerRootNav(rootNavThree);
|
||||
|
||||
const expectedRootNavOne = app.getNavByIdOrName(rootNavOne.id);
|
||||
expect(expectedRootNavOne).toEqual(rootNavOne);
|
||||
|
||||
const expectedRootNavTwo = app.getNavByIdOrName(rootNavTwo.id);
|
||||
expect(expectedRootNavTwo).toEqual(rootNavTwo);
|
||||
|
||||
const expectedRootNavThree = app.getNavByIdOrName(rootNavThree.id);
|
||||
expect(expectedRootNavThree).toEqual(rootNavThree);
|
||||
});
|
||||
|
||||
it('should return a proper navs when there are multiple root navs with nested navs', () => {
|
||||
const rootNavOne = mockNavController();
|
||||
const rootNavTwo = mockNavController();
|
||||
const rootNavThree = mockNavController();
|
||||
app.registerRootNav(rootNavOne);
|
||||
app.registerRootNav(rootNavTwo);
|
||||
app.registerRootNav(rootNavThree);
|
||||
|
||||
const childNavOne = mockNavController();
|
||||
childNavOne.parent = rootNavOne;
|
||||
rootNavOne.registerChildNav(childNavOne);
|
||||
|
||||
const childChildNavOne = mockNavController();
|
||||
childChildNavOne.parent = childNavOne;
|
||||
childNavOne.registerChildNav(childChildNavOne);
|
||||
|
||||
const childNavTwo = mockNavController();
|
||||
childNavOne.parent = rootNavTwo;
|
||||
rootNavTwo.registerChildNav(childNavTwo);
|
||||
|
||||
const childChildNavTwo = mockNavController();
|
||||
childChildNavTwo.parent = childNavTwo;
|
||||
childNavTwo.registerChildNav(childChildNavTwo);
|
||||
|
||||
const childNavThree = mockNavController();
|
||||
childNavThree.parent = rootNavThree;
|
||||
rootNavThree.registerChildNav(childNavThree);
|
||||
|
||||
const childChildNavThree = mockNavController();
|
||||
childChildNavThree.parent = childNavThree;
|
||||
childNavThree.registerChildNav(childChildNavThree);
|
||||
|
||||
const expectedRootNavOne = app.getNavByIdOrName(rootNavOne.id);
|
||||
expect(expectedRootNavOne).toEqual(rootNavOne);
|
||||
|
||||
const expectedChildNavOne = app.getNavByIdOrName(childNavOne.id);
|
||||
expect(expectedChildNavOne).toEqual(childNavOne);
|
||||
|
||||
const expectedChildChildNavOne = app.getNavByIdOrName(childChildNavOne.id);
|
||||
expect(expectedChildChildNavOne).toEqual(childChildNavOne);
|
||||
|
||||
const expectedRootNavTwo = app.getNavByIdOrName(rootNavTwo.id);
|
||||
expect(expectedRootNavTwo).toEqual(rootNavTwo);
|
||||
|
||||
const expectedChildNavTwo = app.getNavByIdOrName(childNavTwo.id);
|
||||
expect(expectedChildNavTwo).toEqual(childNavTwo);
|
||||
|
||||
const expectedChildChildNavTwo = app.getNavByIdOrName(childChildNavTwo.id);
|
||||
expect(expectedChildChildNavTwo).toEqual(childChildNavTwo);
|
||||
|
||||
const expectedRootNavThree = app.getNavByIdOrName(rootNavThree.id);
|
||||
expect(expectedRootNavThree).toEqual(rootNavThree);
|
||||
|
||||
const expectedChildNavThree = app.getNavByIdOrName(childNavThree.id);
|
||||
expect(expectedChildNavThree).toEqual(childNavThree);
|
||||
|
||||
const expectedChildChildNavThree = app.getNavByIdOrName(childChildNavThree.id);
|
||||
expect(expectedChildChildNavThree).toEqual(childChildNavThree);
|
||||
});
|
||||
});
|
||||
|
||||
let app: App;
|
||||
let config: Config;
|
||||
let plt: MockPlatform;
|
||||
let portal: OverlayPortal;
|
||||
|
||||
beforeEach(() => {
|
||||
config = mockConfig();
|
||||
|
||||
@@ -60,51 +60,51 @@
|
||||
</ion-row>
|
||||
|
||||
<div class="float-elements-row">
|
||||
<div pull-left>pull-left</div>
|
||||
<div pull-sm-left>pull-sm-left</div>
|
||||
<div pull-md-left>pull-md-left</div>
|
||||
<div pull-lg-left>pull-lg-left</div>
|
||||
<div pull-xl-left>pull-xl-left</div>
|
||||
<div float-left>float-left</div>
|
||||
<div float-sm-left>float-sm-left</div>
|
||||
<div float-md-left>float-md-left</div>
|
||||
<div float-lg-left>float-lg-left</div>
|
||||
<div float-xl-left>float-xl-left</div>
|
||||
</div>
|
||||
|
||||
<div class="float-elements-row">
|
||||
<div pull-right>pull-right</div>
|
||||
<div pull-sm-right>pull-sm-right</div>
|
||||
<div pull-md-right>pull-md-right</div>
|
||||
<div pull-lg-right>pull-lg-right</div>
|
||||
<div pull-xl-right>pull-xl-right</div>
|
||||
<div float-right>float-right</div>
|
||||
<div float-sm-right>float-sm-right</div>
|
||||
<div float-md-right>float-md-right</div>
|
||||
<div float-lg-right>float-lg-right</div>
|
||||
<div float-xl-right>float-xl-right</div>
|
||||
</div>
|
||||
|
||||
<div class="float-elements-row">
|
||||
<div pull-start>pull-start</div>
|
||||
<div pull-sm-start>pull-sm-start</div>
|
||||
<div pull-md-start>pull-md-start</div>
|
||||
<div pull-lg-start>pull-lg-start</div>
|
||||
<div pull-xl-start>pull-xl-start</div>
|
||||
<div float-start>float-start</div>
|
||||
<div float-sm-start>float-sm-start</div>
|
||||
<div float-md-start>float-md-start</div>
|
||||
<div float-lg-start>float-lg-start</div>
|
||||
<div float-xl-start>float-xl-start</div>
|
||||
</div>
|
||||
|
||||
<div class="float-elements-row">
|
||||
<div pull-end>pull-end</div>
|
||||
<div pull-sm-end>pull-sm-end</div>
|
||||
<div pull-md-end>pull-md-end</div>
|
||||
<div pull-lg-end>pull-lg-end</div>
|
||||
<div pull-xl-end>pull-xl-end</div>
|
||||
<div float-end>float-end</div>
|
||||
<div float-sm-end>float-sm-end</div>
|
||||
<div float-md-end>float-md-end</div>
|
||||
<div float-lg-end>float-lg-end</div>
|
||||
<div float-xl-end>float-xl-end</div>
|
||||
</div>
|
||||
|
||||
<div class="float-elements-row" dir="rtl">
|
||||
<div pull-start>pull-start</div>
|
||||
<div pull-sm-start>pull-sm-start</div>
|
||||
<div pull-md-start>pull-md-start</div>
|
||||
<div pull-lg-start>pull-lg-start</div>
|
||||
<div pull-xl-start>pull-xl-start</div>
|
||||
<div float-start>float-start</div>
|
||||
<div float-sm-start>float-sm-start</div>
|
||||
<div float-md-start>float-md-start</div>
|
||||
<div float-lg-start>float-lg-start</div>
|
||||
<div float-xl-start>float-xl-start</div>
|
||||
</div>
|
||||
|
||||
<div class="float-elements-row" dir="rtl">
|
||||
<div pull-end>pull-end</div>
|
||||
<div pull-sm-end>pull-sm-end</div>
|
||||
<div pull-md-end>pull-md-end</div>
|
||||
<div pull-lg-end>pull-lg-end</div>
|
||||
<div pull-xl-end>pull-xl-end</div>
|
||||
<div float-end>float-end</div>
|
||||
<div float-sm-end>float-sm-end</div>
|
||||
<div float-md-end>float-md-end</div>
|
||||
<div float-lg-end>float-lg-end</div>
|
||||
<div float-xl-end>float-xl-end</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
|
||||
|
||||
@@ -11,13 +11,15 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[icon-left] ion-icon {
|
||||
[icon-left] ion-icon, // deprecated
|
||||
[icon-start] ion-icon {
|
||||
@include button-icon;
|
||||
|
||||
@include padding-horizontal(null, .3em);
|
||||
}
|
||||
|
||||
[icon-right] ion-icon {
|
||||
[icon-right] ion-icon, // deprecated
|
||||
[icon-end] ion-icon {
|
||||
@include button-icon;
|
||||
|
||||
@include padding-horizontal(.4em, null);
|
||||
|
||||
@@ -470,8 +470,8 @@ $button-md-strong-font-weight: bold !default;
|
||||
// it's display none, and .md sets to display block.
|
||||
|
||||
.button-effect {
|
||||
@include position(0, null, null, 0);
|
||||
@include border-radius(50%);
|
||||
@include transform-origin(center, center);
|
||||
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
@@ -480,13 +480,19 @@ $button-md-strong-font-weight: bold !default;
|
||||
background-color: $button-md-ripple-background-color;
|
||||
opacity: .2;
|
||||
|
||||
transform-origin: center center;
|
||||
transition-timing-function: ease-in-out;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
@include multi-dir() {
|
||||
// scss-lint:disable PropertySpelling
|
||||
top: 0;
|
||||
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.md .button-effect {
|
||||
.md button .button-effect {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,12 +42,12 @@ import { isTrueProperty } from '../../util/util';
|
||||
* <button ion-button round outline>Outline + Round</button>
|
||||
*
|
||||
* <!-- Icons -->
|
||||
* <button ion-button icon-left>
|
||||
* <button ion-button icon-start>
|
||||
* <ion-icon name="star"></ion-icon>
|
||||
* Left Icon
|
||||
* </button>
|
||||
*
|
||||
* <button ion-button icon-right>
|
||||
* <button ion-button icon-end>
|
||||
* Right Icon
|
||||
* <ion-icon name="star"></ion-icon>
|
||||
* </button>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a ion-button block href="#" icon-left><ion-icon name="help-circle"></ion-icon> a[ion-button][block] icon</a>
|
||||
<button ion-button block icon-left><ion-icon name="help-circle"></ion-icon> button[ion-button][block] icon</button>
|
||||
<a ion-button block href="#" icon-start><ion-icon name="help-circle"></ion-icon> a[ion-button][block] icon</a>
|
||||
<button ion-button block icon-start><ion-icon name="help-circle"></ion-icon> button[ion-button][block] icon</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a ion-button full href="#" icon-left>
|
||||
<a ion-button full href="#" icon-start>
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
a[ion-button][full] + icon
|
||||
</a>
|
||||
<button ion-button full icon-left>
|
||||
<button ion-button full icon-start>
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
button[ion-button][full] + icon
|
||||
</button>
|
||||
|
||||
@@ -10,22 +10,22 @@
|
||||
<ion-content padding>
|
||||
|
||||
<div>
|
||||
<button ion-button icon-left>
|
||||
<button ion-button icon-start>
|
||||
<ion-icon name="home"></ion-icon>
|
||||
Left Icon
|
||||
</button>
|
||||
<a ion-button icon-left>
|
||||
<a ion-button icon-start>
|
||||
<ion-icon name="home"></ion-icon>
|
||||
Left Icon
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button ion-button icon-right>
|
||||
<button ion-button icon-end>
|
||||
Right Icon
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</button>
|
||||
<a ion-button icon-right>
|
||||
<a ion-button icon-end>
|
||||
Right Icon
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</a>
|
||||
@@ -41,22 +41,22 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button ion-button large icon-left>
|
||||
<button ion-button large icon-start>
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
Left, Large
|
||||
</button>
|
||||
<a ion-button large icon-left>
|
||||
<a ion-button large icon-start>
|
||||
<ion-icon name="help-circle"></ion-icon>
|
||||
Left, Large
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button ion-button large icon-right>
|
||||
<button ion-button large icon-end>
|
||||
Right, Large
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</button>
|
||||
<a ion-button large icon-right>
|
||||
<a ion-button large icon-end>
|
||||
Right, Large
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</a>
|
||||
@@ -72,22 +72,22 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button ion-button small icon-left>
|
||||
<button ion-button small icon-start>
|
||||
<ion-icon name="checkmark"></ion-icon>
|
||||
Left, Small
|
||||
</button>
|
||||
<a ion-button small icon-left>
|
||||
<a ion-button small icon-start>
|
||||
<ion-icon name="checkmark"></ion-icon>
|
||||
Left, Small
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button ion-button small icon-right>
|
||||
<button ion-button small icon-end>
|
||||
Right, Small
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
</button>
|
||||
<a ion-button small icon-right>
|
||||
<a ion-button small icon-end>
|
||||
Right, Small
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
</a>
|
||||
|
||||
@@ -17,7 +17,7 @@ $card-ios-margin-bottom: 12px !default;
|
||||
// deprecated
|
||||
$card-ios-margin-left: 12px !default;
|
||||
/// @prop - Margin start of the card
|
||||
$card-ios-margin-start: $card-ios-margin-left;
|
||||
$card-ios-margin-start: $card-ios-margin-left !default;
|
||||
|
||||
/// @prop - Padding top of the card
|
||||
$card-ios-padding-top: 13px !default;
|
||||
@@ -25,7 +25,7 @@ $card-ios-padding-top: 13px !default;
|
||||
// deprecated
|
||||
$card-ios-padding-right: 16px !default;
|
||||
/// @prop - Padding end of the card
|
||||
$card-ios-padding-end: $card-ios-padding-right;
|
||||
$card-ios-padding-end: $card-ios-padding-right !default;
|
||||
|
||||
/// @prop - Padding bottom of the card
|
||||
$card-ios-padding-bottom: 14px !default;
|
||||
@@ -33,7 +33,7 @@ $card-ios-padding-bottom: 14px !default;
|
||||
// deprecated
|
||||
$card-ios-padding-left: 16px !default;
|
||||
/// @prop - Padding start of the card
|
||||
$card-ios-padding-start: $card-ios-padding-left;
|
||||
$card-ios-padding-start: $card-ios-padding-left !default;
|
||||
|
||||
/// @prop - Padding top of the media on the card
|
||||
$card-ios-padding-media-top: 10px !default;
|
||||
@@ -133,7 +133,7 @@ $card-ios-header-color: #333 !default;
|
||||
}
|
||||
|
||||
.card-ios ion-list {
|
||||
margin-bottom: 0;
|
||||
@include margin(null, null, 0, null);
|
||||
}
|
||||
|
||||
.card-ios > .item:last-child,
|
||||
@@ -165,7 +165,7 @@ $card-ios-header-color: #333 !default;
|
||||
|
||||
.card-header-ios + .card-content-ios,
|
||||
.card-ios .item + .card-content-ios {
|
||||
padding-top: 0;
|
||||
@include padding(0, null, null, null);
|
||||
}
|
||||
|
||||
.card .note-ios {
|
||||
@@ -220,7 +220,7 @@ $card-ios-header-color: #333 !default;
|
||||
}
|
||||
|
||||
.card-ios + ion-card {
|
||||
margin-top: 0;
|
||||
@include margin(0, null, null, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user