Compare commits
436 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0560751381 | ||
![]() |
e32c1b692a | ||
![]() |
ae7b96ba13 | ||
![]() |
01b6aad309 | ||
![]() |
40cdab2225 | ||
![]() |
a38127fb47 | ||
![]() |
cd811da672 | ||
![]() |
76fb905916 | ||
![]() |
93d325ccd5 | ||
![]() |
c7d147eb96 | ||
![]() |
70fb65fd00 | ||
![]() |
10863e5817 | ||
![]() |
5f680d4d6d | ||
![]() |
6eca36756a | ||
![]() |
060867dcc4 | ||
![]() |
4d840cba59 | ||
![]() |
0222b5846b | ||
![]() |
ac52e1a6b6 | ||
![]() |
7f3a5ec741 | ||
![]() |
ac7658e1b9 | ||
![]() |
dc0340c79e | ||
![]() |
6a74ef0fbc | ||
![]() |
68df0d2c26 | ||
![]() |
d3656bcecc | ||
![]() |
4834fdaf59 | ||
![]() |
f2aeb703de | ||
![]() |
5a1ca35bc4 | ||
![]() |
2a5a05b28b | ||
![]() |
4a29100ac8 | ||
![]() |
39afb01510 | ||
![]() |
7229899396 | ||
![]() |
740ab7cdcf | ||
![]() |
e22abb4d98 | ||
![]() |
a5f100947a | ||
![]() |
731ceee440 | ||
![]() |
7a87680710 | ||
![]() |
ae0fce613f | ||
![]() |
422de27601 | ||
![]() |
28de0c7cb9 | ||
![]() |
6b32622e18 | ||
![]() |
6731c3daba | ||
![]() |
0cbef9a073 | ||
![]() |
e97d961234 | ||
![]() |
d42a6623fb | ||
![]() |
1f163cd1d6 | ||
![]() |
6d690b5daa | ||
![]() |
15df5f749a | ||
![]() |
e295206965 | ||
![]() |
0e7501b47a | ||
![]() |
6bf8aefe7a | ||
![]() |
43baa2388f | ||
![]() |
48415ed6f0 | ||
![]() |
002ac471da | ||
![]() |
9e45589085 | ||
![]() |
3c93d07124 | ||
![]() |
024aba075c | ||
![]() |
a86d038875 | ||
![]() |
bc8a93e842 | ||
![]() |
4c18f637ae | ||
![]() |
fc189b2577 | ||
![]() |
778ddb257a | ||
![]() |
2d4f4b5d12 | ||
![]() |
912742f1ca | ||
![]() |
0746485136 | ||
![]() |
265489518e | ||
![]() |
00dd566b47 | ||
![]() |
59fd91d785 | ||
![]() |
56712aa771 | ||
![]() |
529e4b1565 | ||
![]() |
9ff4617956 | ||
![]() |
8887d75723 | ||
![]() |
7717ff187a | ||
![]() |
98b18cd49f | ||
![]() |
fe23a6e77e | ||
![]() |
d7c4898081 | ||
![]() |
98c509fecb | ||
![]() |
a92f111b66 | ||
![]() |
de1c44f6e3 | ||
![]() |
183b079175 | ||
![]() |
8f8caa13b7 | ||
![]() |
195dc0748b | ||
![]() |
2c6f84b25d | ||
![]() |
8e726f7d7b | ||
![]() |
2d1102f5bf | ||
![]() |
0437598609 | ||
![]() |
bc2bf184a2 | ||
![]() |
b51ce62c58 | ||
![]() |
25b532e819 | ||
![]() |
69c8226a9f | ||
![]() |
5326537985 | ||
![]() |
ada486a1dd | ||
![]() |
563e8e3e56 | ||
![]() |
dd931c73ec | ||
![]() |
b8975a90ca | ||
![]() |
f44161503a | ||
![]() |
6c55a130b1 | ||
![]() |
144a624088 | ||
![]() |
f561f5a460 | ||
![]() |
916914be13 | ||
![]() |
9a98de941d | ||
![]() |
0f1de35604 | ||
![]() |
d89f57f9d5 | ||
![]() |
ac5b69f783 | ||
![]() |
5ddd6dcedd | ||
![]() |
ad68332fa0 | ||
![]() |
2880cf9ef1 | ||
![]() |
64a8584a92 | ||
![]() |
97897ab738 | ||
![]() |
9378f44d6d | ||
![]() |
afa46af4c6 | ||
![]() |
dbffdcc442 | ||
![]() |
06d68a1b9f | ||
![]() |
75dd3c5ca5 | ||
![]() |
23f56198a5 | ||
![]() |
69167e4519 | ||
![]() |
10feafcf27 | ||
![]() |
3f3fed95be | ||
![]() |
94433f3b9e | ||
![]() |
aa753878e6 | ||
![]() |
3513ae40cc | ||
![]() |
979e7b6086 | ||
![]() |
41f008d109 | ||
![]() |
c950410ee1 | ||
![]() |
b0fa504d39 | ||
![]() |
426f9710a0 | ||
![]() |
ae01c70bba | ||
![]() |
3341a97154 | ||
![]() |
2056e1f05c | ||
![]() |
3938a8be75 | ||
![]() |
393db94b8d | ||
![]() |
65744e4ae1 | ||
![]() |
56bc86992c | ||
![]() |
9426c02648 | ||
![]() |
0b356d4163 | ||
![]() |
a886659444 | ||
![]() |
3649958595 | ||
![]() |
8919577c54 | ||
![]() |
84eff4219e | ||
![]() |
c11e84ee18 | ||
![]() |
1ce5a495d3 | ||
![]() |
1f532aaa5a | ||
![]() |
e81982ef90 | ||
![]() |
776bc38999 | ||
![]() |
7e7ef8ee25 | ||
![]() |
dd90d92573 | ||
![]() |
1b862820e9 | ||
![]() |
1a642231cd | ||
![]() |
138e0d79cd | ||
![]() |
f0a43716e2 | ||
![]() |
2be27fb888 | ||
![]() |
74f07f40e0 | ||
![]() |
aa66e84e44 | ||
![]() |
e1bc3f5c1a | ||
![]() |
f5b366147b | ||
![]() |
3147a92ee9 | ||
![]() |
ffedbde0b3 | ||
![]() |
e543c734ab | ||
![]() |
fbe6871a94 | ||
![]() |
f43cb9398c | ||
![]() |
1e04df9ac7 | ||
![]() |
840ca05fe8 | ||
![]() |
facc9d498d | ||
![]() |
9d0999027f | ||
![]() |
c00dd5a3f3 | ||
![]() |
3908a63381 | ||
![]() |
20f9e51b8f | ||
![]() |
232203242a | ||
![]() |
0ca634e697 | ||
![]() |
7fd9918024 | ||
![]() |
b0aacb81d4 | ||
![]() |
6c850eb031 | ||
![]() |
0df61ad107 | ||
![]() |
fa985ac067 | ||
![]() |
06f9197361 | ||
![]() |
c2bad1249e | ||
![]() |
9d69ff8ddd | ||
![]() |
3fd33f8eb0 | ||
![]() |
501a243b3f | ||
![]() |
b91b9efc91 | ||
![]() |
03718c95ce | ||
![]() |
0834710c18 | ||
![]() |
9a9a7de9a4 | ||
![]() |
ff51691221 | ||
![]() |
2ad90ab0d3 | ||
![]() |
c5872e6782 | ||
![]() |
d20877bf3f | ||
![]() |
b3089b4963 | ||
![]() |
880b03101e | ||
![]() |
451d996414 | ||
![]() |
ea3669e334 | ||
![]() |
ea2987c7af | ||
![]() |
5b823dedcc | ||
![]() |
80f7c83bdd | ||
![]() |
53072b10da | ||
![]() |
30c2f560b1 | ||
![]() |
18c4976f3b | ||
![]() |
0139173c7c | ||
![]() |
f3c9954a68 | ||
![]() |
e8765352e8 | ||
![]() |
9e61ad897e | ||
![]() |
0d81151cbc | ||
![]() |
70319722a1 | ||
![]() |
cfa5b6567d | ||
![]() |
41698bf5fd | ||
![]() |
23c50e27fc | ||
![]() |
0ae8ea254a | ||
![]() |
19deca159b | ||
![]() |
dc3e8aa0fb | ||
![]() |
a9222c0ade | ||
![]() |
ea3127e3f9 | ||
![]() |
8e30f7b1aa | ||
![]() |
46d81b48ac | ||
![]() |
3e51a2cb26 | ||
![]() |
faf60d9310 | ||
![]() |
0639cb9de1 | ||
![]() |
810d025488 | ||
![]() |
efe49c141a | ||
![]() |
a3d9878c9d | ||
![]() |
10213d0ca0 | ||
![]() |
0e1919c2db | ||
![]() |
d579b8ce05 | ||
![]() |
d69ba735ee | ||
![]() |
2991b1b217 | ||
![]() |
b18cf21e99 | ||
![]() |
c17098dae6 | ||
![]() |
43e3073687 | ||
![]() |
f28878f92f | ||
![]() |
a10bdefa8b | ||
![]() |
2f377dbcdd | ||
![]() |
e2e7b4943e | ||
![]() |
b8a1363bb2 | ||
![]() |
e9e6a58dd0 | ||
![]() |
5932a79713 | ||
![]() |
7c6a082afd | ||
![]() |
8a2fe5b7c9 | ||
![]() |
c9eb4910eb | ||
![]() |
a634a5abbc | ||
![]() |
41225026e4 | ||
![]() |
e9f2203347 | ||
![]() |
906b3ec8e7 | ||
![]() |
1cb0c4644a | ||
![]() |
9d28a27215 | ||
![]() |
f04aef48f2 | ||
![]() |
d249852f4a | ||
![]() |
707dd59767 | ||
![]() |
4d2570576a | ||
![]() |
76e58e6cca | ||
![]() |
a27066b9d2 | ||
![]() |
29dfc8f3ac | ||
![]() |
b5533e0ee5 | ||
![]() |
b275d378df | ||
![]() |
96655f7aac | ||
![]() |
253f509493 | ||
![]() |
5a02ae2f84 | ||
![]() |
f860752902 | ||
![]() |
efa126f157 | ||
![]() |
715135b117 | ||
![]() |
c30fc52d99 | ||
![]() |
434eb971e4 | ||
![]() |
6e31e22d41 | ||
![]() |
8fef926cd2 | ||
![]() |
7698afedb1 | ||
![]() |
a583d12660 | ||
![]() |
a867d71ece | ||
![]() |
84b43daf65 | ||
![]() |
9b3423b50d | ||
![]() |
d6041d83ec | ||
![]() |
a638f504eb | ||
![]() |
a29c756251 | ||
![]() |
f206eb94bb | ||
![]() |
3d6e82eccd | ||
![]() |
154289305e | ||
![]() |
469b1e4a9a | ||
![]() |
7fee1fd442 | ||
![]() |
0ee5b7efa5 | ||
![]() |
afff84c03f | ||
![]() |
23f2a7069f | ||
![]() |
42260702f7 | ||
![]() |
eec231d21e | ||
![]() |
95344d6039 | ||
![]() |
1c9839e91d | ||
![]() |
bc1a66e907 | ||
![]() |
2a83dbb0d8 | ||
![]() |
4007d00403 | ||
![]() |
61e32ac3c4 | ||
![]() |
43ee10fbbd | ||
![]() |
eb90039ea1 | ||
![]() |
5d318ff234 | ||
![]() |
f3361abdd7 | ||
![]() |
52cbe894e9 | ||
![]() |
41c2030534 | ||
![]() |
daee41a40a | ||
![]() |
68bd45ba87 | ||
![]() |
0f6407750b | ||
![]() |
95fca24fd8 | ||
![]() |
a8f6542115 | ||
![]() |
c6b618d020 | ||
![]() |
ad6052e397 | ||
![]() |
e9d1709156 | ||
![]() |
b5d3de50cc | ||
![]() |
734d37b231 | ||
![]() |
bc2063807c | ||
![]() |
2a528fcb15 | ||
![]() |
752b83ac81 | ||
![]() |
56be3375ec | ||
![]() |
1b83b3fb15 | ||
![]() |
14d4625ede | ||
![]() |
fd880a8de4 | ||
![]() |
bd3dddce4b | ||
![]() |
1336a9451f | ||
![]() |
d280077412 | ||
![]() |
2b578f5c61 | ||
![]() |
12dcb313af | ||
![]() |
f576851ecc | ||
![]() |
ca6cb66c32 | ||
![]() |
484233f6c1 | ||
![]() |
3d8799b3a2 | ||
![]() |
8733843c11 | ||
![]() |
f1097914c5 | ||
![]() |
06776d1d10 | ||
![]() |
2b31b6dc3f | ||
![]() |
2254ac23e4 | ||
![]() |
38c678fdcd | ||
![]() |
1a655836cb | ||
![]() |
2e466f4bea | ||
![]() |
7b06fa88ab | ||
![]() |
3d712894ae | ||
![]() |
75b8edae03 | ||
![]() |
fe7f48c1d5 | ||
![]() |
29600cbb19 | ||
![]() |
5581e97d2a | ||
![]() |
19262d9f90 | ||
![]() |
1eb1c6315d | ||
![]() |
3807599a4d | ||
![]() |
2ed41d9e38 | ||
![]() |
5eb9c01bb6 | ||
![]() |
09d9662386 | ||
![]() |
844cbd9774 | ||
![]() |
373a47dda9 | ||
![]() |
83f12f3047 | ||
![]() |
bbc416cdcd | ||
![]() |
07f2098655 | ||
![]() |
9b53a6e779 | ||
![]() |
65f8505fb6 | ||
![]() |
5a5ea45c40 | ||
![]() |
52a3657b48 | ||
![]() |
3824e3f858 | ||
![]() |
05aa5e0179 | ||
![]() |
4ddeb030e7 | ||
![]() |
afe6380429 | ||
![]() |
947ea17a09 | ||
![]() |
a190c45a64 | ||
![]() |
902781803f | ||
![]() |
0d480ac0dc | ||
![]() |
6934bf4863 | ||
![]() |
7e7ea33fb0 | ||
![]() |
5bd8c6887e | ||
![]() |
d28ab372c8 | ||
![]() |
d0ccf5f169 | ||
![]() |
ecde15298a | ||
![]() |
983e5f2d7e | ||
![]() |
5fc4299e0a | ||
![]() |
1823d5dd1c | ||
![]() |
91d4da0d2f | ||
![]() |
22eb8e26fc | ||
![]() |
f6002c1702 | ||
![]() |
14138f6382 | ||
![]() |
f11daa2031 | ||
![]() |
31a435ef5b | ||
![]() |
3e92b22258 | ||
![]() |
2e5457c824 | ||
![]() |
1ab5fba92e | ||
![]() |
e1e57ddaa7 | ||
![]() |
ee7cb48877 | ||
![]() |
a30c57090a | ||
![]() |
8a49ec4f27 | ||
![]() |
697b6c040c | ||
![]() |
4008e36e80 | ||
![]() |
e47bb52084 | ||
![]() |
ac2b530f4b | ||
![]() |
64bf6edf00 | ||
![]() |
adf6235479 | ||
![]() |
04c18ac1aa | ||
![]() |
1b26dd8cdb | ||
![]() |
f721b06bde | ||
![]() |
0bc8443e12 | ||
![]() |
db17231597 | ||
![]() |
540626a3a6 | ||
![]() |
391bfcede5 | ||
![]() |
d8de6488dd | ||
![]() |
151fb66848 | ||
![]() |
02424ff0d0 | ||
![]() |
f0925d9705 | ||
![]() |
212b806eda | ||
![]() |
b9431e88fb | ||
![]() |
7790cfa0d0 | ||
![]() |
41b5149509 | ||
![]() |
06f865640d | ||
![]() |
824f74f27b | ||
![]() |
5301c43eed | ||
![]() |
f280d1aef1 | ||
![]() |
5e741d42a6 | ||
![]() |
0035d41030 | ||
![]() |
08f447ceec | ||
![]() |
8953f123e3 | ||
![]() |
6274007e3b | ||
![]() |
ee76be7783 | ||
![]() |
a8c720bc3a | ||
![]() |
ac47a3cd93 | ||
![]() |
041458a3d2 | ||
![]() |
2cb74b748f | ||
![]() |
cb0bfe7a43 | ||
![]() |
8ee11aeaa6 | ||
![]() |
bf89fcb361 | ||
![]() |
4f70c5b6f7 | ||
![]() |
ad3ebec2a5 | ||
![]() |
3f5d61f2dd | ||
![]() |
11ada7f78b | ||
![]() |
0b96bc7456 | ||
![]() |
fefadadff3 | ||
![]() |
946057ae29 | ||
![]() |
d4293aaaaa | ||
![]() |
e3dcc227f6 | ||
![]() |
c9230dd90e | ||
![]() |
234af9ba59 | ||
![]() |
7204028d3e | ||
![]() |
f7c55952bf | ||
![]() |
e38e3bd135 | ||
![]() |
cd20c01ba1 | ||
![]() |
12a191ef3f | ||
![]() |
65e67b3c3a | ||
![]() |
32e57f6197 | ||
![]() |
7de69ba29b | ||
![]() |
44193c0b94 | ||
![]() |
6db8241ffa | ||
![]() |
33c594516c |
19
.circleci/README.md
Normal file
19
.circleci/README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Encryption
|
||||||
|
|
||||||
|
Based on https://github.com/circleci/encrypted-files
|
||||||
|
|
||||||
|
In the CircleCI web UI, we have a secret variable called `KEY`
|
||||||
|
https://circleci.com/gh/angular/angular/edit#env-vars
|
||||||
|
which is only exposed to non-fork builds
|
||||||
|
(see "Pass secrets to builds from forked pull requests" under
|
||||||
|
https://circleci.com/gh/angular/angular/edit#advanced-settings)
|
||||||
|
|
||||||
|
We use this as a symmetric AES encryption key to encrypt tokens like
|
||||||
|
a GitHub token that enables publishing snapshots.
|
||||||
|
|
||||||
|
To create the github_token file, we take this approach:
|
||||||
|
- Find the angular-builds:token in http://valentine
|
||||||
|
- Go inside the ngcontainer docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it angular/ngcontainer`
|
||||||
|
- echo "https://[token]:@github.com" > credentials
|
||||||
|
- openssl aes-256-cbc -e -in credentials -out .circleci/github_token -k $KEY
|
||||||
|
- If needed, base64-encode the result so you can copy-paste it out of docker: `base64 github_token`
|
@ -12,8 +12,8 @@
|
|||||||
## IMPORTANT
|
## IMPORTANT
|
||||||
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
|
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
|
||||||
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
|
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
|
||||||
var_1: &docker_image angular/ngcontainer:0.2.0
|
var_1: &docker_image angular/ngcontainer:0.3.3
|
||||||
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.2.0
|
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.3
|
||||||
|
|
||||||
# Define common ENV vars
|
# Define common ENV vars
|
||||||
var_3: &define_env_vars
|
var_3: &define_env_vars
|
||||||
@ -63,7 +63,7 @@ jobs:
|
|||||||
- run: yarn install --frozen-lockfile --non-interactive
|
- run: yarn install --frozen-lockfile --non-interactive
|
||||||
- run: ./node_modules/.bin/gulp lint
|
- run: ./node_modules/.bin/gulp lint
|
||||||
|
|
||||||
build:
|
test:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
steps:
|
||||||
@ -80,38 +80,115 @@ jobs:
|
|||||||
|
|
||||||
- run: ls /home/circleci/bazel_repository_cache || true
|
- run: ls /home/circleci/bazel_repository_cache || true
|
||||||
- run: bazel info release
|
- run: bazel info release
|
||||||
- run: bazel run @yarn//:yarn
|
- run: bazel run @nodejs//:yarn
|
||||||
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
|
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
|
||||||
# This avoids waiting for the slowest build target to finish before running the first test
|
# This avoids waiting for the slowest build target to finish before running the first test
|
||||||
# See https://github.com/bazelbuild/bazel/issues/4257
|
# See https://github.com/bazelbuild/bazel/issues/4257
|
||||||
# NOTE: Angular developers should typically just bazel build //packages/... or bazel test //packages/...
|
# NOTE: Angular developers should typically just bazel build //packages/... or bazel test //packages/...
|
||||||
- run: bazel query --output=label //... | xargs bazel test
|
- run: bazel query --output=label //... | xargs bazel test
|
||||||
|
|
||||||
# We run the integration tests outside of Bazel for now.
|
|
||||||
# See comments inside this script.
|
|
||||||
- run: xvfb-run --auto-servernum ./integration/run_tests.sh
|
|
||||||
|
|
||||||
# CircleCI will allow us to go back and view/download these artifacts from past builds.
|
# CircleCI will allow us to go back and view/download these artifacts from past builds.
|
||||||
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
|
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
|
||||||
|
# The destination keys need be format {projectName}/{context}/{fileName} so that the github-robot can process them for size calculations
|
||||||
|
# projectName should remain consistant to group files
|
||||||
|
# context and fileName can be almost anything (within usual URI rules)
|
||||||
|
# There should only be exactly 2 forward slashes in the path
|
||||||
|
# This is so they're backwards compatiable with the existing data we have on bundle sizes
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js
|
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js
|
||||||
destination: packages/core/test/bundling/hello_world/bundle.min.js
|
destination: core/hello_world/bundle
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js
|
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js
|
||||||
destination: packages/core/test/bundling/todo/bundle.min.js
|
destination: core/todo/bundle
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js.brotli
|
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js.br
|
||||||
destination: packages/core/test/bundling/hello_world/bundle.min.js.brotli
|
destination: core/hello_world/bundle.br
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.brotli
|
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.br
|
||||||
destination: packages/core/test/bundling/todo/bundle.min.js.brotli
|
destination: core/todo/bundle.br
|
||||||
|
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: *cache_key
|
key: *cache_key
|
||||||
paths:
|
paths:
|
||||||
- "node_modules"
|
- "node_modules"
|
||||||
- "~/bazel_repository_cache"
|
- "~/bazel_repository_cache"
|
||||||
|
|
||||||
|
# This job exists only for backwards-compatibility with old scripts and tests
|
||||||
|
# that rely on the pre-Bazel dist/packages-dist layout.
|
||||||
|
# It duplicates some work with the job above: we build the bazel packages
|
||||||
|
# twice. Even though we have a remote cache, these jobs will typically run in
|
||||||
|
# parallel so up-to-date outputs will not be available at the time the build
|
||||||
|
# starts.
|
||||||
|
# No new jobs should depend on this one.
|
||||||
|
build-packages-dist:
|
||||||
|
<<: *job_defaults
|
||||||
|
resource_class: xlarge
|
||||||
|
steps:
|
||||||
|
- *define_env_vars
|
||||||
|
- checkout:
|
||||||
|
<<: *post_checkout
|
||||||
|
# See remote cache documentation in /docs/BAZEL.md
|
||||||
|
- run: .circleci/setup_cache.sh
|
||||||
|
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||||
|
- *setup-bazel-remote-cache
|
||||||
|
|
||||||
|
- run: bazel run @nodejs//:yarn
|
||||||
|
- run: scripts/build-packages-dist.sh
|
||||||
|
|
||||||
|
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||||
|
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: dist
|
||||||
|
paths:
|
||||||
|
- packages-dist
|
||||||
|
|
||||||
|
# We run the integration tests outside of Bazel for now.
|
||||||
|
# They are a separate workflow job so that they can be easily re-run.
|
||||||
|
# When the tests are ported to bazel test targets, they should move to the "test"
|
||||||
|
# job above, as part of the bazel test command. That has flaky_test_attempts so the
|
||||||
|
# need to re-run manually should be alleviated.
|
||||||
|
# See comments inside the integration/run_tests.sh script.
|
||||||
|
integration_test:
|
||||||
|
<<: *job_defaults
|
||||||
|
# Note: we run Bazel in one of the integration tests, and it can consume >2G
|
||||||
|
# of memory. Together with the system under test, this can exhaust the RAM
|
||||||
|
# on a 4G worker so we use a larger machine here too.
|
||||||
|
resource_class: xlarge
|
||||||
|
steps:
|
||||||
|
- *define_env_vars
|
||||||
|
- checkout:
|
||||||
|
<<: *post_checkout
|
||||||
|
- attach_workspace:
|
||||||
|
at: dist
|
||||||
|
- run: xvfb-run --auto-servernum ./integration/run_tests.sh
|
||||||
|
|
||||||
|
# This job updates the content of repos like github.com/angular/core-builds
|
||||||
|
# for every green build on angular/angular.
|
||||||
|
publish_snapshot:
|
||||||
|
<<: *job_defaults
|
||||||
|
steps:
|
||||||
|
# See below - ideally this job should not trigger for non-upstream builds.
|
||||||
|
# But since it does, we have to check this condition.
|
||||||
|
- run:
|
||||||
|
name: Skip this job for Pull Requests and Fork builds
|
||||||
|
# Note, `|| true` on the end makes this step always exit 0
|
||||||
|
command: '[[
|
||||||
|
-v CIRCLE_PR_NUMBER
|
||||||
|
|| "$CIRCLE_PROJECT_USERNAME" != "angular"
|
||||||
|
|| "$CIRCLE_PROJECT_REPONAME" != "angular"
|
||||||
|
]] && circleci step halt || true'
|
||||||
|
- checkout:
|
||||||
|
<<: *post_checkout
|
||||||
|
- attach_workspace:
|
||||||
|
at: dist
|
||||||
|
# CircleCI has a config setting to force SSH for all github connections
|
||||||
|
# This is not compatible with our mechanism of using a Personal Access Token
|
||||||
|
# Clear the global setting
|
||||||
|
- run: git config --global --unset "url.ssh://git@github.com.insteadof"
|
||||||
|
- run:
|
||||||
|
name: Decrypt github credentials
|
||||||
|
command: 'openssl aes-256-cbc -d -in .circleci/github_token -k "${KEY}" -out ~/.git_credentials'
|
||||||
|
- run: ./scripts/ci/publish-build-artifacts.sh
|
||||||
|
|
||||||
aio_monitoring:
|
aio_monitoring:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
steps:
|
steps:
|
||||||
@ -126,7 +203,24 @@ workflows:
|
|||||||
default_workflow:
|
default_workflow:
|
||||||
jobs:
|
jobs:
|
||||||
- lint
|
- lint
|
||||||
- build
|
- test
|
||||||
|
- build-packages-dist
|
||||||
|
- integration_test:
|
||||||
|
requires:
|
||||||
|
- build-packages-dist
|
||||||
|
- publish_snapshot:
|
||||||
|
# Note: no filters on this job because we want it to run for all upstream branches
|
||||||
|
# We'd really like to filter out pull requests here, but not yet available:
|
||||||
|
# https://discuss.circleci.com/t/workflows-pull-request-filter/14396/4
|
||||||
|
# Instead, the job just exits immediately at the first step.
|
||||||
|
requires:
|
||||||
|
# Only publish if tests and integration tests pass
|
||||||
|
- test
|
||||||
|
- integration_test
|
||||||
|
# Get the artifacts to publish from the build-packages-dist job
|
||||||
|
# since the publishing script expects the legacy outputs layout.
|
||||||
|
- build-packages-dist
|
||||||
|
|
||||||
aio_monitoring:
|
aio_monitoring:
|
||||||
jobs:
|
jobs:
|
||||||
- aio_monitoring
|
- aio_monitoring
|
||||||
|
BIN
.circleci/github_token
Normal file
BIN
.circleci/github_token
Normal file
Binary file not shown.
11
.github/angular-robot.yml
vendored
11
.github/angular-robot.yml
vendored
@ -1,5 +1,14 @@
|
|||||||
# Configuration for angular-robot
|
# Configuration for angular-robot
|
||||||
|
|
||||||
|
#options for the size plugin
|
||||||
|
size:
|
||||||
|
disabled: false
|
||||||
|
maxSizeIncrease: 1000
|
||||||
|
circleCiStatusName: "ci/circleci: build-packages-dist"
|
||||||
|
status:
|
||||||
|
disabled: false
|
||||||
|
context: "ci/angular: size"
|
||||||
|
|
||||||
# options for the merge plugin
|
# options for the merge plugin
|
||||||
merge:
|
merge:
|
||||||
# the status will be added to your pull requests
|
# the status will be added to your pull requests
|
||||||
@ -36,10 +45,12 @@ merge:
|
|||||||
- "packages/language-service/**"
|
- "packages/language-service/**"
|
||||||
- "**/.gitignore"
|
- "**/.gitignore"
|
||||||
- "**/.gitkeep"
|
- "**/.gitkeep"
|
||||||
|
- "**/package.json"
|
||||||
- "**/tsconfig-build.json"
|
- "**/tsconfig-build.json"
|
||||||
- "**/tsconfig.json"
|
- "**/tsconfig.json"
|
||||||
- "**/rollup.config.js"
|
- "**/rollup.config.js"
|
||||||
- "**/BUILD.bazel"
|
- "**/BUILD.bazel"
|
||||||
|
- "packages/**/integrationtest/**"
|
||||||
- "packages/**/test/**"
|
- "packages/**/test/**"
|
||||||
|
|
||||||
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
|
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
# alexeagle - Alex Eagle
|
# alexeagle - Alex Eagle
|
||||||
# alxhub - Alex Rickabaugh
|
# alxhub - Alex Rickabaugh
|
||||||
# andrewseguin - Andrew Seguin
|
# andrewseguin - Andrew Seguin
|
||||||
|
# brandonroberts - Brandon Roberts
|
||||||
# brocco - Mike Brocchi
|
# brocco - Mike Brocchi
|
||||||
# chuckjaz - Chuck Jazdzewski
|
|
||||||
# filipesilva - Filipe Silva
|
# filipesilva - Filipe Silva
|
||||||
# gkalpak - George Kalpakas
|
# gkalpak - George Kalpakas
|
||||||
# hansl - Hans Larsen
|
# hansl - Hans Larsen
|
||||||
@ -17,12 +17,12 @@
|
|||||||
# jasonaden - Jason Aden
|
# jasonaden - Jason Aden
|
||||||
# kapunahelewong - Kapunahele Wong
|
# kapunahelewong - Kapunahele Wong
|
||||||
# kara - Kara Erickson
|
# kara - Kara Erickson
|
||||||
|
# kyliau - Keen Yee Liau
|
||||||
# matsko - Matias Niemelä
|
# matsko - Matias Niemelä
|
||||||
# mhevery - Misko Hevery
|
# mhevery - Misko Hevery
|
||||||
# petebacondarwin - Pete Bacon Darwin
|
# petebacondarwin - Pete Bacon Darwin
|
||||||
# pkozlowski-opensource - Pawel Kozlowski
|
# pkozlowski-opensource - Pawel Kozlowski
|
||||||
# robwormald - Rob Wormald
|
# robwormald - Rob Wormald
|
||||||
# tinayuangao - Tina Gao
|
|
||||||
# vicb - Victor Berchet
|
# vicb - Victor Berchet
|
||||||
# vikerman - Vikram Subramanian
|
# vikerman - Vikram Subramanian
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ groups:
|
|||||||
- "tools/bazel.rc"
|
- "tools/bazel.rc"
|
||||||
users:
|
users:
|
||||||
- alexeagle #primary
|
- alexeagle #primary
|
||||||
- chuckjaz
|
- kyliau
|
||||||
- IgorMinar #fallback
|
- IgorMinar #fallback
|
||||||
- mhevery
|
- mhevery
|
||||||
- vikerman #fallback
|
- vikerman #fallback
|
||||||
@ -132,7 +132,7 @@ groups:
|
|||||||
- "packages/core/*"
|
- "packages/core/*"
|
||||||
users:
|
users:
|
||||||
- mhevery #primary
|
- mhevery #primary
|
||||||
- chuckjaz
|
- jasonaden
|
||||||
- kara
|
- kara
|
||||||
- vicb
|
- vicb
|
||||||
- IgorMinar #fallback
|
- IgorMinar #fallback
|
||||||
@ -153,7 +153,7 @@ groups:
|
|||||||
- "packages/compiler/src/i18n/*"
|
- "packages/compiler/src/i18n/*"
|
||||||
users:
|
users:
|
||||||
- vicb #primary
|
- vicb #primary
|
||||||
- chuckjaz
|
- alxhub
|
||||||
- IgorMinar #fallback
|
- IgorMinar #fallback
|
||||||
- mhevery #fallback
|
- mhevery #fallback
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ groups:
|
|||||||
- "packages/compiler-cli/src/ngtools*"
|
- "packages/compiler-cli/src/ngtools*"
|
||||||
users:
|
users:
|
||||||
- alexeagle
|
- alexeagle
|
||||||
- chuckjaz
|
- alxhub
|
||||||
- vicb
|
- vicb
|
||||||
- IgorMinar #fallback
|
- IgorMinar #fallback
|
||||||
- mhevery #fallback
|
- mhevery #fallback
|
||||||
@ -217,7 +217,6 @@ groups:
|
|||||||
- "aio/content/examples/reactive-forms/*"
|
- "aio/content/examples/reactive-forms/*"
|
||||||
users:
|
users:
|
||||||
- kara #primary
|
- kara #primary
|
||||||
- tinayuangao #secondary
|
|
||||||
- IgorMinar #fallback
|
- IgorMinar #fallback
|
||||||
- mhevery #fallback
|
- mhevery #fallback
|
||||||
|
|
||||||
@ -236,7 +235,7 @@ groups:
|
|||||||
files:
|
files:
|
||||||
- "packages/language-service/*"
|
- "packages/language-service/*"
|
||||||
users:
|
users:
|
||||||
- chuckjaz #primary
|
- kyliau #primary
|
||||||
# needs secondary
|
# needs secondary
|
||||||
- vicb
|
- vicb
|
||||||
- IgorMinar #fallback
|
- IgorMinar #fallback
|
||||||
@ -352,6 +351,7 @@ groups:
|
|||||||
- petebacondarwin
|
- petebacondarwin
|
||||||
- gkalpak
|
- gkalpak
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
|
- brandonroberts
|
||||||
- mhevery #fallback
|
- mhevery #fallback
|
||||||
|
|
||||||
angular.io-marketing:
|
angular.io-marketing:
|
||||||
|
10
BUILD.bazel
10
BUILD.bazel
@ -11,7 +11,7 @@ exports_files([
|
|||||||
# This ensures that package.json in subdirectories get installed as well.
|
# This ensures that package.json in subdirectories get installed as well.
|
||||||
alias(
|
alias(
|
||||||
name = "install",
|
name = "install",
|
||||||
actual = "@yarn//:yarn",
|
actual = "@nodejs//:yarn",
|
||||||
)
|
)
|
||||||
|
|
||||||
node_modules_filegroup(
|
node_modules_filegroup(
|
||||||
@ -44,14 +44,16 @@ filegroup(
|
|||||||
"//:node_modules/zone.js/dist/zone.js",
|
"//:node_modules/zone.js/dist/zone.js",
|
||||||
"//:node_modules/zone.js/dist/zone-testing.js",
|
"//:node_modules/zone.js/dist/zone-testing.js",
|
||||||
"//:node_modules/zone.js/dist/task-tracking.js",
|
"//:node_modules/zone.js/dist/task-tracking.js",
|
||||||
|
"//:test-events.js",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
name = "angularjs",
|
name = "angularjs_scripts",
|
||||||
# do not sort
|
|
||||||
srcs = [
|
srcs = [
|
||||||
"//:node_modules/angular/angular.js",
|
"//:node_modules/angular-1.5/angular.js",
|
||||||
|
"//:node_modules/angular-mocks-1.5/angular-mocks.js",
|
||||||
"//:node_modules/angular-mocks/angular-mocks.js",
|
"//:node_modules/angular-mocks/angular-mocks.js",
|
||||||
|
"//:node_modules/angular/angular.js",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
824
CHANGELOG.md
824
CHANGELOG.md
@ -1,3 +1,346 @@
|
|||||||
|
<a name="6.0.9"></a>
|
||||||
|
## [6.0.9](https://github.com/angular/angular/compare/6.0.8...6.0.9) (2018-07-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([3c93d07](https://github.com/angular/angular/commit/3c93d07)), closes [#24831](https://github.com/angular/angular/issues/24831)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.8"></a>
|
||||||
|
## [6.0.8](https://github.com/angular/angular/compare/6.0.7...6.0.8) (2018-07-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **common:** do not round factional seconds ([#24831](https://github.com/angular/angular/issues/24831)) ([0746485](https://github.com/angular/angular/commit/0746485)), closes [#24384](https://github.com/angular/angular/issues/24384)
|
||||||
|
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([9a98de9](https://github.com/angular/angular/commit/9a98de9)), closes [#24155](https://github.com/angular/angular/issues/24155)
|
||||||
|
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([a92f111](https://github.com/angular/angular/commit/a92f111)), closes [#24609](https://github.com/angular/angular/issues/24609)
|
||||||
|
* **compiler-cli:** Use typescript to resolve modules for metadata ([#22856](https://github.com/angular/angular/issues/22856)) ([7717ff1](https://github.com/angular/angular/commit/7717ff1))
|
||||||
|
* **core:** use addCustomEqualityTester instead of overriding toEqual ([#22983](https://github.com/angular/angular/issues/22983)) ([b8975a9](https://github.com/angular/angular/commit/b8975a9)), closes [#22939](https://github.com/angular/angular/issues/22939)
|
||||||
|
* **language-service:** do not overwrite native `Reflect` ([#24299](https://github.com/angular/angular/issues/24299)) ([de1c44f](https://github.com/angular/angular/commit/de1c44f)), closes [#21420](https://github.com/angular/angular/issues/21420)
|
||||||
|
* **router:** add ability to recover from malformed url ([#23283](https://github.com/angular/angular/issues/23283)) ([2d4f4b5](https://github.com/angular/angular/commit/2d4f4b5)), closes [#21468](https://github.com/angular/angular/issues/21468)
|
||||||
|
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([183b079](https://github.com/angular/angular/commit/183b079))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **core:** add support for ShadowDOM v1 ([#24718](https://github.com/angular/angular/issues/24718)) ([6c55a13](https://github.com/angular/angular/commit/6c55a13))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.7"></a>
|
||||||
|
## [6.0.7](https://github.com/angular/angular/compare/6.0.6...6.0.7) (2018-06-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** set animations styles properly on platform-server ([#24624](https://github.com/angular/angular/issues/24624)) ([0b356d4](https://github.com/angular/angular/commit/0b356d4))
|
||||||
|
* **common:** use correct ICU plural for locale mk ([#24659](https://github.com/angular/angular/issues/24659)) ([64a8584](https://github.com/angular/angular/commit/64a8584))
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.6"></a>
|
||||||
|
## [6.0.6](https://github.com/angular/angular/compare/6.0.5...6.0.6) (2018-06-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([e543c73](https://github.com/angular/angular/commit/e543c73)), closes [#20363](https://github.com/angular/angular/issues/20363)
|
||||||
|
* **core:** Injector correctly honors the @Self flag ([#24520](https://github.com/angular/angular/issues/24520)) ([f5b3661](https://github.com/angular/angular/commit/f5b3661))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.5"></a>
|
||||||
|
## [6.0.5](https://github.com/angular/angular/compare/6.0.4...6.0.5) (2018-06-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([0139173](https://github.com/angular/angular/commit/0139173))
|
||||||
|
* **bazel:** Allow ng_module to depend on targets w no deps ([#24446](https://github.com/angular/angular/issues/24446)) ([ea3669e](https://github.com/angular/angular/commit/ea3669e))
|
||||||
|
* **docs-infra:** use script nomodule to load IE polyfills, skip other polyfills ([#24317](https://github.com/angular/angular/issues/24317)) ([e876535](https://github.com/angular/angular/commit/e876535)), closes [#23647](https://github.com/angular/angular/issues/23647)
|
||||||
|
* **router:** fix lazy loading of aux routes ([#23459](https://github.com/angular/angular/issues/23459)) ([d20877b](https://github.com/angular/angular/commit/d20877b)), closes [#10981](https://github.com/angular/angular/issues/10981)
|
||||||
|
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([ea2987c](https://github.com/angular/angular/commit/ea2987c)), closes [#24095](https://github.com/angular/angular/issues/24095)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.4"></a>
|
||||||
|
## [6.0.4](https://github.com/angular/angular/compare/6.0.3...6.0.4) (2018-06-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([c9eb491](https://github.com/angular/angular/commit/c9eb491))
|
||||||
|
* **animations:** retain trigger-state for nodes that are moved around ([#24238](https://github.com/angular/angular/issues/24238)) ([19deca1](https://github.com/angular/angular/commit/19deca1))
|
||||||
|
* **forms:** properly handle special properties in FormGroup.get ([#22249](https://github.com/angular/angular/issues/22249)) ([dc3e8aa](https://github.com/angular/angular/commit/dc3e8aa)), closes [#17195](https://github.com/angular/angular/issues/17195)
|
||||||
|
* **platform-server:** avoid clash between server and client style encapsulation attributes ([#24158](https://github.com/angular/angular/issues/24158)) ([e9f2203](https://github.com/angular/angular/commit/e9f2203))
|
||||||
|
* **platform-server:** avoid dependency cycle when using http interceptor ([#24229](https://github.com/angular/angular/issues/24229)) ([2991b1b](https://github.com/angular/angular/commit/2991b1b)), closes [#23023](https://github.com/angular/angular/issues/23023)
|
||||||
|
* **platform-server:** don't reflect innerHTML property to attibute ([#24213](https://github.com/angular/angular/issues/24213)) ([c17098d](https://github.com/angular/angular/commit/c17098d)), closes [#19278](https://github.com/angular/angular/issues/19278)
|
||||||
|
* **platform-server:** provide Domino DOM types globally ([#24116](https://github.com/angular/angular/issues/24116)) ([906b3ec](https://github.com/angular/angular/commit/906b3ec)), closes [#23280](https://github.com/angular/angular/issues/23280) [#23133](https://github.com/angular/angular/issues/23133)
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.3"></a>
|
||||||
|
## [6.0.3](https://github.com/angular/angular/compare/6.0.2...6.0.3) (2018-05-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0ee5b7e](https://github.com/angular/angular/commit/0ee5b7e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.2"></a>
|
||||||
|
## [6.0.2](https://github.com/angular/angular/compare/6.0.1...6.0.2) (2018-05-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([752b83a](https://github.com/angular/angular/commit/752b83a))
|
||||||
|
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([c6b618d](https://github.com/angular/angular/commit/c6b618d))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.1"></a>
|
||||||
|
# [6.0.1](https://github.com/angular/angular/compare/6.0.0...6.0.1) (2018-05-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** properly clean up queried element styles in safari/edge ([#23686](https://github.com/angular/angular/issues/23686)) ([3824e3f](https://github.com/angular/angular/commit/3824e3f))
|
||||||
|
* **animations:** retain state styling for nodes that are moved around ([#23686](https://github.com/angular/angular/issues/23686)) ([05aa5e0](https://github.com/angular/angular/commit/05aa5e0))
|
||||||
|
* **core:** call ngOnDestroy on all services that have it ([#23755](https://github.com/angular/angular/issues/23755)) ([5581e97](https://github.com/angular/angular/commit/5581e97)), closes [#22466](https://github.com/angular/angular/issues/22466) [#22240](https://github.com/angular/angular/issues/22240) [#14818](https://github.com/angular/angular/issues/14818)
|
||||||
|
* **elements:** always check to create strategy ([#23825](https://github.com/angular/angular/issues/23825)) ([d280077](https://github.com/angular/angular/commit/d280077))
|
||||||
|
* **router:** avoid freezing queryParams in-place ([#22663](https://github.com/angular/angular/issues/22663)) ([3d8799b](https://github.com/angular/angular/commit/3d8799b)), closes [#22617](https://github.com/angular/angular/issues/22617)
|
||||||
|
* **router:** correct the segment parsing so it won't break on ampersand ([#23684](https://github.com/angular/angular/issues/23684)) ([8733843](https://github.com/angular/angular/commit/8733843))
|
||||||
|
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([2254ac2](https://github.com/angular/angular/commit/2254ac2)), closes [#23526](https://github.com/angular/angular/issues/23526)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="6.0.0"></a>
|
||||||
|
# [6.0.0](https://github.com/angular/angular/compare/6.0.0-beta.0...6.0.0) (2018-05-03)
|
||||||
|
|
||||||
|
### Release Highlights & Update instructions
|
||||||
|
|
||||||
|
Angular v6 is the first release of Angular that unifies the Framework, Material and CLI.
|
||||||
|
|
||||||
|
To learn about the release highlights and our new CLI-powered update workflow for your projects please check out the [v6 release announcement](https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Dependency updates
|
||||||
|
|
||||||
|
* @angular/core now depends on
|
||||||
|
* TypeScript 2.7
|
||||||
|
* RxJS 6.0.0
|
||||||
|
* tslib 1.9.0
|
||||||
|
* @angular/platform-server now depends on Domino 2.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Small Features
|
||||||
|
|
||||||
|
* **animations:** only use the WA-polyfill alongside AnimationBuilder ([#22143](https://github.com/angular/angular/issues/22143)) ([b2f366b](https://github.com/angular/angular/commit/b2f366b)), closes [#17496](https://github.com/angular/angular/issues/17496)
|
||||||
|
* **animations:** expose `element` and `params` within transition matchers ([#22693](https://github.com/angular/angular/issues/22693)) ([58b94e6](https://github.com/angular/angular/commit/58b94e6))
|
||||||
|
* **common:** better error message when non-template element used in NgIf ([#22274](https://github.com/angular/angular/issues/22274)) ([67cf11d](https://github.com/angular/angular/commit/67cf11d)), closes [#16410](https://github.com/angular/angular/issues/16410)
|
||||||
|
* **common:** better error message when non-template element used in NgIf ([#22274](https://github.com/angular/angular/issues/22274)) ([67cf11d](https://github.com/angular/angular/commit/67cf11d)), closes [#16410](https://github.com/angular/angular/issues/16410)
|
||||||
|
* **common:** export functions to format numbers, percents, currencies & dates ([#22423](https://github.com/angular/angular/issues/22423)) ([4180912](https://github.com/angular/angular/commit/4180912)), closes [#20536](https://github.com/angular/angular/issues/20536)
|
||||||
|
* **compiler:** lower @NgModule ids if needed ([#23031](https://github.com/angular/angular/issues/23031)) ([bd024c0](https://github.com/angular/angular/commit/bd024c0))
|
||||||
|
* **compiler:** implement "enableIvy" compiler option ([#21427](https://github.com/angular/angular/issues/21427)) ([64d16de](https://github.com/angular/angular/commit/64d16de))
|
||||||
|
* **compiler:** mark @NgModules in provider lists for identification at runtime ([#22005](https://github.com/angular/angular/issues/22005)) ([2d5e7d1](https://github.com/angular/angular/commit/2d5e7d1))
|
||||||
|
* **compiler:** add support for marker tags in xliff serializers ([#21250](https://github.com/angular/angular/issues/21250)) ([f74130c](https://github.com/angular/angular/commit/f74130c)), closes [#21078](https://github.com/angular/angular/issues/21078)
|
||||||
|
* **compiler:** support for singleline, multiline & jsdoc comments ([#22715](https://github.com/angular/angular/issues/22715)) ([3b167be](https://github.com/angular/angular/commit/3b167be))
|
||||||
|
* **compiler-cli:** lower loadChildren fields to allow dynamic module paths ([#23088](https://github.com/angular/angular/issues/23088)) ([550433a](https://github.com/angular/angular/commit/550433a))
|
||||||
|
* **compiler-cli:** check unvalidated combination of ngc and TypeScript ([#22293](https://github.com/angular/angular/issues/22293)) ([3ceee99](https://github.com/angular/angular/commit/3ceee99)), closes [#20669](https://github.com/angular/angular/issues/20669)
|
||||||
|
* **compiler-cli:** reflect static methods added to classes in metadata ([#21926](https://github.com/angular/angular/issues/21926)) ([eb8ddd2](https://github.com/angular/angular/commit/eb8ddd2))
|
||||||
|
* **compiler-cli:** Check unvalidated combination of ngc and TypeScript ([#22293](https://github.com/angular/angular/issues/22293)) ([3ceee99](https://github.com/angular/angular/commit/3ceee99)), closes [#20669](https://github.com/angular/angular/issues/20669)
|
||||||
|
* **compiler-cli:** add resource inlining to ngc ([#22615](https://github.com/angular/angular/issues/22615)) ([b5be18f](https://github.com/angular/angular/commit/b5be18f))
|
||||||
|
* **compiler-cli:** require node 8 as runtime engine ([#22669](https://github.com/angular/angular/issues/22669)) ([c602563](https://github.com/angular/angular/commit/c602563))
|
||||||
|
* **core:** add binding name to content changed error ([#20352](https://github.com/angular/angular/issues/20352)) ([d3bf54b](https://github.com/angular/angular/commit/d3bf54b))
|
||||||
|
* **core:** optional generic type for ElementRef ([#20765](https://github.com/angular/angular/issues/20765)) ([d3d9aac](https://github.com/angular/angular/commit/d3d9aac)), closes [#13139](https://github.com/angular/angular/issues/13139)
|
||||||
|
* **core:** set `preserveWhitespaces` to false by default ([#22046](https://github.com/angular/angular/issues/22046)) ([f1a0632](https://github.com/angular/angular/commit/f1a0632)), closes [#22027](https://github.com/angular/angular/issues/22027)
|
||||||
|
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([5c89d6b](https://github.com/angular/angular/commit/5c89d6b)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
||||||
|
* **core:** change @Injectable() to support tree-shakeable tokens ([#22005](https://github.com/angular/angular/issues/22005)) ([235a235](https://github.com/angular/angular/commit/235a235))
|
||||||
|
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([b7544cc](https://github.com/angular/angular/commit/b7544cc)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
||||||
|
* **core:** allow direct scoping of @Injectables to the root injector ([#22185](https://github.com/angular/angular/issues/22185)) ([7ac34e4](https://github.com/angular/angular/commit/7ac34e4))
|
||||||
|
* **core:** add task tracking to Testability ([#16863](https://github.com/angular/angular/issues/16863)) ([37fedd0](https://github.com/angular/angular/commit/37fedd0))
|
||||||
|
* **forms:** handle string with and without line boundary on pattern validator ([#19256](https://github.com/angular/angular/issues/19256)) ([54bf179](https://github.com/angular/angular/commit/54bf179))
|
||||||
|
* **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665)
|
||||||
|
* **forms:** allow markAsPending to emit events ([#20212](https://github.com/angular/angular/issues/20212)) ([e86b64b](https://github.com/angular/angular/commit/e86b64b)), closes [#17958](https://github.com/angular/angular/issues/17958)
|
||||||
|
* **platform-browser:** add token marking which the type of animation module nearest in the injector tree ([#23075](https://github.com/angular/angular/issues/23075)) ([b551f84](https://github.com/angular/angular/commit/b551f84))
|
||||||
|
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
|
||||||
|
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
|
||||||
|
* **platform-server:** bump Domino to v2.0 ([#22411](https://github.com/angular/angular/issues/22411)) ([d3827a0](https://github.com/angular/angular/commit/d3827a0))
|
||||||
|
* **router:** add navigationSource and restoredState to NavigationStart event ([#21728](https://github.com/angular/angular/issues/21728)) ([c40ae7f](https://github.com/angular/angular/commit/c40ae7f))
|
||||||
|
* **service-worker:** add support for configuring navigations URLs ([#23339](https://github.com/angular/angular/issues/23339)) ([08325aa](https://github.com/angular/angular/commit/08325aa)), closes [#20404](https://github.com/angular/angular/issues/20404)
|
||||||
|
* **service-worker:** add helper script which will uninstall SW ([#21863](https://github.com/angular/angular/issues/21863)) ([b10540a](https://github.com/angular/angular/commit/b10540a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** report correct totalTime value even during noOp animations ([#22225](https://github.com/angular/angular/issues/22225)) ([e1bf067](https://github.com/angular/angular/commit/e1bf067))
|
||||||
|
* **animations:** avoid animation insertions during router back/refresh ([#21977](https://github.com/angular/angular/issues/21977)) ([f88fba0](https://github.com/angular/angular/commit/f88fba0)), closes [#19712](https://github.com/angular/angular/issues/19712)
|
||||||
|
* **animations:** treat numeric state name values as strings ([#22923](https://github.com/angular/angular/issues/22923)) ([e5e1b0d](https://github.com/angular/angular/commit/e5e1b0d))
|
||||||
|
* **animations:** report correct totalTime value even during noOp animations ([#22225](https://github.com/angular/angular/issues/22225)) ([e1bf067](https://github.com/angular/angular/commit/e1bf067))
|
||||||
|
* **animations:** fix increment/decrement aliases example ([#18323](https://github.com/angular/angular/issues/18323)) ([d2aa8ac](https://github.com/angular/angular/commit/d2aa8ac))
|
||||||
|
* **common:** NgClass should properly take className changes into account ([#21937](https://github.com/angular/angular/issues/21937)) ([4a42669](https://github.com/angular/angular/commit/4a42669)), closes [#21932](https://github.com/angular/angular/issues/21932)
|
||||||
|
* **common:** fix the titlecase pipe ([#22600](https://github.com/angular/angular/issues/22600)) ([7966744](https://github.com/angular/angular/commit/7966744))
|
||||||
|
* **common:** add locale currency values ([#21783](https://github.com/angular/angular/issues/21783)) ([420cc7a](https://github.com/angular/angular/commit/420cc7a)), closes [#20385](https://github.com/angular/angular/issues/20385)
|
||||||
|
* **common:** round currencies based on decimal digits in `CurrencyPipe` ([#21783](https://github.com/angular/angular/issues/21783)) ([44154e7](https://github.com/angular/angular/commit/44154e7)), closes [#10189](https://github.com/angular/angular/issues/10189)
|
||||||
|
* **common:** weaken AsyncPipe transform signature ([#22169](https://github.com/angular/angular/issues/22169)) ([be59c3a](https://github.com/angular/angular/commit/be59c3a))
|
||||||
|
* **common:** http testing library should not convert null to a string when flushing a mock request ([#21417](https://github.com/angular/angular/issues/21417)) ([8b14488](https://github.com/angular/angular/commit/8b14488)), closes [#20744](https://github.com/angular/angular/issues/20744)
|
||||||
|
* **common:** correct mapping of Observable methods ([#20518](https://github.com/angular/angular/issues/20518)) ([2639b4b](https://github.com/angular/angular/commit/2639b4b)), closes [#20516](https://github.com/angular/angular/issues/20516)
|
||||||
|
* **common:** then and else template might be set to null ([#22298](https://github.com/angular/angular/issues/22298)) ([8115edc](https://github.com/angular/angular/commit/8115edc))
|
||||||
|
* **common:** A null value should remove the style on IE ([#21679](https://github.com/angular/angular/issues/21679)) ([7d49443](https://github.com/angular/angular/commit/7d49443)), closes [#21064](https://github.com/angular/angular/issues/21064)
|
||||||
|
* **common:** fallback to last defined value for named date and time formats ([#21299](https://github.com/angular/angular/issues/21299)) ([879756d](https://github.com/angular/angular/commit/879756d)), closes [#21282](https://github.com/angular/angular/issues/21282)
|
||||||
|
* **common:** set correct timezone for ISO8601 dates in Safari ([#21506](https://github.com/angular/angular/issues/21506)) ([05208b8](https://github.com/angular/angular/commit/05208b8)), closes [#21491](https://github.com/angular/angular/issues/21491)
|
||||||
|
* **compiler:** fix ICU select messages to use male/female/other ([#21713](https://github.com/angular/angular/issues/21713)) ([cb5090c](https://github.com/angular/angular/commit/cb5090c))
|
||||||
|
* **compiler:** avoid a crash in ngc-wrapped. ([#23468](https://github.com/angular/angular/issues/23468)) ([0bc8443](https://github.com/angular/angular/commit/0bc8443))
|
||||||
|
* **compiler:** handle undefined annotation metadata ([#23349](https://github.com/angular/angular/issues/23349)) ([b9431e8](https://github.com/angular/angular/commit/b9431e8))
|
||||||
|
* **compiler:** don't typecheck all inputs ([#22899](https://github.com/angular/angular/issues/22899)) ([838a610](https://github.com/angular/angular/commit/838a610))
|
||||||
|
* **compiler:** fix support for html-like text in translatable attributes ([#23053](https://github.com/angular/angular/issues/23053)) ([28058b7](https://github.com/angular/angular/commit/28058b7))
|
||||||
|
* **compiler:** take quoting into account when determining if object literals can be shared ([#22942](https://github.com/angular/angular/issues/22942)) ([d98e9e7](https://github.com/angular/angular/commit/d98e9e7))
|
||||||
|
* **compiler:** do not emit line/char in ngsummary files. ([#22840](https://github.com/angular/angular/issues/22840)) ([5c387a7](https://github.com/angular/angular/commit/5c387a7))
|
||||||
|
* **compiler:** make unary plus operator consistent to JavaScript ([#22154](https://github.com/angular/angular/issues/22154)) ([72f8abd](https://github.com/angular/angular/commit/72f8abd)), closes [#22089](https://github.com/angular/angular/issues/22089)
|
||||||
|
* **compiler:** allow tree-shakeable injectables to depend on string tokens ([#22376](https://github.com/angular/angular/issues/22376)) ([dd53447](https://github.com/angular/angular/commit/dd53447))
|
||||||
|
* **compiler:** don't strip `/*# sourceURL ... */` ([#16088](https://github.com/angular/angular/issues/16088)) ([5f681f9](https://github.com/angular/angular/commit/5f681f9))
|
||||||
|
* **compiler:** cache external reference resolution ([#21359](https://github.com/angular/angular/issues/21359)) ([e3e2fc0](https://github.com/angular/angular/commit/e3e2fc0))
|
||||||
|
* **compiler:** make `.ngsummary.json` files idempotent ([#21448](https://github.com/angular/angular/issues/21448)) ([e64b1e9](https://github.com/angular/angular/commit/e64b1e9))
|
||||||
|
* **compiler-cli:** shorten resolved module name in fileNameToModuleName to npm package name for typings ([#23231](https://github.com/angular/angular/issues/23231)) ([6199ea5](https://github.com/angular/angular/commit/6199ea5))
|
||||||
|
* **compiler-cli:** strictMetadataEmit should not break on non-compliant libraries ([#23275](https://github.com/angular/angular/issues/23275)) ([5814355](https://github.com/angular/angular/commit/5814355)), closes [#22210](https://github.com/angular/angular/issues/22210)
|
||||||
|
* **compiler-cli:** flat module index metadata should be transformed ([#23129](https://github.com/angular/angular/issues/23129)) ([f99cb5c](https://github.com/angular/angular/commit/f99cb5c))
|
||||||
|
* **compiler-cli:** use numeric comparison for TypeScript version ([#22705](https://github.com/angular/angular/issues/22705)) ([193737a](https://github.com/angular/angular/commit/193737a)), closes [#22593](https://github.com/angular/angular/issues/22593)
|
||||||
|
* **compiler-cli:** disableTypeScriptVersionCheck should be applied even for older tsc versions ([#22669](https://github.com/angular/angular/issues/22669)) ([3f70aba](https://github.com/angular/angular/commit/3f70aba))
|
||||||
|
* **compiler-cli:** emit correct css string escape sequences ([#22776](https://github.com/angular/angular/issues/22776)) ([6e5e819](https://github.com/angular/angular/commit/6e5e819))
|
||||||
|
* **compiler-cli:** do not fold errors past calls in the collector ([#21708](https://github.com/angular/angular/issues/21708)) ([dd86790](https://github.com/angular/angular/commit/dd86790))
|
||||||
|
* **compiler-cli:** do not lower expressions in non-modules ([#21649](https://github.com/angular/angular/issues/21649)) ([7f93aad](https://github.com/angular/angular/commit/7f93aad))
|
||||||
|
* **core:** fix [#20582](https://github.com/angular/angular/issues/20582), don't need to wrap zone in location change listener ([#20640](https://github.com/angular/angular/issues/20640)) ([f791e9f](https://github.com/angular/angular/commit/f791e9f))
|
||||||
|
* **core:** fix proper propagation of subscriptions in EventEmitter ([#22016](https://github.com/angular/angular/issues/22016)) ([e81606c](https://github.com/angular/angular/commit/e81606c)), closes [#21999](https://github.com/angular/angular/issues/21999)
|
||||||
|
* **core:** fix chained http call ([#20924](https://github.com/angular/angular/issues/20924)) ([7e3f9a4](https://github.com/angular/angular/commit/7e3f9a4)), closes [#20921](https://github.com/angular/angular/issues/20921)
|
||||||
|
* **core:** should check Zone existence when scheduleMicroTask ([#20656](https://github.com/angular/angular/issues/20656)) ([3a86940](https://github.com/angular/angular/commit/3a86940))
|
||||||
|
* **core:** avoid eager providers re-initialization ([#23559](https://github.com/angular/angular/issues/23559)) ([697b6c0](https://github.com/angular/angular/commit/697b6c0))
|
||||||
|
* **core:** add stacktrace in log when error during cleanup component in TestBed ([#22162](https://github.com/angular/angular/issues/22162)) ([16d1700](https://github.com/angular/angular/commit/16d1700))
|
||||||
|
* **core:** ensure initial value of QueryList length ([#21980](https://github.com/angular/angular/issues/21980)) ([#21982](https://github.com/angular/angular/issues/21982)) ([e56de10](https://github.com/angular/angular/commit/e56de10)), closes [#21980](https://github.com/angular/angular/issues/21980)
|
||||||
|
* **core:** use appropriate inert document strategy for Firefox & Safari ([#17019](https://github.com/angular/angular/issues/17019)) ([a751649](https://github.com/angular/angular/commit/a751649))
|
||||||
|
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([a7ebf5a](https://github.com/angular/angular/commit/a7ebf5a)), closes [#19978](https://github.com/angular/angular/issues/19978)
|
||||||
|
* **core:** require factory to be provided for shakeable InjectionToken ([#22207](https://github.com/angular/angular/issues/22207)) ([f755db7](https://github.com/angular/angular/commit/f755db7)), closes [#22205](https://github.com/angular/angular/issues/22205)
|
||||||
|
* **core:** remove core animation import symbols ([#22692](https://github.com/angular/angular/issues/22692)) ([f5a98f4](https://github.com/angular/angular/commit/f5a98f4))
|
||||||
|
* **forms:** improve error message for invalid value accessors ([#22731](https://github.com/angular/angular/issues/22731)) ([23cc3ef](https://github.com/angular/angular/commit/23cc3ef))
|
||||||
|
* **forms:** make Validators.email support optional controls ([#20869](https://github.com/angular/angular/issues/20869)) ([140e7c0](https://github.com/angular/angular/commit/140e7c0))
|
||||||
|
* **forms:** prevent event emission on enable/disable when emitEvent is false ([#12366](https://github.com/angular/angular/issues/12366)) ([#21018](https://github.com/angular/angular/issues/21018)) ([0bcfae7](https://github.com/angular/angular/commit/0bcfae7))
|
||||||
|
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([9744a1c](https://github.com/angular/angular/commit/9744a1c)), closes [#21513](https://github.com/angular/angular/issues/21513)
|
||||||
|
* **forms:** publish missing types ([#19941](https://github.com/angular/angular/issues/19941)) ([2707012](https://github.com/angular/angular/commit/2707012))
|
||||||
|
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([3e6a86f](https://github.com/angular/angular/commit/3e6a86f)), closes [#21513](https://github.com/angular/angular/issues/21513)
|
||||||
|
* **language-service:** Clear caches when program changes ([#21337](https://github.com/angular/angular/issues/21337)) ([43e1520](https://github.com/angular/angular/commit/43e1520)), closes [#19405](https://github.com/angular/angular/issues/19405)
|
||||||
|
* **platform-browser:** add @Injectable where it was missing ([#22005](https://github.com/angular/angular/issues/22005)) ([0a1a397](https://github.com/angular/angular/commit/0a1a397))
|
||||||
|
* **platform-browser:** support 0/false/null values in transfer_state ([#22179](https://github.com/angular/angular/issues/22179)) ([6435ecd](https://github.com/angular/angular/commit/6435ecd))
|
||||||
|
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
|
||||||
|
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
|
||||||
|
* **platform-server:** require node v8+ ([#23331](https://github.com/angular/angular/issues/23331)) ([bbfa1d3](https://github.com/angular/angular/commit/bbfa1d3))
|
||||||
|
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([40ba009](https://github.com/angular/angular/commit/40ba009)), closes [#19235](https://github.com/angular/angular/issues/19235)
|
||||||
|
* **platform-server:** add styles to elements correctly ([#22527](https://github.com/angular/angular/issues/22527)) ([cd2ebd2](https://github.com/angular/angular/commit/cd2ebd2))
|
||||||
|
* **router:** cache route handle if found ([#22475](https://github.com/angular/angular/issues/22475)) ([d8de648](https://github.com/angular/angular/commit/d8de648)), closes [#22474](https://github.com/angular/angular/issues/22474)
|
||||||
|
* **router:** don't use spread operator to workaround an issue in closure compiler ([#22884](https://github.com/angular/angular/issues/22884)) ([e6c731f](https://github.com/angular/angular/commit/e6c731f))
|
||||||
|
* **router:** make locationSyncBootstrapListener public due to change in output after TS 2.7 update in [#22669](https://github.com/angular/angular/issues/22669) ([#22896](https://github.com/angular/angular/issues/22896)) ([623d769](https://github.com/angular/angular/commit/623d769))
|
||||||
|
* **router:** correct over-encoding of URL fragment ([#22687](https://github.com/angular/angular/issues/22687)) ([0bf6fa5](https://github.com/angular/angular/commit/0bf6fa5))
|
||||||
|
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([45eff4c](https://github.com/angular/angular/commit/45eff4c)), closes [#22203](https://github.com/angular/angular/issues/22203)
|
||||||
|
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([094666d](https://github.com/angular/angular/commit/094666d)), closes [#10280](https://github.com/angular/angular/issues/10280)
|
||||||
|
* **router:** don't use ParamsInheritanceStrategy in declarations ([#21574](https://github.com/angular/angular/issues/21574)) ([925e654](https://github.com/angular/angular/commit/925e654)), closes [#21456](https://github.com/angular/angular/issues/21456)
|
||||||
|
* **service-worker:** add badge to NOTIFICATION_OPTION_NAMES ([#23241](https://github.com/angular/angular/issues/23241)) ([fb59b2d](https://github.com/angular/angular/commit/fb59b2d)), closes [#23196](https://github.com/angular/angular/issues/23196)
|
||||||
|
* **service-worker:** let `*` match 0 characters in globs ([#23339](https://github.com/angular/angular/issues/23339)) ([6c2c958](https://github.com/angular/angular/commit/6c2c958))
|
||||||
|
* **service-worker:** do not enter degraded mode when offline ([#22883](https://github.com/angular/angular/issues/22883)) ([9e9b8dd](https://github.com/angular/angular/commit/9e9b8dd)), closes [#21636](https://github.com/angular/angular/issues/21636)
|
||||||
|
* **service-worker:** fix LruList bugs ([#22769](https://github.com/angular/angular/issues/22769)) ([8c2a578](https://github.com/angular/angular/commit/8c2a578)), closes [#22218](https://github.com/angular/angular/issues/22218) [#22768](https://github.com/angular/angular/issues/22768)
|
||||||
|
* **service-worker:** ignore invalid `only-if-cached` requests ([#22883](https://github.com/angular/angular/issues/22883)) ([d9dc46e](https://github.com/angular/angular/commit/d9dc46e)), closes [#22362](https://github.com/angular/angular/issues/22362)
|
||||||
|
* **service-worker:** properly handle invalid hashes in all scenarios ([#21288](https://github.com/angular/angular/issues/21288)) ([3951098](https://github.com/angular/angular/commit/3951098))
|
||||||
|
* **upgrade:** correctly handle downgraded `OnPush` components ([#22209](https://github.com/angular/angular/issues/22209)) ([ad9ce5c](https://github.com/angular/angular/commit/ad9ce5c)), closes [#14286](https://github.com/angular/angular/issues/14286)
|
||||||
|
* **upgrade:** propagate return value of resumeBootstrap ([#22754](https://github.com/angular/angular/issues/22754)) ([a2330ff](https://github.com/angular/angular/commit/a2330ff)), closes [#22723](https://github.com/angular/angular/issues/22723)
|
||||||
|
* **upgrade:** two-way binding and listening for event ([#22772](https://github.com/angular/angular/issues/22772)) ([2b3de63](https://github.com/angular/angular/commit/2b3de63)), closes [#22734](https://github.com/angular/angular/issues/22734)
|
||||||
|
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([8a85888](https://github.com/angular/angular/commit/8a85888)), closes [#22392](https://github.com/angular/angular/issues/22392)
|
||||||
|
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([f089bf5](https://github.com/angular/angular/commit/f089bf5))
|
||||||
|
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([13ab91e](https://github.com/angular/angular/commit/13ab91e)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Possible Breaking Changes
|
||||||
|
|
||||||
|
* **animations:** When animation is triggered within a disabled zone, the associated event (which an instance of AnimationEvent) will no longer report the totalTime as 0 (it will emit the actual time of the animation).
|
||||||
|
|
||||||
|
To detect if an animation event is reporting a disabled animation then the `event.disabled` property can be used instead.
|
||||||
|
|
||||||
|
|
||||||
|
* **compiler:** The `<template>` tag was deprecated in Angular v4 to avoid collisions (i.e. when using Web Components).
|
||||||
|
|
||||||
|
This change removes support for `<template>`. `<ng-template>` should be used instead.
|
||||||
|
|
||||||
|
BEFORE:
|
||||||
|
|
||||||
|
<!-- html template -->
|
||||||
|
<template>some template content</template>
|
||||||
|
|
||||||
|
# tsconfig.json
|
||||||
|
{
|
||||||
|
# ...
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
# ...
|
||||||
|
# This option is no more supported and will have no effect
|
||||||
|
"enableLegacyTemplate": [true|false]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AFTER:
|
||||||
|
|
||||||
|
<!-- html template -->
|
||||||
|
<ng-template>some template content</ng-template>
|
||||||
|
|
||||||
|
* **core:** it is no longer possible to import animation-related functions from @angular/core. All animation symbols must now be imported from @angular/animations.
|
||||||
|
|
||||||
|
|
||||||
|
* **forms:** - `AbstractControl#statusChanges` now emits an event of `'PENDING'` when you call `AbstractControl#markAsPending`
|
||||||
|
- Previously it did not emit an event when you called `markAsPending`
|
||||||
|
- To migrate you would need to ensure that if you are filtering or checking events from `statusChanges` that you account for the new event when calling `markAsPending`
|
||||||
|
|
||||||
|
|
||||||
|
* **forms:** ngModelChange is now emitted after the value/validity is updated on its control.
|
||||||
|
|
||||||
|
Previously, ngModelChange was emitted before its underlying control was updated.
|
||||||
|
This was fine if you passed through the value directly through the $event keyword, e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
<input [(ngModel)]="name" (ngModelChange)="onChange($event)">
|
||||||
|
|
||||||
|
onChange(value) {
|
||||||
|
console.log(value); // would log updated value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
However, if you had a handler for the ngModelChange event that checked the value through the control,
|
||||||
|
you would get the old value rather than the updated value. e.g:
|
||||||
|
|
||||||
|
```
|
||||||
|
<input #modelDir="ngModel" [(ngModel)]="name" (ngModelChange)="onChange(modelDir)">
|
||||||
|
|
||||||
|
onChange(ngModel: NgModel) {
|
||||||
|
console.log(ngModel.value); // would log old value, not updated value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now the value and validity will be updated before the ngModelChange event is emitted,
|
||||||
|
so the same setup will log the updated value.
|
||||||
|
|
||||||
|
```
|
||||||
|
onChange(ngModel: NgModel) {
|
||||||
|
console.log(ngModel.value); // will log updated value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
We think this order will be less confusing when the control is checked directly.
|
||||||
|
You will only need to update your app if it has relied on this bug to keep track of the old control value.
|
||||||
|
If that is the case, you should be able to track the old value directly by saving it on your component.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.2.10"></a>
|
<a name="5.2.10"></a>
|
||||||
## [5.2.10](https://github.com/angular/angular/compare/5.2.9...5.2.10) (2018-04-16)
|
## [5.2.10](https://github.com/angular/angular/compare/5.2.9...5.2.10) (2018-04-16)
|
||||||
|
|
||||||
@ -29,231 +372,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-rc.5"></a>
|
|
||||||
## [6.0.0-rc.5](https://github.com/angular/angular/compare/6.0.0-rc.4...6.0.0-rc.5) (2018-04-14)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler:** use correct global name in compiler.umd.js ([#23354](https://github.com/angular/angular/issues/23354)) ([b76dd3b](https://github.com/angular/angular/commit/b76dd3b)), closes [#23343](https://github.com/angular/angular/issues/23343)
|
|
||||||
* **compiler-cli:** shorten resolved module name in fileNameToModuleName to npm package name for typings ([#23231](https://github.com/angular/angular/issues/23231)) ([6199ea5](https://github.com/angular/angular/commit/6199ea5))
|
|
||||||
* **elements:** include schematics in npm distro ([#23350](https://github.com/angular/angular/issues/23350)) ([9fabe2f](https://github.com/angular/angular/commit/9fabe2f))
|
|
||||||
* **service-worker:** let `*` match 0 characters in globs ([#23339](https://github.com/angular/angular/issues/23339)) ([6c2c958](https://github.com/angular/angular/commit/6c2c958))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **platform-browser:** add token marking which the type of animation module nearest in the injector tree ([#23075](https://github.com/angular/angular/issues/23075)) ([b551f84](https://github.com/angular/angular/commit/b551f84))
|
|
||||||
* **service-worker:** add support for configuring navigations URLs ([#23339](https://github.com/angular/angular/issues/23339)) ([08325aa](https://github.com/angular/angular/commit/08325aa)), closes [#20404](https://github.com/angular/angular/issues/20404)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-rc.4"></a>
|
|
||||||
## [6.0.0-rc.4](https://github.com/angular/angular/compare/6.0.0-rc.3...6.0.0-rc.4) (2018-04-12)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bazel:** set rollup output.name and amd.id ([#23274](https://github.com/angular/angular/issues/23274)) ([3e8eef6](https://github.com/angular/angular/commit/3e8eef6)), closes [#23238](https://github.com/angular/angular/issues/23238)
|
|
||||||
* **common:** replace i18n locale undefined values by a const ([#23265](https://github.com/angular/angular/issues/23265)) ([5706810](https://github.com/angular/angular/commit/5706810)), closes [#22988](https://github.com/angular/angular/issues/22988)
|
|
||||||
* **common:** workaround UMD/webpack limitation ([#23271](https://github.com/angular/angular/issues/23271)) ([5a298b1](https://github.com/angular/angular/commit/5a298b1)), closes [#23217](https://github.com/angular/angular/issues/23217)
|
|
||||||
* **compiler:** Pretty print object instead of [Object object] ([#22689](https://github.com/angular/angular/issues/22689)) ([8555a3a](https://github.com/angular/angular/commit/8555a3a))
|
|
||||||
* **compiler-cli:** strictMetadataEmit should not break on non-compliant libraries ([#23275](https://github.com/angular/angular/issues/23275)) ([5814355](https://github.com/angular/angular/commit/5814355)), closes [#22210](https://github.com/angular/angular/issues/22210)
|
|
||||||
* **elements:** avoid exception when window is undefined ([#23324](https://github.com/angular/angular/issues/23324)) ([af46d09](https://github.com/angular/angular/commit/af46d09))
|
|
||||||
* **platform-server:** require node v8+ ([#23331](https://github.com/angular/angular/issues/23331)) ([bbfa1d3](https://github.com/angular/angular/commit/bbfa1d3))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **elements:** add schematics ([#23298](https://github.com/angular/angular/issues/23298)) ([37d2cb4](https://github.com/angular/angular/commit/37d2cb4))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-rc.3"></a>
|
|
||||||
## [6.0.0-rc.3](https://github.com/angular/angular/compare/6.0.0-rc.2...6.0.0-rc.3) (2018-04-06)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bazel:** don't produce ngfactory files for ng_packages ([#23237](https://github.com/angular/angular/issues/23237)) ([da58a55](https://github.com/angular/angular/commit/da58a55))
|
|
||||||
* **compiler-cli:** don't lower expressions in flat module metadata ([#23226](https://github.com/angular/angular/issues/23226)) ([11ea3a3](https://github.com/angular/angular/commit/11ea3a3))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-rc.2"></a>
|
|
||||||
## [6.0.0-rc.2](https://github.com/angular/angular/compare/6.0.0-rc.1...6.0.0-rc.2) (2018-04-05)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **common:** `locales` are not being shipped ([#23136](https://github.com/angular/angular/issues/23136)) ([7ca7720](https://github.com/angular/angular/commit/7ca7720))
|
|
||||||
* **common:** properly take className changes into account ([#21937](https://github.com/angular/angular/issues/21937)) ([4a42669](https://github.com/angular/angular/commit/4a42669)), closes [#21932](https://github.com/angular/angular/issues/21932)
|
|
||||||
* **compiler-cli:** flat module index metadata should be transformed ([#23129](https://github.com/angular/angular/issues/23129)) ([f99cb5c](https://github.com/angular/angular/commit/f99cb5c))
|
|
||||||
* **core:** inject() should always work in an NgModule injection scope ([#23148](https://github.com/angular/angular/issues/23148)) ([fab6b39](https://github.com/angular/angular/commit/fab6b39)), closes [angular/material2#10586](https://github.com/angular/material2/issues/10586)
|
|
||||||
* **forms:** improve error message for invalid value accessors ([#22731](https://github.com/angular/angular/issues/22731)) ([23cc3ef](https://github.com/angular/angular/commit/23cc3ef))
|
|
||||||
* **upgrade:** correctly handle downgraded `OnPush` components ([#22209](https://github.com/angular/angular/issues/22209)) ([ad9ce5c](https://github.com/angular/angular/commit/ad9ce5c)), closes [#14286](https://github.com/angular/angular/issues/14286)
|
|
||||||
* **upgrade:** propagate return value of resumeBootstrap ([#22754](https://github.com/angular/angular/issues/22754)) ([a2330ff](https://github.com/angular/angular/commit/a2330ff)), closes [#22723](https://github.com/angular/angular/issues/22723)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **compiler-cli:** lower loadChildren fields to allow dynamic module paths ([#23088](https://github.com/angular/angular/issues/23088)) ([550433a](https://github.com/angular/angular/commit/550433a))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-rc.1"></a>
|
|
||||||
## [6.0.0-rc.1](https://github.com/angular/angular/compare/6.0.0-rc.0...6.0.0-rc.1) (2018-03-30)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **animations:** avoid animation insertions during router back/refresh ([#21977](https://github.com/angular/angular/issues/21977)) ([f88fba0](https://github.com/angular/angular/commit/f88fba0)), closes [#19712](https://github.com/angular/angular/issues/19712)
|
|
||||||
* **animations:** treat numeric state name values as strings ([#22923](https://github.com/angular/angular/issues/22923)) ([e5e1b0d](https://github.com/angular/angular/commit/e5e1b0d))
|
|
||||||
* **bazel:** complete the rollup globals list for all angular entrypoints ([#23080](https://github.com/angular/angular/issues/23080)) ([439030f](https://github.com/angular/angular/commit/439030f))
|
|
||||||
* **bazel:** don't inline tslib into fesms ([#23044](https://github.com/angular/angular/issues/23044)) ([0049743](https://github.com/angular/angular/commit/0049743))
|
|
||||||
* **bazel:** don't try to do flatmoduleindex under Blaze ([#23083](https://github.com/angular/angular/issues/23083)) ([be10bf5](https://github.com/angular/angular/commit/be10bf5))
|
|
||||||
* **bazel:** downlevel decorators in fesm5 files ([#23078](https://github.com/angular/angular/issues/23078)) ([481b22e](https://github.com/angular/angular/commit/481b22e))
|
|
||||||
* **bazel:** ng_package packages attr not forwarded to npm_package ([#22967](https://github.com/angular/angular/issues/22967)) ([2aabbc5](https://github.com/angular/angular/commit/2aabbc5))
|
|
||||||
* **bazel:** ng_package should include private exports in fesms ([#23054](https://github.com/angular/angular/issues/23054)) ([0d9140c](https://github.com/angular/angular/commit/0d9140c))
|
|
||||||
* **bazel:** pass --global option to rollup ([#23073](https://github.com/angular/angular/issues/23073)) ([45e090b](https://github.com/angular/angular/commit/45e090b))
|
|
||||||
* **common:** titlecase pipe ([#22600](https://github.com/angular/angular/issues/22600)) ([7966744](https://github.com/angular/angular/commit/7966744))
|
|
||||||
* **compiler:** don't typecheck all inputs ([#22899](https://github.com/angular/angular/issues/22899)) ([838a610](https://github.com/angular/angular/commit/838a610))
|
|
||||||
* consistently rewrite Injector to INJECTOR ([#23008](https://github.com/angular/angular/issues/23008)) ([884bf0e](https://github.com/angular/angular/commit/884bf0e))
|
|
||||||
* **compiler:** fix support for html-like text in translatable attributes ([#23053](https://github.com/angular/angular/issues/23053)) ([28058b7](https://github.com/angular/angular/commit/28058b7))
|
|
||||||
* **compiler:** take quoting into account when determining if object literals can be shared ([#22942](https://github.com/angular/angular/issues/22942)) ([d98e9e7](https://github.com/angular/angular/commit/d98e9e7))
|
|
||||||
* **compiler-cli:** use numeric comparison for TypeScript version ([#22705](https://github.com/angular/angular/issues/22705)) ([193737a](https://github.com/angular/angular/commit/193737a)), closes [#22593](https://github.com/angular/angular/issues/22593)
|
|
||||||
* **core:** don't override ngInjectableDef in the decorator if present on the type ([#22943](https://github.com/angular/angular/issues/22943)) ([6f01917](https://github.com/angular/angular/commit/6f01917))
|
|
||||||
* **service-worker:** do not enter degraded mode when offline ([#22883](https://github.com/angular/angular/issues/22883)) ([9e9b8dd](https://github.com/angular/angular/commit/9e9b8dd)), closes [#21636](https://github.com/angular/angular/issues/21636)
|
|
||||||
* **service-worker:** fix LruList bugs ([#22769](https://github.com/angular/angular/issues/22769)) ([8c2a578](https://github.com/angular/angular/commit/8c2a578)), closes [#22218](https://github.com/angular/angular/issues/22218) [#22768](https://github.com/angular/angular/issues/22768)
|
|
||||||
* **service-worker:** ignore invalid `only-if-cached` requests ([#22883](https://github.com/angular/angular/issues/22883)) ([d9dc46e](https://github.com/angular/angular/commit/d9dc46e)), closes [#22362](https://github.com/angular/angular/issues/22362)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **bazel:** prefix private-export (barred-latin-o) symbols ([#23007](https://github.com/angular/angular/issues/23007)) ([27e14b2](https://github.com/angular/angular/commit/27e14b2))
|
|
||||||
* **compiler:** lower @NgModule ids if needed ([#23031](https://github.com/angular/angular/issues/23031)) ([bd024c0](https://github.com/angular/angular/commit/bd024c0))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-rc.0"></a>
|
|
||||||
# [6.0.0-rc.0](https://github.com/angular/angular/compare/6.0.0-beta.8...6.0.0-rc.0) (2018-03-21)
|
|
||||||
|
|
||||||
v6 framework is now feature complete, the cli and material/cdk parts of the v6 release and other integrations are still
|
|
||||||
in works and will be completed by the time we cut v6.0.0.
|
|
||||||
|
|
||||||
Please [file new issues](https://github.com/angular/angular/issues/new) at our issue tracker with as many details as
|
|
||||||
possible, and ideally also a include a good reproduction of the problem.
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bazel:** correct expected outs for external sources in ng_module ([#22755](https://github.com/angular/angular/issues/22755)) ([bfe077a](https://github.com/angular/angular/commit/bfe077a))
|
|
||||||
* **compiler:** do not emit line/char in ngsummary files. ([#22840](https://github.com/angular/angular/issues/22840)) ([5c387a7](https://github.com/angular/angular/commit/5c387a7))
|
|
||||||
* correct several esm2015 entry-points in package.jsons ([#22892](https://github.com/angular/angular/issues/22892)) ([7d095b9](https://github.com/angular/angular/commit/7d095b9))
|
|
||||||
* **router:** don't use spread operator to workaround an issue in closure compiler ([#22884](https://github.com/angular/angular/issues/22884)) ([e6c731f](https://github.com/angular/angular/commit/e6c731f))
|
|
||||||
* **router:** make locationSyncBootstrapListener public due to change in output after TS 2.7 update in [#22669](https://github.com/angular/angular/issues/22669) ([#22896](https://github.com/angular/angular/issues/22896)) ([623d769](https://github.com/angular/angular/commit/623d769))
|
|
||||||
* **upgrade:** two-way binding and listening for event ([#22772](https://github.com/angular/angular/issues/22772)) ([2b3de63](https://github.com/angular/angular/commit/2b3de63)), closes [#22734](https://github.com/angular/angular/issues/22734)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **core:** update the package output of build.sh to [APF v6](https://goo.gl/jB3GVv) ([#22808](https://github.com/angular/angular/issues/22808)) ([ce63dc6](https://github.com/angular/angular/commit/ce63dc6))
|
|
||||||
* **core:** upgrade rxjs to 6.0.0-beta.0, please see this [RxJS Upgrade Guide](https://goo.gl/osWFzo) for more info ([#22573](https://github.com/angular/angular/issues/22573)) ([b43f8bc](https://github.com/angular/angular/commit/b43f8bc))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-beta.8"></a>
|
|
||||||
## [6.0.0-beta.8](https://github.com/angular/angular/compare/6.0.0-beta.7...6.0.0-beta.8) (2018-03-16)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **aio:** constrain error logging to improve reporting ([#22713](https://github.com/angular/angular/issues/22713)) ([049757b](https://github.com/angular/angular/commit/049757b))
|
|
||||||
* **compiler-cli:** annotate Ivy fields as [@nocollapse](https://github.com/nocollapse) in closure mode ([#22691](https://github.com/angular/angular/issues/22691)) ([6e00410](https://github.com/angular/angular/commit/6e00410))
|
|
||||||
* **compiler-cli:** disableTypeScriptVersionCheck should be applied even for older tsc versions ([#22669](https://github.com/angular/angular/issues/22669)) ([3f70aba](https://github.com/angular/angular/commit/3f70aba))
|
|
||||||
* **compiler-cli:** emit correct css string escape sequences ([#22776](https://github.com/angular/angular/issues/22776)) ([6e5e819](https://github.com/angular/angular/commit/6e5e819))
|
|
||||||
* **compiler-cli:** enableResourceInlining handles both styles and styleUrls ([#22688](https://github.com/angular/angular/issues/22688)) ([40315be](https://github.com/angular/angular/commit/40315be))
|
|
||||||
* **compiler-cli:** generate proper exports.* identifiers in cjs output ([#22564](https://github.com/angular/angular/issues/22564)) ([0d8deb0](https://github.com/angular/angular/commit/0d8deb0))
|
|
||||||
* **compiler-cli:** resolve resource URLs before loading them under enableResourceInlining ([#22688](https://github.com/angular/angular/issues/22688)) ([123efba](https://github.com/angular/angular/commit/123efba))
|
|
||||||
* **core:** remove core animation import symbols ([#22692](https://github.com/angular/angular/issues/22692)) ([f5a98f4](https://github.com/angular/angular/commit/f5a98f4))
|
|
||||||
* **elements:** fix elements test bootstrap ([#22839](https://github.com/angular/angular/issues/22839)) ([5d82d8d](https://github.com/angular/angular/commit/5d82d8d))
|
|
||||||
* overloading a function doesn't generate all of the signatures ([#22569](https://github.com/angular/angular/issues/22569)) ([e8326e6](https://github.com/angular/angular/commit/e8326e6))
|
|
||||||
* **platform-server:** add styles to elements correctly ([#22527](https://github.com/angular/angular/issues/22527)) ([cd2ebd2](https://github.com/angular/angular/commit/cd2ebd2))
|
|
||||||
* **router:** correct over-encoding of URL fragment ([#22687](https://github.com/angular/angular/issues/22687)) ([0bf6fa5](https://github.com/angular/angular/commit/0bf6fa5))
|
|
||||||
|
|
||||||
|
|
||||||
### Code Refactoring
|
|
||||||
|
|
||||||
* **compiler:** Drop support for the deprecated `<template>`. Use `<ng-template>` instead ([#22783](https://github.com/angular/angular/issues/22783)) ([0ebd577](https://github.com/angular/angular/commit/0ebd577))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **aio:** add hack, remove me ([#22413](https://github.com/angular/angular/issues/22413)) ([4d506ac](https://github.com/angular/angular/commit/4d506ac))
|
|
||||||
* **aio:** migrate embedded comp to elements ([#22413](https://github.com/angular/angular/issues/22413)) ([7c9b411](https://github.com/angular/angular/commit/7c9b411))
|
|
||||||
* **aio:** update payload size ([#22413](https://github.com/angular/angular/issues/22413)) ([400460c](https://github.com/angular/angular/commit/400460c))
|
|
||||||
* **animations:** expose `element` and `params` within transition matchers ([#22693](https://github.com/angular/angular/issues/22693)) ([58b94e6](https://github.com/angular/angular/commit/58b94e6))
|
|
||||||
* **bazel:** change ng_package rule to APF v6 ([#22782](https://github.com/angular/angular/issues/22782)) ([88b3198](https://github.com/angular/angular/commit/88b3198))
|
|
||||||
* **compiler:** support for singleline, multiline & jsdoc comments ([#22715](https://github.com/angular/angular/issues/22715)) ([3b167be](https://github.com/angular/angular/commit/3b167be))
|
|
||||||
* **compiler-cli:** add resource inlining to ngc ([#22615](https://github.com/angular/angular/issues/22615)) ([b5be18f](https://github.com/angular/angular/commit/b5be18f))
|
|
||||||
* **compiler-cli:** require node 8 as runtime engine ([#22669](https://github.com/angular/angular/issues/22669)) ([c602563](https://github.com/angular/angular/commit/c602563))
|
|
||||||
* **core:** add task tracking to Testability ([#16863](https://github.com/angular/angular/issues/16863)) ([37fedd0](https://github.com/angular/angular/commit/37fedd0))
|
|
||||||
* **elements:** add polyfill for elements es5 shim ([#22413](https://github.com/angular/angular/issues/22413)) ([863aff1](https://github.com/angular/angular/commit/863aff1))
|
|
||||||
* **elements:** add support for creating custom elements ([#22413](https://github.com/angular/angular/issues/22413)) ([22b96b9](https://github.com/angular/angular/commit/22b96b9))
|
|
||||||
* **elements:** add tests for component factory strategy ([#22413](https://github.com/angular/angular/issues/22413)) ([d2be675](https://github.com/angular/angular/commit/d2be675))
|
|
||||||
* **elements:** another polyfill solution ([#22413](https://github.com/angular/angular/issues/22413)) ([cf3ff7d](https://github.com/angular/angular/commit/cf3ff7d))
|
|
||||||
* **elements:** fix lint ([#22413](https://github.com/angular/angular/issues/22413)) ([0b45dfa](https://github.com/angular/angular/commit/0b45dfa))
|
|
||||||
* **elements:** fix payload size ([#22413](https://github.com/angular/angular/issues/22413)) ([fe21437](https://github.com/angular/angular/commit/fe21437))
|
|
||||||
* **elements:** fix test ([#22413](https://github.com/angular/angular/issues/22413)) ([44f637a](https://github.com/angular/angular/commit/44f637a))
|
|
||||||
* **elements:** George's comments ([#22413](https://github.com/angular/angular/issues/22413)) ([46efd4b](https://github.com/angular/angular/commit/46efd4b))
|
|
||||||
* **elements:** injector create ([#22413](https://github.com/angular/angular/issues/22413)) ([87f60bc](https://github.com/angular/angular/commit/87f60bc))
|
|
||||||
* **elements:** make bazel happy ([#22413](https://github.com/angular/angular/issues/22413)) ([39a12d2](https://github.com/angular/angular/commit/39a12d2))
|
|
||||||
* **elements:** provide type, not factory; remove config need ([#22413](https://github.com/angular/angular/issues/22413)) ([1936808](https://github.com/angular/angular/commit/1936808))
|
|
||||||
* **elements:** rebase ([#22413](https://github.com/angular/angular/issues/22413)) ([d72f445](https://github.com/angular/angular/commit/d72f445))
|
|
||||||
* **elements:** remove attribute/input from config ([#22413](https://github.com/angular/angular/issues/22413)) ([688096b](https://github.com/angular/angular/commit/688096b))
|
|
||||||
* **elements:** rename API to createCustomElement ([#22413](https://github.com/angular/angular/issues/22413)) ([167fdf7](https://github.com/angular/angular/commit/167fdf7))
|
|
||||||
* **elements:** update package.json with latest ([#22413](https://github.com/angular/angular/issues/22413)) ([2e450f6](https://github.com/angular/angular/commit/2e450f6))
|
|
||||||
* mark angular packages as side-effect free ([#22785](https://github.com/angular/angular/issues/22785)) ([44de10e](https://github.com/angular/angular/commit/44de10e))
|
|
||||||
* tree-shakeable providers API updates ([#22655](https://github.com/angular/angular/issues/22655)) ([db56836](https://github.com/angular/angular/commit/db56836))
|
|
||||||
* update tslib to 1.9.0 ([#22667](https://github.com/angular/angular/issues/22667)) ([489fec1](https://github.com/angular/angular/commit/489fec1))
|
|
||||||
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* **compiler:** The `<template>` tag was deprecated in Angular v4 to avoid collisions (i.e. when
|
|
||||||
using Web Components).
|
|
||||||
|
|
||||||
This commit removes support for `<template>`. `<ng-template>` should be used
|
|
||||||
instead.
|
|
||||||
|
|
||||||
BEFORE:
|
|
||||||
|
|
||||||
<!-- html template -->
|
|
||||||
<template>some template content</template>
|
|
||||||
|
|
||||||
# tsconfig.json
|
|
||||||
{
|
|
||||||
# ...
|
|
||||||
"angularCompilerOptions": {
|
|
||||||
# ...
|
|
||||||
# This option is no more supported and will have no effect
|
|
||||||
"enableLegacyTemplate": [true|false]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AFTER:
|
|
||||||
|
|
||||||
<!-- html template -->
|
|
||||||
<ng-template>some template content</ng-template>
|
|
||||||
* **core:** it is no longer possible to import
|
|
||||||
animation-related functions from @angular/core. All
|
|
||||||
animation symbols must now be imported from @angular/animations.
|
|
||||||
* after this change, npm and yarn will issue incompatible peerDependencies warning
|
|
||||||
|
|
||||||
We don't expect this to actually break an application, but the application/library package.json
|
|
||||||
will need to be updated to provide tslib 1.9.0 or higher.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.2.9"></a>
|
<a name="5.2.9"></a>
|
||||||
## [5.2.9](https://github.com/angular/angular/compare/5.2.8...5.2.9) (2018-03-14)
|
## [5.2.9](https://github.com/angular/angular/compare/5.2.8...5.2.9) (2018-03-14)
|
||||||
|
|
||||||
@ -265,18 +383,6 @@ will need to be updated to provide tslib 1.9.0 or higher.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-beta.7"></a>
|
|
||||||
# [6.0.0-beta.7](https://github.com/angular/angular/compare/6.0.0-beta.6...6.0.0-beta.7) (2018-03-07)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bazel:** fixes for ng_package on Windows ([#22597](https://github.com/angular/angular/issues/22597)) ([4c40812](https://github.com/angular/angular/commit/4c40812))
|
|
||||||
* **compiler:** allow tree-shakeable injectables to depend on string tokens ([#22376](https://github.com/angular/angular/issues/22376)) ([dd53447](https://github.com/angular/angular/commit/dd53447))
|
|
||||||
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([fa974c7](https://github.com/angular/angular/commit/fa974c7)), closes [#10280](https://github.com/angular/angular/issues/10280)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.2.8"></a>
|
<a name="5.2.8"></a>
|
||||||
## [5.2.8](https://github.com/angular/angular/compare/5.2.7...5.2.8) (2018-03-07)
|
## [5.2.8](https://github.com/angular/angular/compare/5.2.7...5.2.8) (2018-03-07)
|
||||||
|
|
||||||
@ -291,63 +397,6 @@ will need to be updated to provide tslib 1.9.0 or higher.
|
|||||||
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-beta.6"></a>
|
|
||||||
# [6.0.0-beta.6](https://github.com/angular/angular/compare/6.0.0-beta.5...6.0.0-beta.6) (2018-02-28)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **animations:** only use the WA-polyfill alongside AnimationBuilder ([#22143](https://github.com/angular/angular/issues/22143)) ([b2f366b](https://github.com/angular/angular/commit/b2f366b)), closes [#17496](https://github.com/angular/angular/issues/17496)
|
|
||||||
* **animations:** report correct totalTime value even during noOp animations ([#22225](https://github.com/angular/angular/issues/22225)) ([e1bf067](https://github.com/angular/angular/commit/e1bf067))
|
|
||||||
* **bazel:** ng_package includes transitive .d.ts and flatModuleMetadata ([#22499](https://github.com/angular/angular/issues/22499)) ([aabe16c](https://github.com/angular/angular/commit/aabe16c)), closes [#22419](https://github.com/angular/angular/issues/22419)
|
|
||||||
* **common:** correct mapping of Observable methods ([#20518](https://github.com/angular/angular/issues/20518)) ([2639b4b](https://github.com/angular/angular/commit/2639b4b)), closes [#20516](https://github.com/angular/angular/issues/20516)
|
|
||||||
* **common:** then and else template might be set to null ([#22298](https://github.com/angular/angular/issues/22298)) ([8115edc](https://github.com/angular/angular/commit/8115edc))
|
|
||||||
* **compiler-cli:** add missing entry point to package, update tsickle ([#22295](https://github.com/angular/angular/issues/22295)) ([28ac244](https://github.com/angular/angular/commit/28ac244))
|
|
||||||
* **core:** export inject() from [@angular](https://github.com/angular)/core ([#22389](https://github.com/angular/angular/issues/22389)) ([f8749bf](https://github.com/angular/angular/commit/f8749bf)), closes [#22388](https://github.com/angular/angular/issues/22388)
|
|
||||||
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([a7ebf5a](https://github.com/angular/angular/commit/a7ebf5a)), closes [#19978](https://github.com/angular/angular/issues/19978)
|
|
||||||
* **core:** require factory to be provided for shakeable InjectionToken ([#22207](https://github.com/angular/angular/issues/22207)) ([f755db7](https://github.com/angular/angular/commit/f755db7)), closes [#22205](https://github.com/angular/angular/issues/22205)
|
|
||||||
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([3e6a86f](https://github.com/angular/angular/commit/3e6a86f)), closes [#21513](https://github.com/angular/angular/issues/21513)
|
|
||||||
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([40ba009](https://github.com/angular/angular/commit/40ba009)), closes [#19235](https://github.com/angular/angular/issues/19235)
|
|
||||||
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([45eff4c](https://github.com/angular/angular/commit/45eff4c)), closes [#22203](https://github.com/angular/angular/issues/22203)
|
|
||||||
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([094666d](https://github.com/angular/angular/commit/094666d)), closes [#10280](https://github.com/angular/angular/issues/10280)
|
|
||||||
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([8a85888](https://github.com/angular/angular/commit/8a85888)), closes [#22392](https://github.com/angular/angular/issues/22392)
|
|
||||||
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([f089bf5](https://github.com/angular/angular/commit/f089bf5))
|
|
||||||
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([13ab91e](https://github.com/angular/angular/commit/13ab91e)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **bazel:** add an ng_package rule ([#22221](https://github.com/angular/angular/issues/22221)) ([b43b164](https://github.com/angular/angular/commit/b43b164))
|
|
||||||
* **bazel:** introduce a binary stamping feature ([#22176](https://github.com/angular/angular/issues/22176)) ([bba65e0](https://github.com/angular/angular/commit/bba65e0))
|
|
||||||
* **bazel:** ng_module produces bundle index ([#22176](https://github.com/angular/angular/issues/22176)) ([029dbf0](https://github.com/angular/angular/commit/029dbf0))
|
|
||||||
* **bazel:** ng_package adds package.json props ([#22499](https://github.com/angular/angular/issues/22499)) ([b6c9410](https://github.com/angular/angular/commit/b6c9410)), closes [#22416](https://github.com/angular/angular/issues/22416)
|
|
||||||
* **common:** better error message when non-template element used in NgIf ([#22274](https://github.com/angular/angular/issues/22274)) ([67cf11d](https://github.com/angular/angular/commit/67cf11d)), closes [#16410](https://github.com/angular/angular/issues/16410)
|
|
||||||
* **common:** export functions to format numbers, percents, currencies & dates ([#22423](https://github.com/angular/angular/issues/22423)) ([4180912](https://github.com/angular/angular/commit/4180912)), closes [#20536](https://github.com/angular/angular/issues/20536)
|
|
||||||
* **compiler-cli:** Check unvalidated combination of ngc and TypeScript ([#22293](https://github.com/angular/angular/issues/22293)) ([3ceee99](https://github.com/angular/angular/commit/3ceee99)), closes [#20669](https://github.com/angular/angular/issues/20669)
|
|
||||||
* **core:** set preserveWhitespaces to false by default ([#22046](https://github.com/angular/angular/issues/22046)) ([f1a0632](https://github.com/angular/angular/commit/f1a0632)), closes [#22027](https://github.com/angular/angular/issues/22027)
|
|
||||||
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([5c89d6b](https://github.com/angular/angular/commit/5c89d6b)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
|
||||||
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([b7544cc](https://github.com/angular/angular/commit/b7544cc)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
|
||||||
* **forms:** allow markAsPending to emit events ([#20212](https://github.com/angular/angular/issues/20212)) ([e86b64b](https://github.com/angular/angular/commit/e86b64b)), closes [#17958](https://github.com/angular/angular/issues/17958)
|
|
||||||
* allow direct scoping of @Injectables to the root injector ([#22185](https://github.com/angular/angular/issues/22185)) ([7ac34e4](https://github.com/angular/angular/commit/7ac34e4))
|
|
||||||
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
|
|
||||||
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
|
|
||||||
* **platform-server:** bump Domino to v2.0 ([#22411](https://github.com/angular/angular/issues/22411)) ([d3827a0](https://github.com/angular/angular/commit/d3827a0))
|
|
||||||
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* **platform-server:** * Bump the dependency on Domino to 2.0 to resolve issues with
|
|
||||||
namespacing
|
|
||||||
* **forms:** - `AbstractControl#statusChanges` now emits an event of `'PENDING'` when you call `AbstractControl#markAsPending`
|
|
||||||
- Previously it did not emit an event when you called `markAsPending`
|
|
||||||
- To migrate you would need to ensure that if you are filtering or checking events from `statusChanges` that you account for the new event when calling `markAsPending`
|
|
||||||
* **animations:** When animation is trigged within a disabled zone, the
|
|
||||||
associated event (which an instance of AnimationEvent) will no longer
|
|
||||||
report the totalTime as 0 (it will emit the actual time of the
|
|
||||||
animation). To detect if an animation event is reporting a disabled
|
|
||||||
animation then the `event.disabled` property can be used instead.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.2.7"></a>
|
<a name="5.2.7"></a>
|
||||||
## [5.2.7](https://github.com/angular/angular/compare/5.2.6...5.2.7) (2018-02-28)
|
## [5.2.7](https://github.com/angular/angular/compare/5.2.6...5.2.7) (2018-02-28)
|
||||||
@ -361,72 +410,7 @@ animation then the `event.disabled` property can be used instead.
|
|||||||
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
|
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
|
||||||
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
||||||
|
|
||||||
<a name="6.0.0-beta.5"></a>
|
|
||||||
# [6.0.0-beta.5](https://github.com/angular/angular/compare/6.0.0-beta.4...6.0.0-beta.5) (2018-02-22)
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **animations:** report correct totalTime value even during noOp animations ([#22225](https://github.com/angular/angular/issues/22225)) ([e1bf067](https://github.com/angular/angular/commit/e1bf067))
|
|
||||||
* **common:** correct mapping of Observable methods ([#20518](https://github.com/angular/angular/issues/20518)) ([2639b4b](https://github.com/angular/angular/commit/2639b4b)), closes [#20516](https://github.com/angular/angular/issues/20516)
|
|
||||||
* **common:** then and else template might be set to null ([#22298](https://github.com/angular/angular/issues/22298)) ([8115edc](https://github.com/angular/angular/commit/8115edc))
|
|
||||||
* **compiler-cli:** add missing entry point to package, update tsickle ([#22295](https://github.com/angular/angular/issues/22295)) ([28ac244](https://github.com/angular/angular/commit/28ac244))
|
|
||||||
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([a7ebf5a](https://github.com/angular/angular/commit/a7ebf5a)), closes [#19978](https://github.com/angular/angular/issues/19978)
|
|
||||||
* **core:** require factory to be provided for shakeable InjectionToken ([#22207](https://github.com/angular/angular/issues/22207)) ([f755db7](https://github.com/angular/angular/commit/f755db7)), closes [#22205](https://github.com/angular/angular/issues/22205)
|
|
||||||
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([3e6a86f](https://github.com/angular/angular/commit/3e6a86f)), closes [#21513](https://github.com/angular/angular/issues/21513)
|
|
||||||
* **core:** set `preserveWhitespaces` to false by default ([#22046](https://github.com/angular/angular/issues/22046)) ([f1a0632](https://github.com/angular/angular/commit/f1a0632)), closes [#22027](https://github.com/angular/angular/issues/22027)
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **common:** better error message when non-template element used in NgIf ([#22274](https://github.com/angular/angular/issues/22274)) ([67cf11d](https://github.com/angular/angular/commit/67cf11d)), closes [#16410](https://github.com/angular/angular/issues/16410)
|
|
||||||
* **compiler-cli:** Check unvalidated combination of ngc and TypeScript ([#22293](https://github.com/angular/angular/issues/22293)) ([3ceee99](https://github.com/angular/angular/commit/3ceee99)), closes [#20669](https://github.com/angular/angular/issues/20669)
|
|
||||||
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([5c89d6b](https://github.com/angular/angular/commit/5c89d6b)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
|
||||||
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
|
|
||||||
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* **animations:** When animation is triggered within a disabled zone, the
|
|
||||||
associated event (which an instance of AnimationEvent) will no longer
|
|
||||||
report the totalTime as 0 (it will emit the actual time of the
|
|
||||||
animation). To detect if an animation event is reporting a disabled
|
|
||||||
animation then the `event.disabled` property can be used instead.
|
|
||||||
|
|
||||||
* **forms:** ngModelChange is now emitted after the value/validity is updated on its control.
|
|
||||||
|
|
||||||
Previously, ngModelChange was emitted before its underlying control was updated.
|
|
||||||
This was fine if you passed through the value directly through the $event keyword, e.g.
|
|
||||||
|
|
||||||
```
|
|
||||||
<input [(ngModel)]="name" (ngModelChange)="onChange($event)">
|
|
||||||
|
|
||||||
onChange(value) {
|
|
||||||
console.log(value); // would log updated value
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
However, if you had a handler for the ngModelChange event that checked the value through the control,
|
|
||||||
you would get the old value rather than the updated value. e.g:
|
|
||||||
|
|
||||||
```
|
|
||||||
<input #modelDir="ngModel" [(ngModel)]="name" (ngModelChange)="onChange(modelDir)">
|
|
||||||
|
|
||||||
onChange(ngModel: NgModel) {
|
|
||||||
console.log(ngModel.value); // would log old value, not updated value
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now the value and validity will be updated before the ngModelChange event is emitted,
|
|
||||||
so the same setup will log the updated value.
|
|
||||||
|
|
||||||
```
|
|
||||||
onChange(ngModel: NgModel) {
|
|
||||||
console.log(ngModel.value); // will log updated value
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
We think this order will be less confusing when the control is checked directly.
|
|
||||||
You will only need to update your app if it has relied on this bug to keep track of the old control value.
|
|
||||||
If that is the case, you should be able to track the old value directly by saving it on your component.
|
|
||||||
|
|
||||||
<a name="5.2.6"></a>
|
<a name="5.2.6"></a>
|
||||||
## [5.2.6](https://github.com/angular/angular/compare/5.2.5...5.2.6) (2018-02-22)
|
## [5.2.6](https://github.com/angular/angular/compare/5.2.5...5.2.6) (2018-02-22)
|
||||||
@ -439,34 +423,7 @@ If that is the case, you should be able to track the old value directly by savin
|
|||||||
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([5ec38f2](https://github.com/angular/angular/commit/5ec38f2)), closes [#19978](https://github.com/angular/angular/issues/19978)
|
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([5ec38f2](https://github.com/angular/angular/commit/5ec38f2)), closes [#19978](https://github.com/angular/angular/issues/19978)
|
||||||
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([ee91de9](https://github.com/angular/angular/commit/ee91de9)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([ee91de9](https://github.com/angular/angular/commit/ee91de9)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
||||||
|
|
||||||
<a name="6.0.0-beta.4"></a>
|
|
||||||
# [6.0.0-beta.4](https://github.com/angular/angular/compare/6.0.0-beta.3...6.0.0-beta.4) (2018-02-14)
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bazel:** allow TS to read ambient typings ([#21876](https://github.com/angular/angular/issues/21876)) ([b081dfe](https://github.com/angular/angular/commit/b081dfe)), closes [#21872](https://github.com/angular/angular/issues/21872)
|
|
||||||
* **bazel:** improve error message for missing assets ([#22096](https://github.com/angular/angular/issues/22096)) ([dcf64a0](https://github.com/angular/angular/commit/dcf64a0)), closes [#22095](https://github.com/angular/angular/issues/22095)
|
|
||||||
* **common:** add locale currency values ([#21783](https://github.com/angular/angular/issues/21783)) ([420cc7a](https://github.com/angular/angular/commit/420cc7a)), closes [#20385](https://github.com/angular/angular/issues/20385)
|
|
||||||
* **common:** round currencies based on decimal digits in `CurrencyPipe` ([#21783](https://github.com/angular/angular/issues/21783)) ([44154e7](https://github.com/angular/angular/commit/44154e7)), closes [#10189](https://github.com/angular/angular/issues/10189)
|
|
||||||
* **common:** weaken AsyncPipe transform signature ([#22169](https://github.com/angular/angular/issues/22169)) ([be59c3a](https://github.com/angular/angular/commit/be59c3a))
|
|
||||||
* **compiler:** make unary plus operator consistent to JavaScript ([#22154](https://github.com/angular/angular/issues/22154)) ([72f8abd](https://github.com/angular/angular/commit/72f8abd)), closes [#22089](https://github.com/angular/angular/issues/22089)
|
|
||||||
* **core:** add stacktrace in log when error during cleanup component in TestBed ([#22162](https://github.com/angular/angular/issues/22162)) ([16d1700](https://github.com/angular/angular/commit/16d1700))
|
|
||||||
* **core:** ensure initial value of QueryList length ([#21980](https://github.com/angular/angular/issues/21980)) ([#21982](https://github.com/angular/angular/issues/21982)) ([e56de10](https://github.com/angular/angular/commit/e56de10)), closes [#21980](https://github.com/angular/angular/issues/21980)
|
|
||||||
* **core:** use appropriate inert document strategy for Firefox & Safari ([#17019](https://github.com/angular/angular/issues/17019)) ([a751649](https://github.com/angular/angular/commit/a751649))
|
|
||||||
* **forms:** make Validators.email support optional controls ([#20869](https://github.com/angular/angular/issues/20869)) ([140e7c0](https://github.com/angular/angular/commit/140e7c0))
|
|
||||||
* **forms:** prevent event emission on enable/disable when emitEvent is false ([#12366](https://github.com/angular/angular/issues/12366)) ([#21018](https://github.com/angular/angular/issues/21018)) ([0bcfae7](https://github.com/angular/angular/commit/0bcfae7))
|
|
||||||
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([9744a1c](https://github.com/angular/angular/commit/9744a1c)), closes [#21513](https://github.com/angular/angular/issues/21513)
|
|
||||||
* **language-service:** correct instructions to install the language service ([#22000](https://github.com/angular/angular/issues/22000)) ([b37cee3](https://github.com/angular/angular/commit/b37cee3))
|
|
||||||
* **platform-browser:** add @Injectable where it was missing ([#22005](https://github.com/angular/angular/issues/22005)) ([0a1a397](https://github.com/angular/angular/commit/0a1a397))
|
|
||||||
* **platform-browser:** support 0/false/null values in transfer_state ([#22179](https://github.com/angular/angular/issues/22179)) ([6435ecd](https://github.com/angular/angular/commit/6435ecd))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **bazel:** allow explicit specification of factories ([#22003](https://github.com/angular/angular/issues/22003)) ([e442881](https://github.com/angular/angular/commit/e442881))
|
|
||||||
* **compiler:** mark @NgModules in provider lists for identification at runtime ([#22005](https://github.com/angular/angular/issues/22005)) ([2d5e7d1](https://github.com/angular/angular/commit/2d5e7d1))
|
|
||||||
* **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665)
|
|
||||||
* change @Injectable() to support tree-shakeable tokens ([#22005](https://github.com/angular/angular/issues/22005)) ([235a235](https://github.com/angular/angular/commit/235a235))
|
|
||||||
|
|
||||||
<a name="5.2.5"></a>
|
<a name="5.2.5"></a>
|
||||||
## [5.2.5](https://github.com/angular/angular/compare/5.2.4...5.2.5) (2018-02-14)
|
## [5.2.5](https://github.com/angular/angular/compare/5.2.4...5.2.5) (2018-02-14)
|
||||||
@ -485,34 +442,6 @@ If that is the case, you should be able to track the old value directly by savin
|
|||||||
* **language-service:** correct instructions to install the language service ([#22000](https://github.com/angular/angular/issues/22000)) ([0b23573](https://github.com/angular/angular/commit/0b23573))
|
* **language-service:** correct instructions to install the language service ([#22000](https://github.com/angular/angular/issues/22000)) ([0b23573](https://github.com/angular/angular/commit/0b23573))
|
||||||
* **platform-browser:** support 0/false/null values in transfer_state ([#22179](https://github.com/angular/angular/issues/22179)) ([da6ab91](https://github.com/angular/angular/commit/da6ab91))
|
* **platform-browser:** support 0/false/null values in transfer_state ([#22179](https://github.com/angular/angular/issues/22179)) ([da6ab91](https://github.com/angular/angular/commit/da6ab91))
|
||||||
|
|
||||||
<a name="6.0.0-beta.3"></a>
|
|
||||||
# [6.0.0-beta.3](https://github.com/angular/angular/compare/6.0.0-beta.2...6.0.0-beta.3) (2018-02-07)
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **common:** don't convert null to a string when flushing a mock request ([#21417](https://github.com/angular/angular/issues/21417)) ([8b14488](https://github.com/angular/angular/commit/8b14488)), closes [#20744](https://github.com/angular/angular/issues/20744)
|
|
||||||
* **core:** fix [#20582](https://github.com/angular/angular/issues/20582), don't need to wrap zone in location change listener ([#20640](https://github.com/angular/angular/issues/20640)) ([f791e9f](https://github.com/angular/angular/commit/f791e9f))
|
|
||||||
* **core:** fix proper propagation of subscriptions in EventEmitter ([#22016](https://github.com/angular/angular/issues/22016)) ([e81606c](https://github.com/angular/angular/commit/e81606c)), closes [#21999](https://github.com/angular/angular/issues/21999)
|
|
||||||
* **core:** should check Zone existence when scheduleMicroTask ([#20656](https://github.com/angular/angular/issues/20656)) ([3a86940](https://github.com/angular/angular/commit/3a86940))
|
|
||||||
* **forms:** publish missing types ([#19941](https://github.com/angular/angular/issues/19941)) ([2707012](https://github.com/angular/angular/commit/2707012))
|
|
||||||
* **ivy:** generate correct interpolations ([#21946](https://github.com/angular/angular/issues/21946)) ([3cc1d76](https://github.com/angular/angular/commit/3cc1d76))
|
|
||||||
* **ivy:** generate lifecycle pattern ([#21865](https://github.com/angular/angular/issues/21865)) ([f816666](https://github.com/angular/angular/commit/f816666))
|
|
||||||
* **ivy:** improve `bindV` perf and memory usage ([#21881](https://github.com/angular/angular/issues/21881)) ([0846784](https://github.com/angular/angular/commit/0846784))
|
|
||||||
* **ivy:** remove unnecessary parameter of NgOnChangesFeature ([#21879](https://github.com/angular/angular/issues/21879)) ([65cf1ad](https://github.com/angular/angular/commit/65cf1ad))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **compiler-cli:** reflect static methods added to classes in metadata ([#21926](https://github.com/angular/angular/issues/21926)) ([eb8ddd2](https://github.com/angular/angular/commit/eb8ddd2))
|
|
||||||
* **ivy:** add canonical example of a pipe. ([#21834](https://github.com/angular/angular/issues/21834)) ([743d8bc](https://github.com/angular/angular/commit/743d8bc))
|
|
||||||
* **ivy:** add support for attributes on ng-content nodes ([#21935](https://github.com/angular/angular/issues/21935)) ([1aa2947](https://github.com/angular/angular/commit/1aa2947))
|
|
||||||
* **ivy:** memoize array literals in render3 ([#21973](https://github.com/angular/angular/issues/21973)) ([4d62be6](https://github.com/angular/angular/commit/4d62be6))
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
|
|
||||||
* **ivy:** improve Uglify configuration in hello world integration test ([#21985](https://github.com/angular/angular/issues/21985)) ([7e51e52](https://github.com/angular/angular/commit/7e51e52))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.2.4"></a>
|
<a name="5.2.4"></a>
|
||||||
@ -528,17 +457,6 @@ If that is the case, you should be able to track the old value directly by savin
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-beta.2"></a>
|
|
||||||
# [6.0.0-beta.2](https://github.com/angular/angular/compare/6.0.0-beta.1...6.0.0-beta.2) (2018-01-31)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **router:** add navigationSource and restoredState to NavigationStart event ([#21728](https://github.com/angular/angular/issues/21728)) ([c40ae7f](https://github.com/angular/angular/commit/c40ae7f))
|
|
||||||
* **service-worker:** add helper script which will uninstall SW ([#21863](https://github.com/angular/angular/issues/21863)) ([b10540a](https://github.com/angular/angular/commit/b10540a))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.2.3"></a>
|
<a name="5.2.3"></a>
|
||||||
## [5.2.3](https://github.com/angular/angular/compare/5.2.2...5.2.3) (2018-01-31)
|
## [5.2.3](https://github.com/angular/angular/compare/5.2.2...5.2.3) (2018-01-31)
|
||||||
|
|
||||||
@ -556,32 +474,6 @@ If that is the case, you should be able to track the old value directly by savin
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-beta.1"></a>
|
|
||||||
# [6.0.0-beta.1](https://github.com/angular/angular/compare/6.0.0-beta.0...6.0.0-beta.1) (2018-01-25)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **common:** A null value should remove the style on IE ([#21679](https://github.com/angular/angular/issues/21679)) ([7d49443](https://github.com/angular/angular/commit/7d49443)), closes [#21064](https://github.com/angular/angular/issues/21064)
|
|
||||||
* avoid triggering a cli bug ([#21611](https://github.com/angular/angular/issues/21611)) ([0eabd07](https://github.com/angular/angular/commit/0eabd07))
|
|
||||||
* **common:** don't remove special characters when extracting CLDR data ([#21626](https://github.com/angular/angular/issues/21626)) ([135a282](https://github.com/angular/angular/commit/135a282))
|
|
||||||
* **common:** extract plural function from i18n locale data files for TS 2.6 ([#21626](https://github.com/angular/angular/issues/21626)) ([97b18b2](https://github.com/angular/angular/commit/97b18b2)), closes [#21608](https://github.com/angular/angular/issues/21608)
|
|
||||||
* **common:** fallback to last defined value for named date and time formats ([#21299](https://github.com/angular/angular/issues/21299)) ([879756d](https://github.com/angular/angular/commit/879756d)), closes [#21282](https://github.com/angular/angular/issues/21282)
|
|
||||||
* **compiler:** add support for marker tags in xliff serializers ([#21250](https://github.com/angular/angular/issues/21250)) ([f74130c](https://github.com/angular/angular/commit/f74130c)), closes [#21078](https://github.com/angular/angular/issues/21078)
|
|
||||||
* **compiler:** Don't strip `/*# sourceURL ... */` ([#16088](https://github.com/angular/angular/issues/16088)) ([5f681f9](https://github.com/angular/angular/commit/5f681f9))
|
|
||||||
* **compiler:** fix ICU select messages to use male/female/other ([#21713](https://github.com/angular/angular/issues/21713)) ([cb5090c](https://github.com/angular/angular/commit/cb5090c))
|
|
||||||
* **compiler-cli:** do not fold errors past calls in the collector ([#21708](https://github.com/angular/angular/issues/21708)) ([dd86790](https://github.com/angular/angular/commit/dd86790))
|
|
||||||
* **compiler-cli:** do not lower expressions in non-modules ([#21649](https://github.com/angular/angular/issues/21649)) ([7f93aad](https://github.com/angular/angular/commit/7f93aad))
|
|
||||||
* **router:** don't use ParamsInheritanceStrategy in declarations ([#21574](https://github.com/angular/angular/issues/21574)) ([925e654](https://github.com/angular/angular/commit/925e654)), closes [#21456](https://github.com/angular/angular/issues/21456)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **compiler:** implement "enableIvy" compiler option ([#21427](https://github.com/angular/angular/issues/21427)) ([64d16de](https://github.com/angular/angular/commit/64d16de))
|
|
||||||
* **core:** optional generic type for ElementRef ([#20765](https://github.com/angular/angular/issues/20765)) ([d3d9aac](https://github.com/angular/angular/commit/d3d9aac)), closes [#13139](https://github.com/angular/angular/issues/13139)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.2.2"></a>
|
<a name="5.2.2"></a>
|
||||||
## [5.2.2](https://github.com/angular/angular/compare/5.2.1...5.2.2) (2018-01-25)
|
## [5.2.2](https://github.com/angular/angular/compare/5.2.1...5.2.2) (2018-01-25)
|
||||||
|
|
||||||
@ -601,36 +493,6 @@ If that is the case, you should be able to track the old value directly by savin
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="6.0.0-beta.0"></a>
|
|
||||||
# [6.0.0-beta.0](https://github.com/angular/angular/compare/5.2.0...6.0.0-beta.0) (2018-01-17)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **animations:** fix increment/decrement aliases example ([#18323](https://github.com/angular/angular/issues/18323)) ([d2aa8ac](https://github.com/angular/angular/commit/d2aa8ac))
|
|
||||||
* **benchpress:** should still support selenium_webdriver < 3.6.0 ([#21477](https://github.com/angular/angular/issues/21477)) ([9b84a32](https://github.com/angular/angular/commit/9b84a32))
|
|
||||||
* **common:** set correct timezone for ISO8601 dates in Safari ([#21506](https://github.com/angular/angular/issues/21506)) ([05208b8](https://github.com/angular/angular/commit/05208b8)), closes [#21491](https://github.com/angular/angular/issues/21491)
|
|
||||||
* **compiler:** cache external reference resolution ([#21359](https://github.com/angular/angular/issues/21359)) ([e3e2fc0](https://github.com/angular/angular/commit/e3e2fc0))
|
|
||||||
* **compiler:** make `.ngsummary.json` files idempotent ([#21448](https://github.com/angular/angular/issues/21448)) ([e64b1e9](https://github.com/angular/angular/commit/e64b1e9))
|
|
||||||
* **core:** fix chained http call ([#20924](https://github.com/angular/angular/issues/20924)) ([7e3f9a4](https://github.com/angular/angular/commit/7e3f9a4)), closes [#20921](https://github.com/angular/angular/issues/20921)
|
|
||||||
* **ivy:** Add workaround for AJD in google3 ([#21488](https://github.com/angular/angular/issues/21488)) ([6af3672](https://github.com/angular/angular/commit/6af3672))
|
|
||||||
* **language-service:** Clear caches when program changes ([#21337](https://github.com/angular/angular/issues/21337)) ([43e1520](https://github.com/angular/angular/commit/43e1520)), closes [#19405](https://github.com/angular/angular/issues/19405)
|
|
||||||
* **service-worker:** properly handle invalid hashes in all scenarios ([#21288](https://github.com/angular/angular/issues/21288)) ([3951098](https://github.com/angular/angular/commit/3951098))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **bazel:** allow ng_module rules to control whether type checking is enabled ([#21460](https://github.com/angular/angular/issues/21460)) ([cffa0fe](https://github.com/angular/angular/commit/cffa0fe))
|
|
||||||
* **core:** add binding name to content changed error ([#20352](https://github.com/angular/angular/issues/20352)) ([d3bf54b](https://github.com/angular/angular/commit/d3bf54b))
|
|
||||||
* **forms:** handle string with and without line boundary on pattern validator ([#19256](https://github.com/angular/angular/issues/19256)) ([54bf179](https://github.com/angular/angular/commit/54bf179))
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
|
|
||||||
* **ivy:** add missing dom element in render3_function tree benchmark ([#21476](https://github.com/angular/angular/issues/21476)) ([9b5a485](https://github.com/angular/angular/commit/9b5a485))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.2.1"></a>
|
<a name="5.2.1"></a>
|
||||||
## [5.2.1](https://github.com/angular/angular/compare/5.2.0...5.2.1) (2018-01-17)
|
## [5.2.1](https://github.com/angular/angular/compare/5.2.0...5.2.1) (2018-01-17)
|
||||||
|
|
||||||
|
@ -227,10 +227,15 @@ The following is the list of supported scopes:
|
|||||||
|
|
||||||
There are currently a few exceptions to the "use package name" rule:
|
There are currently a few exceptions to the "use package name" rule:
|
||||||
|
|
||||||
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
|
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g.
|
||||||
|
public path changes, package.json changes done to all packages, d.ts file/format changes, changes
|
||||||
|
to bundles, etc.
|
||||||
* **changelog**: used for updating the release notes in CHANGELOG.md
|
* **changelog**: used for updating the release notes in CHANGELOG.md
|
||||||
* **aio**: used for docs-app (angular.io) related changes within the /aio directory of the repo
|
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
|
||||||
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`)
|
repo
|
||||||
|
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
|
||||||
|
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
|
||||||
|
specific package (e.g. `docs: fix typo in tutorial`).
|
||||||
|
|
||||||
### Subject
|
### Subject
|
||||||
The subject contains a succinct description of the change:
|
The subject contains a succinct description of the change:
|
||||||
|
17
README.md
17
README.md
@ -5,10 +5,6 @@
|
|||||||
[](https://www.npmjs.com/@angular/core)
|
[](https://www.npmjs.com/@angular/core)
|
||||||
|
|
||||||
|
|
||||||
[](https://saucelabs.com/u/angular2-ci)
|
|
||||||
|
|
||||||
*Safari (7+), iOS (7+) and IE mobile (11) are tested on [BrowserStack][browserstack].*
|
|
||||||
|
|
||||||
# Angular
|
# Angular
|
||||||
|
|
||||||
Angular is a development platform for building mobile and desktop web applications using Typescript/JavaScript and other languages.
|
Angular is a development platform for building mobile and desktop web applications using Typescript/JavaScript and other languages.
|
||||||
@ -17,12 +13,19 @@ Angular is a development platform for building mobile and desktop web applicatio
|
|||||||
|
|
||||||
[Get started in 5 minutes][quickstart].
|
[Get started in 5 minutes][quickstart].
|
||||||
|
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
[Learn about the latest improvements][changelog].
|
||||||
|
|
||||||
|
|
||||||
## Want to help?
|
## Want to help?
|
||||||
|
|
||||||
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
|
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
|
||||||
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
|
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
|
||||||
|
|
||||||
[browserstack]: https://www.browserstack.com/automate/public-build/LzF3RzBVVGt6VWE2S0hHaC9uYllOZz09LS1BVjNTclBKV0x4eVRlcjA4QVY1M0N3PT0=--eb4ce8c8dc2c1c5b2b5352d473ee12a73ac20e06
|
[browserstack]: https://www.browserstack.com/automate/public-build/LzF3RzBVVGt6VWE2S0hHaC9uYllOZz09LS1BVjNTclBKV0x4eVRlcjA4QVY1M0N3PT0=--eb4ce8c8dc2c1c5b2b5352d473ee12a73ac20e06
|
||||||
[contributing]: http://github.com/angular/angular/blob/master/CONTRIBUTING.md
|
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md
|
||||||
[quickstart]: https://angular.io/docs/ts/latest/quickstart.html
|
[quickstart]: https://angular.io/guide/quickstart
|
||||||
[ng]: http://angular.io
|
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
|
||||||
|
[ng]: https://angular.io
|
||||||
|
144
WORKSPACE
144
WORKSPACE
@ -1,56 +1,28 @@
|
|||||||
workspace(name = "angular")
|
workspace(name = "angular")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Download Bazel toolchain dependencies as needed by build actions
|
||||||
|
#
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "build_bazel_rules_nodejs",
|
name = "build_bazel_rules_nodejs",
|
||||||
url = "https://github.com/bazelbuild/rules_nodejs/archive/1931156c232a08356dfda02e9c8b0275c2e63c00.zip",
|
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.10.1.zip",
|
||||||
strip_prefix = "rules_nodejs-1931156c232a08356dfda02e9c8b0275c2e63c00",
|
strip_prefix = "rules_nodejs-0.10.1",
|
||||||
sha256 = "9cfe33276a6ac0076ee9ee159c4a2576f9851c0f437435b5ac19b2e592493078",
|
sha256 = "634206524d90dc03c52392fa3f19a16637d2bcf154910436fe1d669a0d9d7b9c",
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
http_archive(
|
||||||
|
name = "io_bazel_rules_webtesting",
|
||||||
check_bazel_version("0.11.1")
|
url = "https://github.com/bazelbuild/rules_webtesting/archive/v0.2.0.zip",
|
||||||
node_repositories(package_json = ["//:package.json"])
|
strip_prefix = "rules_webtesting-0.2.0",
|
||||||
|
sha256 = "cecc12f07e95740750a40d38e8b14b76fefa1551bef9332cb432d564d693723c",
|
||||||
yarn_install(
|
|
||||||
name = "ts-api-guardian_runtime_deps",
|
|
||||||
package_json = "//tools/ts-api-guardian:package.json",
|
|
||||||
yarn_lock = "//tools/ts-api-guardian:yarn.lock",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "build_bazel_rules_typescript",
|
name = "build_bazel_rules_typescript",
|
||||||
url = "https://github.com/bazelbuild/rules_typescript/archive/0.12.1.zip",
|
url = "https://github.com/bazelbuild/rules_typescript/archive/0.15.3.zip",
|
||||||
strip_prefix = "rules_typescript-0.12.1",
|
strip_prefix = "rules_typescript-0.15.3",
|
||||||
sha256 = "24e2c36f60508c6d270ae4265b89b381e3f66d550e70c367ed3755ad8d7ce3b0",
|
sha256 = "a2b26ac3fc13036011196063db1bf7f1eae81334449201dc28087ebfa3708c99",
|
||||||
)
|
|
||||||
|
|
||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
|
|
||||||
|
|
||||||
ts_setup_workspace()
|
|
||||||
|
|
||||||
local_repository(
|
|
||||||
name = "rxjs",
|
|
||||||
path = "node_modules/rxjs/src",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Point to the integration test workspace just so that Bazel doesn't descend into it
|
|
||||||
# when expanding the //... pattern
|
|
||||||
local_repository(
|
|
||||||
name = "bazel_integration_test",
|
|
||||||
path = "integration/bazel",
|
|
||||||
)
|
|
||||||
|
|
||||||
# This commit matches the version of buildifier in angular/ngcontainer
|
|
||||||
# If you change this, also check if it matches the version in the angular/ngcontainer
|
|
||||||
# version in /.circleci/config.yml
|
|
||||||
BAZEL_BUILDTOOLS_VERSION = "70bc7843bb9950fece2bc014ed16de03419e36e2"
|
|
||||||
|
|
||||||
http_archive(
|
|
||||||
name = "com_github_bazelbuild_buildtools",
|
|
||||||
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
|
|
||||||
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
|
|
||||||
sha256 = "367c23a5fe7fc2a7cb57863d3718b4149f0e57426c48c8ad54c45348a0b53cc1",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
@ -59,18 +31,24 @@ http_archive(
|
|||||||
sha256 = "feba3278c13cde8d67e341a837f69a029f698d7a27ddbb2a202be7a10b22142a",
|
sha256 = "feba3278c13cde8d67e341a837f69a029f698d7a27ddbb2a202be7a10b22142a",
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
# This commit matches the version of buildifier in angular/ngcontainer
|
||||||
|
# If you change this, also check if it matches the version in the angular/ngcontainer
|
||||||
|
# version in /.circleci/config.yml
|
||||||
|
BAZEL_BUILDTOOLS_VERSION = "82b21607e00913b16fe1c51bec80232d9d6de31c"
|
||||||
|
|
||||||
go_rules_dependencies()
|
http_archive(
|
||||||
|
name = "com_github_bazelbuild_buildtools",
|
||||||
go_register_toolchains()
|
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
|
||||||
|
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
|
||||||
|
sha256 = "edb24c2f9c55b10a820ec74db0564415c0cf553fa55e9fc709a6332fb6685eff",
|
||||||
|
)
|
||||||
|
|
||||||
# Fetching the Bazel source code allows us to compile the Skylark linter
|
# Fetching the Bazel source code allows us to compile the Skylark linter
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "io_bazel",
|
name = "io_bazel",
|
||||||
url = "https://github.com/bazelbuild/bazel/archive/5a35e72f9e97c06540c479f8c31512fb4656202f.zip",
|
url = "https://github.com/bazelbuild/bazel/archive/968f87900dce45a7af749a965b72dbac51b176b3.zip",
|
||||||
strip_prefix = "bazel-5a35e72f9e97c06540c479f8c31512fb4656202f",
|
strip_prefix = "bazel-968f87900dce45a7af749a965b72dbac51b176b3",
|
||||||
sha256 = "ed33a52874c14e3b487fb50f390c541fab9c81a33d986d38fb01766a66dbcd21",
|
sha256 = "e373d2ae24955c1254c495c9c421c009d88966565c35e4e8444c082cb1f0f48f",
|
||||||
)
|
)
|
||||||
|
|
||||||
# We have a source dependency on the Devkit repository, because it's built with
|
# We have a source dependency on the Devkit repository, because it's built with
|
||||||
@ -88,7 +66,67 @@ http_archive(
|
|||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "org_brotli",
|
name = "org_brotli",
|
||||||
url = "https://github.com/google/brotli/archive/c6333e1e79fb62ea088443f192293f964409b04e.zip",
|
url = "https://github.com/google/brotli/archive/f9b8c02673c576a3e807edbf3a9328e9e7af6d7c.zip",
|
||||||
strip_prefix = "brotli-c6333e1e79fb62ea088443f192293f964409b04e",
|
strip_prefix = "brotli-f9b8c02673c576a3e807edbf3a9328e9e7af6d7c",
|
||||||
sha256 = "3f781988dee7dd3bcce2bf238294663cfaaf3b6433505bdb762e24d0a284d1dc",
|
sha256 = "8a517806d2b7c8505ba5c53934e7d7c70d341b68ffd268e9044d35b564a48828",
|
||||||
|
)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Load and install our dependencies downloaded above.
|
||||||
|
#
|
||||||
|
|
||||||
|
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
||||||
|
|
||||||
|
check_bazel_version("0.15.0")
|
||||||
|
node_repositories(package_json = ["//:package.json"])
|
||||||
|
|
||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||||
|
|
||||||
|
go_rules_dependencies()
|
||||||
|
go_register_toolchains()
|
||||||
|
|
||||||
|
load("@io_bazel_rules_webtesting//web:repositories.bzl", "browser_repositories", "web_test_repositories")
|
||||||
|
|
||||||
|
web_test_repositories()
|
||||||
|
browser_repositories(
|
||||||
|
chromium = True,
|
||||||
|
firefox = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
|
||||||
|
|
||||||
|
ts_setup_workspace()
|
||||||
|
|
||||||
|
#
|
||||||
|
# Point Bazel to WORKSPACEs that live in subdirectories
|
||||||
|
#
|
||||||
|
|
||||||
|
local_repository(
|
||||||
|
name = "rxjs",
|
||||||
|
path = "node_modules/rxjs/src",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Point to the integration test workspace just so that Bazel doesn't descend into it
|
||||||
|
# when expanding the //... pattern
|
||||||
|
local_repository(
|
||||||
|
name = "bazel_integration_test",
|
||||||
|
path = "integration/bazel",
|
||||||
|
)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ask Bazel to manage these toolchain dependencies for us.
|
||||||
|
# Bazel will run `yarn install` when one of these toolchains is requested during
|
||||||
|
# a build.
|
||||||
|
#
|
||||||
|
|
||||||
|
yarn_install(
|
||||||
|
name = "ts-api-guardian_runtime_deps",
|
||||||
|
package_json = "//tools/ts-api-guardian:package.json",
|
||||||
|
yarn_lock = "//tools/ts-api-guardian:yarn.lock",
|
||||||
|
)
|
||||||
|
|
||||||
|
yarn_install(
|
||||||
|
name = "http-server_runtime_deps",
|
||||||
|
package_json = "//tools/http-server:package.json",
|
||||||
|
yarn_lock = "//tools/http-server:yarn.lock",
|
||||||
)
|
)
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
||||||
"project": {
|
|
||||||
"name": "site"
|
|
||||||
},
|
|
||||||
"apps": [
|
|
||||||
{
|
|
||||||
"root": "src",
|
|
||||||
"outDir": "dist",
|
|
||||||
"assets": [
|
|
||||||
"assets",
|
|
||||||
"generated",
|
|
||||||
"app/search/search-worker.js",
|
|
||||||
"favicon.ico",
|
|
||||||
"pwa-manifest.json",
|
|
||||||
"google385281288605d160.html",
|
|
||||||
{ "glob": "custom-elements.min.js", "input": "../node_modules/@webcomponents/custom-elements", "output": "./assets/js" },
|
|
||||||
{ "glob": "native-shim.js", "input": "../node_modules/@webcomponents/custom-elements/src", "output": "./assets/js" }
|
|
||||||
],
|
|
||||||
"index": "index.html",
|
|
||||||
"main": "main.ts",
|
|
||||||
"polyfills": "polyfills.ts",
|
|
||||||
"test": "test.ts",
|
|
||||||
"tsconfig": "tsconfig.app.json",
|
|
||||||
"testTsconfig": "tsconfig.spec.json",
|
|
||||||
"prefix": "aio",
|
|
||||||
"serviceWorker": false,
|
|
||||||
"styles": [
|
|
||||||
"styles.scss"
|
|
||||||
],
|
|
||||||
"scripts": [
|
|
||||||
],
|
|
||||||
"environmentSource": "environments/environment.ts",
|
|
||||||
"environments": {
|
|
||||||
"dev": "environments/environment.ts",
|
|
||||||
"next": "environments/environment.next.ts",
|
|
||||||
"stable": "environments/environment.stable.ts",
|
|
||||||
"archive": "environments/environment.archive.ts"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"e2e": {
|
|
||||||
"protractor": {
|
|
||||||
"config": "tests/e2e/protractor.conf.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": [
|
|
||||||
{
|
|
||||||
"project": "src/tsconfig.app.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"project": "src/tsconfig.spec.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"project": "tests/e2e/tsconfig.e2e.json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"test": {
|
|
||||||
"karma": {
|
|
||||||
"config": "src/karma.conf.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaults": {
|
|
||||||
"styleExt": "scss",
|
|
||||||
"component": {
|
|
||||||
"inlineStyle": true
|
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"namedChunks": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packageManager": "yarn"
|
|
||||||
}
|
|
@ -22,7 +22,8 @@ Here are the most important tasks you might need to use:
|
|||||||
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.
|
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.
|
||||||
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console.
|
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console.
|
||||||
* `yarn lint` - check that the doc-viewer code follows our style rules.
|
* `yarn lint` - check that the doc-viewer code follows our style rules.
|
||||||
* `yarn test` - watch all the source files, for the doc-viewer, and run all the unit tests when any change.
|
* `yarn test` - run all the unit tests once.
|
||||||
|
* `yarn test --watch` - watch all the source files, for the doc-viewer, and run all the unit tests when any change.
|
||||||
* `yarn e2e` - run all the e2e tests for the doc-viewer.
|
* `yarn e2e` - run all the e2e tests for the doc-viewer.
|
||||||
|
|
||||||
* `yarn docs` - generate all the docs from the source files.
|
* `yarn docs` - generate all the docs from the source files.
|
||||||
|
@ -52,8 +52,7 @@ export class BuildCleaner {
|
|||||||
protected removeDir(dir: string) {
|
protected removeDir(dir: string) {
|
||||||
try {
|
try {
|
||||||
if (shell.test('-d', dir)) {
|
if (shell.test('-d', dir)) {
|
||||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
shell.chmod('-R', 'a+w', dir);
|
||||||
(shell as any).chmod('-R', 'a+w', dir);
|
|
||||||
shell.rm('-rf', dir);
|
shell.rm('-rf', dir);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -106,8 +106,7 @@ export class BuildCreator extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
shell.chmod('-R', 'a-w', outputDir);
|
||||||
(shell as any).chmod('-R', 'a-w', outputDir);
|
|
||||||
shell.rm('-f', inputFile);
|
shell.rm('-f', inputFile);
|
||||||
resolve();
|
resolve();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -98,8 +98,7 @@ class Helper {
|
|||||||
const prDir = this.getPrDir(pr, isPublic);
|
const prDir = this.getPrDir(pr, isPublic);
|
||||||
|
|
||||||
if (fs.existsSync(prDir)) {
|
if (fs.existsSync(prDir)) {
|
||||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
shell.chmod('-R', 'a+w', prDir);
|
||||||
(shell as any).chmod('-R', 'a+w', prDir);
|
|
||||||
shell.rm('-rf', prDir);
|
shell.rm('-rf', prDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "yarn clean-dist",
|
"prebuild": "yarn clean-dist",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"build-watch": "yarn tsc --watch",
|
"build-watch": "yarn build --watch",
|
||||||
"clean-dist": "node --eval \"require('shelljs').rm('-rf', 'dist')\"",
|
"clean-dist": "node --eval \"require('shelljs').rm('-rf', 'dist')\"",
|
||||||
"dev": "concurrently --kill-others --raw --success first \"yarn build-watch\" \"yarn test-watch\"",
|
"dev": "concurrently --kill-others --raw --success first \"yarn build-watch\" \"yarn test-watch\"",
|
||||||
"lint": "tslint --project tsconfig.json",
|
"lint": "tslint --project tsconfig.json",
|
||||||
@ -33,7 +33,7 @@
|
|||||||
"@types/jasmine": "^2.6.0",
|
"@types/jasmine": "^2.6.0",
|
||||||
"@types/jsonwebtoken": "^7.2.3",
|
"@types/jsonwebtoken": "^7.2.3",
|
||||||
"@types/node": "^8.0.30",
|
"@types/node": "^8.0.30",
|
||||||
"@types/shelljs": "^0.7.4",
|
"@types/shelljs": "^0.8.0",
|
||||||
"@types/supertest": "^2.0.3",
|
"@types/supertest": "^2.0.3",
|
||||||
"concurrently": "^3.5.0",
|
"concurrently": "^3.5.0",
|
||||||
"nodemon": "^1.12.1",
|
"nodemon": "^1.12.1",
|
||||||
|
@ -69,9 +69,9 @@
|
|||||||
"@types/express-serve-static-core" "*"
|
"@types/express-serve-static-core" "*"
|
||||||
"@types/mime" "*"
|
"@types/mime" "*"
|
||||||
|
|
||||||
"@types/shelljs@^0.7.4":
|
"@types/shelljs@^0.8.0":
|
||||||
version "0.7.4"
|
version "0.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.4.tgz#137b5f31306eaff4de120ffe5b9d74b297809cfc"
|
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.0.tgz#0caa56b68baae4f68f44e0dd666ab30b098e3632"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/glob" "*"
|
"@types/glob" "*"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
set -eux -o pipefail
|
set -eux -o pipefail
|
||||||
exec 3>&1
|
exec 3>&1
|
||||||
|
|
||||||
echo "\n\n[`date`] - Updating the preview server..."
|
echo -e "\n\n[`date`] - Updating the preview server..."
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
readonly HOST_REPO_DIR=$1
|
readonly HOST_REPO_DIR=$1
|
||||||
|
189
aio/angular.json
Normal file
189
aio/angular.json
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"cli": {
|
||||||
|
"packageManager": "yarn"
|
||||||
|
},
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"site": {
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"projectType": "application",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"main": "src/main.ts",
|
||||||
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
|
"aot": true,
|
||||||
|
"optimization": true,
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": true,
|
||||||
|
"statsJson": true,
|
||||||
|
"extractCss": true,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"namedChunks": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"assets": [
|
||||||
|
"src/assets",
|
||||||
|
"src/generated",
|
||||||
|
"src/app/search/search-worker.js",
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/pwa-manifest.json",
|
||||||
|
"src/google385281288605d160.html",
|
||||||
|
{
|
||||||
|
"glob": "custom-elements.min.js",
|
||||||
|
"input": "node_modules/@webcomponents/custom-elements",
|
||||||
|
"output": "/assets/js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"glob": "native-shim.js",
|
||||||
|
"input": "node_modules/@webcomponents/custom-elements/src",
|
||||||
|
"output": "/assets/js"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"fast": {
|
||||||
|
"optimization": false
|
||||||
|
},
|
||||||
|
"next": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"src": "src/environments/environment.ts",
|
||||||
|
"replaceWith": "src/environments/environment.next.ts"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stable": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"src": "src/environments/environment.ts",
|
||||||
|
"replaceWith": "src/environments/environment.stable.ts"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"archive": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"src": "src/environments/environment.ts",
|
||||||
|
"replaceWith": "src/environments/environment.archive.ts"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "site:build"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"fast": {
|
||||||
|
"browserTarget": "site:build:fast"
|
||||||
|
},
|
||||||
|
"next": {
|
||||||
|
"browserTarget": "site:build:next"
|
||||||
|
},
|
||||||
|
"stable": {
|
||||||
|
"browserTarget": "site:build:stable"
|
||||||
|
},
|
||||||
|
"archive": {
|
||||||
|
"browserTarget": "site:build:archive"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "site:build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "src/test.ts",
|
||||||
|
"karmaConfig": "src/karma.conf.js",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
|
"scripts": [],
|
||||||
|
"styles": [
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"assets": [
|
||||||
|
"src/assets",
|
||||||
|
"src/generated",
|
||||||
|
"src/app/search/search-worker.js",
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/pwa-manifest.json",
|
||||||
|
"src/google385281288605d160.html",
|
||||||
|
{
|
||||||
|
"glob": "custom-elements.min.js",
|
||||||
|
"input": "node_modules/@webcomponents/custom-elements",
|
||||||
|
"output": "/assets/js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"glob": "native-shim.js",
|
||||||
|
"input": "node_modules/@webcomponents/custom-elements/src",
|
||||||
|
"output": "/assets/js"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": [
|
||||||
|
"src/tsconfig.app.json",
|
||||||
|
"src/tsconfig.spec.json"
|
||||||
|
],
|
||||||
|
"exclude": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"site-e2e": {
|
||||||
|
"root": "",
|
||||||
|
"projectType": "application",
|
||||||
|
"cli": {},
|
||||||
|
"schematics": {},
|
||||||
|
"architect": {
|
||||||
|
"e2e": {
|
||||||
|
"builder": "@angular-devkit/build-angular:protractor",
|
||||||
|
"options": {
|
||||||
|
"protractorConfig": "tests/e2e/protractor.conf.js",
|
||||||
|
"devServerTarget": "site:serve"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": [
|
||||||
|
"tests/e2e/tsconfig.e2e.json"
|
||||||
|
],
|
||||||
|
"exclude": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"inlineStyle": true,
|
||||||
|
"prefix": "aio",
|
||||||
|
"styleext": "scss"
|
||||||
|
},
|
||||||
|
"@schematics/angular:directive": {
|
||||||
|
"prefix": "aio"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
aio/content/examples/.DS_Store
vendored
BIN
aio/content/examples/.DS_Store
vendored
Binary file not shown.
8
aio/content/examples/.gitignore
vendored
8
aio/content/examples/.gitignore
vendored
@ -13,18 +13,20 @@
|
|||||||
**/src/tsconfig.app.json
|
**/src/tsconfig.app.json
|
||||||
**/src/tsconfig.spec.json
|
**/src/tsconfig.spec.json
|
||||||
**/src/typings.d.ts
|
**/src/typings.d.ts
|
||||||
**/e2e/app.po.ts
|
**/e2e/src/app.po.ts
|
||||||
**/e2e/tsconfig.e2e.json
|
**/e2e/tsconfig.e2e.json
|
||||||
|
**/src/karma.conf.js
|
||||||
**/.angular-cli.json
|
**/.angular-cli.json
|
||||||
**/.editorconfig
|
**/.editorconfig
|
||||||
|
**/angular.json
|
||||||
**/tsconfig.json
|
**/tsconfig.json
|
||||||
**/bs-config.e2e.json
|
**/bs-config.e2e.json
|
||||||
**/bs-config.json
|
**/bs-config.json
|
||||||
**/package.json
|
**/package.json
|
||||||
**/tslint.json
|
**/tslint.json
|
||||||
**/karma.conf.js
|
|
||||||
**/karma-test-shim.js
|
**/karma-test-shim.js
|
||||||
**/browser-test-shim.js
|
**/browser-test-shim.js
|
||||||
|
**/browserslist
|
||||||
**/node_modules
|
**/node_modules
|
||||||
|
|
||||||
# built files
|
# built files
|
||||||
@ -58,6 +60,8 @@ dist/
|
|||||||
!rollup-config.js
|
!rollup-config.js
|
||||||
aot-compiler/**/*.d.ts
|
aot-compiler/**/*.d.ts
|
||||||
aot-compiler/**/*.factory.d.ts
|
aot-compiler/**/*.factory.d.ts
|
||||||
|
upgrade-phonecat-2-hybrid/aot/**/*
|
||||||
|
!upgrade-phonecat-2-hybrid/aot/index.html
|
||||||
|
|
||||||
# i18n
|
# i18n
|
||||||
!i18n/src/systemjs-text-plugin.js
|
!i18n/src/systemjs-text-plugin.js
|
||||||
|
@ -40,5 +40,7 @@ export class HighlightDirective {
|
|||||||
// #docregion color-2
|
// #docregion color-2
|
||||||
@Input() appHighlight: string;
|
@Input() appHighlight: string;
|
||||||
// #enddocregion color-2
|
// #enddocregion color-2
|
||||||
}
|
|
||||||
|
|
||||||
|
// #docregion
|
||||||
|
}
|
||||||
|
// #enddocregion
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { HttpModule } from '@angular/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
// #docregion directive-import
|
// #docregion directive-import
|
||||||
@ -24,7 +24,7 @@ import { ItemDirective } from './item.directive';
|
|||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpModule
|
HttpClientModule
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
# MasterProject
|
|
||||||
|
|
||||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0-rc.0.
|
|
||||||
|
|
||||||
## Development server
|
|
||||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
|
||||||
|
|
||||||
## Code scaffolding
|
|
||||||
|
|
||||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.
|
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
|
|
||||||
|
|
||||||
## Running unit tests
|
|
||||||
|
|
||||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
||||||
|
|
||||||
## Running end-to-end tests
|
|
||||||
|
|
||||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
|
||||||
Before running the tests make sure you are serving the app via `ng serve`.
|
|
||||||
|
|
||||||
## Further help
|
|
||||||
|
|
||||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
|
@ -3,7 +3,7 @@
|
|||||||
"!**/*.d.ts",
|
"!**/*.d.ts",
|
||||||
"!**/*.js",
|
"!**/*.js",
|
||||||
"!**/*.[0-9].*",
|
"!**/*.[0-9].*",
|
||||||
".angular-cli.json",
|
"angular.json",
|
||||||
"protractor.conf.js"
|
"protractor.conf.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,18 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|||||||
selector: 'app-voter',
|
selector: 'app-voter',
|
||||||
template: `
|
template: `
|
||||||
<h4>{{name}}</h4>
|
<h4>{{name}}</h4>
|
||||||
<button (click)="vote(true)" [disabled]="voted">Agree</button>
|
<button (click)="vote(true)" [disabled]="didVote">Agree</button>
|
||||||
<button (click)="vote(false)" [disabled]="voted">Disagree</button>
|
<button (click)="vote(false)" [disabled]="didVote">Disagree</button>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
export class VoterComponent {
|
export class VoterComponent {
|
||||||
@Input() name: string;
|
@Input() name: string;
|
||||||
@Output() onVoted = new EventEmitter<boolean>();
|
@Output() voted = new EventEmitter<boolean>();
|
||||||
voted = false;
|
didVote = false;
|
||||||
|
|
||||||
vote(agreed: boolean) {
|
vote(agreed: boolean) {
|
||||||
this.onVoted.emit(agreed);
|
this.voted.emit(agreed);
|
||||||
this.voted = true;
|
this.didVote = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
@ -8,7 +8,7 @@ import { Component } from '@angular/core';
|
|||||||
<h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
|
<h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
|
||||||
<app-voter *ngFor="let voter of voters"
|
<app-voter *ngFor="let voter of voters"
|
||||||
[name]="voter"
|
[name]="voter"
|
||||||
(onVoted)="onVoted($event)">
|
(voted)="onVoted($event)">
|
||||||
</app-voter>
|
</app-voter>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { HttpModule } from '@angular/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
|
||||||
// import { AppRoutingModule } from './app-routing.module';
|
// import { AppRoutingModule } from './app-routing.module';
|
||||||
import { LocationStrategy,
|
import { LocationStrategy,
|
||||||
@ -54,7 +54,7 @@ const c_components = [
|
|||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpModule,
|
HttpClientModule,
|
||||||
InMemoryWebApiModule.forRoot(HeroData)
|
InMemoryWebApiModule.forRoot(HeroData)
|
||||||
// AppRoutingModule TODO: add routes
|
// AppRoutingModule TODO: add routes
|
||||||
],
|
],
|
||||||
|
@ -50,7 +50,7 @@ const templateC = `
|
|||||||
})
|
})
|
||||||
// #docregion carol-class
|
// #docregion carol-class
|
||||||
export class CarolComponent {
|
export class CarolComponent {
|
||||||
name= 'Carol';
|
name = 'Carol';
|
||||||
// #docregion carol-ctor
|
// #docregion carol-ctor
|
||||||
constructor( @Optional() public parent: Parent ) { }
|
constructor( @Optional() public parent: Parent ) { }
|
||||||
// #enddocregion carol-ctor
|
// #enddocregion carol-ctor
|
||||||
@ -63,7 +63,7 @@ export class CarolComponent {
|
|||||||
template: templateC
|
template: templateC
|
||||||
})
|
})
|
||||||
export class ChrisComponent {
|
export class ChrisComponent {
|
||||||
name= 'Chris';
|
name = 'Chris';
|
||||||
constructor( @Optional() public parent: Parent ) { }
|
constructor( @Optional() public parent: Parent ) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ export class BarryComponent implements Parent {
|
|||||||
providers: [ provideParent(BobComponent) ]
|
providers: [ provideParent(BobComponent) ]
|
||||||
})
|
})
|
||||||
export class BobComponent implements Parent {
|
export class BobComponent implements Parent {
|
||||||
name= 'Bob';
|
name = 'Bob';
|
||||||
constructor( @SkipSelf() @Optional() public parent: Parent ) { }
|
constructor( @SkipSelf() @Optional() public parent: Parent ) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ export class BobComponent implements Parent {
|
|||||||
// #enddocregion beth-providers
|
// #enddocregion beth-providers
|
||||||
})
|
})
|
||||||
export class BethComponent implements Parent {
|
export class BethComponent implements Parent {
|
||||||
name= 'Beth';
|
name = 'Beth';
|
||||||
constructor( @SkipSelf() @Optional() public parent: Parent ) { }
|
constructor( @SkipSelf() @Optional() public parent: Parent ) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ export class BethComponent implements Parent {
|
|||||||
export class AlexComponent extends Base
|
export class AlexComponent extends Base
|
||||||
// #enddocregion alex-class-signature
|
// #enddocregion alex-class-signature
|
||||||
{
|
{
|
||||||
name= 'Alex';
|
name = 'Alex';
|
||||||
}
|
}
|
||||||
// #enddocregion alex, alex-1
|
// #enddocregion alex, alex-1
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ export class AlexComponent extends Base
|
|||||||
export class AliceComponent implements Parent
|
export class AliceComponent implements Parent
|
||||||
// #enddocregion alice-class-signature
|
// #enddocregion alice-class-signature
|
||||||
{
|
{
|
||||||
name= 'Alice';
|
name = 'Alice';
|
||||||
}
|
}
|
||||||
// #enddocregion alice
|
// #enddocregion alice
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ describe('Dependency Injection Tests', function () {
|
|||||||
let heroes = element.all(by.css('#authorized app-hero-list div'));
|
let heroes = element.all(by.css('#authorized app-hero-list div'));
|
||||||
expect(heroes.count()).toBeGreaterThan(0);
|
expect(heroes.count()).toBeGreaterThan(0);
|
||||||
|
|
||||||
let filteredHeroes = heroes.filter(function(elem: ElementFinder, index: number){
|
let filteredHeroes = heroes.filter(function(elem: ElementFinder, index: number) {
|
||||||
return elem.getText().then(function(text: string) {
|
return elem.getText().then(function(text: string) {
|
||||||
return /secret/.test(text);
|
return /secret/.test(text);
|
||||||
});
|
});
|
@ -19,7 +19,7 @@ import { AdComponent } from './ad.component';
|
|||||||
// #docregion class
|
// #docregion class
|
||||||
export class AdBannerComponent implements OnInit, OnDestroy {
|
export class AdBannerComponent implements OnInit, OnDestroy {
|
||||||
@Input() ads: AdItem[];
|
@Input() ads: AdItem[];
|
||||||
currentAdIndex: number = -1;
|
currentAdIndex = -1;
|
||||||
@ViewChild(AdDirective) adHost: AdDirective;
|
@ViewChild(AdDirective) adHost: AdDirective;
|
||||||
interval: any;
|
interval: any;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ describe('Dynamic Form', function () {
|
|||||||
element(by.css('select option[value="solid"]')).click();
|
element(by.css('select option[value="solid"]')).click();
|
||||||
|
|
||||||
let saveButton = element.all(by.css('button')).get(0);
|
let saveButton = element.all(by.css('button')).get(0);
|
||||||
saveButton.click().then(function(){
|
saveButton.click().then(function() {
|
||||||
expect(element(by.xpath("//strong[contains(text(),'Saved the following values')]")).isPresent()).toBe(true);
|
expect(element(by.xpath("//strong[contains(text(),'Saved the following values')]")).isPresent()).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1,5 +1,5 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
export class QuestionBase<T>{
|
export class QuestionBase<T> {
|
||||||
value: T;
|
value: T;
|
||||||
key: string;
|
key: string;
|
||||||
label: string;
|
label: string;
|
||||||
|
69
aio/content/examples/elements/e2e/src/app.e2e-spec.ts
Normal file
69
aio/content/examples/elements/e2e/src/app.e2e-spec.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
|
import { browser, by, element } from 'protractor';
|
||||||
|
|
||||||
|
/* tslint:disable:quotemark */
|
||||||
|
describe('Elements', () => {
|
||||||
|
const messageInput = element(by.css('input'));
|
||||||
|
const popupButtons = element.all(by.css('button'));
|
||||||
|
|
||||||
|
beforeEach(() => browser.get(''));
|
||||||
|
|
||||||
|
describe('popup component', () => {
|
||||||
|
const popupComponentButton = popupButtons.get(0);
|
||||||
|
const popupComponent = element(by.css('popup-component'));
|
||||||
|
const closeButton = popupComponent.element(by.css('button'));
|
||||||
|
|
||||||
|
it('should be displayed on button click', () => {
|
||||||
|
expect(popupComponent.isPresent()).toBe(false);
|
||||||
|
|
||||||
|
popupComponentButton.click();
|
||||||
|
expect(popupComponent.isPresent()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display the specified message', () => {
|
||||||
|
messageInput.clear();
|
||||||
|
messageInput.sendKeys('Angular rocks!');
|
||||||
|
|
||||||
|
popupComponentButton.click();
|
||||||
|
expect(popupComponent.getText()).toContain('Popup: Angular rocks!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be closed on "close" button click', () => {
|
||||||
|
popupComponentButton.click();
|
||||||
|
expect(popupComponent.isPresent()).toBe(true);
|
||||||
|
|
||||||
|
closeButton.click();
|
||||||
|
expect(popupComponent.isPresent()).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('popup element', () => {
|
||||||
|
const popupElementButton = popupButtons.get(1);
|
||||||
|
const popupElement = element(by.css('popup-element'));
|
||||||
|
const closeButton = popupElement.element(by.css('button'));
|
||||||
|
|
||||||
|
it('should be displayed on button click', () => {
|
||||||
|
expect(popupElement.isPresent()).toBe(false);
|
||||||
|
|
||||||
|
popupElementButton.click();
|
||||||
|
expect(popupElement.isPresent()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display the specified message', () => {
|
||||||
|
messageInput.clear();
|
||||||
|
messageInput.sendKeys('Angular rocks!');
|
||||||
|
|
||||||
|
popupElementButton.click();
|
||||||
|
expect(popupElement.getText()).toContain('Popup: Angular rocks!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be closed on "close" button click', () => {
|
||||||
|
popupElementButton.click();
|
||||||
|
expect(popupElement.isPresent()).toBe(true);
|
||||||
|
|
||||||
|
closeButton.click();
|
||||||
|
expect(popupElement.isPresent()).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
3
aio/content/examples/elements/example-config.json
Normal file
3
aio/content/examples/elements/example-config.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"projectType": "elements"
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
// #docregion
|
|
||||||
import { Component, Injector } from '@angular/core';
|
import { Component, Injector } from '@angular/core';
|
||||||
import { createNgElementConstructor } from '../elements-dist';
|
import { createCustomElement } from '@angular/elements';
|
||||||
import { PopupService } from './popup.service';
|
import { PopupService } from './popup.service';
|
||||||
import { PopupComponent } from './popup.component';
|
import { PopupComponent } from './popup.component';
|
||||||
|
|
||||||
@ -8,19 +7,15 @@ import { PopupComponent } from './popup.component';
|
|||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
template: `
|
template: `
|
||||||
<input #input value="Message">
|
<input #input value="Message">
|
||||||
<button (click)="popup.showAsComponent(input.value)">
|
<button (click)="popup.showAsComponent(input.value)">Show as component</button>
|
||||||
Show as component </button>
|
<button (click)="popup.showAsElement(input.value)">Show as element</button>
|
||||||
<button (click)="popup.showAsElement(input.value)">
|
`,
|
||||||
Show as element </button>
|
|
||||||
`
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
constructor(private injector: Injector, public popup: PopupService) {
|
constructor(injector: Injector, public popup: PopupService) {
|
||||||
// on init, convert PopupComponent to a custom element
|
// Convert `PopupComponent` to a custom element.
|
||||||
const PopupElement =
|
const PopupElement = createCustomElement(PopupComponent, {injector});
|
||||||
createNgElementConstructor(PopupComponent, {injector: this.injector});
|
// Register the custom element with the browser.
|
||||||
// register the custom element with the browser.
|
customElements.define('popup-element', PopupElement);
|
||||||
customElements.define('popup-element', PopupElement);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
// #docregion
|
import { NgModule } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { PopupService } from './popup.service';
|
|
||||||
import { PopupComponent } from './popup.component';
|
import { PopupComponent } from './popup.component';
|
||||||
|
import { PopupService } from './popup.service';
|
||||||
|
|
||||||
// include the PopupService provider,
|
// Include the `PopupService` provider,
|
||||||
// but exclude PopupComponent from compilation,
|
// but exclude `PopupComponent` from compilation,
|
||||||
// because it will be added dynamically
|
// because it will be added dynamically.
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent, PopupComponent],
|
|
||||||
imports: [BrowserModule, BrowserAnimationsModule],
|
imports: [BrowserModule, BrowserAnimationsModule],
|
||||||
providers: [PopupService],
|
providers: [PopupService],
|
||||||
|
declarations: [AppComponent, PopupComponent],
|
||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
entryComponents: [PopupComponent],
|
entryComponents: [PopupComponent],
|
||||||
})
|
})
|
||||||
|
export class AppModule {
|
||||||
export class AppModule {}
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
// #docregion
|
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { AnimationEvent } from '@angular/animations';
|
|
||||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-popup',
|
selector: 'my-popup',
|
||||||
template: 'Popup: {{message}}',
|
template: `
|
||||||
|
<span>Popup: {{message}}</span>
|
||||||
|
<button (click)="closed.next()">✖</button>
|
||||||
|
`,
|
||||||
host: {
|
host: {
|
||||||
'[@state]': 'state',
|
'[@state]': 'state',
|
||||||
'(@state.done)': 'onAnimationDone($event)',
|
|
||||||
},
|
},
|
||||||
animations: [
|
animations: [
|
||||||
trigger('state', [
|
trigger('state', [
|
||||||
@ -27,13 +27,17 @@ import { animate, state, style, transition, trigger } from '@angular/animations'
|
|||||||
height: 48px;
|
height: 48px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-top: 1px solid black;
|
border-top: 1px solid black;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
`]
|
`]
|
||||||
})
|
})
|
||||||
|
|
||||||
export class PopupComponent {
|
export class PopupComponent {
|
||||||
private state: 'opened' | 'closed' = 'closed';
|
private state: 'opened' | 'closed' = 'closed';
|
||||||
|
|
||||||
@ -41,18 +45,10 @@ export class PopupComponent {
|
|||||||
set message(message: string) {
|
set message(message: string) {
|
||||||
this._message = message;
|
this._message = message;
|
||||||
this.state = 'opened';
|
this.state = 'opened';
|
||||||
|
|
||||||
setTimeout(() => this.state = 'closed', 2000);
|
|
||||||
}
|
}
|
||||||
get message(): string { return this._message; }
|
get message(): string { return this._message; }
|
||||||
_message: string;
|
_message: string;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
closed = new EventEmitter();
|
closed = new EventEmitter();
|
||||||
|
|
||||||
onAnimationDone(e: AnimationEvent) {
|
|
||||||
if (e.toState === 'closed') {
|
|
||||||
this.closed.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
|
|
||||||
// #docregion
|
|
||||||
import { ApplicationRef, ComponentFactoryResolver, Injectable, Injector } from '@angular/core';
|
import { ApplicationRef, ComponentFactoryResolver, Injectable, Injector } from '@angular/core';
|
||||||
|
import { NgElement, WithProperties } from '@angular/elements';
|
||||||
import { PopupComponent } from './popup.component';
|
import { PopupComponent } from './popup.component';
|
||||||
import { NgElementConstructor } from '../elements-dist';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PopupService {
|
export class PopupService {
|
||||||
@ -40,7 +39,7 @@ export class PopupService {
|
|||||||
// This uses the new custom-element method to add the popup to the DOM.
|
// This uses the new custom-element method to add the popup to the DOM.
|
||||||
showAsElement(message: string) {
|
showAsElement(message: string) {
|
||||||
// Create element
|
// Create element
|
||||||
const popupEl = document.createElement('popup-element');
|
const popupEl: NgElement & WithProperties<PopupComponent> = document.createElement('popup-element') as any;
|
||||||
|
|
||||||
// Listen to the close event
|
// Listen to the close event
|
||||||
popupEl.addEventListener('closed', () => document.body.removeChild(popupEl));
|
popupEl.addEventListener('closed', () => document.body.removeChild(popupEl));
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
<!-- #docregion -->
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<base href="/">
|
|
||||||
<title>Angular With Webpack</title>
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<base href="/">
|
||||||
|
<title>Elements</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<my-app>Loading...</my-app>
|
<app-root></app-root>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
<!-- #enddocregion -->
|
|
@ -1,4 +1,3 @@
|
|||||||
// tslint:disable:no-unused-variable
|
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
@ -10,4 +9,3 @@ if (environment.production) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||||
|
|
@ -16,6 +16,7 @@ describe('Form Validation Tests', function () {
|
|||||||
|
|
||||||
tests('Template-Driven Form');
|
tests('Template-Driven Form');
|
||||||
bobTests();
|
bobTests();
|
||||||
|
crossValidationTests();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Reactive form', () => {
|
describe('Reactive form', () => {
|
||||||
@ -25,6 +26,7 @@ describe('Form Validation Tests', function () {
|
|||||||
|
|
||||||
tests('Reactive Form');
|
tests('Reactive Form');
|
||||||
bobTests();
|
bobTests();
|
||||||
|
crossValidationTests();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -42,7 +44,8 @@ let page: {
|
|||||||
powerOption: ElementFinder,
|
powerOption: ElementFinder,
|
||||||
errorMessages: ElementArrayFinder,
|
errorMessages: ElementArrayFinder,
|
||||||
heroFormButtons: ElementArrayFinder,
|
heroFormButtons: ElementArrayFinder,
|
||||||
heroSubmitted: ElementFinder
|
heroSubmitted: ElementFinder,
|
||||||
|
crossValidationErrorMessage: ElementFinder,
|
||||||
};
|
};
|
||||||
|
|
||||||
function getPage(sectionTag: string) {
|
function getPage(sectionTag: string) {
|
||||||
@ -59,7 +62,8 @@ function getPage(sectionTag: string) {
|
|||||||
powerOption: section.element(by.css('#power option')),
|
powerOption: section.element(by.css('#power option')),
|
||||||
errorMessages: section.all(by.css('div.alert')),
|
errorMessages: section.all(by.css('div.alert')),
|
||||||
heroFormButtons: buttons,
|
heroFormButtons: buttons,
|
||||||
heroSubmitted: section.element(by.css('.submitted-message'))
|
heroSubmitted: section.element(by.css('.submitted-message')),
|
||||||
|
crossValidationErrorMessage: section.element(by.css('.cross-validation-error-message')),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,3 +176,29 @@ function bobTests() {
|
|||||||
expectFormIsValid();
|
expectFormIsValid();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function crossValidationTests() {
|
||||||
|
const emsg = 'Name cannot match alter ego.';
|
||||||
|
|
||||||
|
it(`should produce "${emsg}" error after setting name and alter ego to the same value`, function () {
|
||||||
|
page.nameInput.clear();
|
||||||
|
page.nameInput.sendKeys('Batman');
|
||||||
|
|
||||||
|
page.alterEgoInput.clear();
|
||||||
|
page.alterEgoInput.sendKeys('Batman');
|
||||||
|
|
||||||
|
expectFormIsInvalid();
|
||||||
|
expect(page.crossValidationErrorMessage.getText()).toBe(emsg);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be ok again with different values', function () {
|
||||||
|
page.nameInput.clear();
|
||||||
|
page.nameInput.sendKeys('Batman');
|
||||||
|
|
||||||
|
page.alterEgoInput.clear();
|
||||||
|
page.alterEgoInput.sendKeys('Superman');
|
||||||
|
|
||||||
|
expectFormIsValid();
|
||||||
|
expect(page.crossValidationErrorMessage.isPresent()).toBe(false);
|
||||||
|
});
|
||||||
|
}
|
@ -7,7 +7,7 @@ import { AppComponent } from './app.component';
|
|||||||
import { HeroFormTemplateComponent } from './template/hero-form-template.component';
|
import { HeroFormTemplateComponent } from './template/hero-form-template.component';
|
||||||
import { HeroFormReactiveComponent } from './reactive/hero-form-reactive.component';
|
import { HeroFormReactiveComponent } from './reactive/hero-form-reactive.component';
|
||||||
import { ForbiddenValidatorDirective } from './shared/forbidden-name.directive';
|
import { ForbiddenValidatorDirective } from './shared/forbidden-name.directive';
|
||||||
|
import { IdentityRevealedValidatorDirective } from './shared/identity-revealed.directive';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -19,7 +19,8 @@ import { ForbiddenValidatorDirective } from './shared/forbidden-name.directive';
|
|||||||
AppComponent,
|
AppComponent,
|
||||||
HeroFormTemplateComponent,
|
HeroFormTemplateComponent,
|
||||||
HeroFormReactiveComponent,
|
HeroFormReactiveComponent,
|
||||||
ForbiddenValidatorDirective
|
ForbiddenValidatorDirective,
|
||||||
|
IdentityRevealedValidatorDirective
|
||||||
],
|
],
|
||||||
bootstrap: [ AppComponent ]
|
bootstrap: [ AppComponent ]
|
||||||
})
|
})
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
/* tslint:disable: member-ordering forin */
|
||||||
|
// #docplaster
|
||||||
|
// #docregion
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { forbiddenNameValidator } from '../shared/forbidden-name.directive';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-hero-form-reactive',
|
||||||
|
templateUrl: './hero-form-reactive.component.html',
|
||||||
|
styleUrls: ['./hero-form-reactive.component.css'],
|
||||||
|
})
|
||||||
|
export class HeroFormReactiveComponent implements OnInit {
|
||||||
|
|
||||||
|
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
|
||||||
|
|
||||||
|
hero = {name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0]};
|
||||||
|
|
||||||
|
heroForm: FormGroup;
|
||||||
|
|
||||||
|
// #docregion form-group
|
||||||
|
ngOnInit(): void {
|
||||||
|
// #docregion custom-validator
|
||||||
|
this.heroForm = new FormGroup({
|
||||||
|
'name': new FormControl(this.hero.name, [
|
||||||
|
Validators.required,
|
||||||
|
Validators.minLength(4),
|
||||||
|
forbiddenNameValidator(/bob/i) // <-- Here's how you pass in the custom validator.
|
||||||
|
]),
|
||||||
|
'alterEgo': new FormControl(this.hero.alterEgo),
|
||||||
|
'power': new FormControl(this.hero.power, Validators.required)
|
||||||
|
});
|
||||||
|
// #enddocregion custom-validator
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() { return this.heroForm.get('name'); }
|
||||||
|
|
||||||
|
get power() { return this.heroForm.get('power'); }
|
||||||
|
// #enddocregion form-group
|
||||||
|
}
|
||||||
|
// #enddocregion
|
@ -0,0 +1,5 @@
|
|||||||
|
/* #docregion cross-validation-error-css */
|
||||||
|
.cross-validation-error input {
|
||||||
|
border-left: 5px solid red;
|
||||||
|
}
|
||||||
|
/* #enddocregion cross-validation-error-css */
|
@ -7,33 +7,41 @@
|
|||||||
|
|
||||||
<div [hidden]="formDir.submitted">
|
<div [hidden]="formDir.submitted">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
|
||||||
|
<div class="form-group">
|
||||||
|
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<!-- #docregion name-with-error-msg -->
|
<!-- #docregion name-with-error-msg -->
|
||||||
<input id="name" class="form-control"
|
<input id="name" class="form-control"
|
||||||
formControlName="name" required >
|
formControlName="name" required >
|
||||||
|
|
||||||
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
||||||
class="alert alert-danger">
|
class="alert alert-danger">
|
||||||
|
|
||||||
<div *ngIf="name.errors.required">
|
<div *ngIf="name.errors.required">
|
||||||
Name is required.
|
Name is required.
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="name.errors.minlength">
|
<div *ngIf="name.errors.minlength">
|
||||||
Name must be at least 4 characters long.
|
Name must be at least 4 characters long.
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="name.errors.forbiddenName">
|
<div *ngIf="name.errors.forbiddenName">
|
||||||
Name cannot be Bob.
|
Name cannot be Bob.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- #enddocregion name-with-error-msg -->
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion name-with-error-msg -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input id="alterEgo" class="form-control"
|
<input id="alterEgo" class="form-control"
|
||||||
formControlName="alterEgo" >
|
formControlName="alterEgo" >
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- #docregion cross-validation-error-message -->
|
||||||
|
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
|
||||||
|
Name cannot match alter ego.
|
||||||
|
</div>
|
||||||
|
<!-- #enddocregion cross-validation-error-message -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -1,40 +1,36 @@
|
|||||||
/* tslint:disable: member-ordering forin */
|
/* tslint:disable: member-ordering forin */
|
||||||
// #docplaster
|
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
import { forbiddenNameValidator } from '../shared/forbidden-name.directive';
|
import { forbiddenNameValidator } from '../shared/forbidden-name.directive';
|
||||||
|
import { identityRevealedValidator } from '../shared/identity-revealed.directive';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-hero-form-reactive',
|
selector: 'app-hero-form-reactive',
|
||||||
templateUrl: './hero-form-reactive.component.html'
|
templateUrl: './hero-form-reactive.component.html',
|
||||||
|
styleUrls: ['./hero-form-reactive.component.css'],
|
||||||
})
|
})
|
||||||
export class HeroFormReactiveComponent implements OnInit {
|
export class HeroFormReactiveComponent implements OnInit {
|
||||||
|
|
||||||
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
|
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
|
||||||
|
|
||||||
hero = {name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0]};
|
hero = { name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0] };
|
||||||
|
|
||||||
heroForm: FormGroup;
|
heroForm: FormGroup;
|
||||||
|
|
||||||
// #docregion form-group
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// #docregion custom-validator
|
|
||||||
this.heroForm = new FormGroup({
|
this.heroForm = new FormGroup({
|
||||||
'name': new FormControl(this.hero.name, [
|
'name': new FormControl(this.hero.name, [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.minLength(4),
|
Validators.minLength(4),
|
||||||
forbiddenNameValidator(/bob/i) // <-- Here's how you pass in the custom validator.
|
forbiddenNameValidator(/bob/i)
|
||||||
]),
|
]),
|
||||||
'alterEgo': new FormControl(this.hero.alterEgo),
|
'alterEgo': new FormControl(this.hero.alterEgo),
|
||||||
'power': new FormControl(this.hero.power, Validators.required)
|
'power': new FormControl(this.hero.power, Validators.required)
|
||||||
});
|
}, { validators: identityRevealedValidator }); // <-- add custom validator at the FormGroup level
|
||||||
// #enddocregion custom-validator
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() { return this.heroForm.get('name'); }
|
get name() { return this.heroForm.get('name'); }
|
||||||
|
|
||||||
get power() { return this.heroForm.get('power'); }
|
get power() { return this.heroForm.get('power'); }
|
||||||
// #enddocregion form-group
|
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
@ -5,7 +5,7 @@ import { AbstractControl, NG_VALIDATORS, Validator, ValidatorFn, Validators } fr
|
|||||||
// #docregion custom-validator
|
// #docregion custom-validator
|
||||||
/** A hero's name can't match the given regular expression */
|
/** A hero's name can't match the given regular expression */
|
||||||
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
||||||
return (control: AbstractControl): {[key: string]: any} => {
|
return (control: AbstractControl): {[key: string]: any} | null => {
|
||||||
const forbidden = nameRe.test(control.value);
|
const forbidden = nameRe.test(control.value);
|
||||||
return forbidden ? {'forbiddenName': {value: control.value}} : null;
|
return forbidden ? {'forbiddenName': {value: control.value}} : null;
|
||||||
};
|
};
|
||||||
@ -22,7 +22,7 @@ export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
|||||||
export class ForbiddenValidatorDirective implements Validator {
|
export class ForbiddenValidatorDirective implements Validator {
|
||||||
@Input('appForbiddenName') forbiddenName: string;
|
@Input('appForbiddenName') forbiddenName: string;
|
||||||
|
|
||||||
validate(control: AbstractControl): {[key: string]: any} {
|
validate(control: AbstractControl): {[key: string]: any} | null {
|
||||||
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
|
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
// #docregion
|
||||||
|
import { Directive } from '@angular/core';
|
||||||
|
import { AbstractControl, FormGroup, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from '@angular/forms';
|
||||||
|
|
||||||
|
// #docregion cross-validation-validator
|
||||||
|
/** A hero's name can't match the hero's alter ego */
|
||||||
|
export const identityRevealedValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
|
||||||
|
const name = control.get('name');
|
||||||
|
const alterEgo = control.get('alterEgo');
|
||||||
|
|
||||||
|
return name && alterEgo && name.value === alterEgo.value ? { 'identityRevealed': true } : null;
|
||||||
|
};
|
||||||
|
// #enddocregion cross-validation-validator
|
||||||
|
|
||||||
|
// #docregion cross-validation-directive
|
||||||
|
@Directive({
|
||||||
|
selector: '[appIdentityRevealed]',
|
||||||
|
providers: [{ provide: NG_VALIDATORS, useExisting: IdentityRevealedValidatorDirective, multi: true }]
|
||||||
|
})
|
||||||
|
export class IdentityRevealedValidatorDirective implements Validator {
|
||||||
|
validate(control: AbstractControl): ValidationErrors {
|
||||||
|
return identityRevealedValidator(control)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #enddocregion cross-validation-directive
|
@ -0,0 +1,4 @@
|
|||||||
|
/* #docregion */
|
||||||
|
.cross-validation-error input {
|
||||||
|
border-left: 5px solid red;
|
||||||
|
}
|
@ -2,41 +2,48 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<h1>Template-Driven Form</h1>
|
<h1>Template-Driven Form</h1>
|
||||||
<!-- #docregion form-tag-->
|
<!-- #docregion cross-validation-register-validator -->
|
||||||
<form #heroForm="ngForm">
|
<form #heroForm="ngForm" appIdentityRevealed>
|
||||||
<!-- #enddocregion form-tag-->
|
<!-- #enddocregion cross-validation-register-validator -->
|
||||||
<div [hidden]="heroForm.submitted">
|
<div [hidden]="heroForm.submitted">
|
||||||
|
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">Name</label>
|
||||||
|
<!-- #docregion name-with-error-msg -->
|
||||||
|
<!-- #docregion name-input -->
|
||||||
|
<input id="name" name="name" class="form-control"
|
||||||
|
required minlength="4" appForbiddenName="bob"
|
||||||
|
[(ngModel)]="hero.name" #name="ngModel" >
|
||||||
|
<!-- #enddocregion name-input -->
|
||||||
|
|
||||||
<div class="form-group">
|
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
||||||
<label for="name">Name</label>
|
class="alert alert-danger">
|
||||||
<!-- #docregion name-with-error-msg -->
|
|
||||||
<!-- #docregion name-input -->
|
|
||||||
<input id="name" name="name" class="form-control"
|
|
||||||
required minlength="4" appForbiddenName="bob"
|
|
||||||
[(ngModel)]="hero.name" #name="ngModel" >
|
|
||||||
<!-- #enddocregion name-input -->
|
|
||||||
|
|
||||||
<div *ngIf="name.invalid && (name.dirty || name.touched)"
|
<div *ngIf="name.errors.required">
|
||||||
class="alert alert-danger">
|
Name is required.
|
||||||
|
</div>
|
||||||
|
<div *ngIf="name.errors.minlength">
|
||||||
|
Name must be at least 4 characters long.
|
||||||
|
</div>
|
||||||
|
<div *ngIf="name.errors.forbiddenName">
|
||||||
|
Name cannot be Bob.
|
||||||
|
</div>
|
||||||
|
|
||||||
<div *ngIf="name.errors.required">
|
|
||||||
Name is required.
|
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="name.errors.minlength">
|
<!-- #enddocregion name-with-error-msg -->
|
||||||
Name must be at least 4 characters long.
|
|
||||||
</div>
|
|
||||||
<div *ngIf="name.errors.forbiddenName">
|
|
||||||
Name cannot be Bob.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion name-with-error-msg -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input id="alterEgo" class="form-control"
|
<input id="alterEgo" class="form-control"
|
||||||
name="alterEgo" [(ngModel)]="hero.alterEgo" >
|
name="alterEgo" [(ngModel)]="hero.alterEgo" >
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- #docregion cross-validation-error-message -->
|
||||||
|
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
|
||||||
|
Name cannot match alter ego.
|
||||||
|
</div>
|
||||||
|
<!-- #enddocregion cross-validation-error-message -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -62,5 +69,4 @@
|
|||||||
<button (click)="heroForm.resetForm({})">Add new hero</button>
|
<button (click)="heroForm.resetForm({})">Add new hero</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
// #docregion component
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-hero-form-template',
|
selector: 'app-hero-form-template',
|
||||||
templateUrl: './hero-form-template.component.html'
|
templateUrl: './hero-form-template.component.html',
|
||||||
|
styleUrls: ['./hero-form-template.component.css'],
|
||||||
})
|
})
|
||||||
export class HeroFormTemplateComponent {
|
export class HeroFormTemplateComponent {
|
||||||
|
|
||||||
@ -14,3 +16,4 @@ export class HeroFormTemplateComponent {
|
|||||||
hero = {name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0]};
|
hero = {name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0]};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// #enddocregion
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"description": "Validation",
|
"description": "Validation",
|
||||||
"files":[
|
"files":[
|
||||||
"!**/*.d.ts",
|
"!**/*.d.ts",
|
||||||
"!**/*.js"
|
"!**/*.js",
|
||||||
|
"!**/*.[1].*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ describe('HttpClient testing', () => {
|
|||||||
|
|
||||||
// Create mock ErrorEvent, raised when something goes wrong at the network level.
|
// Create mock ErrorEvent, raised when something goes wrong at the network level.
|
||||||
// Connection timeout, DNS error, offline, etc
|
// Connection timeout, DNS error, offline, etc
|
||||||
const errorEvent = new ErrorEvent('so sad', {
|
const mockError = new ErrorEvent('Network error', {
|
||||||
message: emsg,
|
message: emsg,
|
||||||
// #enddocregion network-error
|
// #enddocregion network-error
|
||||||
// The rest of this is optional and not used.
|
// The rest of this is optional and not used.
|
||||||
@ -162,7 +162,7 @@ describe('HttpClient testing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Respond with mock error
|
// Respond with mock error
|
||||||
req.error(errorEvent);
|
req.error(mockError);
|
||||||
});
|
});
|
||||||
// #enddocregion network-error
|
// #enddocregion network-error
|
||||||
|
|
||||||
|
@ -38,8 +38,6 @@ export class MyCounterComponent implements OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************/
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'counter-parent',
|
selector: 'counter-parent',
|
||||||
template: `
|
template: `
|
||||||
|
@ -72,8 +72,6 @@ export class DoCheckComponent implements DoCheck {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************/
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'do-check-parent',
|
selector: 'do-check-parent',
|
||||||
templateUrl: './do-check-parent.component.html',
|
templateUrl: './do-check-parent.component.html',
|
||||||
|
@ -46,8 +46,6 @@ export class OnChangesComponent implements OnChanges {
|
|||||||
reset() { this.changeLog = []; }
|
reset() { this.changeLog = []; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************/
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'on-changes-parent',
|
selector: 'on-changes-parent',
|
||||||
templateUrl: './on-changes-parent.component.html',
|
templateUrl: './on-changes-parent.component.html',
|
||||||
|
@ -4,7 +4,8 @@ button {
|
|||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
code, .code {
|
code,
|
||||||
|
.code {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
color: black;
|
color: black;
|
||||||
font-family: Courier, sans-serif;
|
font-family: Courier, sans-serif;
|
||||||
@ -21,14 +22,18 @@ div.code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
margin: 40px 0
|
margin: 40px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
td, th {
|
td,
|
||||||
|
th {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #docregion p-span */
|
/* #docregion p-span */
|
||||||
p span { color: red; font-size: 70%; }
|
p span {
|
||||||
|
color: red;
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
/* #enddocregion p-span */
|
/* #enddocregion p-span */
|
||||||
|
@ -132,7 +132,7 @@
|
|||||||
<!-- #docregion select-span -->
|
<!-- #docregion select-span -->
|
||||||
<select [(ngModel)]="hero">
|
<select [(ngModel)]="hero">
|
||||||
<span *ngFor="let h of heroes">
|
<span *ngFor="let h of heroes">
|
||||||
<span *ngIf="showSad || h?.emotion != 'sad'">
|
<span *ngIf="showSad || h?.emotion !== 'sad'">
|
||||||
<option [ngValue]="h">{{h.name}} ({{h?.emotion}})</option>
|
<option [ngValue]="h">{{h.name}} ({{h?.emotion}})</option>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@ -147,7 +147,7 @@
|
|||||||
<!-- #docregion select-ngcontainer -->
|
<!-- #docregion select-ngcontainer -->
|
||||||
<select [(ngModel)]="hero">
|
<select [(ngModel)]="hero">
|
||||||
<ng-container *ngFor="let h of heroes">
|
<ng-container *ngFor="let h of heroes">
|
||||||
<ng-container *ngIf="showSad || h?.emotion != 'sad'">
|
<ng-container *ngIf="showSad || h?.emotion !== 'sad'">
|
||||||
<option [ngValue]="h">{{h.name}} ({{h?.emotion}})</option>
|
<option [ngValue]="h">{{h.name}} ({{h?.emotion}})</option>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -6,14 +6,15 @@ import { heroes } from './hero';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: [ './app.component.css' ]
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
heroes = heroes;
|
heroes = heroes;
|
||||||
hero = this.heroes[0];
|
hero = this.heroes[0];
|
||||||
heroTraits = [ 'honest', 'brave', 'considerate' ];
|
heroTraits = ['honest', 'brave', 'considerate'];
|
||||||
|
|
||||||
// flags for the table
|
// flags for the table
|
||||||
|
|
||||||
attrDirs = true;
|
attrDirs = true;
|
||||||
strucDirs = true;
|
strucDirs = true;
|
||||||
divNgIf = false;
|
divNgIf = false;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { ContentComponent } from './content.component';
|
import { ContentComponent } from './content.component';
|
||||||
import { heroComponents } from './hero.components';
|
import { heroComponents } from './hero.components';
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
import { Hero } from './hero';
|
import { Hero } from './hero';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -33,11 +34,15 @@ export class ConfusedHeroComponent {
|
|||||||
export class UnknownHeroComponent {
|
export class UnknownHeroComponent {
|
||||||
@Input() hero: Hero;
|
@Input() hero: Hero;
|
||||||
get message() {
|
get message() {
|
||||||
return this.hero && this.hero.name ?
|
return this.hero && this.hero.name
|
||||||
`${this.hero.name} is strange and mysterious.` :
|
? `${this.hero.name} is strange and mysterious.`
|
||||||
'Are you feeling indecisive?';
|
: 'Are you feeling indecisive?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const heroComponents =
|
export const heroComponents = [
|
||||||
[ HappyHeroComponent, SadHeroComponent, ConfusedHeroComponent, UnknownHeroComponent ];
|
HappyHeroComponent,
|
||||||
|
SadHeroComponent,
|
||||||
|
ConfusedHeroComponent,
|
||||||
|
UnknownHeroComponent
|
||||||
|
];
|
||||||
|
@ -6,8 +6,8 @@ export class Hero {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const heroes: Hero[] = [
|
export const heroes: Hero[] = [
|
||||||
{ id: 1, name: 'Mr. Nice', emotion: 'happy'},
|
{ id: 1, name: 'Mr. Nice', emotion: 'happy' },
|
||||||
{ id: 2, name: 'Narco', emotion: 'sad' },
|
{ id: 2, name: 'Narco', emotion: 'sad' },
|
||||||
{ id: 3, name: 'Windstorm', emotion: 'confused' },
|
{ id: 3, name: 'Windstorm', emotion: 'confused' },
|
||||||
{ id: 4, name: 'Magneta'}
|
{ id: 4, name: 'Magneta' }
|
||||||
];
|
];
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
import { HttpModule } from '@angular/http';
|
|
||||||
|
|
||||||
/* App Root */
|
/* App Root */
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
@ -15,7 +15,7 @@ function sequenceSubscriber(observer) {
|
|||||||
if (idx === arr.length - 1) {
|
if (idx === arr.length - 1) {
|
||||||
observer.complete();
|
observer.complete();
|
||||||
} else {
|
} else {
|
||||||
doSequence(arr, idx++);
|
doSequence(arr, ++idx);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ function multicastSequenceSubscriber() {
|
|||||||
},
|
},
|
||||||
complete() {
|
complete() {
|
||||||
// Notify all complete callbacks
|
// Notify all complete callbacks
|
||||||
observers.forEach(obs => obs.complete());
|
observers.slice(0).forEach(obs => obs.complete());
|
||||||
}
|
}
|
||||||
}, seq, 0);
|
}, seq, 0);
|
||||||
}
|
}
|
||||||
@ -121,13 +121,13 @@ function doSequence(observer, arr, idx) {
|
|||||||
if (idx === arr.length - 1) {
|
if (idx === arr.length - 1) {
|
||||||
observer.complete();
|
observer.complete();
|
||||||
} else {
|
} else {
|
||||||
doSequence(observer, arr, idx++);
|
doSequence(observer, arr, ++idx);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Observable that will deliver the above sequence
|
// Create a new Observable that will deliver the above sequence
|
||||||
const multicastSequence = new Observable(multicastSequenceSubscriber);
|
const multicastSequence = new Observable(multicastSequenceSubscriber());
|
||||||
|
|
||||||
// Subscribe starts the clock, and begins to emit after 1 second
|
// Subscribe starts the clock, and begins to emit after 1 second
|
||||||
multicastSequence.subscribe({
|
multicastSequence.subscribe({
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { HttpClientModule } from '@angular//common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import {
|
import {
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
[1030/162525.401:ERROR:process_reader_win.cc(123)] NtOpenThread: {Acceso denegado} Un proceso ha solicitado acceso a un objeto, pero no se le han concedido esos derechos de acceso. (0xc0000022)
|
|
||||||
[1030/162525.402:ERROR:exception_snapshot_win.cc(87)] thread ID 26896 not found in process
|
|
||||||
[1030/162525.402:WARNING:crash_report_exception_handler.cc(62)] ProcessSnapshotWin::Initialize failed
|
|
File diff suppressed because it is too large
Load Diff
145
aio/content/examples/reactive-forms/e2e/src/app.e2e-spec.ts
Normal file
145
aio/content/examples/reactive-forms/e2e/src/app.e2e-spec.ts
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
|
describe('Reactive forms', function () {
|
||||||
|
const nameEditor = element(by.css('app-name-editor'));
|
||||||
|
const profileEditor = element(by.css('app-profile-editor'));
|
||||||
|
const nameEditorLink = element(by.cssContainingText('app-root > nav > a', 'Name Editor'));
|
||||||
|
const profileEditorLink = element(by.cssContainingText('app-root > nav > a', 'Profile Editor'));
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
browser.get('');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Name Editor', function () {
|
||||||
|
const nameInput = nameEditor.element(by.css('input'));
|
||||||
|
const updateButton = nameEditor.element(by.buttonText('Update Name'));
|
||||||
|
const nameText = 'John Smith';
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await nameEditorLink.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await nameInput.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the name value when the name control is updated', async () => {
|
||||||
|
await nameInput.sendKeys(nameText);
|
||||||
|
|
||||||
|
const value = await nameInput.getAttribute('value');
|
||||||
|
|
||||||
|
expect(value).toBe(nameText);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the name control when the Update Name button is clicked', async () => {
|
||||||
|
await nameInput.sendKeys(nameText);
|
||||||
|
const value = await nameInput.getAttribute('value');
|
||||||
|
|
||||||
|
expect(value).toBe(nameText);
|
||||||
|
await updateButton.click();
|
||||||
|
|
||||||
|
const value = await nameInput.getAttribute('value');
|
||||||
|
|
||||||
|
expect(value).toBe('Nancy');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the displayed control value when the name control updated', async () => {
|
||||||
|
await nameInput.sendKeys(nameText);
|
||||||
|
const valueElement = nameEditor.element(by.cssContainingText('p', 'Value:'));
|
||||||
|
const nameValueElement = await valueElement.getText();
|
||||||
|
const nameValue = nameValueElement.toString().replace('Value: ', '');
|
||||||
|
|
||||||
|
expect(nameValue).toBe(nameText);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Profile Editor', function () {
|
||||||
|
const firstNameInput = getInput('firstName');
|
||||||
|
const lastNameInput = getInput('lastName');
|
||||||
|
const streetInput = getInput('street');
|
||||||
|
const addAliasButton = element(by.buttonText('Add Alias'));
|
||||||
|
const updateButton = profileEditor.element(by.buttonText('Update Profile'));
|
||||||
|
const profile = {
|
||||||
|
firstName: 'John',
|
||||||
|
lastName: 'Smith',
|
||||||
|
street: '345 South Lane',
|
||||||
|
city: 'Northtown',
|
||||||
|
state: 'XX',
|
||||||
|
zip: 12345
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await profileEditorLink.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await browser.get('');
|
||||||
|
await profileEditorLink.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be invalid by default', async () => {
|
||||||
|
expect(await profileEditor.getText()).toContain('Form Status: INVALID');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be valid if the First Name is filled in', async () => {
|
||||||
|
await firstNameInput.clear();
|
||||||
|
await firstNameInput.sendKeys('John Smith');
|
||||||
|
|
||||||
|
expect(await profileEditor.getText()).toContain('Form Status: VALID');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the name when the button is clicked', async () => {
|
||||||
|
await firstNameInput.clear();
|
||||||
|
await streetInput.clear();
|
||||||
|
await firstNameInput.sendKeys('John');
|
||||||
|
await streetInput.sendKeys('345 Smith Lane');
|
||||||
|
const firstNameInitial = await firstNameInput.getAttribute('value');
|
||||||
|
const streetNameInitial = await streetInput.getAttribute('value');
|
||||||
|
|
||||||
|
expect(firstNameInitial).toBe('John');
|
||||||
|
expect(streetNameInitial).toBe('345 Smith Lane');
|
||||||
|
await updateButton.click();
|
||||||
|
|
||||||
|
const nameValue = await firstNameInput.getAttribute('value');
|
||||||
|
const streetValue = await streetInput.getAttribute('value');
|
||||||
|
|
||||||
|
expect(nameValue).toBe('Nancy');
|
||||||
|
expect(streetValue).toBe('123 Drew Street');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add an alias field when the Add Alias button is clicked', async () => {
|
||||||
|
await addAliasButton.click();
|
||||||
|
|
||||||
|
const aliasInputs = profileEditor.all(by.cssContainingText('label', 'Alias'));
|
||||||
|
|
||||||
|
expect(await aliasInputs.count()).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the displayed form value when form inputs are updated', async () => {
|
||||||
|
const aliasText = 'Johnny';
|
||||||
|
const inputs = await Promise.all(
|
||||||
|
Object.keys(profile)
|
||||||
|
.map(key =>
|
||||||
|
getInput(key).sendKeys(`${profile[key]}`)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const aliasInputs = profileEditor.all(by.cssContainingText('label', 'Alias'));
|
||||||
|
const aliasInput = aliasInputs.get(0).element(by.css('input'));
|
||||||
|
await aliasInput.sendKeys(aliasText);
|
||||||
|
const formValueElement = profileEditor.all(by.cssContainingText('p', 'Form Value:'));
|
||||||
|
const formValue = await formValueElement.getText();
|
||||||
|
const formJson = JSON.parse(formValue.toString().replace('Form Value:', ''));
|
||||||
|
|
||||||
|
expect(profile.firstName).toBe(formJson.firstName);
|
||||||
|
expect(profile.lastName).toBe(formJson.lastName);
|
||||||
|
expect(formJson.aliases[0]).toBe(aliasText);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function getInput(key: string) {
|
||||||
|
return element(by.css(`input[formcontrolname=${key}`));
|
||||||
|
}
|
||||||
|
});
|
@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"description": "Angular Reactive Forms (final)",
|
|
||||||
"files":[
|
|
||||||
"src/styles.css",
|
|
||||||
|
|
||||||
"src/app/app.component.ts",
|
|
||||||
"src/app/app.component.html",
|
|
||||||
"src/app/app.component.css",
|
|
||||||
"src/app/app.module.ts",
|
|
||||||
"src/app/data-model.ts",
|
|
||||||
"src/app/hero.service.ts",
|
|
||||||
"src/app/hero-detail/hero-detail.component.html",
|
|
||||||
"src/app/hero-detail/hero-detail.component.ts",
|
|
||||||
"src/app/hero-detail/hero-detail.component.css",
|
|
||||||
"src/app/hero-list/hero-list.component.html",
|
|
||||||
"src/app/hero-list/hero-list.component.ts",
|
|
||||||
"src/app/hero-list/hero-list.component.css",
|
|
||||||
|
|
||||||
"src/main-final.ts",
|
|
||||||
"src/index-final.html"
|
|
||||||
],
|
|
||||||
"main": "src/index-final.html",
|
|
||||||
"tags": ["reactive", "forms"]
|
|
||||||
}
|
|
@ -1,4 +1,10 @@
|
|||||||
<div class="container">
|
<!-- #docplaster -->
|
||||||
<h1>Reactive Forms</h1>
|
<h1>Reactive Forms</h1>
|
||||||
<app-hero-detail></app-hero-detail>
|
|
||||||
</div>
|
<!-- #docregion app-name-editor-->
|
||||||
|
<app-name-editor></app-name-editor>
|
||||||
|
<!-- #enddocregion app-name-editor-->
|
||||||
|
|
||||||
|
<!-- #docregion app-profile-editor -->
|
||||||
|
<app-profile-editor></app-profile-editor>
|
||||||
|
<!-- #enddocregion app-profile-editor -->
|
@ -1,4 +1,17 @@
|
|||||||
<div class="container">
|
<!-- #docplaster -->
|
||||||
<h1>Reactive Forms</h1>
|
<!-- #docregion app-name-editor -->
|
||||||
<app-hero-list></app-hero-list>
|
<h1>Reactive Forms</h1>
|
||||||
</div>
|
|
||||||
|
<!-- #enddocregion app-name-editor -->
|
||||||
|
<nav>
|
||||||
|
<a (click)="toggleEditor('name')">Name Editor</a>
|
||||||
|
<a (click)="toggleEditor('profile')">Profile Editor</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- #docregion app-name-editor -->
|
||||||
|
<app-name-editor *ngIf="showNameEditor"></app-name-editor>
|
||||||
|
<!-- #enddocregion app-name-editor -->
|
||||||
|
|
||||||
|
<!-- #docregion app-profile-editor -->
|
||||||
|
<app-profile-editor *ngIf="showProfileEditor"></app-profile-editor>
|
||||||
|
<!-- #enddocregion app-profile-editor -->
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
it('should create the app', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
}));
|
||||||
|
it(`should have as title 'app'`, async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app.title).toEqual('app');
|
||||||
|
}));
|
||||||
|
it('should render title in a h1 tag', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
|
expect(compiled.querySelector('h1').textContent).toContain('Welcome to reactive-forms!');
|
||||||
|
}));
|
||||||
|
});
|
@ -1,9 +1,24 @@
|
|||||||
// #docregion
|
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
export type EditorType = 'name' | 'profile';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent { }
|
export class AppComponent {
|
||||||
|
editor: EditorType = 'name';
|
||||||
|
|
||||||
|
get showNameEditor() {
|
||||||
|
return this.editor === 'name';
|
||||||
|
}
|
||||||
|
|
||||||
|
get showProfileEditor() {
|
||||||
|
return this.editor === 'profile';
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleEditor(type: EditorType) {
|
||||||
|
this.editor = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,45 +1,34 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
// #docregion v1
|
import { NgModule } from '@angular/core';
|
||||||
import { NgModule } from '@angular/core';
|
// #docregion imports
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { ReactiveFormsModule } from '@angular/forms'; // <-- #1 import module
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
// #enddocregion imports
|
||||||
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
|
import { AppComponent } from './app.component';
|
||||||
// #enddocregion v1
|
import { NameEditorComponent } from './name-editor/name-editor.component';
|
||||||
// #docregion hero-service-list
|
import { ProfileEditorComponent } from './profile-editor/profile-editor.component';
|
||||||
// add JavaScript imports
|
|
||||||
import { HeroListComponent } from './hero-list/hero-list.component';
|
|
||||||
import { HeroService } from './hero.service';
|
|
||||||
// #docregion v1
|
|
||||||
|
|
||||||
|
// #docregion imports
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
// #enddocregion imports
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
HeroDetailComponent,
|
NameEditorComponent,
|
||||||
// #enddocregion v1
|
ProfileEditorComponent
|
||||||
HeroListComponent // <--declare HeroListComponent
|
|
||||||
// #docregion v1
|
|
||||||
],
|
],
|
||||||
// #enddocregion hero-service-list
|
// #docregion imports
|
||||||
imports: [
|
imports: [
|
||||||
|
// #enddocregion imports
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
ReactiveFormsModule // <-- #2 add to @NgModule imports
|
// #docregion imports
|
||||||
|
// other imports ...
|
||||||
|
ReactiveFormsModule
|
||||||
],
|
],
|
||||||
// #enddocregion v1
|
// #enddocregion imports
|
||||||
// export for the DemoModule
|
providers: [],
|
||||||
// #docregion hero-service-list
|
bootstrap: [AppComponent]
|
||||||
// ...
|
// #docregion imports
|
||||||
exports: [
|
|
||||||
AppComponent,
|
|
||||||
HeroDetailComponent,
|
|
||||||
HeroListComponent // <-- export HeroListComponent
|
|
||||||
],
|
|
||||||
providers: [ HeroService ], // <-- provide HeroService
|
|
||||||
// #enddocregion hero-service-list
|
|
||||||
// #docregion v1
|
|
||||||
bootstrap: [ AppComponent ]
|
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
// #enddocregion v1
|
// #enddocregion imports
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
// #docregion
|
|
||||||
// #docregion model-classes
|
|
||||||
export class Hero {
|
|
||||||
id = 0;
|
|
||||||
name = '';
|
|
||||||
addresses: Address[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Address {
|
|
||||||
street = '';
|
|
||||||
city = '';
|
|
||||||
state = '';
|
|
||||||
zip = '';
|
|
||||||
}
|
|
||||||
// #enddocregion model-classes
|
|
||||||
|
|
||||||
export const heroes: Hero[] = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: 'Whirlwind',
|
|
||||||
addresses: [
|
|
||||||
{street: '123 Main', city: 'Anywhere', state: 'CA', zip: '94801'},
|
|
||||||
{street: '456 Maple', city: 'Somewhere', state: 'VA', zip: '23226'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'Bombastic',
|
|
||||||
addresses: [
|
|
||||||
{street: '789 Elm', city: 'Smallville', state: 'OH', zip: '04501'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: 'Magneta',
|
|
||||||
addresses: [ ]
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const states = ['CA', 'MD', 'OH', 'VA'];
|
|
@ -1,40 +0,0 @@
|
|||||||
<div class="container">
|
|
||||||
<h1>Reactive Forms</h1>
|
|
||||||
<h4><i>Pick a demo:</i>
|
|
||||||
<select [selectedIndex]="demo - 1" (change)="selectDemo($event.target.selectedIndex)">
|
|
||||||
<option *ngFor="let demo of demos">{{demo}}</option>
|
|
||||||
</select>
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="demo">
|
|
||||||
<app-hero-list *ngIf="demo===final"></app-hero-list>
|
|
||||||
<app-hero-detail-1 *ngIf="demo===1"></app-hero-detail-1>
|
|
||||||
<app-hero-detail-2 *ngIf="demo===2"></app-hero-detail-2>
|
|
||||||
<app-hero-detail-3 *ngIf="demo===3"></app-hero-detail-3>
|
|
||||||
<app-hero-detail-4 *ngIf="demo===4"></app-hero-detail-4>
|
|
||||||
<app-hero-detail-5 *ngIf="demo===5"></app-hero-detail-5>
|
|
||||||
|
|
||||||
<div *ngIf="demo >= 6 && demo !== final" >
|
|
||||||
|
|
||||||
<h3 *ngIf="isLoading"><i>Loading heroes ... </i></h3>
|
|
||||||
<h3 *ngIf="!isLoading">Select a hero:</h3>
|
|
||||||
|
|
||||||
<nav>
|
|
||||||
<button (click)="getHeroes()" class="btn btn-primary">Refresh</button>
|
|
||||||
<a *ngFor="let hero of heroes | async" (click)="select(hero)">{{hero.name}}</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div *ngIf="selectedHero">
|
|
||||||
<hr>
|
|
||||||
<h2>Hero Detail</h2>
|
|
||||||
<h3>Editing: {{selectedHero.name}}</h3>
|
|
||||||
<app-hero-detail-6 [hero]=selectedHero *ngIf="demo===6"></app-hero-detail-6>
|
|
||||||
<app-hero-detail-7 [hero]=selectedHero *ngIf="demo===7"></app-hero-detail-7>
|
|
||||||
<app-hero-detail-8 [hero]=selectedHero *ngIf="demo===8"></app-hero-detail-8>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user