Compare commits
469 Commits
10.0.12
...
creating-l
Author | SHA1 | Date | |
---|---|---|---|
63149810c1 | |||
e3bc073f7b | |||
4b9b094c47 | |||
75e59cc837 | |||
6ad701074a | |||
fb4df0a54c | |||
7b0fba0983 | |||
7bd65e5f1b | |||
c90d9fd468 | |||
4bd3debef2 | |||
43b1210f86 | |||
189686bea1 | |||
66592ac5a3 | |||
066da01295 | |||
03ca38a478 | |||
6452285a71 | |||
a81e82028a | |||
958d06fa69 | |||
15b311ac9f | |||
5717054caa | |||
44cf633cb1 | |||
957e152656 | |||
9ccf7631c6 | |||
225fdf9ac8 | |||
b206732b25 | |||
efef4b7dc1 | |||
92c7145139 | |||
d133525502 | |||
cd1817bf6d | |||
0d1491b1a6 | |||
f67774d84b | |||
37668d159e | |||
38554288f5 | |||
04dcc3bceb | |||
0910a2fc0d | |||
3325cb2f86 | |||
a1e8443bfb | |||
599d34b41e | |||
7fd1733882 | |||
2e42123870 | |||
4cbb90daf7 | |||
cf2663b034 | |||
95681b16bd | |||
e620827fa8 | |||
7f82a2c1c8 | |||
a9910f5991 | |||
ad7046b934 | |||
d72b1e44c6 | |||
eae13e42f3 | |||
3373453736 | |||
4a6dcd006b | |||
7c3c8d6d10 | |||
655da32837 | |||
5b31a0a294 | |||
5d3d8b8330 | |||
c8c74153b1 | |||
9dc5e8e7e2 | |||
1a7a7360b0 | |||
8edf5ba29d | |||
72f1eec3ad | |||
136acdfab6 | |||
095cfd961d | |||
38a7021d5e | |||
b3b03c35b5 | |||
fd45f7485d | |||
58f6079873 | |||
e382632473 | |||
cf9a47ba53 | |||
56dd3e77ac | |||
6c9401c338 | |||
019a696a6a | |||
8b25a64200 | |||
bd71f10234 | |||
e0b35bfc18 | |||
c1539b16ae | |||
737506e79c | |||
469aba0140 | |||
d8c47b971c | |||
24b420527a | |||
bf641e1b4b | |||
406f801b70 | |||
c8e77d8536 | |||
6ea2d1e20e | |||
09eee5b312 | |||
904ebfebf3 | |||
545f1dbac9 | |||
b00121c9a6 | |||
45d79efc3f | |||
1d9e56eba0 | |||
e7c722574f | |||
b358495a6c | |||
f4fac406b9 | |||
5fd2c8f2d6 | |||
421e807f80 | |||
df8b387570 | |||
f01b0337d2 | |||
4ec3026a9a | |||
9021d3f5e1 | |||
81542b3b72 | |||
9185c6e971 | |||
69472a1ed0 | |||
10aba15154 | |||
36dd817913 | |||
0eaa084ced | |||
62e19c8813 | |||
95669df4c3 | |||
6b311552f0 | |||
66947cf9fa | |||
a259a84d3f | |||
d1aa4678be | |||
04c220bbdf | |||
72d6032fa4 | |||
53d4859f48 | |||
f66f4a1b3f | |||
88d68d2d21 | |||
4783a071f3 | |||
9322b9a060 | |||
9bd4b74b06 | |||
e6afcf1f94 | |||
4b4b74548d | |||
1550663b9e | |||
c40cbecdd1 | |||
209a365511 | |||
fb735d625b | |||
d19ef6534f | |||
667aba7508 | |||
d380e93b82 | |||
2156beed0c | |||
b98314e306 | |||
e50c7dcc4c | |||
6b731a067a | |||
0a3dbc1e8a | |||
b24a24ec58 | |||
13ef5d6c7d | |||
54373cc895 | |||
bbe3543c69 | |||
bdbbff6a1a | |||
f81d3f6199 | |||
d0c0f25a48 | |||
1f796e9479 | |||
1237d9cbea | |||
b3969e9654 | |||
6eb868b63a | |||
82a2207f4a | |||
289a96b078 | |||
cb2ab26296 | |||
79850983e6 | |||
fc7e77934f | |||
90b93da743 | |||
ec32eba02c | |||
596fbb3f06 | |||
aed6b131bb | |||
d148fdccf2 | |||
1801d0c650 | |||
a5c30733cb | |||
d7dd2959c8 | |||
a5ffca0576 | |||
196bfa8fae | |||
1d5ca55aab | |||
e0033f1e10 | |||
9206a26e1d | |||
11dd2bef2d | |||
6fc80690ae | |||
f6d2705942 | |||
79dc14199b | |||
71956250dd | |||
e84539f809 | |||
873330b82c | |||
a177b1b7b1 | |||
435a28e937 | |||
c2b4d92708 | |||
a87951a28f | |||
6b565ba8f2 | |||
c29f830c4b | |||
cde4653c62 | |||
e07d940b9b | |||
ee1526029f | |||
eba9dd364e | |||
78a44768e0 | |||
98c047b763 | |||
543b679762 | |||
c00f4ab2ae | |||
2038568f3e | |||
c509243af5 | |||
d4544da804 | |||
b950d4675f | |||
ae5257cda6 | |||
8fd8143ab8 | |||
acf3cff9ee | |||
c5b125b7db | |||
fc5c34d1b8 | |||
0879d2e85d | |||
83fe963a4b | |||
e0eeb4afcb | |||
c942662d79 | |||
6341a837c1 | |||
f954ab6f10 | |||
3ee666580a | |||
dbc2364d16 | |||
eee2fd22e0 | |||
638dd15f61 | |||
9c668e091f | |||
b2816a1536 | |||
2cbc429291 | |||
4c7f32f28c | |||
8572e885b4 | |||
0e3e9cd382 | |||
9118f49a63 | |||
d37049a2a2 | |||
d12cdb5019 | |||
ce879fc416 | |||
712f1bd0b7 | |||
d2fb552116 | |||
5103d908c8 | |||
9318e23e64 | |||
290bc7334d | |||
190561d8a6 | |||
ddb0a4e2e5 | |||
07a07e34bc | |||
dda3f49952 | |||
decd95e7f0 | |||
6abb8d0d91 | |||
2b2146bc58 | |||
3a698e2d08 | |||
8a74508130 | |||
ef1fb6dee4 | |||
e36d5b201a | |||
77b62a52c0 | |||
616543ded0 | |||
2170ea270a | |||
80d0067048 | |||
5218916a7e | |||
1c1eb3045c | |||
4967997536 | |||
666e6d15fa | |||
f3ec37ebbf | |||
cc3b1ebd96 | |||
29490cce30 | |||
bedc0451a0 | |||
a0595f4b4f | |||
8924ec1474 | |||
4481bebb38 | |||
f5bbfd7b8c | |||
41ce5240f2 | |||
243824ef74 | |||
c95802f26f | |||
71c0363bb5 | |||
e03adaf9b0 | |||
38dfbc775f | |||
5229809adb | |||
9d88ca07f8 | |||
97383488e8 | |||
cb566add3c | |||
5c40fd65fa | |||
2b53b07c70 | |||
6de5a12a9d | |||
3a418ab63b | |||
c8c0063499 | |||
34259e90cb | |||
d0c69d207c | |||
1f0818002c | |||
fd65958b88 | |||
12f674f404 | |||
413a0fb1ae | |||
85abfd2171 | |||
1601ee6f6a | |||
6898eab946 | |||
62a85f5e55 | |||
a8af8551ec | |||
7e0eccc4ef | |||
2a970a0af8 | |||
bd7f440357 | |||
d0437b3be0 | |||
1d844b9bd8 | |||
53e95233c3 | |||
879a674420 | |||
71f008f906 | |||
1197965e69 | |||
8154bbd538 | |||
f5e39999d7 | |||
ff33ab1379 | |||
7521834296 | |||
1185aa07a3 | |||
ceca5dded5 | |||
2a145f2463 | |||
e0dfa42d6e | |||
cc37af2314 | |||
87a679b210 | |||
a7359d494a | |||
66e6b932d8 | |||
cc49a91de7 | |||
300c2fec9c | |||
a7faa6bb65 | |||
bcc0a035cc | |||
e99bcbb4d4 | |||
adc9d5cdcb | |||
d330cd85ac | |||
09d6dc50ef | |||
7ac166ff08 | |||
ae4f81cbab | |||
c1fdfd4f14 | |||
62e4acc3d1 | |||
1091ddbb8e | |||
b45acb8d32 | |||
104abe04ba | |||
1bc807c81a | |||
d3b5e5696f | |||
34e4098e85 | |||
8dcf618411 | |||
7cc7955b5d | |||
a075260751 | |||
aba33de5f5 | |||
fe0782afa9 | |||
3545520e81 | |||
5ea9119322 | |||
2e355fd4d3 | |||
12f2101d08 | |||
d3a817549b | |||
c5493c192c | |||
d17084bf97 | |||
f150a304e8 | |||
886e3ebcca | |||
bf682d73d4 | |||
8f3695e20e | |||
829ddf95e5 | |||
fb10f62efc | |||
8197557fcf | |||
e7a0e87c41 | |||
ab9bc8a9ec | |||
469d2b4640 | |||
31796e8e2f | |||
284123c6ba | |||
7259208893 | |||
7e5f6c2dc1 | |||
97dc85ba5e | |||
a937889c3b | |||
aa8f1d569b | |||
5dba3bf1fd | |||
6651b4171d | |||
8c682c52b1 | |||
e5b09cc49a | |||
b199ef6bfc | |||
583a9d38a1 | |||
1fce6d6bae | |||
39f973430a | |||
20346ff192 | |||
bd9c1e6cfc | |||
d76a872efb | |||
a398d6af45 | |||
e836eaf448 | |||
ae364864f6 | |||
cc552dd702 | |||
021dd33ed8 | |||
684726cdac | |||
7b005bb9cf | |||
401ef71ae5 | |||
0a1d078a74 | |||
35502c739c | |||
b2ccc34f9c | |||
eaa38a5adc | |||
cb1373106b | |||
f6ee911cbb | |||
a3313709ea | |||
0eacba5829 | |||
bb924b63e6 | |||
7301e70ddd | |||
7edb026619 | |||
0b7845964b | |||
55979fe0ae | |||
6280cf95b4 | |||
8d817daf78 | |||
946f1179e9 | |||
87fdd23157 | |||
713fb3b587 | |||
0cb0f66c17 | |||
db11a0ddbf | |||
779344012a | |||
650974e1b3 | |||
ed3c549063 | |||
3a116179b1 | |||
5e64c2b1df | |||
d63ecf4c5f | |||
77efddcac3 | |||
d887ba85ad | |||
0c75a06b1e | |||
aaa20093b2 | |||
5568d824dd | |||
17996bf719 | |||
2a330a60ed | |||
569d1ef583 | |||
85b6c94cc6 | |||
818d93d7e9 | |||
d4c0962c7b | |||
e31208beb1 | |||
3569fdf451 | |||
eb6ba9ac80 | |||
4e7a4543b8 | |||
753fed285c | |||
dffcca73e4 | |||
c8f7fc22c7 | |||
b2bd38699b | |||
c025357fb8 | |||
57411c85b9 | |||
07a8016118 | |||
4d69da57ca | |||
7f98b87ca0 | |||
c61decf7e5 | |||
6e7bd939f6 | |||
2021ad12cf | |||
c4f4675ebf | |||
34827559b9 | |||
65c3888d01 | |||
e648a0c4ca | |||
965a688c97 | |||
ab3f4c9fe1 | |||
40f3bb5638 | |||
a08d18a1fe | |||
64d6f35f94 | |||
caa4ab3235 | |||
06a8ad28a7 | |||
382aa50c54 | |||
044a19966d | |||
17e98198f4 | |||
561c0f81a0 | |||
4414be77c4 | |||
1b55da10b1 | |||
78ea2527a1 | |||
4456e7e4de | |||
92c436dd1a | |||
b45f336635 | |||
c3651cec0b | |||
3b52f7066b | |||
8bb741198b | |||
26849ca99d | |||
4d0e175a65 | |||
bd7393fc68 | |||
08ff8aa055 | |||
f60d159d71 | |||
6aa5bfa21a | |||
227ba625e6 | |||
e64176019a | |||
1fc7891add | |||
e7930fcc15 | |||
4b40740324 | |||
a36667d984 | |||
9791c9ecaf | |||
df082307b9 | |||
98d820030c | |||
f001aef2dc | |||
64fc8b8ee5 | |||
a62c1c441c | |||
3d154ab795 | |||
d1ea1f4c7f | |||
5aeb9a4124 | |||
ecce99470a | |||
540c29cd6b | |||
7827501d2a | |||
e28f13a102 | |||
e0002ef9ba | |||
367f6fe12d | |||
9b3ca19675 | |||
9388e47e1e | |||
171d967993 | |||
40e357411e | |||
52c7aae4df | |||
87b1aeac0f | |||
93be1f1543 | |||
cdb5d07606 | |||
3e5fa56956 |
9
.bazelrc
9
.bazelrc
@ -136,6 +136,15 @@ build:remote --remote_executor=remotebuildexecution.googleapis.com
|
|||||||
# retry mechanism and we do not want to retry unnecessarily if Karma already tried multiple times.
|
# retry mechanism and we do not want to retry unnecessarily if Karma already tried multiple times.
|
||||||
test:saucelabs --flaky_test_attempts=1
|
test:saucelabs --flaky_test_attempts=1
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# NodeJS rules settings
|
||||||
|
# These settings are required for rules_nodejs
|
||||||
|
###############################
|
||||||
|
|
||||||
|
# Turn on managed directories feature in Bazel
|
||||||
|
# This allows us to avoid installing a second copy of node_modules
|
||||||
|
common --experimental_allow_incremental_repository_updates
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
# User bazel configuration
|
# User bazel configuration
|
||||||
# NOTE: This needs to be the *last* entry in the config.
|
# NOTE: This needs to be the *last* entry in the config.
|
||||||
|
@ -32,8 +32,8 @@ var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelver
|
|||||||
|
|
||||||
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
||||||
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
||||||
var_5: &components_repo_unit_tests_cache_key v9-angular-components-09e68db8ed5b1253f2fe38ff954ef0df019fc25a
|
var_5: &components_repo_unit_tests_cache_key v7-angular-components-f428c00465dfcf8a020237f22532480eedbd2cb6
|
||||||
var_6: &components_repo_unit_tests_cache_key_fallback v9-angular-components-
|
var_6: &components_repo_unit_tests_cache_key_fallback v7-angular-components-
|
||||||
|
|
||||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
||||||
# `build-ivy-npm-packages`.
|
# `build-ivy-npm-packages`.
|
||||||
@ -656,18 +656,6 @@ jobs:
|
|||||||
- run: yarn tsc -p packages
|
- run: yarn tsc -p packages
|
||||||
- run: yarn tsc -p modules
|
- run: yarn tsc -p modules
|
||||||
- run: yarn bazel build //packages/zone.js:npm_package
|
- run: yarn bazel build //packages/zone.js:npm_package
|
||||||
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
|
|
||||||
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
|
|
||||||
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
|
|
||||||
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
|
|
||||||
# test in all supported browsers on Saucelabs anyway until this job can be removed.
|
|
||||||
- run:
|
|
||||||
name: Preparing Bazel-generated fixtures required in legacy tests
|
|
||||||
command: |
|
|
||||||
yarn bazel build //packages/core/test:downleveled_es5_fixture
|
|
||||||
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
|
|
||||||
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
|
|
||||||
dist/all/@angular/core/test/reflection/es5_downleveled_inheritance_fixture.js
|
|
||||||
- run:
|
- run:
|
||||||
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
|
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
|
||||||
name: Waiting for Saucelabs tunnel to connect
|
name: Waiting for Saucelabs tunnel to connect
|
||||||
@ -743,8 +731,8 @@ jobs:
|
|||||||
- run: yarn --cwd packages/zone.js promisetest
|
- run: yarn --cwd packages/zone.js promisetest
|
||||||
- run: yarn --cwd packages/zone.js promisefinallytest
|
- run: yarn --cwd packages/zone.js promisefinallytest
|
||||||
- run: yarn bazel build //packages/zone.js:npm_package &&
|
- run: yarn bazel build //packages/zone.js:npm_package &&
|
||||||
cp dist/bin/packages/zone.js/npm_package/dist/zone-mix.js ./packages/zone.js/test/extra/ &&
|
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/ &&
|
||||||
cp dist/bin/packages/zone.js/npm_package/dist/zone-patch-electron.js ./packages/zone.js/test/extra/ &&
|
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ &&
|
||||||
yarn --cwd packages/zone.js electrontest
|
yarn --cwd packages/zone.js electrontest
|
||||||
- run: yarn --cwd packages/zone.js jesttest
|
- run: yarn --cwd packages/zone.js jesttest
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ setPublicVar COMPONENTS_REPO_TMP_DIR "/tmp/angular-components-repo"
|
|||||||
setPublicVar COMPONENTS_REPO_URL "https://github.com/angular/components.git"
|
setPublicVar COMPONENTS_REPO_URL "https://github.com/angular/components.git"
|
||||||
setPublicVar COMPONENTS_REPO_BRANCH "master"
|
setPublicVar COMPONENTS_REPO_BRANCH "master"
|
||||||
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI `config.yml`.
|
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI `config.yml`.
|
||||||
setPublicVar COMPONENTS_REPO_COMMIT "09e68db8ed5b1253f2fe38ff954ef0df019fc25a"
|
setPublicVar COMPONENTS_REPO_COMMIT "f428c00465dfcf8a020237f22532480eedbd2cb6"
|
||||||
|
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
|
69
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
69
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
@ -1,69 +0,0 @@
|
|||||||
---
|
|
||||||
name: "\U0001F41EBug report"
|
|
||||||
about: Report a bug in the Angular Framework
|
|
||||||
---
|
|
||||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
|
||||||
|
|
||||||
Oh hi there! 😄
|
|
||||||
|
|
||||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
|
||||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
|
||||||
|
|
||||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
|
||||||
|
|
||||||
|
|
||||||
# 🐞 bug report
|
|
||||||
|
|
||||||
### Affected Package
|
|
||||||
<!-- Can you pin-point one or more @angular/* packages as the source of the bug? -->
|
|
||||||
<!-- ✍️edit: --> The issue is caused by package @angular/....
|
|
||||||
|
|
||||||
|
|
||||||
### Is this a regression?
|
|
||||||
|
|
||||||
<!-- Did this behavior use to work in the previous version? -->
|
|
||||||
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
|
|
||||||
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<!-- ✍️--> A clear and concise description of the problem...
|
|
||||||
|
|
||||||
|
|
||||||
## 🔬 Minimal Reproduction
|
|
||||||
<!--
|
|
||||||
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-ivy
|
|
||||||
-->
|
|
||||||
<!-- ✍️--> https://stackblitz.com/...
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue.
|
|
||||||
A good way to make a minimal reproduction is to create a new app via `ng new repro-app` and add the minimum possible code to show the problem.
|
|
||||||
Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
|
|
||||||
|
|
||||||
Issues that don't have enough info and can't be reproduced will be closed.
|
|
||||||
|
|
||||||
You can read more about issue submission guidelines here: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-submitting-an-issue
|
|
||||||
-->
|
|
||||||
|
|
||||||
## 🔥 Exception or Error
|
|
||||||
<pre><code>
|
|
||||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
|
||||||
<!-- ✍️-->
|
|
||||||
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
|
|
||||||
## 🌍 Your Environment
|
|
||||||
|
|
||||||
**Angular Version:**
|
|
||||||
<pre><code>
|
|
||||||
<!-- run `ng version` and paste output below -->
|
|
||||||
<!-- ✍️-->
|
|
||||||
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
**Anything else relevant?**
|
|
||||||
<!-- ✍️Is this a browser specific issue? If so, please specify the browser and version. -->
|
|
||||||
|
|
||||||
<!-- ✍️Do any of these matter: operating system, IDE, package manager, HTTP server, ...? If so, please mention it below. -->
|
|
32
.github/ISSUE_TEMPLATE/2-feature-request.md
vendored
32
.github/ISSUE_TEMPLATE/2-feature-request.md
vendored
@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
name: "\U0001F680Feature request"
|
|
||||||
about: Suggest a feature for Angular Framework
|
|
||||||
|
|
||||||
---
|
|
||||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
|
||||||
|
|
||||||
Oh hi there! 😄
|
|
||||||
|
|
||||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
|
||||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
|
||||||
|
|
||||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
|
||||||
|
|
||||||
|
|
||||||
# 🚀 feature request
|
|
||||||
|
|
||||||
### Relevant Package
|
|
||||||
<!-- Can you pin-point one or more @angular/* packages the are relevant for this feature request? -->
|
|
||||||
<!-- ✍️edit: --> This feature request is for @angular/....
|
|
||||||
|
|
||||||
|
|
||||||
### Description
|
|
||||||
<!-- ✍️--> A clear and concise description of the problem or missing capability...
|
|
||||||
|
|
||||||
|
|
||||||
### Describe the solution you'd like
|
|
||||||
<!-- ✍️--> If you have a solution in mind, please describe it.
|
|
||||||
|
|
||||||
|
|
||||||
### Describe alternatives you've considered
|
|
||||||
<!-- ✍️--> Have you considered any alternative solutions or workarounds?
|
|
55
.github/ISSUE_TEMPLATE/3-docs-bug.md
vendored
55
.github/ISSUE_TEMPLATE/3-docs-bug.md
vendored
@ -1,55 +0,0 @@
|
|||||||
---
|
|
||||||
name: "📚 Docs or angular.io issue report"
|
|
||||||
about: Report an issue in Angular's documentation or angular.io application
|
|
||||||
|
|
||||||
---
|
|
||||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
|
||||||
|
|
||||||
Oh hi there! 😄
|
|
||||||
|
|
||||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
|
||||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
|
||||||
|
|
||||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
|
||||||
|
|
||||||
# 📚 Docs or angular.io bug report
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<!-- ✍️edit:--> A clear and concise description of the problem...
|
|
||||||
|
|
||||||
|
|
||||||
## 🔬 Minimal Reproduction
|
|
||||||
|
|
||||||
### What's the affected URL?**
|
|
||||||
<!-- ✍️edit:--> https://angular.io/...
|
|
||||||
|
|
||||||
### Reproduction Steps**
|
|
||||||
<!-- If applicable please list the steps to take to reproduce the issue -->
|
|
||||||
<!-- ✍️edit:-->
|
|
||||||
|
|
||||||
### Expected vs Actual Behavior**
|
|
||||||
<!-- If applicable please describe the difference between the expected and actual behavior after following the repro steps. -->
|
|
||||||
<!-- ✍️edit:-->
|
|
||||||
|
|
||||||
|
|
||||||
## 📷Screenshot
|
|
||||||
<!-- Often a screenshot can help to capture the issue better than a long description. -->
|
|
||||||
<!-- ✍️upload a screenshot:-->
|
|
||||||
|
|
||||||
|
|
||||||
## 🔥 Exception or Error
|
|
||||||
<pre><code>
|
|
||||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
|
||||||
<!-- ✍️-->
|
|
||||||
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
|
|
||||||
## 🌍 Your Environment
|
|
||||||
|
|
||||||
### Browser info
|
|
||||||
<!-- ✍️Is this a browser specific issue? If so, please specify the device, browser, and version. -->
|
|
||||||
|
|
||||||
### Anything else relevant?
|
|
||||||
<!-- ✍️Please provide additional info if necessary. -->
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
name: ⚠️ Security issue disclosure
|
|
||||||
about: Report a security issue in Angular Framework, Material, or CLI
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
|
||||||
|
|
||||||
Please read https://angular.io/guide/security#report-issues on how to disclose security related issues.
|
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
|
16
.github/ISSUE_TEMPLATE/5-support-request.md
vendored
16
.github/ISSUE_TEMPLATE/5-support-request.md
vendored
@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
name: "❓Support request"
|
|
||||||
about: Questions and requests for support
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
|
||||||
|
|
||||||
Please do not file questions or support requests on the GitHub issues tracker.
|
|
||||||
|
|
||||||
You can get your questions answered using other communication channels. Please see:
|
|
||||||
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
|
|
||||||
|
|
||||||
Thank you!
|
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
|
13
.github/ISSUE_TEMPLATE/6-angular-cli.md
vendored
13
.github/ISSUE_TEMPLATE/6-angular-cli.md
vendored
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
name: "\U0001F6E0️Angular CLI"
|
|
||||||
about: Issues and feature requests for Angular CLI
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
|
||||||
|
|
||||||
Please file any Angular CLI issues at: https://github.com/angular/angular-cli/issues/new
|
|
||||||
|
|
||||||
For the time being, we keep Angular CLI issues in a separate repository.
|
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
|
13
.github/ISSUE_TEMPLATE/7-angular-components.md
vendored
13
.github/ISSUE_TEMPLATE/7-angular-components.md
vendored
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
name: "\U0001F48EAngular Components"
|
|
||||||
about: Issues and feature requests for Angular Components
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
|
||||||
|
|
||||||
Please file any Angular Components issues at: https://github.com/angular/components/issues/new
|
|
||||||
|
|
||||||
For the time being, we keep Angular Components issues in a separate repository.
|
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
|
22
.github/ISSUE_TEMPLATE/8-translate-docs.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/8-translate-docs.md
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
name: "📚Traducir doc al español"
|
||||||
|
about: Solicitud para traducir ciertos docs al español
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
📚Traducir: <!-- ✍️ editar: --> creating-libraries.md
|
||||||
|
|
||||||
|
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||||
|
|
||||||
|
Traducción de la documentación oficial de Angular a español
|
||||||
|
|
||||||
|
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||||
|
|
||||||
|
|
||||||
|
## Nombre del archivo:
|
||||||
|
<!-- ✍️ editar: --> creating-libraries.md
|
||||||
|
|
||||||
|
|
||||||
|
## Ruta donde se encuentra el archivo dentro del proyecto de Angular
|
||||||
|
|
||||||
|
<!-- ✍️ editar: --> https://github.com/angular-hispano/angular/blob/master/aio/content/guide/creating-libraries.md
|
62
.github/PULL_REQUEST_TEMPLATE.md
vendored
62
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,43 +1,35 @@
|
|||||||
## PR Checklist
|
## Lista de Verificación del PR
|
||||||
Please check if your PR fulfills the following requirements:
|
Comprueba si tu PR cumple los siguientes requisitos:
|
||||||
|
|
||||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
|
- [ ] El mensaje de commit conforme con [nuestras reglas](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit)
|
||||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
- [ ] Prueba los cambios que agregaste (arreglo de bugs / funcionalidades)
|
||||||
- [ ] Docs have been added / updated (for bug fixes / features)
|
- [ ] Revisa tus traducciones o cambios de contenido
|
||||||
|
- [ ] Consulté el [diccionario de términos](https://github.com/angular-hispano/angular/issues/9) en español
|
||||||
|
- [ ] Se han creado dos archivos con la extensión correspondiente(.en.md para el archivo en inglés y .md para el Archivo en español)
|
||||||
|
- [ ] PR enlazada con el issue correspondiente
|
||||||
|
|
||||||
|
|
||||||
## PR Type
|
## Tipo de PR
|
||||||
What kind of change does this PR introduce?
|
¿Qué tipo de cambio introduce este PR?
|
||||||
|
|
||||||
<!-- Please check the one that applies to this PR using "x". -->
|
<!-- Marca con una "x" las opciones que aplican. -->
|
||||||
|
|
||||||
- [ ] Bugfix
|
- [ ] Bugfix
|
||||||
- [ ] Feature
|
- [ ] Funcionalidad
|
||||||
- [ ] Code style update (formatting, local variables)
|
- [ ] Actualizar el estilo del código (formato, variables locales)
|
||||||
- [ ] Refactoring (no functional changes, no api changes)
|
- [ ] Refactorización (no cambios en la funcionalidad, no cambios en el api)
|
||||||
- [ ] Build related changes
|
- [ ] Cambios relacionados al build
|
||||||
- [ ] CI related changes
|
- [ ] Cambios relacionados al CI (Integración continua)
|
||||||
- [ ] Documentation content changes
|
- [ ] Cambios en el contenido de la documentación
|
||||||
- [ ] angular.io application / infrastructure changes
|
- [ ] Cambios en la aplicación / infrastructura de angular.io
|
||||||
- [ ] Other... Please describe:
|
- [ ] Otro... Por favor describela:
|
||||||
|
|
||||||
|
## ¿Cuál es el comportamiento actual?
|
||||||
|
<!-- Describe el comportamiento actual que está modificando o vincule a un problema relevante.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
## What is the current behavior?
|
## ¿Cuál es el nuevo comportamiento?
|
||||||
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
|
<!--
|
||||||
|
Ejemplo: Archivo en inglés traducido al español
|
||||||
Issue Number: N/A
|
-->
|
||||||
|
|
||||||
|
|
||||||
## What is the new behavior?
|
|
||||||
|
|
||||||
|
|
||||||
## Does this PR introduce a breaking change?
|
|
||||||
|
|
||||||
- [ ] Yes
|
|
||||||
- [ ] No
|
|
||||||
|
|
||||||
|
|
||||||
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
|
|
||||||
|
|
||||||
|
|
||||||
## Other information
|
|
||||||
|
@ -7,6 +7,18 @@ export const commitMessage: CommitMessageConfig = {
|
|||||||
maxLineLength: 120,
|
maxLineLength: 120,
|
||||||
minBodyLength: 20,
|
minBodyLength: 20,
|
||||||
minBodyLengthTypeExcludes: ['docs'],
|
minBodyLengthTypeExcludes: ['docs'],
|
||||||
|
types: [
|
||||||
|
'build',
|
||||||
|
'ci',
|
||||||
|
'docs',
|
||||||
|
'feat',
|
||||||
|
'fix',
|
||||||
|
'perf',
|
||||||
|
'refactor',
|
||||||
|
'release',
|
||||||
|
'style',
|
||||||
|
'test',
|
||||||
|
],
|
||||||
scopes: [
|
scopes: [
|
||||||
'animations',
|
'animations',
|
||||||
'bazel',
|
'bazel',
|
||||||
|
173
.pullapprove.yml
173
.pullapprove.yml
@ -67,25 +67,6 @@ version: 3
|
|||||||
# Meta field that goes unused by PullApprove to allow for defining aliases to be
|
# Meta field that goes unused by PullApprove to allow for defining aliases to be
|
||||||
# used throughout the config.
|
# used throughout the config.
|
||||||
meta:
|
meta:
|
||||||
# The following groups have no file based conditions and will be initially `active` on all PRs
|
|
||||||
# - `global-approvers`
|
|
||||||
# - `global-docs-approvers`
|
|
||||||
# - `required-minimum-review`
|
|
||||||
#
|
|
||||||
# By checking the number of active/pending/rejected groups when these are excluded, we can determine
|
|
||||||
# if any other groups are matched.
|
|
||||||
#
|
|
||||||
# Note: Because all inactive groups start as pending, we are only checking pending and rejected active groups.
|
|
||||||
#
|
|
||||||
# Also note that the ordering of groups matters in this file. The only groups visible to the current
|
|
||||||
# one are those that appear above it.
|
|
||||||
no-groups-above-this-pending: &no-groups-above-this-pending
|
|
||||||
len(groups.active.pending.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
|
|
||||||
no-groups-above-this-rejected: &no-groups-above-this-rejected
|
|
||||||
len(groups.active.rejected.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
|
|
||||||
no-groups-above-this-active: &no-groups-above-this-active
|
|
||||||
len(groups.active.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
|
|
||||||
|
|
||||||
can-be-global-approved: &can-be-global-approved "\"global-approvers\" not in groups.approved"
|
can-be-global-approved: &can-be-global-approved "\"global-approvers\" not in groups.approved"
|
||||||
can-be-global-docs-approved: &can-be-global-docs-approved "\"global-docs-approvers\" not in groups.approved"
|
can-be-global-docs-approved: &can-be-global-docs-approved "\"global-docs-approvers\" not in groups.approved"
|
||||||
defaults: &defaults
|
defaults: &defaults
|
||||||
@ -115,54 +96,6 @@ pullapprove_conditions:
|
|||||||
|
|
||||||
|
|
||||||
groups:
|
groups:
|
||||||
# =========================================================
|
|
||||||
# Require review on all PRs
|
|
||||||
#
|
|
||||||
# All PRs require at least one review. This rule will not
|
|
||||||
# request any reviewers, however will require that at least
|
|
||||||
# one review is provided before the group is satisfied.
|
|
||||||
# =========================================================
|
|
||||||
required-minimum-review:
|
|
||||||
reviews:
|
|
||||||
request: 0 # Do not request any reviews from the reviewer group
|
|
||||||
required: 1 # Require that all PRs have approval from at least one of the users in the group
|
|
||||||
author_value: 0 # The author of the PR cannot provide an approval for themself
|
|
||||||
reviewers:
|
|
||||||
users:
|
|
||||||
- aikidave # Dave Shevitz
|
|
||||||
- alan-agius4 # Alan Agius
|
|
||||||
- alxhub # Alex Rickabaugh
|
|
||||||
- AndrewKushnir # Andrew Kushnir
|
|
||||||
- andrewseguin # Andrew Seguin
|
|
||||||
- atscott # Andrew Scott
|
|
||||||
- ayazhafiz # Ayaz Hafiz
|
|
||||||
- clydin # Charles Lyding
|
|
||||||
- crisbeto # Kristiyan Kostadinov
|
|
||||||
- dennispbrown # Denny Brown
|
|
||||||
- devversion # Paul Gschwendtner
|
|
||||||
- dgp1130 # Doug Parker
|
|
||||||
- filipesilva # Filipe Silva
|
|
||||||
- gkalpak # Georgios Kalpakas
|
|
||||||
- gregmagolan # Greg Magolan
|
|
||||||
- IgorMinar # Igor Minar
|
|
||||||
- jbogarthyde # Judy Bogart
|
|
||||||
- jelbourn # Jeremy Elbourn
|
|
||||||
- JiaLiPassion # Jia Li
|
|
||||||
- JoostK # Joost Koehoorn
|
|
||||||
- josephperrott # Joey Perrott
|
|
||||||
- juleskremer # Jules Kremer
|
|
||||||
- kapunahelewong # Kapunahele Wong
|
|
||||||
- kara # Kara Erickson
|
|
||||||
- kyliau # Keen Yee Liau
|
|
||||||
- manughub # Manu Murthy
|
|
||||||
- mgechev # Minko Gechev
|
|
||||||
- mhevery # Miško Hevery
|
|
||||||
- michaelprentice # Michael Prentice
|
|
||||||
- mmalerba # Miles Malerba
|
|
||||||
- petebacondarwin # Pete Bacon Darwin
|
|
||||||
- pkozlowski-opensource # Pawel Kozlowski
|
|
||||||
- StephenFluin # Stephen Fluin
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Global Approvers
|
# Global Approvers
|
||||||
#
|
#
|
||||||
@ -199,6 +132,57 @@ groups:
|
|||||||
required: 1
|
required: 1
|
||||||
reviewed_for: required
|
reviewed_for: required
|
||||||
|
|
||||||
|
# =========================================================
|
||||||
|
# Require review on all PRs
|
||||||
|
#
|
||||||
|
# All PRs require at least one review. This rule will not
|
||||||
|
# request any reviewers, however will require that at least
|
||||||
|
# one review is provided before the group is satisfied.
|
||||||
|
# =========================================================
|
||||||
|
required-minimum-review:
|
||||||
|
conditions:
|
||||||
|
- *can-be-global-approved
|
||||||
|
- *can-be-global-docs-approved
|
||||||
|
reviews:
|
||||||
|
request: 0 # Do not request any reviews from the reviewer group
|
||||||
|
required: 1 # Require that all PRs have approval from at least one of the users in the group
|
||||||
|
author_value: 0 # The author of the PR cannot provide an approval for themself
|
||||||
|
reviewers:
|
||||||
|
users:
|
||||||
|
- aikidave # Dave Shevitz
|
||||||
|
- alan-agius4 # Alan Agius
|
||||||
|
- alxhub # Alex Rickabaugh
|
||||||
|
- AndrewKushnir # Andrew Kushnir
|
||||||
|
- andrewseguin # Andrew Seguin
|
||||||
|
- atscott # Andrew Scott
|
||||||
|
- ayazhafiz # Ayaz Hafiz
|
||||||
|
- clydin # Charles Lyding
|
||||||
|
- crisbeto # Kristiyan Kostadinov
|
||||||
|
- dennispbrown # Denny Brown
|
||||||
|
- devversion # Paul Gschwendtner
|
||||||
|
- dgp1130 # Doug Parker
|
||||||
|
- filipesilva # Filipe Silva
|
||||||
|
- gkalpak # Georgios Kalpakas
|
||||||
|
- gregmagolan # Greg Magolan
|
||||||
|
- IgorMinar # Igor Minar
|
||||||
|
- jbogarthyde # Judy Bogart
|
||||||
|
- jelbourn # Jeremy Elbourn
|
||||||
|
- JiaLiPassion # Jia Li
|
||||||
|
- JoostK # Joost Koehoorn
|
||||||
|
- josephperrott # Joey Perrott
|
||||||
|
- juleskremer # Jules Kremer
|
||||||
|
- kapunahelewong # Kapunahele Wong
|
||||||
|
- kara # Kara Erickson
|
||||||
|
- kyliau # Keen Yee Liau
|
||||||
|
- manughub # Manu Murthy
|
||||||
|
- mgechev # Minko Gechev
|
||||||
|
- mhevery # Miško Hevery
|
||||||
|
- mmalerba # Miles Malerba
|
||||||
|
- petebacondarwin # Pete Bacon Darwin
|
||||||
|
- pkozlowski-opensource # Pawel Kozlowski
|
||||||
|
- Splaktar # Michael Prentice
|
||||||
|
- StephenFluin # Stephen Fluin
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Framework: Animations
|
# Framework: Animations
|
||||||
# =========================================================
|
# =========================================================
|
||||||
@ -332,6 +316,7 @@ groups:
|
|||||||
'aio/content/images/guide/dependency-injection-in-action/**',
|
'aio/content/images/guide/dependency-injection-in-action/**',
|
||||||
'aio/content/guide/dependency-injection-navtree.md',
|
'aio/content/guide/dependency-injection-navtree.md',
|
||||||
'aio/content/guide/dependency-injection-providers.md',
|
'aio/content/guide/dependency-injection-providers.md',
|
||||||
|
'aio/content/guide/lightweight-injection-tokens.md',
|
||||||
'aio/content/guide/displaying-data.md',
|
'aio/content/guide/displaying-data.md',
|
||||||
'aio/content/examples/displaying-data/**',
|
'aio/content/examples/displaying-data/**',
|
||||||
'aio/content/images/guide/displaying-data/**',
|
'aio/content/images/guide/displaying-data/**',
|
||||||
@ -505,8 +490,8 @@ groups:
|
|||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
'packages/core/src/i18n/**',
|
'packages/core/src/i18n/**',
|
||||||
'packages/core/src/render3/i18n/**',
|
'packages/core/src/render3/i18n.ts',
|
||||||
'packages/core/src/render3/instructions/i18n.ts',
|
'packages/core/src/render3/i18n.md',
|
||||||
'packages/core/src/render3/interfaces/i18n.ts',
|
'packages/core/src/render3/interfaces/i18n.ts',
|
||||||
'packages/common/locales/**',
|
'packages/common/locales/**',
|
||||||
'packages/common/src/i18n/**',
|
'packages/common/src/i18n/**',
|
||||||
@ -783,6 +768,21 @@ groups:
|
|||||||
- JiaLiPassion
|
- JiaLiPassion
|
||||||
- mhevery
|
- mhevery
|
||||||
|
|
||||||
|
# =========================================================
|
||||||
|
# in-memory-web-api
|
||||||
|
# =========================================================
|
||||||
|
in-memory-web-api:
|
||||||
|
conditions:
|
||||||
|
- *can-be-global-approved
|
||||||
|
- *can-be-global-docs-approved
|
||||||
|
- >
|
||||||
|
contains_any_globs(files, [
|
||||||
|
'packages/misc/angular-in-memory-web-api/**',
|
||||||
|
])
|
||||||
|
reviewers:
|
||||||
|
users:
|
||||||
|
- IgorMinar
|
||||||
|
- crisbeto
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Benchpress
|
# Benchpress
|
||||||
@ -863,7 +863,6 @@ groups:
|
|||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
'aio/content/guide/roadmap.md',
|
|
||||||
'aio/content/marketing/**',
|
'aio/content/marketing/**',
|
||||||
'aio/content/images/bios/**',
|
'aio/content/images/bios/**',
|
||||||
'aio/content/images/marketing/**',
|
'aio/content/images/marketing/**',
|
||||||
@ -1143,8 +1142,6 @@ groups:
|
|||||||
public-api:
|
public-api:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
conditions:
|
conditions:
|
||||||
- *no-groups-above-this-pending
|
|
||||||
- *no-groups-above-this-rejected
|
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
@ -1158,16 +1155,14 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- alxhub
|
- alxhub
|
||||||
- atscott
|
|
||||||
- jelbourn
|
- jelbourn
|
||||||
- petebacondarwin
|
- petebacondarwin
|
||||||
- pkozlowski-opensource
|
- pkozlowski-opensource
|
||||||
reviews:
|
reviews:
|
||||||
request: 4 # Request reviews from four people
|
request: -1 # request reviews from everyone
|
||||||
required: 3 # Require that three people approve
|
required: 3 # require at least 3 approvals
|
||||||
reviewed_for: required
|
reviewed_for: required
|
||||||
|
|
||||||
|
|
||||||
@ -1177,8 +1172,6 @@ groups:
|
|||||||
size-tracking:
|
size-tracking:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
conditions:
|
conditions:
|
||||||
- *no-groups-above-this-pending
|
|
||||||
- *no-groups-above-this-rejected
|
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
@ -1186,16 +1179,14 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- alxhub
|
- alxhub
|
||||||
- atscott
|
|
||||||
- jelbourn
|
- jelbourn
|
||||||
- petebacondarwin
|
- petebacondarwin
|
||||||
- pkozlowski-opensource
|
- pkozlowski-opensource
|
||||||
reviews:
|
reviews:
|
||||||
request: 4 # Request reviews from four people
|
request: -1 # request reviews from everyone
|
||||||
required: 2 # Require that two people approve
|
required: 2 # require at least 2 approvals
|
||||||
reviewed_for: required
|
reviewed_for: required
|
||||||
|
|
||||||
|
|
||||||
@ -1205,8 +1196,6 @@ groups:
|
|||||||
circular-dependencies:
|
circular-dependencies:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
conditions:
|
conditions:
|
||||||
- *no-groups-above-this-pending
|
|
||||||
- *no-groups-above-this-rejected
|
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
@ -1214,11 +1203,9 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- alxhub
|
|
||||||
- atscott
|
|
||||||
- jelbourn
|
- jelbourn
|
||||||
|
- josephperrott
|
||||||
- petebacondarwin
|
- petebacondarwin
|
||||||
- pkozlowski-opensource
|
- pkozlowski-opensource
|
||||||
|
|
||||||
@ -1240,10 +1227,7 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- alxhub
|
|
||||||
- atscott
|
|
||||||
- jelbourn
|
- jelbourn
|
||||||
- josephperrott
|
- josephperrott
|
||||||
- mhevery
|
- mhevery
|
||||||
@ -1273,7 +1257,14 @@ groups:
|
|||||||
# `global-approvers` can still approve PRs that match this `fallback` rule,
|
# `global-approvers` can still approve PRs that match this `fallback` rule,
|
||||||
# but that should be an exception and not an expectation.
|
# but that should be an exception and not an expectation.
|
||||||
conditions:
|
conditions:
|
||||||
- *no-groups-above-this-active
|
# The following groups have no file based conditions and will be initially `active` on all PRs
|
||||||
|
# - `global-approvers`
|
||||||
|
# - `global-docs-approvers`
|
||||||
|
# - `required-minimum-review`
|
||||||
|
#
|
||||||
|
# By checking the number of active groups when these are excluded, we can determine
|
||||||
|
# if any other groups are matched.
|
||||||
|
- len(groups.active.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
|
||||||
# When any of the `global-*` groups is approved, they cause other groups to deactivate.
|
# When any of the `global-*` groups is approved, they cause other groups to deactivate.
|
||||||
# In those cases, the condition above would evaluate to `true` while in reality, only a global
|
# In those cases, the condition above would evaluate to `true` while in reality, only a global
|
||||||
# approval has been provided. To ensure we don't activate the fallback group in such cases,
|
# approval has been provided. To ensure we don't activate the fallback group in such cases,
|
||||||
|
@ -20,9 +20,9 @@ filegroup(
|
|||||||
# do not sort
|
# do not sort
|
||||||
srcs = [
|
srcs = [
|
||||||
"@npm//:node_modules/core-js/client/core.js",
|
"@npm//:node_modules/core-js/client/core.js",
|
||||||
"//packages/zone.js/dist:zone.js",
|
"//packages/zone.js/bundles:zone.umd.js",
|
||||||
"//packages/zone.js/dist:zone-testing.js",
|
"//packages/zone.js/bundles:zone-testing.umd.js",
|
||||||
"//packages/zone.js/dist:task-tracking.js",
|
"//packages/zone.js/bundles:task-tracking.umd.js",
|
||||||
"//:test-events.js",
|
"//:test-events.js",
|
||||||
"//:third_party/shims_for_IE.js",
|
"//:third_party/shims_for_IE.js",
|
||||||
# Including systemjs because it defines `__eval`, which produces correct stack traces.
|
# Including systemjs because it defines `__eval`, which produces correct stack traces.
|
||||||
|
335
CHANGELOG.md
335
CHANGELOG.md
@ -1,116 +1,3 @@
|
|||||||
<a name="10.0.12"></a>
|
|
||||||
## 10.0.12 (2020-08-24)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler-cli:** adding references to const enums in runtime code ([#38542](https://github.com/angular/angular/issues/38542)) ([814b436](https://github.com/angular/angular/commit/814b436)), closes [#38513](https://github.com/angular/angular/issues/38513)
|
|
||||||
* **core:** remove closing body tag from inert DOM builder ([#38454](https://github.com/angular/angular/issues/38454)) ([5528536](https://github.com/angular/angular/commit/5528536))
|
|
||||||
* **localize:** include the last placeholder in parsed translation text ([#38452](https://github.com/angular/angular/issues/38452)) ([57d1a48](https://github.com/angular/angular/commit/57d1a48))
|
|
||||||
* **localize:** parse all parts of a translation with nested HTML ([#38452](https://github.com/angular/angular/issues/38452)) ([07b99f5](https://github.com/angular/angular/commit/07b99f5)), closes [#38422](https://github.com/angular/angular/issues/38422)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **language-service:** introduce hybrid visitor to locate AST node ([#38540](https://github.com/angular/angular/issues/38540)) ([66d8c22](https://github.com/angular/angular/commit/66d8c22))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.11"></a>
|
|
||||||
## 10.0.11 (2020-08-19)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **router:** ensure routerLinkActive updates when associated routerLinks change (resubmit of [#38349](https://github.com/angular/angular/issues/38349)) ([#38511](https://github.com/angular/angular/issues/38511)) ([0af9533](https://github.com/angular/angular/commit/0af9533)), closes [#18469](https://github.com/angular/angular/issues/18469)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.10"></a>
|
|
||||||
## 10.0.10 (2020-08-17)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **common:** Allow scrolling when browser supports scrollTo ([#38468](https://github.com/angular/angular/issues/38468)) ([b32126c](https://github.com/angular/angular/commit/b32126c)), closes [#30630](https://github.com/angular/angular/issues/30630)
|
|
||||||
* **core:** detect DI parameters in JIT mode for downleveled ES2015 classes ([#38500](https://github.com/angular/angular/issues/38500)) ([863acb6](https://github.com/angular/angular/commit/863acb6)), closes [#38453](https://github.com/angular/angular/issues/38453)
|
|
||||||
* **core:** error if CSS custom property in host binding has number in name ([#38432](https://github.com/angular/angular/issues/38432)) ([cb83b8a](https://github.com/angular/angular/commit/cb83b8a)), closes [#37292](https://github.com/angular/angular/issues/37292)
|
|
||||||
* **core:** fix multiple nested views removal from ViewContainerRef ([#38317](https://github.com/angular/angular/issues/38317)) ([d5e09f4](https://github.com/angular/angular/commit/d5e09f4)), closes [#38201](https://github.com/angular/angular/issues/38201)
|
|
||||||
* **ngcc:** detect synthesized delegate constructors for downleveled ES2015 classes ([#38500](https://github.com/angular/angular/issues/38500)) ([f3dd6c2](https://github.com/angular/angular/commit/f3dd6c2)), closes [#38453](https://github.com/angular/angular/issues/38453) [#38453](https://github.com/angular/angular/issues/38453)
|
|
||||||
* **router:** ensure routerLinkActive updates when associated routerLinks change ([#38349](https://github.com/angular/angular/issues/38349)) ([989e8a1](https://github.com/angular/angular/commit/989e8a1)), closes [#18469](https://github.com/angular/angular/issues/18469)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.9"></a>
|
|
||||||
## 10.0.9 (2020-08-12)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **common:** ensure scrollRestoration is writable ([#30630](https://github.com/angular/angular/issues/30630)) ([#38357](https://github.com/angular/angular/issues/38357)) ([58f4b3a](https://github.com/angular/angular/commit/58f4b3a)), closes [#30629](https://github.com/angular/angular/issues/30629)
|
|
||||||
* **compiler:** evaluate safe navigation expressions in correct binding order ([#37911](https://github.com/angular/angular/issues/37911)) ([f5b9d87](https://github.com/angular/angular/commit/f5b9d87)), closes [#37194](https://github.com/angular/angular/issues/37194)
|
|
||||||
* **compiler-cli:** avoid creating value expressions for symbols from type-only imports ([#38415](https://github.com/angular/angular/issues/38415)) ([ca2b4bc](https://github.com/angular/angular/commit/ca2b4bc)), closes [#37912](https://github.com/angular/angular/issues/37912)
|
|
||||||
* **compiler-cli:** infer quote expressions as any type in type checker ([#37917](https://github.com/angular/angular/issues/37917)) ([5b87c67](https://github.com/angular/angular/commit/5b87c67)), closes [#36568](https://github.com/angular/angular/issues/36568)
|
|
||||||
* **compiler-cli:** mark eager `NgModuleFactory` construction as not side effectful ([#38320](https://github.com/angular/angular/issues/38320)) ([016a41b](https://github.com/angular/angular/commit/016a41b)), closes [#38147](https://github.com/angular/angular/issues/38147)
|
|
||||||
* **compiler-cli:** match wrapHost parameter types within plugin interface ([#38004](https://github.com/angular/angular/issues/38004)) ([df01a82](https://github.com/angular/angular/commit/df01a82))
|
|
||||||
* **compiler-cli:** preserve quotes in class member names ([#38387](https://github.com/angular/angular/issues/38387)) ([c9acb7b](https://github.com/angular/angular/commit/c9acb7b)), closes [#38311](https://github.com/angular/angular/issues/38311)
|
|
||||||
* **core:** prevent NgModule scope being overwritten in JIT compiler ([#37795](https://github.com/angular/angular/issues/37795)) ([3acebdc](https://github.com/angular/angular/commit/3acebdc)), closes [#37105](https://github.com/angular/angular/issues/37105)
|
|
||||||
* **core:** queries not matching string injection tokens ([#38321](https://github.com/angular/angular/issues/38321)) ([32109dc](https://github.com/angular/angular/commit/32109dc)), closes [#38313](https://github.com/angular/angular/issues/38313) [#38315](https://github.com/angular/angular/issues/38315)
|
|
||||||
* **core:** Store the currently selected ICU in `LView` ([#38345](https://github.com/angular/angular/issues/38345)) ([ee5123f](https://github.com/angular/angular/commit/ee5123f))
|
|
||||||
* **platform-server:** remove styles added by ServerStylesHost on destruction ([#38367](https://github.com/angular/angular/issues/38367)) ([7f11149](https://github.com/angular/angular/commit/7f11149))
|
|
||||||
* **router:** prevent calling unsubscribe on undefined subscription in RouterPreloader ([#38344](https://github.com/angular/angular/issues/38344)) ([4151314](https://github.com/angular/angular/commit/4151314))
|
|
||||||
* **service-worker:** fix the chrome debugger syntax highlighter ([#38332](https://github.com/angular/angular/issues/38332)) ([f5d5bac](https://github.com/angular/angular/commit/f5d5bac))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.8"></a>
|
|
||||||
## 10.0.8 (2020-08-04)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler:** add PURE annotation to getInheritedFactory calls ([#38291](https://github.com/angular/angular/issues/38291)) ([03d8e31](https://github.com/angular/angular/commit/03d8e31))
|
|
||||||
* **compiler:** update unparsable character reference entity error messages ([#38319](https://github.com/angular/angular/issues/38319)) ([cea4678](https://github.com/angular/angular/commit/cea4678)), closes [#26067](https://github.com/angular/angular/issues/26067)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.7"></a>
|
|
||||||
## 10.0.7 (2020-07-30)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler:** Metadata should not include methods on Object.prototype ([#38292](https://github.com/angular/angular/issues/38292)) ([879ff08](https://github.com/angular/angular/commit/879ff08))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.6"></a>
|
|
||||||
## 10.0.6 (2020-07-28)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler:** share identical stylesheets between components in the same file ([#38213](https://github.com/angular/angular/issues/38213)) ([264950b](https://github.com/angular/angular/commit/264950b)), closes [#38204](https://github.com/angular/angular/issues/38204)
|
|
||||||
* **compiler-cli:** Add support for string literal class members ([#38226](https://github.com/angular/angular/issues/38226)) ([b1e7775](https://github.com/angular/angular/commit/b1e7775))
|
|
||||||
* **core:** `Attribute` decorator `attributeName` is mandatory ([#38131](https://github.com/angular/angular/issues/38131)) ([1c4fcce](https://github.com/angular/angular/commit/1c4fcce)), closes [#32658](https://github.com/angular/angular/issues/32658)
|
|
||||||
* **core:** unify the signature between ngZone and noopZone ([#37581](https://github.com/angular/angular/issues/37581)) ([d5264f5](https://github.com/angular/angular/commit/d5264f5))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.5"></a>
|
|
||||||
## 10.0.5 (2020-07-22)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler:** properly associate source spans for implicitly closed elements ([#38126](https://github.com/angular/angular/issues/38126)) ([e80278c](https://github.com/angular/angular/commit/e80278c)), closes [#36118](https://github.com/angular/angular/issues/36118)
|
|
||||||
* **compiler-cli:** ensure file_system handles mixed Windows drives ([#38030](https://github.com/angular/angular/issues/38030)) ([dba4023](https://github.com/angular/angular/commit/dba4023)), closes [#36777](https://github.com/angular/angular/issues/36777)
|
|
||||||
* **core:** Allow modification of lifecycle hooks any time before bootstrap ([#38119](https://github.com/angular/angular/issues/38119)) ([14b4718](https://github.com/angular/angular/commit/14b4718)), closes [#30497](https://github.com/angular/angular/issues/30497)
|
|
||||||
* **core:** error due to integer overflow when there are too many host bindings ([#38014](https://github.com/angular/angular/issues/38014)) ([7b6e73c](https://github.com/angular/angular/commit/7b6e73c)), closes [#37876](https://github.com/angular/angular/issues/37876) [#37876](https://github.com/angular/angular/issues/37876)
|
|
||||||
* **core:** incorrectly validating properties on ng-content and ng-container ([#37773](https://github.com/angular/angular/issues/37773)) ([17ddab9](https://github.com/angular/angular/commit/17ddab9))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.4"></a>
|
<a name="10.0.4"></a>
|
||||||
## 10.0.4 (2020-07-15)
|
## 10.0.4 (2020-07-15)
|
||||||
|
|
||||||
@ -131,6 +18,61 @@
|
|||||||
* **bazel:** provide LinkablePackageInfo from ng_module ([#37778](https://github.com/angular/angular/issues/37778)) ([6cd10a1](https://github.com/angular/angular/commit/6cd10a1)), closes [/github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl#L144-L146](https://github.com//github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl/issues/L144-L146)
|
* **bazel:** provide LinkablePackageInfo from ng_module ([#37778](https://github.com/angular/angular/issues/37778)) ([6cd10a1](https://github.com/angular/angular/commit/6cd10a1)), closes [/github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl#L144-L146](https://github.com//github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl/issues/L144-L146)
|
||||||
|
|
||||||
|
|
||||||
|
<a name="10.1.0-next.1"></a>
|
||||||
|
# 10.1.0-next.1 (2020-07-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **bazel:** ng_module rule does not expose flat module information in Ivy ([#36971](https://github.com/angular/angular/issues/36971)) ([1550663](https://github.com/angular/angular/commit/1550663))
|
||||||
|
* **compiler:** check more cases for pipe usage inside host bindings ([#37883](https://github.com/angular/angular/issues/37883)) ([9322b9a](https://github.com/angular/angular/commit/9322b9a)), closes [#34655](https://github.com/angular/angular/issues/34655) [#37610](https://github.com/angular/angular/issues/37610)
|
||||||
|
* **compiler-cli:** ensure file_system handles mixed Windows drives ([#37959](https://github.com/angular/angular/issues/37959)) ([6b31155](https://github.com/angular/angular/commit/6b31155)), closes [#36777](https://github.com/angular/angular/issues/36777)
|
||||||
|
* **language-service:** remove completion for string ([#37983](https://github.com/angular/angular/issues/37983)) ([10aba15](https://github.com/angular/angular/commit/10aba15))
|
||||||
|
* **ngcc:** report a warning if ngcc tries to use a solution-style tsconfig ([#38003](https://github.com/angular/angular/issues/38003)) ([b358495](https://github.com/angular/angular/commit/b358495)), closes [#36386](https://github.com/angular/angular/issues/36386)
|
||||||
|
* **router:** ensure duplicate popstate/hashchange events are handled correctly ([#37674](https://github.com/angular/angular/issues/37674)) ([9185c6e](https://github.com/angular/angular/commit/9185c6e)), closes [/github.com/angular/angular/issues/16710#issuecomment-646919529](https://github.com//github.com/angular/angular/issues/16710/issues/issuecomment-646919529) [#16710](https://github.com/angular/angular/issues/16710)
|
||||||
|
* **service-worker:** correctly handle relative base href ([#37922](https://github.com/angular/angular/issues/37922)) ([d19ef65](https://github.com/angular/angular/commit/d19ef65)), closes [#25055](https://github.com/angular/angular/issues/25055) [#25055](https://github.com/angular/angular/issues/25055)
|
||||||
|
* **service-worker:** correctly serve `ngsw/state` with a non-root SW scope ([#37922](https://github.com/angular/angular/issues/37922)) ([2156bee](https://github.com/angular/angular/commit/2156bee)), closes [#30505](https://github.com/angular/angular/issues/30505)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="10.1.0-next.0"></a>
|
||||||
|
# 10.1.0-next.0 (2020-07-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **common:** date pipe gives wrong week number ([#37632](https://github.com/angular/angular/issues/37632)) ([ef1fb6d](https://github.com/angular/angular/commit/ef1fb6d)), closes [#33961](https://github.com/angular/angular/issues/33961)
|
||||||
|
* **compiler-cli:** ensure source-maps can handle webpack:// protocol ([#32912](https://github.com/angular/angular/issues/32912)) ([decd95e](https://github.com/angular/angular/commit/decd95e))
|
||||||
|
* **compiler-cli:** only read source-map comment from last line ([#32912](https://github.com/angular/angular/issues/32912)) ([07a07e3](https://github.com/angular/angular/commit/07a07e3))
|
||||||
|
* **core:** determine required DOMParser feature availability ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([c509243](https://github.com/angular/angular/commit/c509243))
|
||||||
|
* **core:** do not trigger CSP alert/report in Firefox and Chrome ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([b950d46](https://github.com/angular/angular/commit/b950d46)), closes [#25214](https://github.com/angular/angular/issues/25214)
|
||||||
|
* **forms:** handle form groups/arrays own pending async validation ([#22575](https://github.com/angular/angular/issues/22575)) ([77b62a5](https://github.com/angular/angular/commit/77b62a5)), closes [#10064](https://github.com/angular/angular/issues/10064)
|
||||||
|
* **language-service:** non-existent module format in package output ([#37623](https://github.com/angular/angular/issues/37623)) ([413a0fb](https://github.com/angular/angular/commit/413a0fb))
|
||||||
|
* **router:** fix navigation ignoring logic to compare to the browser url ([#37716](https://github.com/angular/angular/issues/37716)) ([a5ffca0](https://github.com/angular/angular/commit/a5ffca0)), closes [#16710](https://github.com/angular/angular/issues/16710) [#13586](https://github.com/angular/angular/issues/13586)
|
||||||
|
* **router:** properly compare array queryParams for equality ([#37709](https://github.com/angular/angular/issues/37709)) ([#37860](https://github.com/angular/angular/issues/37860)) ([1801d0c](https://github.com/angular/angular/commit/1801d0c))
|
||||||
|
* **router:** remove parenthesis for primary outlet segment after removing auxiliary outlet segment ([#24656](https://github.com/angular/angular/issues/24656)) ([#37163](https://github.com/angular/angular/issues/37163)) ([71f008f](https://github.com/angular/angular/commit/71f008f))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **bazel:** provide LinkablePackageInfo from ng_module ([#37623](https://github.com/angular/angular/issues/37623)) ([6898eab](https://github.com/angular/angular/commit/6898eab))
|
||||||
|
* **compiler-cli:** add `SourceFile.getOriginalLocation()` to sourcemaps package ([#32912](https://github.com/angular/angular/issues/32912)) ([6abb8d0](https://github.com/angular/angular/commit/6abb8d0))
|
||||||
|
* **compiler-cli:** explain why an expression cannot be used in AOT compilations ([#37587](https://github.com/angular/angular/issues/37587)) ([712f1bd](https://github.com/angular/angular/commit/712f1bd))
|
||||||
|
* **core:** support injection token as predicate in queries ([#37506](https://github.com/angular/angular/issues/37506)) ([97dc85b](https://github.com/angular/angular/commit/97dc85b)), closes [#21152](https://github.com/angular/angular/issues/21152) [#36144](https://github.com/angular/angular/issues/36144)
|
||||||
|
* **localize:** expose `canParse()` diagnostics ([#37909](https://github.com/angular/angular/issues/37909)) ([ec32eba](https://github.com/angular/angular/commit/ec32eba)), closes [#37901](https://github.com/angular/angular/issues/37901)
|
||||||
|
* **localize:** implement message extraction tool ([#32912](https://github.com/angular/angular/issues/32912)) ([190561d](https://github.com/angular/angular/commit/190561d))
|
||||||
|
* **platform-browser:** Allow `sms`-URLs ([#31463](https://github.com/angular/angular/issues/31463)) ([fc5c34d](https://github.com/angular/angular/commit/fc5c34d)), closes [#31462](https://github.com/angular/angular/issues/31462)
|
||||||
|
* **platform-server:** add option for absolute URL HTTP support ([#37539](https://github.com/angular/angular/issues/37539)) ([d37049a](https://github.com/angular/angular/commit/d37049a)), closes [#37071](https://github.com/angular/angular/issues/37071)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **compiler-cli:** fix regressions in incremental program reuse ([#37641](https://github.com/angular/angular/issues/37641)) ([5103d90](https://github.com/angular/angular/commit/5103d90))
|
||||||
|
* **ngcc:** shortcircuit tokenizing in ESM dependency host ([#37639](https://github.com/angular/angular/issues/37639)) ([bd7f440](https://github.com/angular/angular/commit/bd7f440))
|
||||||
|
* **ngcc:** use `EntryPointManifest` to speed up noop `ProgramBaseEntryPointFinder` ([#37665](https://github.com/angular/angular/issues/37665)) ([9318e23](https://github.com/angular/angular/commit/9318e23))
|
||||||
|
* **router:** apply prioritizedGuardValue operator to optimize CanLoad guards ([#37523](https://github.com/angular/angular/issues/37523)) ([d7dd295](https://github.com/angular/angular/commit/d7dd295))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.3"></a>
|
<a name="10.0.3"></a>
|
||||||
## 10.0.3 (2020-07-08)
|
## 10.0.3 (2020-07-08)
|
||||||
@ -142,6 +84,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="9.1.12"></a>
|
||||||
|
## [9.1.12](https://github.com/angular/angular/compare/9.1.11...9.1.12) (2020-07-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **core:** infinite loop if injectable using inheritance has a custom decorator ([6c1ab47](https://github.com/angular/angular/commit/6c1ab47)), closes [#35733](https://github.com/angular/angular/issues/35733)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.2"></a>
|
<a name="10.0.2"></a>
|
||||||
## [10.0.2](https://github.com/angular/angular/compare/10.0.1...10.0.2) (2020-06-30)
|
## [10.0.2](https://github.com/angular/angular/compare/10.0.1...10.0.2) (2020-06-30)
|
||||||
|
|
||||||
@ -253,7 +205,6 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **compiler:** avoid undefined expressions in holey array ([#36343](https://github.com/angular/angular/issues/36343)) ([5516802](https://github.com/angular/angular/commit/5516802))
|
* **compiler:** avoid undefined expressions in holey array ([#36343](https://github.com/angular/angular/issues/36343)) ([5516802](https://github.com/angular/angular/commit/5516802))
|
||||||
* **compiler:** handle type references to namespaced symbols correctly ([#36106](https://github.com/angular/angular/issues/36106)) ([4aa4e6f](https://github.com/angular/angular/commit/4aa4e6f)), closes [#36006](https://github.com/angular/angular/issues/36006)
|
* **compiler:** handle type references to namespaced symbols correctly ([#36106](https://github.com/angular/angular/issues/36106)) ([4aa4e6f](https://github.com/angular/angular/commit/4aa4e6f)), closes [#36006](https://github.com/angular/angular/issues/36006)
|
||||||
* **compiler:** normalize line endings in ICU expansions ([#36741](https://github.com/angular/angular/issues/36741)) ([70dd27f](https://github.com/angular/angular/commit/70dd27f)), closes [#36725](https://github.com/angular/angular/issues/36725)
|
* **compiler:** normalize line endings in ICU expansions ([#36741](https://github.com/angular/angular/issues/36741)) ([70dd27f](https://github.com/angular/angular/commit/70dd27f)), closes [#36725](https://github.com/angular/angular/issues/36725)
|
||||||
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
|
|
||||||
* **compiler:** remove outdated and invalid warning for unresolved DI parameters ([#36985](https://github.com/angular/angular/issues/36985)) ([d0280a0](https://github.com/angular/angular/commit/d0280a0))
|
* **compiler:** remove outdated and invalid warning for unresolved DI parameters ([#36985](https://github.com/angular/angular/issues/36985)) ([d0280a0](https://github.com/angular/angular/commit/d0280a0))
|
||||||
* **compiler:** resolve enum values in binary operations ([#36461](https://github.com/angular/angular/issues/36461)) ([64022f5](https://github.com/angular/angular/commit/64022f5)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
* **compiler:** resolve enum values in binary operations ([#36461](https://github.com/angular/angular/issues/36461)) ([64022f5](https://github.com/angular/angular/commit/64022f5)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
||||||
* **compiler:** switch to 'referencedFiles' for shim generation ([#36211](https://github.com/angular/angular/issues/36211)) ([4213e8d](https://github.com/angular/angular/commit/4213e8d))
|
* **compiler:** switch to 'referencedFiles' for shim generation ([#36211](https://github.com/angular/angular/issues/36211)) ([4213e8d](https://github.com/angular/angular/commit/4213e8d))
|
||||||
@ -510,6 +461,30 @@ subscribe to the observable and call markForCheck as needed.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="9.1.11"></a>
|
||||||
|
## [9.1.11](https://github.com/angular/angular/compare/9.1.10...9.1.11) (2020-06-10)
|
||||||
|
|
||||||
|
### Reverts
|
||||||
|
|
||||||
|
* **elements:** fire custom element output events during component initialization ([dc9da17](https://github.com/angular/angular/commit/dc9da17))
|
||||||
|
|
||||||
|
|
||||||
|
<a name="9.1.10"></a>
|
||||||
|
## [9.1.10](https://github.com/angular/angular/compare/9.1.9...9.1.10) (2020-06-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **elements:** fire custom element output events during component initialization ([454e073](https://github.com/angular/angular/commit/454e073)), closes [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L167-L170](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts/issues/L167-L170) [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L164](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts/issues/L164) [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts#L158](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts/issues/L158) [#36141](https://github.com/angular/angular/issues/36141)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **ngcc:** cache parsed tsconfig between runs ([1aae94a](https://github.com/angular/angular/commit/1aae94a)), closes [#37417](https://github.com/angular/angular/issues/37417) [#36882](https://github.com/angular/angular/issues/36882)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.9"></a>
|
<a name="9.1.9"></a>
|
||||||
## [9.1.9](https://github.com/angular/angular/compare/9.1.8...9.1.9) (2020-05-20)
|
## [9.1.9](https://github.com/angular/angular/compare/9.1.8...9.1.9) (2020-05-20)
|
||||||
|
|
||||||
@ -551,6 +526,7 @@ This release contains various API docs improvements.
|
|||||||
* **compiler-cli**: Revert "fix(compiler-cli): fix case-sensitivity issues in NgtscCompilerHost (#36968)" (#37003)
|
* **compiler-cli**: Revert "fix(compiler-cli): fix case-sensitivity issues in NgtscCompilerHost (#36968)" (#37003)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.5"></a>
|
<a name="9.1.5"></a>
|
||||||
## [9.1.5](https://github.com/angular/angular/compare/9.1.4...9.1.5) (2020-05-07)
|
## [9.1.5](https://github.com/angular/angular/compare/9.1.4...9.1.5) (2020-05-07)
|
||||||
|
|
||||||
@ -596,6 +572,7 @@ This release contains various API docs improvements.
|
|||||||
* **ngcc:** recognize enum declarations emitted in JavaScript ([#36550](https://github.com/angular/angular/issues/36550)) ([c440165](https://github.com/angular/angular/commit/c440165)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
* **ngcc:** recognize enum declarations emitted in JavaScript ([#36550](https://github.com/angular/angular/issues/36550)) ([c440165](https://github.com/angular/angular/commit/c440165)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.3"></a>
|
<a name="9.1.3"></a>
|
||||||
## [9.1.3](https://github.com/angular/angular/compare/9.1.2...9.1.3) (2020-04-22)
|
## [9.1.3](https://github.com/angular/angular/compare/9.1.2...9.1.3) (2020-04-22)
|
||||||
|
|
||||||
@ -610,8 +587,8 @@ This release contains various API docs improvements.
|
|||||||
* **core:** prevent unknown property check for AOT-compiled components ([#36072](https://github.com/angular/angular/issues/36072)) ([fe1d9ba](https://github.com/angular/angular/commit/fe1d9ba)), closes [#35945](https://github.com/angular/angular/issues/35945)
|
* **core:** prevent unknown property check for AOT-compiled components ([#36072](https://github.com/angular/angular/issues/36072)) ([fe1d9ba](https://github.com/angular/angular/commit/fe1d9ba)), closes [#35945](https://github.com/angular/angular/issues/35945)
|
||||||
* **core:** properly identify modules affected by overrides in TestBed ([#36649](https://github.com/angular/angular/issues/36649)) ([9724169](https://github.com/angular/angular/commit/9724169)), closes [#36619](https://github.com/angular/angular/issues/36619)
|
* **core:** properly identify modules affected by overrides in TestBed ([#36649](https://github.com/angular/angular/issues/36649)) ([9724169](https://github.com/angular/angular/commit/9724169)), closes [#36619](https://github.com/angular/angular/issues/36619)
|
||||||
* **language-service:** properly evaluate types in comparable expressions ([#36529](https://github.com/angular/angular/issues/36529)) ([5bab498](https://github.com/angular/angular/commit/5bab498))
|
* **language-service:** properly evaluate types in comparable expressions ([#36529](https://github.com/angular/angular/issues/36529)) ([5bab498](https://github.com/angular/angular/commit/5bab498))
|
||||||
* **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([da159bd](https://github.com/angular/angular/commit/da159bd)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596#issuecomment-250890218)
|
* **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([da159bd](https://github.com/angular/angular/commit/da159bd)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596/issues/issuecomment-250890218)
|
||||||
* **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([18be33a](https://github.com/angular/angular/commit/18be33a)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860#issuecomment-614694269)
|
* **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([18be33a](https://github.com/angular/angular/commit/18be33a)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860/issues/issuecomment-614694269)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -632,7 +609,7 @@ This release contains various API docs improvements.
|
|||||||
* **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([a67afcc](https://github.com/angular/angular/commit/a67afcc)), closes [#36492](https://github.com/angular/angular/issues/36492)
|
* **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([a67afcc](https://github.com/angular/angular/commit/a67afcc)), closes [#36492](https://github.com/angular/angular/issues/36492)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
* **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([e06512b](https://github.com/angular/angular/commit/e06512b)) * **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([918e628](https://github.com/angular/angular/commit/918e628)), closes [#issuecomment-608401834](https://github.com/angular/angular#issuecomment-608401834)
|
* **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([e06512b](https://github.com/angular/angular/commit/e06512b)) * **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([918e628](https://github.com/angular/angular/commit/918e628)), closes [#issuecomment-608401834](https://github.com/angular/angular/issues/issuecomment-608401834)
|
||||||
* **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([603b094](https://github.com/angular/angular/commit/603b094))
|
* **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([603b094](https://github.com/angular/angular/commit/603b094))
|
||||||
|
|
||||||
|
|
||||||
@ -652,7 +629,7 @@ This release contains various API docs improvements.
|
|||||||
* **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([a631b99](https://github.com/angular/angular/commit/a631b99))
|
* **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([a631b99](https://github.com/angular/angular/commit/a631b99))
|
||||||
* **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([ff523c9](https://github.com/angular/angular/commit/ff523c9)), closes [#36191](https://github.com/angular/angular/issues/36191)
|
* **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([ff523c9](https://github.com/angular/angular/commit/ff523c9)), closes [#36191](https://github.com/angular/angular/issues/36191)
|
||||||
* **language-service:** use the `HtmlAst` to get the span of HTML tag ([#36371](https://github.com/angular/angular/issues/36371)) ([ffa4e11](https://github.com/angular/angular/commit/ffa4e11))
|
* **language-service:** use the `HtmlAst` to get the span of HTML tag ([#36371](https://github.com/angular/angular/issues/36371)) ([ffa4e11](https://github.com/angular/angular/commit/ffa4e11))
|
||||||
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([136596d](https://github.com/angular/angular/commit/136596d)), closes [36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414#issuecomment-609644282)
|
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([136596d](https://github.com/angular/angular/commit/136596d)), closes [/github.com/angular/angular/issues/36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414/issues/issuecomment-609644282)
|
||||||
* **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([cb0a2a0](https://github.com/angular/angular/commit/cb0a2a0))
|
* **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([cb0a2a0](https://github.com/angular/angular/commit/cb0a2a0))
|
||||||
* **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([879457c](https://github.com/angular/angular/commit/879457c)), closes [#36089](https://github.com/angular/angular/issues/36089)
|
* **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([879457c](https://github.com/angular/angular/commit/879457c)), closes [#36089](https://github.com/angular/angular/issues/36089)
|
||||||
* **ngcc:** correctly identify relative Windows-style import paths ([#36372](https://github.com/angular/angular/issues/36372)) ([0daa488](https://github.com/angular/angular/commit/0daa488))
|
* **ngcc:** correctly identify relative Windows-style import paths ([#36372](https://github.com/angular/angular/issues/36372)) ([0daa488](https://github.com/angular/angular/commit/0daa488))
|
||||||
@ -729,12 +706,9 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **animations:** allow computeStyle to work on elements created in Node ([#35810](https://github.com/angular/angular/issues/35810)) ([17cf04e](https://github.com/angular/angular/commit/17cf04e))
|
* **animations:** allow computeStyle to work on elements created in Node ([#35810](https://github.com/angular/angular/issues/35810)) ([17cf04e](https://github.com/angular/angular/commit/17cf04e))
|
||||||
* **animations:** false positive when detecting Node in Webpack builds ([#35134](https://github.com/angular/angular/issues/35134)) ([dc4ae4b](https://github.com/angular/angular/commit/dc4ae4b)), closes [#35117](https://github.com/angular/angular/issues/35117)
|
* **animations:** false positive when detecting Node in Webpack builds ([#35134](https://github.com/angular/angular/issues/35134)) ([dc4ae4b](https://github.com/angular/angular/commit/dc4ae4b)), closes [#35117](https://github.com/angular/angular/issues/35117)
|
||||||
* **animations:** process shorthand `margin` and `padding` styles correctly ([#35701](https://github.com/angular/angular/issues/35701)) ([35c9f0d](https://github.com/angular/angular/commit/35c9f0d)), closes [#35463](https://github.com/angular/angular/issues/35463)
|
* **animations:** process shorthand `margin` and `padding` styles correctly ([#35701](https://github.com/angular/angular/issues/35701)) ([35c9f0d](https://github.com/angular/angular/commit/35c9f0d)), closes [#35463](https://github.com/angular/angular/issues/35463)
|
||||||
* **bazel:** devserver shows blank page in Windows ([#35159](https://github.com/angular/angular/issues/35159)) ([727f92f](https://github.com/angular/angular/commit/727f92f))
|
|
||||||
* **bazel:** do not use manifest paths for generated imports within compilation unit ([#35841](https://github.com/angular/angular/issues/35841)) ([9581658](https://github.com/angular/angular/commit/9581658))
|
* **bazel:** do not use manifest paths for generated imports within compilation unit ([#35841](https://github.com/angular/angular/issues/35841)) ([9581658](https://github.com/angular/angular/commit/9581658))
|
||||||
* **bazel:** ng_package rule creates incorrect UMD module exports ([#35792](https://github.com/angular/angular/issues/35792)) ([5c2a908](https://github.com/angular/angular/commit/5c2a908)), closes [angular/components#18652](https://github.com/angular/components/issues/18652)
|
* **bazel:** ng_package rule creates incorrect UMD module exports ([#35792](https://github.com/angular/angular/issues/35792)) ([5c2a908](https://github.com/angular/angular/commit/5c2a908)), closes [angular/components#18652](https://github.com/angular/components/issues/18652)
|
||||||
* **bazel:** prod server doesn't serve files in windows ([#35991](https://github.com/angular/angular/issues/35991)) ([96e3449](https://github.com/angular/angular/commit/96e3449))
|
* **bazel:** prod server doesn't serve files in windows ([#35991](https://github.com/angular/angular/issues/35991)) ([96e3449](https://github.com/angular/angular/commit/96e3449))
|
||||||
* **bazel:** spawn prod server using port 4200 ([#35160](https://github.com/angular/angular/issues/35160)) ([829f506](https://github.com/angular/angular/commit/829f506))
|
|
||||||
* **bazel:** update ibazel to 0.11.1 ([#35158](https://github.com/angular/angular/issues/35158)) ([4e6d237](https://github.com/angular/angular/commit/4e6d237))
|
|
||||||
* **bazel:** update several packages for better windows support ([#35991](https://github.com/angular/angular/issues/35991)) ([32f099a](https://github.com/angular/angular/commit/32f099a))
|
* **bazel:** update several packages for better windows support ([#35991](https://github.com/angular/angular/issues/35991)) ([32f099a](https://github.com/angular/angular/commit/32f099a))
|
||||||
* **bazel:** update typescript peer dependency range ([#36013](https://github.com/angular/angular/issues/36013)) ([5e3a898](https://github.com/angular/angular/commit/5e3a898))
|
* **bazel:** update typescript peer dependency range ([#36013](https://github.com/angular/angular/issues/36013)) ([5e3a898](https://github.com/angular/angular/commit/5e3a898))
|
||||||
* **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([407fa42](https://github.com/angular/angular/commit/407fa42)), closes [#35743](https://github.com/angular/angular/issues/35743)
|
* **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([407fa42](https://github.com/angular/angular/commit/407fa42)), closes [#35743](https://github.com/angular/angular/issues/35743)
|
||||||
@ -743,7 +717,6 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([2ce5fa3](https://github.com/angular/angular/commit/2ce5fa3))
|
* **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([2ce5fa3](https://github.com/angular/angular/commit/2ce5fa3))
|
||||||
* **compiler:** do not recurse to find static symbols of same module ([#35262](https://github.com/angular/angular/issues/35262)) ([e179c58](https://github.com/angular/angular/commit/e179c58))
|
* **compiler:** do not recurse to find static symbols of same module ([#35262](https://github.com/angular/angular/issues/35262)) ([e179c58](https://github.com/angular/angular/commit/e179c58))
|
||||||
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
|
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
|
||||||
* **compiler:** report errors for missing binding names ([#34595](https://github.com/angular/angular/issues/34595)) ([d13cab7](https://github.com/angular/angular/commit/d13cab7))
|
|
||||||
* **compiler:** support directive inputs with interpolations on `<ng-template>`s ([#35984](https://github.com/angular/angular/issues/35984)) ([79659ee](https://github.com/angular/angular/commit/79659ee)), closes [#35752](https://github.com/angular/angular/issues/35752)
|
* **compiler:** support directive inputs with interpolations on `<ng-template>`s ([#35984](https://github.com/angular/angular/issues/35984)) ([79659ee](https://github.com/angular/angular/commit/79659ee)), closes [#35752](https://github.com/angular/angular/issues/35752)
|
||||||
* **compiler:** support i18n attributes on `<ng-template>` tags ([#35681](https://github.com/angular/angular/issues/35681)) ([40da51f](https://github.com/angular/angular/commit/40da51f))
|
* **compiler:** support i18n attributes on `<ng-template>` tags ([#35681](https://github.com/angular/angular/issues/35681)) ([40da51f](https://github.com/angular/angular/commit/40da51f))
|
||||||
* **compiler:** type-checking error for duplicate variables in templates ([#35674](https://github.com/angular/angular/issues/35674)) ([2c41bb8](https://github.com/angular/angular/commit/2c41bb8)), closes [#35186](https://github.com/angular/angular/issues/35186)
|
* **compiler:** type-checking error for duplicate variables in templates ([#35674](https://github.com/angular/angular/issues/35674)) ([2c41bb8](https://github.com/angular/angular/commit/2c41bb8)), closes [#35186](https://github.com/angular/angular/issues/35186)
|
||||||
@ -781,19 +754,13 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([f71d132](https://github.com/angular/angular/commit/f71d132))
|
* **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([f71d132](https://github.com/angular/angular/commit/f71d132))
|
||||||
* **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([e066bdd](https://github.com/angular/angular/commit/e066bdd))
|
* **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([e066bdd](https://github.com/angular/angular/commit/e066bdd))
|
||||||
* **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([447a600](https://github.com/angular/angular/commit/447a600)), closes [#36130](https://github.com/angular/angular/issues/36130)
|
* **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([447a600](https://github.com/angular/angular/commit/447a600)), closes [#36130](https://github.com/angular/angular/issues/36130)
|
||||||
* **elements:** schematics fail with schema.json not found error ([#35211](https://github.com/angular/angular/issues/35211)) ([94d002b](https://github.com/angular/angular/commit/94d002b)), closes [#35154](https://github.com/angular/angular/issues/35154)
|
|
||||||
* **forms:** change Array.reduce usage to Array.forEach ([#35349](https://github.com/angular/angular/issues/35349)) ([554c2cb](https://github.com/angular/angular/commit/554c2cb))
|
|
||||||
* **ivy:** `LFrame` needs to release memory on `leaveView()` ([#35156](https://github.com/angular/angular/issues/35156)) ([b9b512f](https://github.com/angular/angular/commit/b9b512f)), closes [#35148](https://github.com/angular/angular/issues/35148)
|
* **ivy:** `LFrame` needs to release memory on `leaveView()` ([#35156](https://github.com/angular/angular/issues/35156)) ([b9b512f](https://github.com/angular/angular/commit/b9b512f)), closes [#35148](https://github.com/angular/angular/issues/35148)
|
||||||
* **ivy:** add attributes and classes to host elements based on selector ([#34481](https://github.com/angular/angular/issues/34481)) ([f95b8ce](https://github.com/angular/angular/commit/f95b8ce))
|
* **ivy:** add attributes and classes to host elements based on selector ([#34481](https://github.com/angular/angular/issues/34481)) ([f95b8ce](https://github.com/angular/angular/commit/f95b8ce))
|
||||||
* **ivy:** ensure module imports are instantiated before the module being declared ([#35172](https://github.com/angular/angular/issues/35172)) ([b6a3a73](https://github.com/angular/angular/commit/b6a3a73))
|
|
||||||
* **ivy:** error if directive with synthetic property binding is on same node as directive that injects ViewContainerRef ([#35343](https://github.com/angular/angular/issues/35343)) ([d6bc63f](https://github.com/angular/angular/commit/d6bc63f)), closes [#35342](https://github.com/angular/angular/issues/35342)
|
* **ivy:** error if directive with synthetic property binding is on same node as directive that injects ViewContainerRef ([#35343](https://github.com/angular/angular/issues/35343)) ([d6bc63f](https://github.com/angular/angular/commit/d6bc63f)), closes [#35342](https://github.com/angular/angular/issues/35342)
|
||||||
* **ivy:** narrow `NgIf` context variables in template type checker ([#35125](https://github.com/angular/angular/issues/35125)) ([40039d8](https://github.com/angular/angular/commit/40039d8)), closes [#34572](https://github.com/angular/angular/issues/34572)
|
* **ivy:** narrow `NgIf` context variables in template type checker ([#35125](https://github.com/angular/angular/issues/35125)) ([40039d8](https://github.com/angular/angular/commit/40039d8)), closes [#34572](https://github.com/angular/angular/issues/34572)
|
||||||
* **ivy:** queries should match elements inside ng-container with the descendants: false option ([#35384](https://github.com/angular/angular/issues/35384)) ([3f4e02b](https://github.com/angular/angular/commit/3f4e02b)), closes [#34768](https://github.com/angular/angular/issues/34768)
|
* **ivy:** queries should match elements inside ng-container with the descendants: false option ([#35384](https://github.com/angular/angular/issues/35384)) ([3f4e02b](https://github.com/angular/angular/commit/3f4e02b)), closes [#34768](https://github.com/angular/angular/issues/34768)
|
||||||
* **ivy:** repeat template guards to narrow types in event handlers ([#35193](https://github.com/angular/angular/issues/35193)) ([dea1b96](https://github.com/angular/angular/commit/dea1b96)), closes [#35073](https://github.com/angular/angular/issues/35073)
|
|
||||||
* **ivy:** set namespace for host elements of dynamically created components ([#35136](https://github.com/angular/angular/issues/35136)) ([480a4c3](https://github.com/angular/angular/commit/480a4c3))
|
|
||||||
* **ivy:** support dynamic query tokens in AOT mode ([#35307](https://github.com/angular/angular/issues/35307)) ([3e3a1ef](https://github.com/angular/angular/commit/3e3a1ef)), closes [#34267](https://github.com/angular/angular/issues/34267)
|
* **ivy:** support dynamic query tokens in AOT mode ([#35307](https://github.com/angular/angular/issues/35307)) ([3e3a1ef](https://github.com/angular/angular/commit/3e3a1ef)), closes [#34267](https://github.com/angular/angular/issues/34267)
|
||||||
* **ivy:** wrong context passed to ngOnDestroy when resolved multiple times ([#35249](https://github.com/angular/angular/issues/35249)) ([5fbfe69](https://github.com/angular/angular/commit/5fbfe69)), closes [#35167](https://github.com/angular/angular/issues/35167)
|
* **ivy:** wrong context passed to ngOnDestroy when resolved multiple times ([#35249](https://github.com/angular/angular/issues/35249)) ([5fbfe69](https://github.com/angular/angular/commit/5fbfe69)), closes [#35167](https://github.com/angular/angular/issues/35167)
|
||||||
* **language-service:** Suggest ? and ! operator on nullable receiver ([#35200](https://github.com/angular/angular/issues/35200)) ([3cc24a9](https://github.com/angular/angular/commit/3cc24a9))
|
|
||||||
* **language-service:** fix calculation of pipe spans ([#35986](https://github.com/angular/angular/issues/35986)) ([406419b](https://github.com/angular/angular/commit/406419b))
|
* **language-service:** fix calculation of pipe spans ([#35986](https://github.com/angular/angular/issues/35986)) ([406419b](https://github.com/angular/angular/commit/406419b))
|
||||||
* **language-service:** get the right 'ElementAst' in the nested HTML tag ([#35317](https://github.com/angular/angular/issues/35317)) ([8e354da](https://github.com/angular/angular/commit/8e354da))
|
* **language-service:** get the right 'ElementAst' in the nested HTML tag ([#35317](https://github.com/angular/angular/issues/35317)) ([8e354da](https://github.com/angular/angular/commit/8e354da))
|
||||||
* **language-service:** infer $implicit value for ngIf template contexts ([#35941](https://github.com/angular/angular/issues/35941)) ([18b1bd4](https://github.com/angular/angular/commit/18b1bd4))
|
* **language-service:** infer $implicit value for ngIf template contexts ([#35941](https://github.com/angular/angular/issues/35941)) ([18b1bd4](https://github.com/angular/angular/commit/18b1bd4))
|
||||||
@ -818,7 +785,6 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ngcc:** correctly detect outer aliased class identifiers in ES5 ([#35527](https://github.com/angular/angular/issues/35527)) ([fde8915](https://github.com/angular/angular/commit/fde8915)), closes [#35399](https://github.com/angular/angular/issues/35399)
|
* **ngcc:** correctly detect outer aliased class identifiers in ES5 ([#35527](https://github.com/angular/angular/issues/35527)) ([fde8915](https://github.com/angular/angular/commit/fde8915)), closes [#35399](https://github.com/angular/angular/issues/35399)
|
||||||
* **ngcc:** do not crash on entry-point that fails to compile ([#36083](https://github.com/angular/angular/issues/36083)) ([ff665b9](https://github.com/angular/angular/commit/ff665b9))
|
* **ngcc:** do not crash on entry-point that fails to compile ([#36083](https://github.com/angular/angular/issues/36083)) ([ff665b9](https://github.com/angular/angular/commit/ff665b9))
|
||||||
* **ngcc:** do not crash on overlapping entry-points ([#36083](https://github.com/angular/angular/issues/36083)) ([c9f554c](https://github.com/angular/angular/commit/c9f554c))
|
* **ngcc:** do not crash on overlapping entry-points ([#36083](https://github.com/angular/angular/issues/36083)) ([c9f554c](https://github.com/angular/angular/commit/c9f554c))
|
||||||
* **ngcc:** ensure that path-mapped secondary entry-points are processed correctly ([#35227](https://github.com/angular/angular/issues/35227)) ([c3c1140](https://github.com/angular/angular/commit/c3c1140)), closes [#35188](https://github.com/angular/angular/issues/35188)
|
|
||||||
* **ngcc:** handle imports in dts files when processing CommonJS ([#35191](https://github.com/angular/angular/issues/35191)) ([b6e8847](https://github.com/angular/angular/commit/b6e8847)), closes [#34356](https://github.com/angular/angular/issues/34356)
|
* **ngcc:** handle imports in dts files when processing CommonJS ([#35191](https://github.com/angular/angular/issues/35191)) ([b6e8847](https://github.com/angular/angular/commit/b6e8847)), closes [#34356](https://github.com/angular/angular/issues/34356)
|
||||||
* **ngcc:** handle mappings outside the content when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([73cf7d5](https://github.com/angular/angular/commit/73cf7d5)), closes [#35709](https://github.com/angular/angular/issues/35709)
|
* **ngcc:** handle mappings outside the content when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([73cf7d5](https://github.com/angular/angular/commit/73cf7d5)), closes [#35709](https://github.com/angular/angular/issues/35709)
|
||||||
* **ngcc:** handle missing sources when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([72c4fda](https://github.com/angular/angular/commit/72c4fda)), closes [#35709](https://github.com/angular/angular/issues/35709)
|
* **ngcc:** handle missing sources when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([72c4fda](https://github.com/angular/angular/commit/72c4fda)), closes [#35709](https://github.com/angular/angular/issues/35709)
|
||||||
@ -1076,7 +1042,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **compiler-cli:** require node 10 as runtime engine ([#34722](https://github.com/angular/angular/issues/34722)) ([7b77b3d](https://github.com/angular/angular/commit/7b77b3d))
|
* **compiler-cli:** require node 10 as runtime engine ([#34722](https://github.com/angular/angular/issues/34722)) ([7b77b3d](https://github.com/angular/angular/commit/7b77b3d))
|
||||||
* **language-service:** specific suggestions for template context diags ([#34751](https://github.com/angular/angular/issues/34751)) ([cc7fca4](https://github.com/angular/angular/commit/cc7fca4))
|
* **language-service:** specific suggestions for template context diags ([#34751](https://github.com/angular/angular/issues/34751)) ([cc7fca4](https://github.com/angular/angular/commit/cc7fca4))
|
||||||
* **language-service:** support multiple symbol definitions ([#34782](https://github.com/angular/angular/issues/34782)) ([2f2396c](https://github.com/angular/angular/commit/2f2396c))
|
* **language-service:** support multiple symbol definitions ([#34782](https://github.com/angular/angular/issues/34782)) ([2f2396c](https://github.com/angular/angular/commit/2f2396c))
|
||||||
* **ngcc:** lock ngcc when processing ([#34722](https://github.com/angular/angular/issues/34722)) ([6dd51f1](https://github.com/angular/angular/commit/6dd51f1)), closes [32431#issuecomment-571825781](https://github.com/angular/angular/issues/32431#issuecomment-571825781)
|
* **ngcc:** lock ngcc when processing ([#34722](https://github.com/angular/angular/issues/34722)) ([6dd51f1](https://github.com/angular/angular/commit/6dd51f1)), closes [/github.com/angular/angular/issues/32431#issuecomment-571825781](https://github.com/angular/angular/issues/32431/issues/issuecomment-571825781)
|
||||||
* work around 'noImplicityAny' incompatibility due to ts3.7 update ([#34798](https://github.com/angular/angular/issues/34798)) ([251d548](https://github.com/angular/angular/commit/251d548))
|
* work around 'noImplicityAny' incompatibility due to ts3.7 update ([#34798](https://github.com/angular/angular/issues/34798)) ([251d548](https://github.com/angular/angular/commit/251d548))
|
||||||
* **animations:** not waiting for child animations to finish when removing parent in Ivy ([#34702](https://github.com/angular/angular/issues/34702)) ([92c17fe](https://github.com/angular/angular/commit/92c17fe)), closes [#33597](https://github.com/angular/angular/issues/33597)
|
* **animations:** not waiting for child animations to finish when removing parent in Ivy ([#34702](https://github.com/angular/angular/issues/34702)) ([92c17fe](https://github.com/angular/angular/commit/92c17fe)), closes [#33597](https://github.com/angular/angular/issues/33597)
|
||||||
* **common:** ensure diffing in ngStyle/ngClass correctly emits value changes ([#34307](https://github.com/angular/angular/issues/34307)) ([93a035f](https://github.com/angular/angular/commit/93a035f)), closes [#34336](https://github.com/angular/angular/issues/34336) [#34444](https://github.com/angular/angular/issues/34444)
|
* **common:** ensure diffing in ngStyle/ngClass correctly emits value changes ([#34307](https://github.com/angular/angular/issues/34307)) ([93a035f](https://github.com/angular/angular/commit/93a035f)), closes [#34336](https://github.com/angular/angular/issues/34336) [#34444](https://github.com/angular/angular/issues/34444)
|
||||||
@ -1207,7 +1173,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ngcc:** do not output duplicate ɵprov properties ([#34085](https://github.com/angular/angular/issues/34085)) ([5a8d25d](https://github.com/angular/angular/commit/5a8d25d))
|
* **ngcc:** do not output duplicate ɵprov properties ([#34085](https://github.com/angular/angular/issues/34085)) ([5a8d25d](https://github.com/angular/angular/commit/5a8d25d))
|
||||||
* **ngcc:** render localized strings when in ES5 format ([#33857](https://github.com/angular/angular/issues/33857)) ([c6695fa](https://github.com/angular/angular/commit/c6695fa))
|
* **ngcc:** render localized strings when in ES5 format ([#33857](https://github.com/angular/angular/issues/33857)) ([c6695fa](https://github.com/angular/angular/commit/c6695fa))
|
||||||
* **ngcc:** render UMD global imports correctly ([#34012](https://github.com/angular/angular/issues/34012)) ([83989b8](https://github.com/angular/angular/commit/83989b8))
|
* **ngcc:** render UMD global imports correctly ([#34012](https://github.com/angular/angular/issues/34012)) ([83989b8](https://github.com/angular/angular/commit/83989b8))
|
||||||
* **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [33685#issuecomment-557091719](https://github.com/angular/angular/issues/33685#issuecomment-557091719)
|
* **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [/github.com/angular/angular/issues/33685#issuecomment-557091719](https://github.com/angular/angular/issues/33685/issues/issuecomment-557091719)
|
||||||
* **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([f1bf5b2](https://github.com/angular/angular/commit/f1bf5b2)), closes [#22223](https://github.com/angular/angular/issues/22223)
|
* **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([f1bf5b2](https://github.com/angular/angular/commit/f1bf5b2)), closes [#22223](https://github.com/angular/angular/issues/22223)
|
||||||
* **service-worker:** allow creating post api requests after cache failure ([#33930](https://github.com/angular/angular/issues/33930)) ([63c9123](https://github.com/angular/angular/commit/63c9123)), closes [#33793](https://github.com/angular/angular/issues/33793)
|
* **service-worker:** allow creating post api requests after cache failure ([#33930](https://github.com/angular/angular/issues/33930)) ([63c9123](https://github.com/angular/angular/commit/63c9123)), closes [#33793](https://github.com/angular/angular/issues/33793)
|
||||||
* **service-worker:** throw when using the unsupported `versionedFiles` option in config ([#33903](https://github.com/angular/angular/issues/33903)) ([250e6fd](https://github.com/angular/angular/commit/250e6fd))
|
* **service-worker:** throw when using the unsupported `versionedFiles` option in config ([#33903](https://github.com/angular/angular/issues/33903)) ([250e6fd](https://github.com/angular/angular/commit/250e6fd))
|
||||||
@ -1286,7 +1252,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **language-service:** Should not crash if expr ends unexpectedly ([#33524](https://github.com/angular/angular/issues/33524)) ([9ebac71](https://github.com/angular/angular/commit/9ebac71))
|
* **language-service:** Should not crash if expr ends unexpectedly ([#33524](https://github.com/angular/angular/issues/33524)) ([9ebac71](https://github.com/angular/angular/commit/9ebac71))
|
||||||
* **ngcc:** handle new `__spreadArrays` tslib helper ([#33617](https://github.com/angular/angular/issues/33617)) ([d749dd3](https://github.com/angular/angular/commit/d749dd3)), closes [#33614](https://github.com/angular/angular/issues/33614)
|
* **ngcc:** handle new `__spreadArrays` tslib helper ([#33617](https://github.com/angular/angular/issues/33617)) ([d749dd3](https://github.com/angular/angular/commit/d749dd3)), closes [#33614](https://github.com/angular/angular/issues/33614)
|
||||||
* **ngcc:** override `getInternalNameOfClass()` and `getAdjacentNameOfClass()` for ES5 ([#33533](https://github.com/angular/angular/issues/33533)) ([93a23b9](https://github.com/angular/angular/commit/93a23b9))
|
* **ngcc:** override `getInternalNameOfClass()` and `getAdjacentNameOfClass()` for ES5 ([#33533](https://github.com/angular/angular/issues/33533)) ([93a23b9](https://github.com/angular/angular/commit/93a23b9))
|
||||||
* **ngcc:** render adjacent statements after static properties ([#33630](https://github.com/angular/angular/issues/33630)) ([fe12d0d](https://github.com/angular/angular/commit/fe12d0d)), closes [/github.com/angular/angular/pull/33337#issuecomment-545487737](https://github.com/angular/angular/pull/33337#issuecomment-545487737)
|
* **ngcc:** render adjacent statements after static properties ([#33630](https://github.com/angular/angular/issues/33630)) ([fe12d0d](https://github.com/angular/angular/commit/fe12d0d)), closes [/github.com/angular/angular/pull/33337#issuecomment-545487737](https://github.com/angular/angular/pull/33337/issues/issuecomment-545487737)
|
||||||
* **ngcc:** render new definitions using the inner name of the class ([#33533](https://github.com/angular/angular/issues/33533)) ([85298e3](https://github.com/angular/angular/commit/85298e3))
|
* **ngcc:** render new definitions using the inner name of the class ([#33533](https://github.com/angular/angular/issues/33533)) ([85298e3](https://github.com/angular/angular/commit/85298e3))
|
||||||
* **service-worker:** ensure initialization before handling messages ([#32525](https://github.com/angular/angular/issues/32525)) ([72eba77](https://github.com/angular/angular/commit/72eba77)), closes [#25611](https://github.com/angular/angular/issues/25611)
|
* **service-worker:** ensure initialization before handling messages ([#32525](https://github.com/angular/angular/issues/32525)) ([72eba77](https://github.com/angular/angular/commit/72eba77)), closes [#25611](https://github.com/angular/angular/issues/25611)
|
||||||
* **compiler:** i18n - ignore `alt-trans` tags in XLIFF 1.2 ([#33450](https://github.com/angular/angular/issues/33450)) ([936700a](https://github.com/angular/angular/commit/936700a)), closes [#33161](https://github.com/angular/angular/issues/33161)
|
* **compiler:** i18n - ignore `alt-trans` tags in XLIFF 1.2 ([#33450](https://github.com/angular/angular/issues/33450)) ([936700a](https://github.com/angular/angular/commit/936700a)), closes [#33161](https://github.com/angular/angular/issues/33161)
|
||||||
@ -1316,7 +1282,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **language-service:** Add directive selectors & banana-in-a-box to completions ([#33311](https://github.com/angular/angular/issues/33311)) ([49eec5d](https://github.com/angular/angular/commit/49eec5d))
|
* **language-service:** Add directive selectors & banana-in-a-box to completions ([#33311](https://github.com/angular/angular/issues/33311)) ([49eec5d](https://github.com/angular/angular/commit/49eec5d))
|
||||||
* **language-service:** Add global symbol for $any() ([#33245](https://github.com/angular/angular/issues/33245)) ([3f257e9](https://github.com/angular/angular/commit/3f257e9))
|
* **language-service:** Add global symbol for $any() ([#33245](https://github.com/angular/angular/issues/33245)) ([3f257e9](https://github.com/angular/angular/commit/3f257e9))
|
||||||
* **language-service:** Preserve CRLF in templates for language-service ([#33241](https://github.com/angular/angular/issues/33241)) ([65a0d2b](https://github.com/angular/angular/commit/65a0d2b))
|
* **language-service:** Preserve CRLF in templates for language-service ([#33241](https://github.com/angular/angular/issues/33241)) ([65a0d2b](https://github.com/angular/angular/commit/65a0d2b))
|
||||||
* **ngcc:** do not fail when multiple workers try to create the same directory ([#33237](https://github.com/angular/angular/issues/33237)) ([8017229](https://github.com/angular/angular/commit/8017229)), closes [/github.com/angular/angular/pull/33049#issuecomment-540485703](https://github.com/angular/angular/pull/33049#issuecomment-540485703)
|
* **ngcc:** do not fail when multiple workers try to create the same directory ([#33237](https://github.com/angular/angular/issues/33237)) ([8017229](https://github.com/angular/angular/commit/8017229)), closes [/github.com/angular/angular/pull/33049#issuecomment-540485703](https://github.com/angular/angular/pull/33049/issues/issuecomment-540485703)
|
||||||
* **bazel:** Remove angular devkit and restore ngc postinstall ([#32946](https://github.com/angular/angular/issues/32946)) ([f036684](https://github.com/angular/angular/commit/f036684))
|
* **bazel:** Remove angular devkit and restore ngc postinstall ([#32946](https://github.com/angular/angular/issues/32946)) ([f036684](https://github.com/angular/angular/commit/f036684))
|
||||||
* **common:** remove deprecated support for intl API ([#29250](https://github.com/angular/angular/issues/29250)) ([9e7668f](https://github.com/angular/angular/commit/9e7668f)), closes [#18284](https://github.com/angular/angular/issues/18284)
|
* **common:** remove deprecated support for intl API ([#29250](https://github.com/angular/angular/issues/29250)) ([9e7668f](https://github.com/angular/angular/commit/9e7668f)), closes [#18284](https://github.com/angular/angular/issues/18284)
|
||||||
* **compiler:** absolute source span for template attribute expressions ([#33189](https://github.com/angular/angular/issues/33189)) ([fd4fed1](https://github.com/angular/angular/commit/fd4fed1))
|
* **compiler:** absolute source span for template attribute expressions ([#33189](https://github.com/angular/angular/issues/33189)) ([fd4fed1](https://github.com/angular/angular/commit/fd4fed1))
|
||||||
@ -1373,7 +1339,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **language-service:** Turn on strict mode for test project ([#32783](https://github.com/angular/angular/issues/32783)) ([28358b6](https://github.com/angular/angular/commit/28358b6))
|
* **language-service:** Turn on strict mode for test project ([#32783](https://github.com/angular/angular/issues/32783)) ([28358b6](https://github.com/angular/angular/commit/28358b6))
|
||||||
* **ngcc:** ensure private exports are added for `ModuleWithProviders` ([#32902](https://github.com/angular/angular/issues/32902)) ([002a97d](https://github.com/angular/angular/commit/002a97d))
|
* **ngcc:** ensure private exports are added for `ModuleWithProviders` ([#32902](https://github.com/angular/angular/issues/32902)) ([002a97d](https://github.com/angular/angular/commit/002a97d))
|
||||||
* **ngcc:** handle presence of both `ctorParameters` and `__decorate` ([#32901](https://github.com/angular/angular/issues/32901)) ([747f0cf](https://github.com/angular/angular/commit/747f0cf))
|
* **ngcc:** handle presence of both `ctorParameters` and `__decorate` ([#32901](https://github.com/angular/angular/issues/32901)) ([747f0cf](https://github.com/angular/angular/commit/747f0cf))
|
||||||
* **ngcc:** make the build-marker error more clear ([#32712](https://github.com/angular/angular/issues/32712)) ([0ea4875](https://github.com/angular/angular/commit/0ea4875)), closes [31354#issuecomment-532080537](https://github.com/angular/angular/issues/31354#issuecomment-532080537)
|
* **ngcc:** make the build-marker error more clear ([#32712](https://github.com/angular/angular/issues/32712)) ([0ea4875](https://github.com/angular/angular/commit/0ea4875)), closes [/github.com/angular/angular/issues/31354#issuecomment-532080537](https://github.com/angular/angular/issues/31354/issues/issuecomment-532080537)
|
||||||
* **upgrade:** fix AngularJsUrlCodec to support Safari ([#32959](https://github.com/angular/angular/issues/32959)) ([39e8ceb](https://github.com/angular/angular/commit/39e8ceb))
|
* **upgrade:** fix AngularJsUrlCodec to support Safari ([#32959](https://github.com/angular/angular/issues/32959)) ([39e8ceb](https://github.com/angular/angular/commit/39e8ceb))
|
||||||
* **ivy:** ensure `window.ng.getDebugNode` returns debug info for component elements ([#32780](https://github.com/angular/angular/issues/32780)) ([5651fa3](https://github.com/angular/angular/commit/5651fa3))
|
* **ivy:** ensure `window.ng.getDebugNode` returns debug info for component elements ([#32780](https://github.com/angular/angular/issues/32780)) ([5651fa3](https://github.com/angular/angular/commit/5651fa3))
|
||||||
* **ivy:** ensure multiple map-based bindings do not skip intermediate values ([#32774](https://github.com/angular/angular/issues/32774)) ([86fd571](https://github.com/angular/angular/commit/86fd571))
|
* **ivy:** ensure multiple map-based bindings do not skip intermediate values ([#32774](https://github.com/angular/angular/issues/32774)) ([86fd571](https://github.com/angular/angular/commit/86fd571))
|
||||||
@ -1482,7 +1448,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** graceful evaluation of unknown or invalid expressions ([#33453](https://github.com/angular/angular/issues/33453)) ([ce30888](https://github.com/angular/angular/commit/ce30888))
|
* **ivy:** graceful evaluation of unknown or invalid expressions ([#33453](https://github.com/angular/angular/issues/33453)) ([ce30888](https://github.com/angular/angular/commit/ce30888))
|
||||||
* **ivy:** implement unknown element detection in jit mode ([#33419](https://github.com/angular/angular/issues/33419)) ([c83f501](https://github.com/angular/angular/commit/c83f501))
|
* **ivy:** implement unknown element detection in jit mode ([#33419](https://github.com/angular/angular/issues/33419)) ([c83f501](https://github.com/angular/angular/commit/c83f501))
|
||||||
* add a flag in bootstrap to enable coalesce event change detection to improve performance ([#30533](https://github.com/angular/angular/issues/30533)) ([44623a1](https://github.com/angular/angular/commit/44623a1))
|
* add a flag in bootstrap to enable coalesce event change detection to improve performance ([#30533](https://github.com/angular/angular/issues/30533)) ([44623a1](https://github.com/angular/angular/commit/44623a1))
|
||||||
* **bazel:** update [@bazel](https://github.com/bazel)/schematics to Bazel 1.0.0 ([#33476](https://github.com/angular/angular/issues/33476)) ([540d104](https://github.com/angular/angular/commit/540d104)), closes [/github.com/angular/angular/pull/33367#issuecomment-547643246](https://github.com/angular/angular/pull/33367#issuecomment-547643246)
|
* **bazel:** update [@bazel](https://github.com/bazel)/schematics to Bazel 1.0.0 ([#33476](https://github.com/angular/angular/issues/33476)) ([540d104](https://github.com/angular/angular/commit/540d104)), closes [/github.com/angular/angular/pull/33367#issuecomment-547643246](https://github.com/angular/angular/pull/33367/issues/issuecomment-547643246)
|
||||||
* **bazel:** update bazel-schematics to use Ivy and new rollup_bundle ([#33435](https://github.com/angular/angular/issues/33435)) ([bf913cc](https://github.com/angular/angular/commit/bf913cc))
|
* **bazel:** update bazel-schematics to use Ivy and new rollup_bundle ([#33435](https://github.com/angular/angular/issues/33435)) ([bf913cc](https://github.com/angular/angular/commit/bf913cc))
|
||||||
* **ivy:** i18n - support inlining of XTB formatted translation files ([#33444](https://github.com/angular/angular/issues/33444)) ([2c623fd](https://github.com/angular/angular/commit/2c623fd))
|
* **ivy:** i18n - support inlining of XTB formatted translation files ([#33444](https://github.com/angular/angular/issues/33444)) ([2c623fd](https://github.com/angular/angular/commit/2c623fd))
|
||||||
* **language-service:** add support for text replacement ([#33091](https://github.com/angular/angular/issues/33091)) ([da4eb91](https://github.com/angular/angular/commit/da4eb91))
|
* **language-service:** add support for text replacement ([#33091](https://github.com/angular/angular/issues/33091)) ([da4eb91](https://github.com/angular/angular/commit/da4eb91))
|
||||||
@ -1524,7 +1490,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** i18n - implement compile-time inlining ([#32881](https://github.com/angular/angular/issues/32881)) ([2cdb3a0](https://github.com/angular/angular/commit/2cdb3a0))
|
* **ivy:** i18n - implement compile-time inlining ([#32881](https://github.com/angular/angular/issues/32881)) ([2cdb3a0](https://github.com/angular/angular/commit/2cdb3a0))
|
||||||
* **ivy:** i18n - render legacy message ids in `$localize` if requested ([#32937](https://github.com/angular/angular/issues/32937)) ([bcbf3e4](https://github.com/angular/angular/commit/bcbf3e4))
|
* **ivy:** i18n - render legacy message ids in `$localize` if requested ([#32937](https://github.com/angular/angular/issues/32937)) ([bcbf3e4](https://github.com/angular/angular/commit/bcbf3e4))
|
||||||
* **language-service:** module definitions on directive hover ([#32763](https://github.com/angular/angular/issues/32763)) ([0d186dd](https://github.com/angular/angular/commit/0d186dd)), closes [#32565](https://github.com/angular/angular/issues/32565)
|
* **language-service:** module definitions on directive hover ([#32763](https://github.com/angular/angular/issues/32763)) ([0d186dd](https://github.com/angular/angular/commit/0d186dd)), closes [#32565](https://github.com/angular/angular/issues/32565)
|
||||||
* **ngcc:** expose `--create-ivy-entry-points` option on ivy-ngcc ([#33049](https://github.com/angular/angular/issues/33049)) ([b2b917d](https://github.com/angular/angular/commit/b2b917d)), closes [/github.com/angular/angular/pull/32999#issuecomment-539937368](https://github.com/angular/angular/pull/32999#issuecomment-539937368)
|
* **ngcc:** expose `--create-ivy-entry-points` option on ivy-ngcc ([#33049](https://github.com/angular/angular/issues/33049)) ([b2b917d](https://github.com/angular/angular/commit/b2b917d)), closes [/github.com/angular/angular/pull/32999#issuecomment-539937368](https://github.com/angular/angular/pull/32999/issues/issuecomment-539937368)
|
||||||
* update rxjs peerDependencies minimum requirment to 6.5.3 ([#32812](https://github.com/angular/angular/issues/32812)) ([66658c4](https://github.com/angular/angular/commit/66658c4))
|
* update rxjs peerDependencies minimum requirment to 6.5.3 ([#32812](https://github.com/angular/angular/issues/32812)) ([66658c4](https://github.com/angular/angular/commit/66658c4))
|
||||||
* **ivy:** support ng-add in localize package ([#32791](https://github.com/angular/angular/issues/32791)) ([e41cbfb](https://github.com/angular/angular/commit/e41cbfb))
|
* **ivy:** support ng-add in localize package ([#32791](https://github.com/angular/angular/issues/32791)) ([e41cbfb](https://github.com/angular/angular/commit/e41cbfb))
|
||||||
* **language-service:** allow retreiving synchronized analyzed NgModules ([#32779](https://github.com/angular/angular/issues/32779)) ([98feee7](https://github.com/angular/angular/commit/98feee7))
|
* **language-service:** allow retreiving synchronized analyzed NgModules ([#32779](https://github.com/angular/angular/issues/32779)) ([98feee7](https://github.com/angular/angular/commit/98feee7))
|
||||||
@ -1903,7 +1869,6 @@ This release contains various API docs improvements.
|
|||||||
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
|
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
|
||||||
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
|
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
|
||||||
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
|
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
|
||||||
* **core:** handle `undefined` meta in `injectArgs` ([#31333](https://github.com/angular/angular/issues/31333)) ([80ccd6c](https://github.com/angular/angular/commit/80ccd6c)), closes [CLI #14888](https://github.com/angular/angular-cli/issues/14888)
|
|
||||||
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
|
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
|
||||||
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
|
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
|
||||||
|
|
||||||
@ -1933,7 +1898,6 @@ This release contains various API docs improvements.
|
|||||||
|
|
||||||
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([4aed480](https://github.com/angular/angular/commit/4aed480))
|
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([4aed480](https://github.com/angular/angular/commit/4aed480))
|
||||||
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([13dbb98](https://github.com/angular/angular/commit/13dbb98)), closes [#22524](https://github.com/angular/angular/issues/22524)
|
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([13dbb98](https://github.com/angular/angular/commit/13dbb98)), closes [#22524](https://github.com/angular/angular/issues/22524)
|
||||||
* **core:** export provider interfaces that are part of the public API types ([#31377](https://github.com/angular/angular/issues/31377)) ([bebf089](https://github.com/angular/angular/commit/bebf089)), closes [/github.com/angular/angular/pull/31377#discussion_r299254408](https://github.com/angular/angular/pull/31377/issues/discussion_r299254408) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L365-L366) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L283-L284) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
|
|
||||||
|
|
||||||
|
|
||||||
<a name="8.1.1"></a>
|
<a name="8.1.1"></a>
|
||||||
@ -2111,7 +2075,6 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add support for TypeScript 3.4 (and drop older versions) ([#29372](https://github.com/angular/angular/issues/29372)) ([ef85336](https://github.com/angular/angular/commit/ef85336))
|
* add support for TypeScript 3.4 (and drop older versions) ([#29372](https://github.com/angular/angular/issues/29372)) ([ef85336](https://github.com/angular/angular/commit/ef85336))
|
||||||
* **common:** add ability to watch for AngularJS URL updates through `onUrlChange` hook ([#30466](https://github.com/angular/angular/issues/30466)) ([8022d36](https://github.com/angular/angular/commit/8022d36))
|
|
||||||
* **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa))
|
* **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa))
|
||||||
* **bazel:** use `rbe_autoconfig()` and new container ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc))
|
* **bazel:** use `rbe_autoconfig()` and new container ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc))
|
||||||
* **common:** add @angular/common/upgrade package for `$location`-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
|
* **common:** add @angular/common/upgrade package for `$location`-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
|
||||||
@ -2228,8 +2191,6 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **bazel:** use `//:tsconfig.json` as the default for `ng_module` ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a))
|
* **bazel:** use `//:tsconfig.json` as the default for `ng_module` ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a))
|
||||||
* **compiler-cli:** ngcc - cope with processing entry-points multiple times ([#29657](https://github.com/angular/angular/issues/29657)) ([6b39c9c](https://github.com/angular/angular/commit/6b39c9c))
|
* **compiler-cli:** ngcc - cope with processing entry-points multiple times ([#29657](https://github.com/angular/angular/issues/29657)) ([6b39c9c](https://github.com/angular/angular/commit/6b39c9c))
|
||||||
* **core:** static-query schematic should detect static queries in getters. ([#29609](https://github.com/angular/angular/issues/29609)) ([33016b8](https://github.com/angular/angular/commit/33016b8))
|
* **core:** static-query schematic should detect static queries in getters. ([#29609](https://github.com/angular/angular/issues/29609)) ([33016b8](https://github.com/angular/angular/commit/33016b8))
|
||||||
* **common:** escape query selector used when anchor scrolling ([#29577](https://github.com/angular/angular/issues/29577)) ([7671c73](https://github.com/angular/angular/commit/7671c73)), closes [#28193](https://github.com/angular/angular/issues/28193)
|
|
||||||
* **router:** adjust setting navigationTransition when a new navigation cancels an existing one ([#29636](https://github.com/angular/angular/issues/29636)) ([e884c0c](https://github.com/angular/angular/commit/e884c0c)), closes [#29389](https://github.com/angular/angular/issues/29389) [#29590](https://github.com/angular/angular/issues/29590)
|
|
||||||
* **bazel:** allow `ng_module` users to set `createExternalSymbolFactoryReexports` ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb))
|
* **bazel:** allow `ng_module` users to set `createExternalSymbolFactoryReexports` ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb))
|
||||||
* **bazel:** workaround problem reading summary files from node_modules ([#29459](https://github.com/angular/angular/issues/29459)) ([769d960](https://github.com/angular/angular/commit/769d960))
|
* **bazel:** workaround problem reading summary files from node_modules ([#29459](https://github.com/angular/angular/issues/29459)) ([769d960](https://github.com/angular/angular/commit/769d960))
|
||||||
* **compiler:** inherit param types when class has a constructor which takes no declared parameters and delegates up ([#29232](https://github.com/angular/angular/issues/29232)) ([0007564](https://github.com/angular/angular/commit/0007564))
|
* **compiler:** inherit param types when class has a constructor which takes no declared parameters and delegates up ([#29232](https://github.com/angular/angular/issues/29232)) ([0007564](https://github.com/angular/angular/commit/0007564))
|
||||||
@ -2256,7 +2217,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **platform-server:** update minimum domino version to latest released ([#28893](https://github.com/angular/angular/issues/28893)) ([79e2ca0](https://github.com/angular/angular/commit/79e2ca0))
|
* **platform-server:** update minimum domino version to latest released ([#28893](https://github.com/angular/angular/issues/28893)) ([79e2ca0](https://github.com/angular/angular/commit/79e2ca0))
|
||||||
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([72ecc45](https://github.com/angular/angular/commit/72ecc45))
|
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([72ecc45](https://github.com/angular/angular/commit/72ecc45))
|
||||||
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([586234b](https://github.com/angular/angular/commit/586234b)), closes [#24338](https://github.com/angular/angular/issues/24338)
|
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([586234b](https://github.com/angular/angular/commit/586234b)), closes [#24338](https://github.com/angular/angular/issues/24338)
|
||||||
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([48214e2](https://github.com/angular/angular/commit/48214e2)), closes [23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012#issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
|
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([48214e2](https://github.com/angular/angular/commit/48214e2)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
|
||||||
* **bazel:** Pin browsers for schematics ([#28913](https://github.com/angular/angular/issues/28913)) ([1145bdb](https://github.com/angular/angular/commit/1145bdb))
|
* **bazel:** Pin browsers for schematics ([#28913](https://github.com/angular/angular/issues/28913)) ([1145bdb](https://github.com/angular/angular/commit/1145bdb))
|
||||||
* **bazel:** rxjs_umd_modules should always be present ([#28881](https://github.com/angular/angular/issues/28881)) ([9ae14db](https://github.com/angular/angular/commit/9ae14db))
|
* **bazel:** rxjs_umd_modules should always be present ([#28881](https://github.com/angular/angular/issues/28881)) ([9ae14db](https://github.com/angular/angular/commit/9ae14db))
|
||||||
* **compiler:** use correct variable in invalid function ([#28656](https://github.com/angular/angular/issues/28656)) ([f75acbd](https://github.com/angular/angular/commit/f75acbd))
|
* **compiler:** use correct variable in invalid function ([#28656](https://github.com/angular/angular/issues/28656)) ([f75acbd](https://github.com/angular/angular/commit/f75acbd))
|
||||||
@ -2318,7 +2279,6 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
|
|
||||||
* **core:** deprecate integration with the Web Tracing Framework (WTF) ([#30642](https://github.com/angular/angular/issues/30642)) ([b408445](https://github.com/angular/angular/commit/b408445))
|
* **core:** deprecate integration with the Web Tracing Framework (WTF) ([#30642](https://github.com/angular/angular/issues/30642)) ([b408445](https://github.com/angular/angular/commit/b408445))
|
||||||
* **platform-webworker:** deprecate platform-webworker ([#30642](https://github.com/angular/angular/issues/30642)) ([361f181](https://github.com/angular/angular/commit/361f181))
|
* **platform-webworker:** deprecate platform-webworker ([#30642](https://github.com/angular/angular/issues/30642)) ([361f181](https://github.com/angular/angular/commit/361f181))
|
||||||
* `TestBed.get()` has two signatures, one which is typed and another which accepts and returns `any`. The signature for `any` is deprecated; all usage of `TestBed.get()` should go through the typed API. This mainly affects string tokens
|
|
||||||
(which aren't supported) and abstract class tokens.
|
(which aren't supported) and abstract class tokens.
|
||||||
|
|
||||||
Before:
|
Before:
|
||||||
@ -2471,7 +2431,7 @@ This release contains various API docs improvements.
|
|||||||
* **animations:** ensure `position` and `display` styles are handled outside of keyframes/web-animations ([#28911](https://github.com/angular/angular/issues/28911)) ([86981b3](https://github.com/angular/angular/commit/86981b3)), closes [#24923](https://github.com/angular/angular/issues/24923) [#25635](https://github.com/angular/angular/issues/25635)
|
* **animations:** ensure `position` and `display` styles are handled outside of keyframes/web-animations ([#28911](https://github.com/angular/angular/issues/28911)) ([86981b3](https://github.com/angular/angular/commit/86981b3)), closes [#24923](https://github.com/angular/angular/issues/24923) [#25635](https://github.com/angular/angular/issues/25635)
|
||||||
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([2a25ac2](https://github.com/angular/angular/commit/2a25ac2))
|
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([2a25ac2](https://github.com/angular/angular/commit/2a25ac2))
|
||||||
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([5669333](https://github.com/angular/angular/commit/5669333)), closes [#24338](https://github.com/angular/angular/issues/24338)
|
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([5669333](https://github.com/angular/angular/commit/5669333)), closes [#24338](https://github.com/angular/angular/issues/24338)
|
||||||
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012#issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
|
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
|
||||||
|
|
||||||
|
|
||||||
<a name="7.2.7"></a>
|
<a name="7.2.7"></a>
|
||||||
@ -2567,14 +2527,6 @@ This release contains various API docs improvements.
|
|||||||
# [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16)
|
# [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
||||||
|
|
||||||
@ -2722,42 +2674,9 @@ This release contains various API docs improvements.
|
|||||||
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21)
|
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
|
|
||||||
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
|
|
||||||
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
|
|
||||||
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
|
|
||||||
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
|
|
||||||
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
|
|
||||||
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
|
|
||||||
* **core:** Remove static dependency from @angular/core to @angular/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
|
|
||||||
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
|
|
||||||
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
|
|
||||||
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
|
|
||||||
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
|
||||||
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
|
|
||||||
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
|
|
||||||
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
|
|
||||||
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
|
|
||||||
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
|
|
||||||
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30))
|
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30))
|
||||||
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
|
|
||||||
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
|
|
||||||
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
|
|
||||||
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
|
|
||||||
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
|
|
||||||
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
|
|
||||||
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
|
|
||||||
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
|
|
||||||
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
|
|
||||||
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
|
|
||||||
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
|
||||||
|
|
||||||
|
|
||||||
<a name="7.1.0-rc.0"></a>
|
<a name="7.1.0-rc.0"></a>
|
||||||
@ -2860,10 +2779,7 @@ This release contains various API docs improvements.
|
|||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
|
|
||||||
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
|
|
||||||
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
|
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
|
||||||
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
@ -3035,7 +2951,6 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
|
|||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0))
|
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0))
|
||||||
* **animations:** set animations styles properly on platform-server ([#24624](https://github.com/angular/angular/issues/24624)) ([0b356d4](https://github.com/angular/angular/commit/0b356d4))
|
|
||||||
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687))
|
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687))
|
||||||
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e))
|
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e))
|
||||||
* **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25))
|
* **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25))
|
||||||
@ -3047,7 +2962,6 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
|
|||||||
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([0b4d85e](https://github.com/angular/angular/commit/0b4d85e)), closes [#24831](https://github.com/angular/angular/issues/24831)
|
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([0b4d85e](https://github.com/angular/angular/commit/0b4d85e)), closes [#24831](https://github.com/angular/angular/issues/24831)
|
||||||
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([ff84c5c](https://github.com/angular/angular/commit/ff84c5c)), closes [#24155](https://github.com/angular/angular/issues/24155)
|
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([ff84c5c](https://github.com/angular/angular/commit/ff84c5c)), 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)) ([dcabb05](https://github.com/angular/angular/commit/dcabb05)), closes [#24609](https://github.com/angular/angular/issues/24609)
|
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([dcabb05](https://github.com/angular/angular/commit/dcabb05)), closes [#24609](https://github.com/angular/angular/issues/24609)
|
||||||
* **common:** use correct ICU plural for locale mk ([#24659](https://github.com/angular/angular/issues/24659)) ([64a8584](https://github.com/angular/angular/commit/64a8584))
|
|
||||||
* **compiler:** fix a few non-tree-shakeable code patterns ([#24677](https://github.com/angular/angular/issues/24677)) ([50d4a4f](https://github.com/angular/angular/commit/50d4a4f))
|
* **compiler:** fix a few non-tree-shakeable code patterns ([#24677](https://github.com/angular/angular/issues/24677)) ([50d4a4f](https://github.com/angular/angular/commit/50d4a4f))
|
||||||
* **compiler:** i18n_extractor now outputs the correct source file name ([#24885](https://github.com/angular/angular/issues/24885)) ([c8ad965](https://github.com/angular/angular/commit/c8ad965)), closes [#24884](https://github.com/angular/angular/issues/24884)
|
* **compiler:** i18n_extractor now outputs the correct source file name ([#24885](https://github.com/angular/angular/issues/24885)) ([c8ad965](https://github.com/angular/angular/commit/c8ad965)), closes [#24884](https://github.com/angular/angular/issues/24884)
|
||||||
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363)
|
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363)
|
||||||
@ -3083,7 +2997,6 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
|
|||||||
* **service-worker:** don't include sourceMappingURL in ngsw-worker ([#24877](https://github.com/angular/angular/issues/24877)) ([8620373](https://github.com/angular/angular/commit/8620373)), closes [#23596](https://github.com/angular/angular/issues/23596)
|
* **service-worker:** don't include sourceMappingURL in ngsw-worker ([#24877](https://github.com/angular/angular/issues/24877)) ([8620373](https://github.com/angular/angular/commit/8620373)), closes [#23596](https://github.com/angular/angular/issues/23596)
|
||||||
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([52d43a9](https://github.com/angular/angular/commit/52d43a9))
|
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([52d43a9](https://github.com/angular/angular/commit/52d43a9))
|
||||||
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095)
|
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095)
|
||||||
* **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:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e))
|
* **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e))
|
||||||
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526)
|
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526)
|
||||||
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2))
|
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2))
|
||||||
@ -3284,8 +3197,6 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
|||||||
* **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:** 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)
|
* **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:** 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))
|
* **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))
|
* **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 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)
|
||||||
@ -3504,12 +3415,7 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
|
|
||||||
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), 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)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
|
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
|
||||||
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
|
|
||||||
* **upgrade:** correctly handle `=` bindings in `@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)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -3904,15 +3810,6 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
|
|||||||
<a name="5.1.0-beta.0"></a>
|
<a name="5.1.0-beta.0"></a>
|
||||||
# [5.1.0-beta.0](https://github.com/angular/angular/compare/5.0.0-rc.4...5.1.0-beta.0) (2017-11-08)
|
# [5.1.0-beta.0](https://github.com/angular/angular/compare/5.0.0-rc.4...5.1.0-beta.0) (2017-11-08)
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler:** don't overwrite missingTranslation's value in JIT ([#19952](https://github.com/angular/angular/issues/19952)) ([799cbb9](https://github.com/angular/angular/commit/799cbb9))
|
|
||||||
* **compiler:** report a reasonable error with invalid metadata ([#20062](https://github.com/angular/angular/issues/20062)) ([da22c48](https://github.com/angular/angular/commit/da22c48))
|
|
||||||
* **compiler-cli:** don't report emit diagnostics when `--noEmitOnError` is off ([#20063](https://github.com/angular/angular/issues/20063)) ([8639995](https://github.com/angular/angular/commit/8639995))
|
|
||||||
* **core:** `__symbol__` should return `__zone_symbol__` without zone.js loaded ([#19541](https://github.com/angular/angular/issues/19541)) ([678d1cf](https://github.com/angular/angular/commit/678d1cf))
|
|
||||||
* **core:** should support event.stopImmediatePropagation ([#19222](https://github.com/angular/angular/issues/19222)) ([7083791](https://github.com/angular/angular/commit/7083791))
|
|
||||||
* **platform-browser:** support Symbols in custom `jasmineToString()` method ([#19794](https://github.com/angular/angular/issues/19794)) ([5a6efa7](https://github.com/angular/angular/commit/5a6efa7))
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **compiler:** introduce `TestBed.overrideTemplateUsingTestingModule` ([a460066](https://github.com/angular/angular/commit/a460066)), closes [#19815](https://github.com/angular/angular/issues/19815)
|
* **compiler:** introduce `TestBed.overrideTemplateUsingTestingModule` ([a460066](https://github.com/angular/angular/commit/a460066)), closes [#19815](https://github.com/angular/angular/issues/19815)
|
||||||
@ -3948,14 +3845,12 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
|
|||||||
* **compiler-cli:** add watch mode to `ngc` ([#18818](https://github.com/angular/angular/issues/18818)) ([06d01b2](https://github.com/angular/angular/commit/06d01b2))
|
* **compiler-cli:** add watch mode to `ngc` ([#18818](https://github.com/angular/angular/issues/18818)) ([06d01b2](https://github.com/angular/angular/commit/06d01b2))
|
||||||
* **compiler-cli:** lower metadata `useValue` and `data` literal fields ([#18905](https://github.com/angular/angular/issues/18905)) ([0e64261](https://github.com/angular/angular/commit/0e64261))
|
* **compiler-cli:** lower metadata `useValue` and `data` literal fields ([#18905](https://github.com/angular/angular/issues/18905)) ([0e64261](https://github.com/angular/angular/commit/0e64261))
|
||||||
* **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345)
|
* **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345)
|
||||||
* **compiler:** allow multiple exportAs names ([#18723](https://github.com/angular/angular/issues/18723)) ([7ec28fe](https://github.com/angular/angular/commit/7ec28fe))
|
|
||||||
* **compiler:** enabled strict checking of parameters to an `@Injectable` ([#19412](https://github.com/angular/angular/issues/19412)) ([dfb8d21](https://github.com/angular/angular/commit/dfb8d21))
|
* **compiler:** enabled strict checking of parameters to an `@Injectable` ([#19412](https://github.com/angular/angular/issues/19412)) ([dfb8d21](https://github.com/angular/angular/commit/dfb8d21))
|
||||||
* **compiler:** make `.ngsummary.json` files portable ([2572bf5](https://github.com/angular/angular/commit/2572bf5))
|
* **compiler:** make `.ngsummary.json` files portable ([2572bf5](https://github.com/angular/angular/commit/2572bf5))
|
||||||
* **compiler:** reuse the TypeScript typecheck for template typechecking. ([#19152](https://github.com/angular/angular/issues/19152)) ([996c7c2](https://github.com/angular/angular/commit/996c7c2))
|
* **compiler:** reuse the TypeScript typecheck for template typechecking. ([#19152](https://github.com/angular/angular/issues/19152)) ([996c7c2](https://github.com/angular/angular/commit/996c7c2))
|
||||||
* **compiler:** set `enableLegacyTemplate` to false by default ([#18756](https://github.com/angular/angular/issues/18756)) ([56238fe](https://github.com/angular/angular/commit/56238fe))
|
* **compiler:** set `enableLegacyTemplate` to false by default ([#18756](https://github.com/angular/angular/issues/18756)) ([56238fe](https://github.com/angular/angular/commit/56238fe))
|
||||||
* **compiler:** use typescript for resolving resource paths ([43226cb](https://github.com/angular/angular/commit/43226cb))
|
* **compiler:** use typescript for resolving resource paths ([43226cb](https://github.com/angular/angular/commit/43226cb))
|
||||||
* **core:** Create StaticInjector which does not depend on Reflect polyfill. ([d9d00bd](https://github.com/angular/angular/commit/d9d00bd))
|
* **core:** Create StaticInjector which does not depend on Reflect polyfill. ([d9d00bd](https://github.com/angular/angular/commit/d9d00bd))
|
||||||
* **core:** add option to remove blank text nodes from compiled templates ([#18823](https://github.com/angular/angular/issues/18823)) ([b8b551c](https://github.com/angular/angular/commit/b8b551c))
|
|
||||||
* **core:** support for bootstrap with custom zone ([#17672](https://github.com/angular/angular/issues/17672)) ([344a5ca](https://github.com/angular/angular/commit/344a5ca))
|
* **core:** support for bootstrap with custom zone ([#17672](https://github.com/angular/angular/issues/17672)) ([344a5ca](https://github.com/angular/angular/commit/344a5ca))
|
||||||
* **forms:** add default updateOn values for groups and arrays ([#18536](https://github.com/angular/angular/issues/18536)) ([ff5c58b](https://github.com/angular/angular/commit/ff5c58b))
|
* **forms:** add default updateOn values for groups and arrays ([#18536](https://github.com/angular/angular/issues/18536)) ([ff5c58b](https://github.com/angular/angular/commit/ff5c58b))
|
||||||
* **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6))
|
* **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6))
|
||||||
@ -4314,7 +4209,6 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
* **animations:** properly collect :enter nodes that exist within multi-level DOM trees ([40f77cb](https://github.com/angular/angular/commit/40f77cb)), closes [#17632](https://github.com/angular/angular/issues/17632)
|
* **animations:** properly collect :enter nodes that exist within multi-level DOM trees ([40f77cb](https://github.com/angular/angular/commit/40f77cb)), closes [#17632](https://github.com/angular/angular/issues/17632)
|
||||||
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
||||||
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
||||||
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
|
|
||||||
* **animations:** remove duplicate license header ([e096a85](https://github.com/angular/angular/commit/e096a85))
|
* **animations:** remove duplicate license header ([e096a85](https://github.com/angular/angular/commit/e096a85))
|
||||||
* **common/http:** document HttpClient, fixing a few other issues ([1855989](https://github.com/angular/angular/commit/1855989))
|
* **common/http:** document HttpClient, fixing a few other issues ([1855989](https://github.com/angular/angular/commit/1855989))
|
||||||
* **common/http:** don't guess Content-Type for FormData bodies ([#18104](https://github.com/angular/angular/issues/18104)) ([4f1e4ff](https://github.com/angular/angular/commit/4f1e4ff)), closes [#18096](https://github.com/angular/angular/issues/18096)
|
* **common/http:** don't guess Content-Type for FormData bodies ([#18104](https://github.com/angular/angular/issues/18104)) ([4f1e4ff](https://github.com/angular/angular/commit/4f1e4ff)), closes [#18096](https://github.com/angular/angular/issues/18096)
|
||||||
@ -4423,7 +4317,6 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
|
|
||||||
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
||||||
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
||||||
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
|
|
||||||
* **animations:** remove duplicate license header ([b192dd5](https://github.com/angular/angular/commit/b192dd5))
|
* **animations:** remove duplicate license header ([b192dd5](https://github.com/angular/angular/commit/b192dd5))
|
||||||
* **forms:** temp roll back breaking change with min/max directives ([b8c39cd](https://github.com/angular/angular/commit/b8c39cd)), closes [#17491](https://github.com/angular/angular/issues/17491)
|
* **forms:** temp roll back breaking change with min/max directives ([b8c39cd](https://github.com/angular/angular/commit/b8c39cd)), closes [#17491](https://github.com/angular/angular/issues/17491)
|
||||||
|
|
||||||
@ -4659,7 +4552,6 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
* **benchpress:** Update types for TypeScript nullability support ([14669f2](https://github.com/angular/angular/commit/14669f2))
|
* **benchpress:** Update types for TypeScript nullability support ([14669f2](https://github.com/angular/angular/commit/14669f2))
|
||||||
* **common:** Update types for TypeScript nullability support ([d8b73e4](https://github.com/angular/angular/commit/d8b73e4))
|
* **common:** Update types for TypeScript nullability support ([d8b73e4](https://github.com/angular/angular/commit/d8b73e4))
|
||||||
* **compiler:** fix build error in xliff2 ([bd704c9](https://github.com/angular/angular/commit/bd704c9))
|
* **compiler:** fix build error in xliff2 ([bd704c9](https://github.com/angular/angular/commit/bd704c9))
|
||||||
* **compiler:** fix inheritance for AOT with summaries ([#15583](https://github.com/angular/angular/issues/15583)) ([8ef621a](https://github.com/angular/angular/commit/8ef621a))
|
|
||||||
* **compiler:** ignore calls to unresolved symbols in metadata ([38a7e0d](https://github.com/angular/angular/commit/38a7e0d)), closes [#15969](https://github.com/angular/angular/issues/15969)
|
* **compiler:** ignore calls to unresolved symbols in metadata ([38a7e0d](https://github.com/angular/angular/commit/38a7e0d)), closes [#15969](https://github.com/angular/angular/issues/15969)
|
||||||
* **compiler:** ignore calls to unresolved symbols in metadata ([#15970](https://github.com/angular/angular/issues/15970)) ([ce47d33](https://github.com/angular/angular/commit/ce47d33)), closes [#15969](https://github.com/angular/angular/issues/15969)
|
* **compiler:** ignore calls to unresolved symbols in metadata ([#15970](https://github.com/angular/angular/issues/15970)) ([ce47d33](https://github.com/angular/angular/commit/ce47d33)), closes [#15969](https://github.com/angular/angular/issues/15969)
|
||||||
* **compiler:** Inform user where Quoted error was thrown ([a77b126](https://github.com/angular/angular/commit/a77b126))
|
* **compiler:** Inform user where Quoted error was thrown ([a77b126](https://github.com/angular/angular/commit/a77b126))
|
||||||
@ -4676,10 +4568,8 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
* **http:** Update types for TypeScript nullability support ([c36ec9b](https://github.com/angular/angular/commit/c36ec9b))
|
* **http:** Update types for TypeScript nullability support ([c36ec9b](https://github.com/angular/angular/commit/c36ec9b))
|
||||||
* **http:** Update types for TypeScript nullability support ([ec028b8](https://github.com/angular/angular/commit/ec028b8))
|
* **http:** Update types for TypeScript nullability support ([ec028b8](https://github.com/angular/angular/commit/ec028b8))
|
||||||
* **language-service:** avoid throwing exceptions when reporting metadata errors ([7764c5c](https://github.com/angular/angular/commit/7764c5c))
|
* **language-service:** avoid throwing exceptions when reporting metadata errors ([7764c5c](https://github.com/angular/angular/commit/7764c5c))
|
||||||
* **language-service:** detect when there isn't a tsconfig.json ([258d539](https://github.com/angular/angular/commit/258d539)), closes [#15874](https://github.com/angular/angular/issues/15874)
|
|
||||||
* **language-service:** improve resilience to incomplete information ([71a8627](https://github.com/angular/angular/commit/71a8627))
|
* **language-service:** improve resilience to incomplete information ([71a8627](https://github.com/angular/angular/commit/71a8627))
|
||||||
* **language-service:** infer correct type of `?.` expressions ([0a3a9af](https://github.com/angular/angular/commit/0a3a9af)), closes [#15885](https://github.com/angular/angular/issues/15885)
|
* **language-service:** infer correct type of `?.` expressions ([0a3a9af](https://github.com/angular/angular/commit/0a3a9af)), closes [#15885](https://github.com/angular/angular/issues/15885)
|
||||||
* **language-service:** initialize static reflector correctly ([fe0d02f](https://github.com/angular/angular/commit/fe0d02f)), closes [#15768](https://github.com/angular/angular/issues/15768)
|
|
||||||
* **language-service:** look for type constructors on canonical symbol ([2ddf3bc](https://github.com/angular/angular/commit/2ddf3bc))
|
* **language-service:** look for type constructors on canonical symbol ([2ddf3bc](https://github.com/angular/angular/commit/2ddf3bc))
|
||||||
* **language-service:** only use canonical symbols ([5a88d2f](https://github.com/angular/angular/commit/5a88d2f))
|
* **language-service:** only use canonical symbols ([5a88d2f](https://github.com/angular/angular/commit/5a88d2f))
|
||||||
* **language-service:** parse extended i18n forms ([bde9771](https://github.com/angular/angular/commit/bde9771))
|
* **language-service:** parse extended i18n forms ([bde9771](https://github.com/angular/angular/commit/bde9771))
|
||||||
@ -4704,7 +4594,6 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **animations:** Update types for TypeScript nullability support ([38d75d4](https://github.com/angular/angular/commit/38d75d4)), closes [#15870](https://github.com/angular/angular/issues/15870)
|
|
||||||
* **compiler:** add source files to xmb/xliff translations ([#14705](https://github.com/angular/angular/issues/14705)) ([4054055](https://github.com/angular/angular/commit/4054055)), closes [#14190](https://github.com/angular/angular/issues/14190)
|
* **compiler:** add source files to xmb/xliff translations ([#14705](https://github.com/angular/angular/issues/14705)) ([4054055](https://github.com/angular/angular/commit/4054055)), closes [#14190](https://github.com/angular/angular/issues/14190)
|
||||||
* **compiler:** Implement i18n XLIFF 2.0 serializer ([#14185](https://github.com/angular/angular/issues/14185)) ([09c4cb2](https://github.com/angular/angular/commit/09c4cb2)), closes [#11735](https://github.com/angular/angular/issues/11735)
|
* **compiler:** Implement i18n XLIFF 2.0 serializer ([#14185](https://github.com/angular/angular/issues/14185)) ([09c4cb2](https://github.com/angular/angular/commit/09c4cb2)), closes [#11735](https://github.com/angular/angular/issues/11735)
|
||||||
* **upgrade:** allow setting the angularjs lib at runtime ([#15168](https://github.com/angular/angular/issues/15168)) ([e927aea](https://github.com/angular/angular/commit/e927aea))
|
* **upgrade:** allow setting the angularjs lib at runtime ([#15168](https://github.com/angular/angular/issues/15168)) ([e927aea](https://github.com/angular/angular/commit/e927aea))
|
||||||
@ -5442,27 +5331,18 @@ returned value being an array.
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **animations:** fix internal jscompiler issue and AOT quoting ([#13798](https://github.com/angular/angular/issues/13798)) ([c2aa981](https://github.com/angular/angular/commit/c2aa981))
|
|
||||||
* **common:** support numeric value as discrete cases for NgPlural ([#13876](https://github.com/angular/angular/issues/13876)) ([f364557](https://github.com/angular/angular/commit/f364557))
|
|
||||||
* **compiler:** [i18n] XMB/XTB placeholder names can contain only A-Z, 0-9, _n ([d02eab4](https://github.com/angular/angular/commit/d02eab4))
|
* **compiler:** [i18n] XMB/XTB placeholder names can contain only A-Z, 0-9, _n ([d02eab4](https://github.com/angular/angular/commit/d02eab4))
|
||||||
* **compiler:** fix regexp to support firefox 31 ([#14082](https://github.com/angular/angular/issues/14082)) ([b2f9d56](https://github.com/angular/angular/commit/b2f9d56)), closes [#14029](https://github.com/angular/angular/issues/14029) [#13900](https://github.com/angular/angular/issues/13900)
|
* **compiler:** fix regexp to support firefox 31 ([#14082](https://github.com/angular/angular/issues/14082)) ([b2f9d56](https://github.com/angular/angular/commit/b2f9d56)), closes [#14029](https://github.com/angular/angular/issues/14029) [#13900](https://github.com/angular/angular/issues/13900)
|
||||||
* **core:** export animation classes required for Renderer impl ([#14002](https://github.com/angular/angular/issues/14002)) ([83361d8](https://github.com/angular/angular/commit/83361d8)), closes [#14001](https://github.com/angular/angular/issues/14001)
|
* **core:** export animation classes required for Renderer impl ([#14002](https://github.com/angular/angular/issues/14002)) ([83361d8](https://github.com/angular/angular/commit/83361d8)), closes [#14001](https://github.com/angular/angular/issues/14001)
|
||||||
* **core:** fix not declared variable in view engine ([#14045](https://github.com/angular/angular/issues/14045)) ([d3a3a8e](https://github.com/angular/angular/commit/d3a3a8e))
|
* **core:** fix not declared variable in view engine ([#14045](https://github.com/angular/angular/issues/14045)) ([d3a3a8e](https://github.com/angular/angular/commit/d3a3a8e))
|
||||||
* **http:** don't create a blob out of ArrayBuffer when type is application/octet-stream ([#13992](https://github.com/angular/angular/issues/13992)) ([1200cf2](https://github.com/angular/angular/commit/1200cf2)), closes [#13973](https://github.com/angular/angular/issues/13973)
|
|
||||||
* **router:** enable loadChildren with function in aot ([#13909](https://github.com/angular/angular/issues/13909)) ([635bf02](https://github.com/angular/angular/commit/635bf02)), closes [#11075](https://github.com/angular/angular/issues/11075)
|
|
||||||
* **router:** routerLinkActive should not throw when not initialized ([#13273](https://github.com/angular/angular/issues/13273)) ([e8ea741](https://github.com/angular/angular/commit/e8ea741)), closes [#13270](https://github.com/angular/angular/issues/13270)
|
|
||||||
* **upgrade:** detect async downgrade component changes ([#13812](https://github.com/angular/angular/issues/13812)) ([d6382bf](https://github.com/angular/angular/commit/d6382bf)), closes [#6385](https://github.com/angular/angular/issues/6385) [#6385](https://github.com/angular/angular/issues/6385) [#10660](https://github.com/angular/angular/issues/10660) [#12318](https://github.com/angular/angular/issues/12318) [#12034](https://github.com/angular/angular/issues/12034)
|
|
||||||
* **upgrade/static:** ensure upgraded injector is initialized early enough ([#14065](https://github.com/angular/angular/issues/14065)) ([6152eb2](https://github.com/angular/angular/commit/6152eb2)), closes [#13811](https://github.com/angular/angular/issues/13811)
|
* **upgrade/static:** ensure upgraded injector is initialized early enough ([#14065](https://github.com/angular/angular/issues/14065)) ([6152eb2](https://github.com/angular/angular/commit/6152eb2)), closes [#13811](https://github.com/angular/angular/issues/13811)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **build:** optionally build an ES2015 distro ([#13471](https://github.com/angular/angular/issues/13471)) ([be6c95a](https://github.com/angular/angular/commit/be6c95a))
|
|
||||||
* **core:** add event support to view engine ([0adb97b](https://github.com/angular/angular/commit/0adb97b))
|
* **core:** add event support to view engine ([0adb97b](https://github.com/angular/angular/commit/0adb97b))
|
||||||
* **core:** add initial view engine ([#14014](https://github.com/angular/angular/issues/14014)) ([2f87eb5](https://github.com/angular/angular/commit/2f87eb5))
|
* **core:** add initial view engine ([#14014](https://github.com/angular/angular/issues/14014)) ([2f87eb5](https://github.com/angular/angular/commit/2f87eb5))
|
||||||
* **core:** add pure expression support to view engine ([6541737](https://github.com/angular/angular/commit/6541737))
|
* **core:** add pure expression support to view engine ([6541737](https://github.com/angular/angular/commit/6541737))
|
||||||
* **core:** Add type information to injector.get() ([#13785](https://github.com/angular/angular/issues/13785)) ([d169c24](https://github.com/angular/angular/commit/d169c24))
|
|
||||||
* **security:** allow calc and gradient functions. ([#13943](https://github.com/angular/angular/issues/13943)) ([e19bf70](https://github.com/angular/angular/commit/e19bf70))
|
|
||||||
* **tsc-wrapped:** Support of vinyl like config file was added ([#13987](https://github.com/angular/angular/issues/13987)) ([0c7726d](https://github.com/angular/angular/commit/0c7726d))
|
* **tsc-wrapped:** Support of vinyl like config file was added ([#13987](https://github.com/angular/angular/issues/13987)) ([0c7726d](https://github.com/angular/angular/commit/0c7726d))
|
||||||
* **upgrade:** Support ng-model in downgraded components ([#10578](https://github.com/angular/angular/issues/10578)) ([e21e9c5](https://github.com/angular/angular/commit/e21e9c5))
|
* **upgrade:** Support ng-model in downgraded components ([#10578](https://github.com/angular/angular/issues/10578)) ([e21e9c5](https://github.com/angular/angular/commit/e21e9c5))
|
||||||
|
|
||||||
@ -5990,19 +5870,12 @@ Note: The 2.3.0-beta.0 release also contains all the changes present in the 2.2.
|
|||||||
|
|
||||||
### Features (summary of all features from 2.2.0-beta.0 - 2.2.0-rc.0 releases)
|
### Features (summary of all features from 2.2.0-beta.0 - 2.2.0-rc.0 releases)
|
||||||
|
|
||||||
* **common:** support narrow forms for month and weekdays in DatePipe ([#12297](https://github.com/angular/angular/issues/12297)) ([f77ab6a](https://github.com/angular/angular/commit/f77ab6a)), closes [#12294](https://github.com/angular/angular/issues/12294)
|
|
||||||
* **core:** map 'for' attribute to 'htmlFor' property ([#10546](https://github.com/angular/angular/issues/10546)) ([634b3bb](https://github.com/angular/angular/commit/634b3bb)), closes [#7516](https://github.com/angular/angular/issues/7516)
|
* **core:** map 'for' attribute to 'htmlFor' property ([#10546](https://github.com/angular/angular/issues/10546)) ([634b3bb](https://github.com/angular/angular/commit/634b3bb)), closes [#7516](https://github.com/angular/angular/issues/7516)
|
||||||
* **core:** add the find method to QueryList ([7c16ef9](https://github.com/angular/angular/commit/7c16ef9))
|
* **core:** add the find method to QueryList ([7c16ef9](https://github.com/angular/angular/commit/7c16ef9))
|
||||||
* **forms:** add hasError and getError to AbstractControlDirective ([#11985](https://github.com/angular/angular/issues/11985)) ([592f40a](https://github.com/angular/angular/commit/592f40a)), closes [#7255](https://github.com/angular/angular/issues/7255)
|
|
||||||
* **forms:** add ng-pending CSS class during async validation ([#11243](https://github.com/angular/angular/issues/11243)) ([97bc971](https://github.com/angular/angular/commit/97bc971)), closes [#10336](https://github.com/angular/angular/issues/10336)
|
|
||||||
* **forms:** add emitEvent to AbstractControl methods ([#11949](https://github.com/angular/angular/issues/11949)) ([b9fc090](https://github.com/angular/angular/commit/b9fc090))
|
* **forms:** add emitEvent to AbstractControl methods ([#11949](https://github.com/angular/angular/issues/11949)) ([b9fc090](https://github.com/angular/angular/commit/b9fc090))
|
||||||
* **forms:** make 'parent' a public property of 'AbstractControl' ([#11855](https://github.com/angular/angular/issues/11855)) ([445e592](https://github.com/angular/angular/commit/445e592))
|
|
||||||
* **forms:** Validator.pattern accepts a RegExp ([#12323](https://github.com/angular/angular/issues/12323)) ([bf60418](https://github.com/angular/angular/commit/bf60418))
|
|
||||||
* **router:** add a provider making angular1/angular2 integration easier ([#12769](https://github.com/angular/angular/issues/12769)) ([6e35d13](https://github.com/angular/angular/commit/6e35d13))
|
* **router:** add a provider making angular1/angular2 integration easier ([#12769](https://github.com/angular/angular/issues/12769)) ([6e35d13](https://github.com/angular/angular/commit/6e35d13))
|
||||||
* **router:** add support for custom url matchers ([7340735](https://github.com/angular/angular/commit/7340735)), closes [#12442](https://github.com/angular/angular/issues/12442) [#12772](https://github.com/angular/angular/issues/12772)
|
* **router:** add support for custom url matchers ([7340735](https://github.com/angular/angular/commit/7340735)), closes [#12442](https://github.com/angular/angular/issues/12442) [#12772](https://github.com/angular/angular/issues/12772)
|
||||||
* **router:** export routerLinkActive w/ isActive property ([c9f58cf](https://github.com/angular/angular/commit/c9f58cf))
|
* **router:** export routerLinkActive w/ isActive property ([c9f58cf](https://github.com/angular/angular/commit/c9f58cf))
|
||||||
* **router:** add support for ng1/ng2 migration ([#12160](https://github.com/angular/angular/issues/12160)) ([8b9ab44](https://github.com/angular/angular/commit/8b9ab44))
|
|
||||||
* **upgrade:** add support for AoT compiled upgrade applications ([d6791ff](https://github.com/angular/angular/commit/d6791ff)), closes [#12239](https://github.com/angular/angular/issues/12239)
|
|
||||||
* **upgrade:** add support for `require` in UpgradeComponent ([fe1d0e2](https://github.com/angular/angular/commit/fe1d0e2))
|
* **upgrade:** add support for `require` in UpgradeComponent ([fe1d0e2](https://github.com/angular/angular/commit/fe1d0e2))
|
||||||
* **upgrade:** add/improve support for lifecycle hooks in UpgradeComponent ([469010e](https://github.com/angular/angular/commit/469010e))
|
* **upgrade:** add/improve support for lifecycle hooks in UpgradeComponent ([469010e](https://github.com/angular/angular/commit/469010e))
|
||||||
|
|
||||||
|
21
README.md
21
README.md
@ -5,22 +5,21 @@
|
|||||||
|
|
||||||
# Angular
|
# Angular
|
||||||
|
|
||||||
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.
|
Angular es una plataforma de desarrollo para construir aplicaciones web y móviles que usa TypeScript/JavaScript y otros lenguajes de programación.
|
||||||
|
|
||||||
## Quickstart
|
## Guía rápida
|
||||||
|
|
||||||
[Get started in 5 minutes][quickstart].
|
[Comienza a usarlo en 5 minutos][quickstart].
|
||||||
|
|
||||||
## Changelog
|
## Registro de cambios (Changelog)
|
||||||
|
|
||||||
[Learn about the latest improvements][changelog].
|
[Últimas mejoras realizadas][changelog].
|
||||||
|
|
||||||
## Want to help?
|
## ¿Quieres ayudar?
|
||||||
|
|
||||||
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
|
¿Quieres encontrar fallos, colaborar con código, o mejorar la documentación? ¡Excelente! Lee nuestras
|
||||||
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).
|
pautas para [colaborar][contributing] y luego revisa algunos de nuestras incidencias (issues) en [ayuda comunitaria](https://github.com/angular-hispano/angular/labels/ayuda%20comunitaria).
|
||||||
|
|
||||||
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md
|
[contributing]: https://github.com/angular-hispano/angular/blob/master/CONTRIBUTING.md
|
||||||
[quickstart]: https://angular.io/start
|
[quickstart]: https://docs.angular.lat/start
|
||||||
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
|
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
|
||||||
[ng]: https://angular.io
|
|
||||||
|
1
aio/content/examples/.gitignore
vendored
1
aio/content/examples/.gitignore
vendored
@ -18,7 +18,6 @@
|
|||||||
**/src/karma.conf.js
|
**/src/karma.conf.js
|
||||||
**/.angular-cli.json
|
**/.angular-cli.json
|
||||||
**/.editorconfig
|
**/.editorconfig
|
||||||
**/.gitignore
|
|
||||||
**/angular.json
|
**/angular.json
|
||||||
**/tsconfig.json
|
**/tsconfig.json
|
||||||
**/bs-config.e2e.json
|
**/bs-config.e2e.json
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Accessibility example e2e tests', () => {
|
describe('Accessibility example e2e tests', () => {
|
||||||
@ -6,11 +8,11 @@ describe('Accessibility example e2e tests', () => {
|
|||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display Accessibility Example', () => {
|
it('should display Accessibility Example', function () {
|
||||||
expect(element(by.css('h1')).getText()).toEqual('Accessibility Example');
|
expect(element(by.css('h1')).getText()).toEqual('Accessibility Example');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should take a number and change progressbar width', () => {
|
it('should take a number and change progressbar width', function () {
|
||||||
element(by.css('input')).sendKeys('16');
|
element(by.css('input')).sendKeys('16');
|
||||||
expect(element(by.css('input')).getAttribute('value')).toEqual('016');
|
expect(element(by.css('input')).getAttribute('value')).toEqual('016');
|
||||||
expect(element(by.css('app-example-progressbar div')).getCssValue('width')).toBe('48px');
|
expect(element(by.css('app-example-progressbar div')).getCssValue('width')).toBe('48px');
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// tslint:disable: no-host-metadata-property
|
|
||||||
// #docregion progressbar-component
|
// #docregion progressbar-component
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('AngularJS to Angular Quick Reference Tests', () => {
|
describe('AngularJS to Angular Quick Reference Tests', function () {
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display no poster images after bootstrap', () => {
|
it('should display no poster images after bootstrap', function () {
|
||||||
testImagesAreDisplayed(false);
|
testImagesAreDisplayed(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display proper movie data', () => {
|
it('should display proper movie data', function () {
|
||||||
// We check only a few samples
|
// We check only a few samples
|
||||||
const expectedSamples: any[] = [
|
let expectedSamples: any[] = [
|
||||||
{row: 0, column: 0, element: 'img', attr: 'src', value: 'images/hero.png', contains: true},
|
{row: 0, column: 0, element: 'img', attr: 'src', value: 'images/hero.png', contains: true},
|
||||||
{row: 0, column: 2, value: 'Celeritas'},
|
{row: 0, column: 2, value: 'Celeritas'},
|
||||||
{row: 1, column: 3, matches: /Dec 1[678], 2015/}, // absorb timezone dif; we care about date format
|
{row: 1, column: 3, matches: /Dec 1[678], 2015/}, // absorb timezone dif; we care about date format
|
||||||
@ -23,17 +25,18 @@ describe('AngularJS to Angular Quick Reference Tests', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Go through the samples
|
// Go through the samples
|
||||||
const movieRows = getMovieRows();
|
let movieRows = getMovieRows();
|
||||||
for (const sample of expectedSamples) {
|
for (let i = 0; i < expectedSamples.length; i++) {
|
||||||
const tableCell = movieRows.get(sample.row)
|
let sample = expectedSamples[i];
|
||||||
|
let tableCell = movieRows.get(sample.row)
|
||||||
.all(by.tagName('td')).get(sample.column);
|
.all(by.tagName('td')).get(sample.column);
|
||||||
// Check the cell or its nested element
|
// Check the cell or its nested element
|
||||||
const elementToCheck = sample.element
|
let elementToCheck = sample.element
|
||||||
? tableCell.element(by.tagName(sample.element))
|
? tableCell.element(by.tagName(sample.element))
|
||||||
: tableCell;
|
: tableCell;
|
||||||
|
|
||||||
// Check element attribute or text
|
// Check element attribute or text
|
||||||
const valueToCheck = sample.attr
|
let valueToCheck = sample.attr
|
||||||
? elementToCheck.getAttribute(sample.attr)
|
? elementToCheck.getAttribute(sample.attr)
|
||||||
: elementToCheck.getText();
|
: elementToCheck.getText();
|
||||||
|
|
||||||
@ -48,42 +51,42 @@ describe('AngularJS to Angular Quick Reference Tests', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display images after Show Poster', () => {
|
it('should display images after Show Poster', function () {
|
||||||
testPosterButtonClick('Show Poster', true);
|
testPosterButtonClick('Show Poster', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide images after Hide Poster', () => {
|
it('should hide images after Hide Poster', function () {
|
||||||
testPosterButtonClick('Hide Poster', false);
|
testPosterButtonClick('Hide Poster', false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display no movie when no favorite hero is specified', () => {
|
it('should display no movie when no favorite hero is specified', function () {
|
||||||
testFavoriteHero(null, 'Please enter your favorite hero.');
|
testFavoriteHero(null, 'Please enter your favorite hero.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display no movie for Magneta', () => {
|
it('should display no movie for Magneta', function () {
|
||||||
testFavoriteHero('Magneta', 'No movie, sorry!');
|
testFavoriteHero('Magneta', 'No movie, sorry!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a movie for Dr Nice', () => {
|
it('should display a movie for Dr Nice', function () {
|
||||||
testFavoriteHero('Dr Nice', 'Excellent choice!');
|
testFavoriteHero('Dr Nice', 'Excellent choice!');
|
||||||
});
|
});
|
||||||
|
|
||||||
function testImagesAreDisplayed(isDisplayed: boolean) {
|
function testImagesAreDisplayed(isDisplayed: boolean) {
|
||||||
const expectedMovieCount = 3;
|
let expectedMovieCount = 3;
|
||||||
|
|
||||||
const movieRows = getMovieRows();
|
let movieRows = getMovieRows();
|
||||||
expect(movieRows.count()).toBe(expectedMovieCount);
|
expect(movieRows.count()).toBe(expectedMovieCount);
|
||||||
for (let i = 0; i < expectedMovieCount; i++) {
|
for (let i = 0; i < expectedMovieCount; i++) {
|
||||||
const movieImage = movieRows.get(i).element(by.css('td > img'));
|
let movieImage = movieRows.get(i).element(by.css('td > img'));
|
||||||
expect(movieImage.isDisplayed()).toBe(isDisplayed);
|
expect(movieImage.isDisplayed()).toBe(isDisplayed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testPosterButtonClick(expectedButtonText: string, isDisplayed: boolean) {
|
function testPosterButtonClick(expectedButtonText: string, isDisplayed: boolean) {
|
||||||
const posterButton = element(by.css('app-movie-list tr > th > button'));
|
let posterButton = element(by.css('app-movie-list tr > th > button'));
|
||||||
expect(posterButton.getText()).toBe(expectedButtonText);
|
expect(posterButton.getText()).toBe(expectedButtonText);
|
||||||
|
|
||||||
posterButton.click().then(() => {
|
posterButton.click().then(function () {
|
||||||
testImagesAreDisplayed(isDisplayed);
|
testImagesAreDisplayed(isDisplayed);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -93,12 +96,12 @@ describe('AngularJS to Angular Quick Reference Tests', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testFavoriteHero(heroName: string, expectedLabel: string) {
|
function testFavoriteHero(heroName: string, expectedLabel: string) {
|
||||||
const movieListComp = element(by.tagName('app-movie-list'));
|
let movieListComp = element(by.tagName('app-movie-list'));
|
||||||
const heroInput = movieListComp.element(by.tagName('input'));
|
let heroInput = movieListComp.element(by.tagName('input'));
|
||||||
const favoriteHeroLabel = movieListComp.element(by.tagName('h3'));
|
let favoriteHeroLabel = movieListComp.element(by.tagName('h3'));
|
||||||
const resultLabel = movieListComp.element(by.css('span > p'));
|
let resultLabel = movieListComp.element(by.css('span > p'));
|
||||||
|
|
||||||
heroInput.clear().then(() => {
|
heroInput.clear().then(function () {
|
||||||
heroInput.sendKeys(heroName || '');
|
heroInput.sendKeys(heroName || '');
|
||||||
expect(resultLabel.getText()).toBe(expectedLabel);
|
expect(resultLabel.getText()).toBe(expectedLabel);
|
||||||
if (heroName) {
|
if (heroName) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, ExpectedConditions as EC } from 'protractor';
|
import { browser, ExpectedConditions as EC } from 'protractor';
|
||||||
import { logging } from 'selenium-webdriver';
|
import { logging } from 'selenium-webdriver';
|
||||||
import * as openClose from './open-close.po';
|
import * as openClose from './open-close.po';
|
||||||
|
@ -34,7 +34,7 @@ export class AppComponent {
|
|||||||
|
|
||||||
// #docregion prepare-router-outlet
|
// #docregion prepare-router-outlet
|
||||||
prepareRoute(outlet: RouterOutlet) {
|
prepareRoute(outlet: RouterOutlet) {
|
||||||
return outlet && outlet.activatedRouteData && outlet.activatedRouteData.animation;
|
return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// #enddocregion prepare-router-outlet
|
// #enddocregion prepare-router-outlet
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
// tslint:disable: variable-name
|
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
|
||||||
import { Component, HostBinding, OnInit } from '@angular/core';
|
import { Component, HostBinding, OnInit } from '@angular/core';
|
||||||
import { trigger, transition, animate, style, query, stagger } from '@angular/animations';
|
import { trigger, transition, animate, style, query, stagger } from '@angular/animations';
|
||||||
import { HEROES } from './mock-heroes';
|
import { HEROES } from './mock-heroes';
|
||||||
@ -54,11 +52,13 @@ export class HeroListPageComponent implements OnInit {
|
|||||||
@HostBinding('@pageAnimations')
|
@HostBinding('@pageAnimations')
|
||||||
public animatePage = true;
|
public animatePage = true;
|
||||||
|
|
||||||
|
_heroes = [];
|
||||||
// #docregion filter-animations
|
// #docregion filter-animations
|
||||||
heroTotal = -1;
|
heroTotal = -1;
|
||||||
// #enddocregion filter-animations
|
// #enddocregion filter-animations
|
||||||
get heroes() { return this._heroes; }
|
get heroes() {
|
||||||
private _heroes = [];
|
return this._heroes;
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this._heroes = HEROES;
|
this._heroes = HEROES;
|
||||||
|
@ -8,7 +8,8 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
|||||||
// #docregion trigger, trigger-wildcard1, trigger-transition
|
// #docregion trigger, trigger-wildcard1, trigger-transition
|
||||||
animations: [
|
animations: [
|
||||||
trigger('openClose', [
|
trigger('openClose', [
|
||||||
// #docregion state1
|
// #enddocregion events1
|
||||||
|
// #docregion state1, events1
|
||||||
// ...
|
// ...
|
||||||
// #enddocregion events1
|
// #enddocregion events1
|
||||||
state('open', style({
|
state('open', style({
|
||||||
@ -33,7 +34,8 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
|||||||
transition('closed => open', [
|
transition('closed => open', [
|
||||||
animate('0.5s')
|
animate('0.5s')
|
||||||
]),
|
]),
|
||||||
// #enddocregion transition2, trigger, component
|
// #enddocregion trigger, component
|
||||||
|
// #enddocregion transition2
|
||||||
// #docregion trigger-wildcard1
|
// #docregion trigger-wildcard1
|
||||||
transition('* => closed', [
|
transition('* => closed', [
|
||||||
animate('1s')
|
animate('1s')
|
||||||
@ -68,9 +70,7 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
|||||||
})
|
})
|
||||||
// #docregion events
|
// #docregion events
|
||||||
export class OpenCloseComponent {
|
export class OpenCloseComponent {
|
||||||
// #enddocregion events1, events, component
|
// #enddocregion events1, events
|
||||||
@Input() logging = false;
|
|
||||||
// #docregion component
|
|
||||||
isOpen = true;
|
isOpen = true;
|
||||||
|
|
||||||
toggle() {
|
toggle() {
|
||||||
@ -78,6 +78,7 @@ export class OpenCloseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #enddocregion component
|
// #enddocregion component
|
||||||
|
@Input() logging = false;
|
||||||
// #docregion events1, events
|
// #docregion events1, events
|
||||||
onAnimationEvent ( event: AnimationEvent ) {
|
onAnimationEvent ( event: AnimationEvent ) {
|
||||||
// #enddocregion events1, events
|
// #enddocregion events1, events
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { protractor, browser, element, by, ElementFinder } from 'protractor';
|
import { protractor, browser, element, by, ElementFinder } from 'protractor';
|
||||||
|
|
||||||
const nameSuffix = 'X';
|
const nameSuffix = 'X';
|
||||||
@ -19,7 +21,7 @@ describe('Architecture', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it(`has h2 '${expectedH2}'`, () => {
|
it(`has h2 '${expectedH2}'`, () => {
|
||||||
const h2 = element.all(by.css('h2')).map((elt: any) => elt.getText());
|
let h2 = element.all(by.css('h2')).map((elt: any) => elt.getText());
|
||||||
expect(h2).toEqual(expectedH2);
|
expect(h2).toEqual(expectedH2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -32,42 +34,42 @@ function heroTests() {
|
|||||||
const targetHero: Hero = { id: 2, name: 'Dr Nice' };
|
const targetHero: Hero = { id: 2, name: 'Dr Nice' };
|
||||||
|
|
||||||
it('has the right number of heroes', () => {
|
it('has the right number of heroes', () => {
|
||||||
const page = getPageElts();
|
let page = getPageElts();
|
||||||
expect(page.heroes.count()).toEqual(3);
|
expect(page.heroes.count()).toEqual(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has no hero details initially', () => {
|
it('has no hero details initially', function () {
|
||||||
const page = getPageElts();
|
let page = getPageElts();
|
||||||
expect(page.heroDetail.isPresent()).toBeFalsy('no hero detail');
|
expect(page.heroDetail.isPresent()).toBeFalsy('no hero detail');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows selected hero details', async () => {
|
it('shows selected hero details', async () => {
|
||||||
await element(by.cssContainingText('li', targetHero.name)).click();
|
await element(by.cssContainingText('li', targetHero.name)).click();
|
||||||
const page = getPageElts();
|
let page = getPageElts();
|
||||||
const hero = await heroFromDetail(page.heroDetail);
|
let hero = await heroFromDetail(page.heroDetail);
|
||||||
expect(hero.id).toEqual(targetHero.id);
|
expect(hero.id).toEqual(targetHero.id);
|
||||||
expect(hero.name).toEqual(targetHero.name);
|
expect(hero.name).toEqual(targetHero.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`shows updated hero name in details`, async () => {
|
it(`shows updated hero name in details`, async () => {
|
||||||
const input = element.all(by.css('input')).first();
|
let input = element.all(by.css('input')).first();
|
||||||
input.sendKeys(nameSuffix);
|
input.sendKeys(nameSuffix);
|
||||||
const page = getPageElts();
|
let page = getPageElts();
|
||||||
const hero = await heroFromDetail(page.heroDetail);
|
let hero = await heroFromDetail(page.heroDetail);
|
||||||
const newName = targetHero.name + nameSuffix;
|
let newName = targetHero.name + nameSuffix;
|
||||||
expect(hero.id).toEqual(targetHero.id);
|
expect(hero.id).toEqual(targetHero.id);
|
||||||
expect(hero.name).toEqual(newName);
|
expect(hero.name).toEqual(newName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function salesTaxTests() {
|
function salesTaxTests() {
|
||||||
it('has no sales tax initially', () => {
|
it('has no sales tax initially', function () {
|
||||||
const page = getPageElts();
|
let page = getPageElts();
|
||||||
expect(page.salesTaxDetail.isPresent()).toBeFalsy('no sales tax info');
|
expect(page.salesTaxDetail.isPresent()).toBeFalsy('no sales tax info');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows sales tax', async () => {
|
it('shows sales tax', async function () {
|
||||||
const page = getPageElts();
|
let page = getPageElts();
|
||||||
page.salesTaxAmountInput.sendKeys('10', protractor.Key.ENTER);
|
page.salesTaxAmountInput.sendKeys('10', protractor.Key.ENTER);
|
||||||
expect(page.salesTaxDetail.getText()).toEqual('The sales tax is $1.00');
|
expect(page.salesTaxDetail.getText()).toEqual('The sales tax is $1.00');
|
||||||
});
|
});
|
||||||
@ -86,11 +88,13 @@ function getPageElts() {
|
|||||||
|
|
||||||
async function heroFromDetail(detail: ElementFinder): Promise<Hero> {
|
async function heroFromDetail(detail: ElementFinder): Promise<Hero> {
|
||||||
// Get hero id from the first <div>
|
// Get hero id from the first <div>
|
||||||
const id = await detail.all(by.css('div')).first().getText();
|
// let _id = await detail.all(by.css('div')).first().getText();
|
||||||
|
let _id = await detail.all(by.css('div')).first().getText();
|
||||||
// Get name from the h2
|
// Get name from the h2
|
||||||
const name = await detail.element(by.css('h4')).getText();
|
// let _name = await detail.element(by.css('h4')).getText();
|
||||||
|
let _name = await detail.element(by.css('h4')).getText();
|
||||||
return {
|
return {
|
||||||
id: +id.substr(id.indexOf(' ') + 1),
|
id: +_id.substr(_id.indexOf(' ') + 1),
|
||||||
name: name.substr(0, name.lastIndexOf(' ')),
|
name: _name.substr(0, _name.lastIndexOf(' '))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ export class BackendService {
|
|||||||
// TODO: get from the database
|
// TODO: get from the database
|
||||||
return Promise.resolve<Hero[]>(HEROES);
|
return Promise.resolve<Hero[]>(HEROES);
|
||||||
}
|
}
|
||||||
const err = new Error('Cannot get object of this type');
|
let err = new Error('Cannot get object of this type');
|
||||||
this.logger.error(err);
|
this.logger.error(err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ export class SalesTaxService {
|
|||||||
constructor(private rateService: TaxRateService) { }
|
constructor(private rateService: TaxRateService) { }
|
||||||
|
|
||||||
getVAT(value: string | number) {
|
getVAT(value: string | number) {
|
||||||
const amount = (typeof value === 'string') ?
|
let amount = (typeof value === 'string') ?
|
||||||
parseFloat(value) : value;
|
parseFloat(value) : value;
|
||||||
return (amount || 0) * this.rateService.getRate('VAT');
|
return (amount || 0) * this.rateService.getRate('VAT');
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,34 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Attribute binding example', () => {
|
describe('Attribute binding example', function () {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display Property Binding with Angular', () => {
|
it('should display Property Binding with Angular', function () {
|
||||||
expect(element(by.css('h1')).getText()).toEqual('Attribute, class, and style bindings');
|
expect(element(by.css('h1')).getText()).toEqual('Attribute, class, and style bindings');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a table', () => {
|
it('should display a table', function() {
|
||||||
expect(element.all(by.css('table')).isPresent()).toBe(true);
|
expect(element.all(by.css('table')).isPresent()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display an Aria button', () => {
|
it('should display an Aria button', function () {
|
||||||
expect(element.all(by.css('button')).get(0).getText()).toBe('Go for it with Aria');
|
expect(element.all(by.css('button')).get(0).getText()).toBe('Go for it with Aria');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a blue background on div', () => {
|
it('should display a blue background on div', function () {
|
||||||
expect(element.all(by.css('div')).get(1).getCssValue('background-color')).toEqual('rgba(25, 118, 210, 1)');
|
expect(element.all(by.css('div')).get(1).getCssValue('background-color')).toEqual('rgba(25, 118, 210, 1)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a blue div with a red border', () => {
|
it('should display a blue div with a red border', function () {
|
||||||
expect(element.all(by.css('div')).get(1).getCssValue('border')).toEqual('2px solid rgb(212, 30, 46)');
|
expect(element.all(by.css('div')).get(1).getCssValue('border')).toEqual('2px solid rgb(212, 30, 46)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a div with many classes', () => {
|
it('should display a div with many classes', function () {
|
||||||
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('special');
|
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('special');
|
||||||
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('clearance');
|
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('clearance');
|
||||||
});
|
});
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { Component, HostBinding } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'comp-with-host-binding',
|
selector: 'comp-with-host-binding',
|
||||||
template: 'I am a component!',
|
template: 'I am a component!',
|
||||||
|
host: {
|
||||||
|
'[class.special]': 'isSpecial',
|
||||||
|
'[style.color]': 'color',
|
||||||
|
'[style.width]': 'width'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
export class CompWithHostBindingComponent {
|
export class CompWithHostBindingComponent {
|
||||||
@HostBinding('class.special')
|
|
||||||
isSpecial = false;
|
isSpecial = false;
|
||||||
|
|
||||||
@HostBinding('style.color')
|
|
||||||
color = 'green';
|
color = 'green';
|
||||||
|
|
||||||
@HostBinding('style.width')
|
|
||||||
width = '200px';
|
width = '200px';
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Attribute directives', () => {
|
describe('Attribute directives', () => {
|
||||||
|
|
||||||
const title = 'My First Attribute Directive';
|
let _title = 'My First Attribute Directive';
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should display correct title: ${title}`, () => {
|
it(`should display correct title: ${_title}`, () => {
|
||||||
expect(element(by.css('h1')).getText()).toEqual(title);
|
expect(element(by.css('h1')).getText()).toEqual(_title);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to select green highlight', () => {
|
it('should be able to select green highlight', () => {
|
||||||
|
@ -3,55 +3,57 @@ import { logging } from 'selenium-webdriver';
|
|||||||
|
|
||||||
describe('Binding syntax e2e tests', () => {
|
describe('Binding syntax e2e tests', () => {
|
||||||
|
|
||||||
beforeEach(() => browser.get(''));
|
beforeEach(function () {
|
||||||
|
browser.get('');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// helper function used to test what's logged to the console
|
// helper function used to test what's logged to the console
|
||||||
async function logChecker(button, contents) {
|
async function logChecker(button, contents) {
|
||||||
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
||||||
const messages = logs.filter(({ message }) => message.indexOf(contents) !== -1 ? true : false);
|
const message = logs.filter(({ message }) => message.indexOf(contents) !== -1 ? true : false);
|
||||||
expect(messages.length).toBeGreaterThan(0);
|
expect(message.length).toBeGreaterThan(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
it('should display Binding syntax', () => {
|
it('should display Binding syntax', function () {
|
||||||
expect(element(by.css('h1')).getText()).toEqual('Binding syntax');
|
expect(element(by.css('h1')).getText()).toEqual('Binding syntax');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display Save button', () => {
|
it('should display Save button', function () {
|
||||||
expect(element.all(by.css('button')).get(0).getText()).toBe('Save');
|
expect(element.all(by.css('button')).get(0).getText()).toBe('Save');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display HTML attributes and DOM properties', () => {
|
it('should display HTML attributes and DOM properties', function () {
|
||||||
expect(element.all(by.css('h2')).get(1).getText()).toBe('HTML attributes and DOM properties');
|
expect(element.all(by.css('h2')).get(1).getText()).toBe('HTML attributes and DOM properties');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display 1. Use the inspector...', () => {
|
it('should display 1. Use the inspector...', function () {
|
||||||
expect(element.all(by.css('p')).get(0).getText()).toContain('1. Use the inspector');
|
expect(element.all(by.css('p')).get(0).getText()).toContain('1. Use the inspector');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display Disabled property vs. attribute', () => {
|
it('should display Disabled property vs. attribute', function () {
|
||||||
expect(element.all(by.css('h3')).get(0).getText()).toBe('Disabled property vs. attribute');
|
expect(element.all(by.css('h3')).get(0).getText()).toBe('Disabled property vs. attribute');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should log a message including Sarah', async () => {
|
it('should log a message including Sarah', async () => {
|
||||||
const attributeButton = element.all(by.css('button')).get(1);
|
let attributeButton = element.all(by.css('button')).get(1);
|
||||||
await attributeButton.click();
|
await attributeButton.click();
|
||||||
const contents = 'Sarah';
|
const contents = 'Sarah';
|
||||||
logChecker(attributeButton, contents);
|
logChecker(attributeButton, contents);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log a message including Sarah for DOM property', async () => {
|
it('should log a message including Sarah for DOM property', async () => {
|
||||||
const DOMPropertyButton = element.all(by.css('button')).get(2);
|
let DOMPropertyButton = element.all(by.css('button')).get(2);
|
||||||
await DOMPropertyButton.click();
|
await DOMPropertyButton.click();
|
||||||
const contents = 'Sarah';
|
const contents = 'Sarah';
|
||||||
logChecker(DOMPropertyButton, contents);
|
logChecker(DOMPropertyButton, contents);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log a message including Sally for DOM property', async () => {
|
it('should log a message including Sally for DOM property', async () => {
|
||||||
const DOMPropertyButton = element.all(by.css('button')).get(2);
|
let DOMPropertyButton = element.all(by.css('button')).get(2);
|
||||||
const input = element(by.css('input'));
|
let input = element(by.css('input'));
|
||||||
input.sendKeys('Sally');
|
input.sendKeys('Sally');
|
||||||
await DOMPropertyButton.click();
|
await DOMPropertyButton.click();
|
||||||
const contents = 'Sally';
|
const contents = 'Sally';
|
||||||
@ -59,14 +61,14 @@ describe('Binding syntax e2e tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log a message that Test Button works', async () => {
|
it('should log a message that Test Button works', async () => {
|
||||||
const testButton = element.all(by.css('button')).get(3);
|
let testButton = element.all(by.css('button')).get(3);
|
||||||
await testButton.click();
|
await testButton.click();
|
||||||
const contents = 'Test';
|
const contents = 'Test';
|
||||||
logChecker(testButton, contents);
|
logChecker(testButton, contents);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should toggle Test Button disabled', async () => {
|
it('should toggle Test Button disabled', async () => {
|
||||||
const toggleButton = element.all(by.css('button')).get(4);
|
let toggleButton = element.all(by.css('button')).get(4);
|
||||||
await toggleButton.click();
|
await toggleButton.click();
|
||||||
const contents = 'true';
|
const contents = 'true';
|
||||||
logChecker(toggleButton, contents);
|
logChecker(toggleButton, contents);
|
||||||
|
@ -26,7 +26,7 @@ export class AppComponent {
|
|||||||
|
|
||||||
toggleDisabled(): any {
|
toggleDisabled(): any {
|
||||||
|
|
||||||
const testButton = document.getElementById('testButton') as HTMLInputElement;
|
let testButton = <HTMLInputElement> document.getElementById('testButton');
|
||||||
testButton.disabled = !testButton.disabled;
|
testButton.disabled = !testButton.disabled;
|
||||||
console.warn(testButton.disabled);
|
console.warn(testButton.disabled);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Built-in Directives', () => {
|
describe('Built-in Directives', function () {
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have title Built-in Directives', () => {
|
it('should have title Built-in Directives', function () {
|
||||||
const title = element.all(by.css('h1')).get(0);
|
let title = element.all(by.css('h1')).get(0);
|
||||||
expect(title.getText()).toEqual('Built-in Directives');
|
expect(title.getText()).toEqual('Built-in Directives');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change first Teapot header', async () => {
|
it('should change first Teapot header', async () => {
|
||||||
const firstLabel = element.all(by.css('p')).get(0);
|
let firstLabel = element.all(by.css('p')).get(0);
|
||||||
const firstInput = element.all(by.css('input')).get(0);
|
let firstInput = element.all(by.css('input')).get(0);
|
||||||
|
|
||||||
expect(firstLabel.getText()).toEqual('Current item name: Teapot');
|
expect(firstLabel.getText()).toEqual('Current item name: Teapot');
|
||||||
firstInput.sendKeys('abc');
|
firstInput.sendKeys('abc');
|
||||||
@ -21,49 +23,49 @@ describe('Built-in Directives', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should modify sentence when modified checkbox checked', () => {
|
it('should modify sentence when modified checkbox checked', function () {
|
||||||
const modifiedChkbxLabel = element.all(by.css('input[type="checkbox"]')).get(1);
|
let modifiedChkbxLabel = element.all(by.css('input[type="checkbox"]')).get(1);
|
||||||
const modifiedSentence = element.all(by.css('div')).get(1);
|
let modifiedSentence = element.all(by.css('div')).get(1);
|
||||||
|
|
||||||
modifiedChkbxLabel.click();
|
modifiedChkbxLabel.click();
|
||||||
expect(modifiedSentence.getText()).toContain('modified');
|
expect(modifiedSentence.getText()).toContain('modified');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should modify sentence when normal checkbox checked', () => {
|
it('should modify sentence when normal checkbox checked', function () {
|
||||||
const normalChkbxLabel = element.all(by.css('input[type="checkbox"]')).get(4);
|
let normalChkbxLabel = element.all(by.css('input[type="checkbox"]')).get(4);
|
||||||
const normalSentence = element.all(by.css('div')).get(7);
|
let normalSentence = element.all(by.css('div')).get(7);
|
||||||
|
|
||||||
normalChkbxLabel.click();
|
normalChkbxLabel.click();
|
||||||
expect(normalSentence.getText()).toContain('normal weight and, extra large');
|
expect(normalSentence.getText()).toContain('normal weight and, extra large');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should toggle app-item-detail', () => {
|
it('should toggle app-item-detail', function () {
|
||||||
const toggleButton = element.all(by.css('button')).get(3);
|
let toggleButton = element.all(by.css('button')).get(3);
|
||||||
const toggledDiv = element.all(by.css('app-item-detail')).get(0);
|
let toggledDiv = element.all(by.css('app-item-detail')).get(0);
|
||||||
|
|
||||||
toggleButton.click();
|
toggleButton.click();
|
||||||
expect(toggledDiv.isDisplayed()).toBe(true);
|
expect(toggledDiv.isDisplayed()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide app-item-detail', () => {
|
it('should hide app-item-detail', function () {
|
||||||
const hiddenMessage = element.all(by.css('p')).get(11);
|
let hiddenMessage = element.all(by.css('p')).get(11);
|
||||||
const hiddenDiv = element.all(by.css('app-item-detail')).get(2);
|
let hiddenDiv = element.all(by.css('app-item-detail')).get(2);
|
||||||
|
|
||||||
expect(hiddenMessage.getText()).toContain('in the DOM');
|
expect(hiddenMessage.getText()).toContain('in the DOM');
|
||||||
expect(hiddenDiv.isDisplayed()).toBe(true);
|
expect(hiddenDiv.isDisplayed()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have 10 lists each containing the string Teapot', () => {
|
it('should have 10 lists each containing the string Teapot', function () {
|
||||||
const listDiv = element.all(by.cssContainingText('.box', 'Teapot'));
|
let listDiv = element.all(by.cssContainingText('.box', 'Teapot'));
|
||||||
expect(listDiv.count()).toBe(10);
|
expect(listDiv.count()).toBe(10);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should switch case', () => {
|
it('should switch case', function () {
|
||||||
const tvRadioButton = element.all(by.css('input[type="radio"]')).get(3);
|
let tvRadioButton = element.all(by.css('input[type="radio"]')).get(3);
|
||||||
const tvDiv = element(by.css('app-lost-item'));
|
let tvDiv = element(by.css('app-lost-item'));
|
||||||
|
|
||||||
const fishbowlRadioButton = element.all(by.css('input[type="radio"]')).get(4);
|
let fishbowlRadioButton = element.all(by.css('input[type="radio"]')).get(4);
|
||||||
const fishbowlDiv = element(by.css('app-unknown-item'));
|
let fishbowlDiv = element(by.css('app-unknown-item'));
|
||||||
|
|
||||||
tvRadioButton.click();
|
tvRadioButton.click();
|
||||||
expect(tvDiv.getText()).toContain('Television');
|
expect(tvDiv.getText()).toContain('Television');
|
||||||
|
@ -30,14 +30,6 @@ export class AppComponent implements OnInit {
|
|||||||
itemsWithTrackByCountReset = 0;
|
itemsWithTrackByCountReset = 0;
|
||||||
itemIdIncrement = 1;
|
itemIdIncrement = 1;
|
||||||
|
|
||||||
// #docregion setClasses
|
|
||||||
currentClasses: {};
|
|
||||||
// #enddocregion setClasses
|
|
||||||
|
|
||||||
// #docregion setStyles
|
|
||||||
currentStyles: {};
|
|
||||||
// #enddocregion setStyles
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.resetItems();
|
this.resetItems();
|
||||||
this.setCurrentClasses();
|
this.setCurrentClasses();
|
||||||
@ -50,17 +42,19 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #docregion setClasses
|
// #docregion setClasses
|
||||||
|
currentClasses: {};
|
||||||
setCurrentClasses() {
|
setCurrentClasses() {
|
||||||
// CSS classes: added/removed per current state of component properties
|
// CSS classes: added/removed per current state of component properties
|
||||||
this.currentClasses = {
|
this.currentClasses = {
|
||||||
saveable: this.canSave,
|
'saveable': this.canSave,
|
||||||
modified: !this.isUnchanged,
|
'modified': !this.isUnchanged,
|
||||||
special: this.isSpecial
|
'special': this.isSpecial
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// #enddocregion setClasses
|
// #enddocregion setClasses
|
||||||
|
|
||||||
// #docregion setStyles
|
// #docregion setStyles
|
||||||
|
currentStyles: {};
|
||||||
setCurrentStyles() {
|
setCurrentStyles() {
|
||||||
// CSS styles: set per current state of component properties
|
// CSS styles: set per current state of component properties
|
||||||
this.currentStyles = {
|
this.currentStyles = {
|
||||||
@ -76,7 +70,11 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
giveNullCustomerValue() {
|
giveNullCustomerValue() {
|
||||||
this.nullCustomer = 'Kelly';
|
!(this.nullCustomer = null) ? (this.nullCustomer = 'Kelly') : (this.nullCustomer = null);
|
||||||
|
}
|
||||||
|
|
||||||
|
resetNullItem() {
|
||||||
|
this.nullCustomer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetItems() {
|
resetItems() {
|
||||||
@ -86,7 +84,7 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resetList() {
|
resetList() {
|
||||||
this.resetItems();
|
this.resetItems()
|
||||||
this.itemsWithTrackByCountReset = 0;
|
this.itemsWithTrackByCountReset = 0;
|
||||||
this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;
|
this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;
|
||||||
}
|
}
|
||||||
@ -109,7 +107,7 @@ export class AppComponent implements OnInit {
|
|||||||
trackByItems(index: number, item: Item): number { return item.id; }
|
trackByItems(index: number, item: Item): number { return item.id; }
|
||||||
// #enddocregion trackByItems
|
// #enddocregion trackByItems
|
||||||
|
|
||||||
trackById(index: number, item: any): number { return item.id; }
|
trackById(index: number, item: any): number { return item['id']; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Built Template Functions Example', () => {
|
describe('Built Template Functions Example', function () {
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have title Built-in Template Functions', () => {
|
it('should have title Built-in Template Functions', function () {
|
||||||
const title = element.all(by.css('h1')).get(0);
|
let title = element.all(by.css('h1')).get(0);
|
||||||
expect(title.getText()).toEqual('Built-in Template Functions');
|
expect(title.getText()).toEqual('Built-in Template Functions');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display $any( ) in h2', () => {
|
it('should display $any( ) in h2', function () {
|
||||||
const header = element(by.css('h2'));
|
let header = element(by.css('h2'));
|
||||||
expect(header.getText()).toContain('$any( )');
|
expect(header.getText()).toContain('$any( )');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,85 +1,87 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Component Communication Cookbook Tests', () => {
|
describe('Component Communication Cookbook Tests', function () {
|
||||||
|
|
||||||
// Note: '?e2e' which app can read to know it is running in protractor
|
// Note: '?e2e' which app can read to know it is running in protractor
|
||||||
// e.g. `if (!/e2e/.test(location.search)) { ...`
|
// e.g. `if (!/e2e/.test(location.search)) { ...`
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('?e2e');
|
browser.get('?e2e');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Parent-to-child communication', () => {
|
describe('Parent-to-child communication', function() {
|
||||||
// #docregion parent-to-child
|
// #docregion parent-to-child
|
||||||
// ...
|
// ...
|
||||||
const heroNames = ['Dr IQ', 'Magneta', 'Bombasto'];
|
let _heroNames = ['Dr IQ', 'Magneta', 'Bombasto'];
|
||||||
const masterName = 'Master';
|
let _masterName = 'Master';
|
||||||
|
|
||||||
it('should pass properties to children properly', () => {
|
it('should pass properties to children properly', function () {
|
||||||
const parent = element.all(by.tagName('app-hero-parent')).get(0);
|
let parent = element.all(by.tagName('app-hero-parent')).get(0);
|
||||||
const heroes = parent.all(by.tagName('app-hero-child'));
|
let heroes = parent.all(by.tagName('app-hero-child'));
|
||||||
|
|
||||||
for (let i = 0; i < heroNames.length; i++) {
|
for (let i = 0; i < _heroNames.length; i++) {
|
||||||
const childTitle = heroes.get(i).element(by.tagName('h3')).getText();
|
let childTitle = heroes.get(i).element(by.tagName('h3')).getText();
|
||||||
const childDetail = heroes.get(i).element(by.tagName('p')).getText();
|
let childDetail = heroes.get(i).element(by.tagName('p')).getText();
|
||||||
expect(childTitle).toEqual(heroNames[i] + ' says:');
|
expect(childTitle).toEqual(_heroNames[i] + ' says:');
|
||||||
expect(childDetail).toContain(masterName);
|
expect(childDetail).toContain(_masterName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// ...
|
// ...
|
||||||
// #enddocregion parent-to-child
|
// #enddocregion parent-to-child
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Parent-to-child communication with setter', () => {
|
describe('Parent-to-child communication with setter', function() {
|
||||||
// #docregion parent-to-child-setter
|
// #docregion parent-to-child-setter
|
||||||
// ...
|
// ...
|
||||||
it('should display trimmed, non-empty names', () => {
|
it('should display trimmed, non-empty names', function () {
|
||||||
const nonEmptyNameIndex = 0;
|
let _nonEmptyNameIndex = 0;
|
||||||
const nonEmptyName = '"Dr IQ"';
|
let _nonEmptyName = '"Dr IQ"';
|
||||||
const parent = element.all(by.tagName('app-name-parent')).get(0);
|
let parent = element.all(by.tagName('app-name-parent')).get(0);
|
||||||
const hero = parent.all(by.tagName('app-name-child')).get(nonEmptyNameIndex);
|
let hero = parent.all(by.tagName('app-name-child')).get(_nonEmptyNameIndex);
|
||||||
|
|
||||||
const displayName = hero.element(by.tagName('h3')).getText();
|
let displayName = hero.element(by.tagName('h3')).getText();
|
||||||
expect(displayName).toEqual(nonEmptyName);
|
expect(displayName).toEqual(_nonEmptyName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should replace empty name with default name', () => {
|
it('should replace empty name with default name', function () {
|
||||||
const emptyNameIndex = 1;
|
let _emptyNameIndex = 1;
|
||||||
const defaultName = '"<no name set>"';
|
let _defaultName = '"<no name set>"';
|
||||||
const parent = element.all(by.tagName('app-name-parent')).get(0);
|
let parent = element.all(by.tagName('app-name-parent')).get(0);
|
||||||
const hero = parent.all(by.tagName('app-name-child')).get(emptyNameIndex);
|
let hero = parent.all(by.tagName('app-name-child')).get(_emptyNameIndex);
|
||||||
|
|
||||||
const displayName = hero.element(by.tagName('h3')).getText();
|
let displayName = hero.element(by.tagName('h3')).getText();
|
||||||
expect(displayName).toEqual(defaultName);
|
expect(displayName).toEqual(_defaultName);
|
||||||
});
|
});
|
||||||
// ...
|
// ...
|
||||||
// #enddocregion parent-to-child-setter
|
// #enddocregion parent-to-child-setter
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Parent-to-child communication with ngOnChanges', () => {
|
describe('Parent-to-child communication with ngOnChanges', function() {
|
||||||
// #docregion parent-to-child-onchanges
|
// #docregion parent-to-child-onchanges
|
||||||
// ...
|
// ...
|
||||||
// Test must all execute in this exact order
|
// Test must all execute in this exact order
|
||||||
it('should set expected initial values', () => {
|
it('should set expected initial values', function () {
|
||||||
const actual = getActual();
|
let actual = getActual();
|
||||||
|
|
||||||
const initialLabel = 'Version 1.23';
|
let initialLabel = 'Version 1.23';
|
||||||
const initialLog = 'Initial value of major set to 1, Initial value of minor set to 23';
|
let initialLog = 'Initial value of major set to 1, Initial value of minor set to 23';
|
||||||
|
|
||||||
expect(actual.label).toBe(initialLabel);
|
expect(actual.label).toBe(initialLabel);
|
||||||
expect(actual.count).toBe(1);
|
expect(actual.count).toBe(1);
|
||||||
expect(actual.logs.get(0).getText()).toBe(initialLog);
|
expect(actual.logs.get(0).getText()).toBe(initialLog);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set expected values after clicking \'Minor\' twice', () => {
|
it('should set expected values after clicking \'Minor\' twice', function () {
|
||||||
const repoTag = element(by.tagName('app-version-parent'));
|
let repoTag = element(by.tagName('app-version-parent'));
|
||||||
const newMinorButton = repoTag.all(by.tagName('button')).get(0);
|
let newMinorButton = repoTag.all(by.tagName('button')).get(0);
|
||||||
|
|
||||||
newMinorButton.click().then(() => {
|
newMinorButton.click().then(function() {
|
||||||
newMinorButton.click().then(() => {
|
newMinorButton.click().then(function() {
|
||||||
const actual = getActual();
|
let actual = getActual();
|
||||||
|
|
||||||
const labelAfter2Minor = 'Version 1.25';
|
let labelAfter2Minor = 'Version 1.25';
|
||||||
const logAfter2Minor = 'minor changed from 24 to 25';
|
let logAfter2Minor = 'minor changed from 24 to 25';
|
||||||
|
|
||||||
expect(actual.label).toBe(labelAfter2Minor);
|
expect(actual.label).toBe(labelAfter2Minor);
|
||||||
expect(actual.count).toBe(3);
|
expect(actual.count).toBe(3);
|
||||||
@ -88,15 +90,15 @@ describe('Component Communication Cookbook Tests', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set expected values after clicking \'Major\' once', () => {
|
it('should set expected values after clicking \'Major\' once', function () {
|
||||||
const repoTag = element(by.tagName('app-version-parent'));
|
let repoTag = element(by.tagName('app-version-parent'));
|
||||||
const newMajorButton = repoTag.all(by.tagName('button')).get(1);
|
let newMajorButton = repoTag.all(by.tagName('button')).get(1);
|
||||||
|
|
||||||
newMajorButton.click().then(() => {
|
newMajorButton.click().then(function() {
|
||||||
const actual = getActual();
|
let actual = getActual();
|
||||||
|
|
||||||
const labelAfterMajor = 'Version 2.0';
|
let labelAfterMajor = 'Version 2.0';
|
||||||
const logAfterMajor = 'major changed from 1 to 2, minor changed from 25 to 0';
|
let logAfterMajor = 'major changed from 1 to 2, minor changed from 25 to 0';
|
||||||
|
|
||||||
expect(actual.label).toBe(labelAfterMajor);
|
expect(actual.label).toBe(labelAfterMajor);
|
||||||
expect(actual.count).toBe(4);
|
expect(actual.count).toBe(4);
|
||||||
@ -105,14 +107,14 @@ describe('Component Communication Cookbook Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function getActual() {
|
function getActual() {
|
||||||
const versionTag = element(by.tagName('app-version-child'));
|
let versionTag = element(by.tagName('app-version-child'));
|
||||||
const label = versionTag.element(by.tagName('h3')).getText();
|
let label = versionTag.element(by.tagName('h3')).getText();
|
||||||
const ul = versionTag.element((by.tagName('ul')));
|
let ul = versionTag.element((by.tagName('ul')));
|
||||||
const logs = ul.all(by.tagName('li'));
|
let logs = ul.all(by.tagName('li'));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label,
|
label: label,
|
||||||
logs,
|
logs: logs,
|
||||||
count: logs.count()
|
count: logs.count()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -121,30 +123,30 @@ describe('Component Communication Cookbook Tests', () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Child-to-parent communication', () => {
|
describe('Child-to-parent communication', function() {
|
||||||
// #docregion child-to-parent
|
// #docregion child-to-parent
|
||||||
// ...
|
// ...
|
||||||
it('should not emit the event initially', () => {
|
it('should not emit the event initially', function () {
|
||||||
const voteLabel = element(by.tagName('app-vote-taker'))
|
let voteLabel = element(by.tagName('app-vote-taker'))
|
||||||
.element(by.tagName('h3')).getText();
|
.element(by.tagName('h3')).getText();
|
||||||
expect(voteLabel).toBe('Agree: 0, Disagree: 0');
|
expect(voteLabel).toBe('Agree: 0, Disagree: 0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should process Agree vote', () => {
|
it('should process Agree vote', function () {
|
||||||
const agreeButton1 = element.all(by.tagName('app-voter')).get(0)
|
let agreeButton1 = element.all(by.tagName('app-voter')).get(0)
|
||||||
.all(by.tagName('button')).get(0);
|
.all(by.tagName('button')).get(0);
|
||||||
agreeButton1.click().then(() => {
|
agreeButton1.click().then(function() {
|
||||||
const voteLabel = element(by.tagName('app-vote-taker'))
|
let voteLabel = element(by.tagName('app-vote-taker'))
|
||||||
.element(by.tagName('h3')).getText();
|
.element(by.tagName('h3')).getText();
|
||||||
expect(voteLabel).toBe('Agree: 1, Disagree: 0');
|
expect(voteLabel).toBe('Agree: 1, Disagree: 0');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should process Disagree vote', () => {
|
it('should process Disagree vote', function () {
|
||||||
const agreeButton1 = element.all(by.tagName('app-voter')).get(1)
|
let agreeButton1 = element.all(by.tagName('app-voter')).get(1)
|
||||||
.all(by.tagName('button')).get(1);
|
.all(by.tagName('button')).get(1);
|
||||||
agreeButton1.click().then(() => {
|
agreeButton1.click().then(function() {
|
||||||
const voteLabel = element(by.tagName('app-vote-taker'))
|
let voteLabel = element(by.tagName('app-vote-taker'))
|
||||||
.element(by.tagName('h3')).getText();
|
.element(by.tagName('h3')).getText();
|
||||||
expect(voteLabel).toBe('Agree: 1, Disagree: 1');
|
expect(voteLabel).toBe('Agree: 1, Disagree: 1');
|
||||||
});
|
});
|
||||||
@ -155,31 +157,31 @@ describe('Component Communication Cookbook Tests', () => {
|
|||||||
|
|
||||||
// Can't run timer tests in protractor because
|
// Can't run timer tests in protractor because
|
||||||
// interaction w/ zones causes all tests to freeze & timeout.
|
// interaction w/ zones causes all tests to freeze & timeout.
|
||||||
xdescribe('Parent calls child via local var', () => {
|
xdescribe('Parent calls child via local var', function() {
|
||||||
countDownTimerTests('countdown-parent-lv');
|
countDownTimerTests('countdown-parent-lv');
|
||||||
});
|
});
|
||||||
|
|
||||||
xdescribe('Parent calls ViewChild', () => {
|
xdescribe('Parent calls ViewChild', function() {
|
||||||
countDownTimerTests('countdown-parent-vc');
|
countDownTimerTests('countdown-parent-vc');
|
||||||
});
|
});
|
||||||
|
|
||||||
function countDownTimerTests(parentTag: string) {
|
function countDownTimerTests(parentTag: string) {
|
||||||
// #docregion countdown-timer-tests
|
// #docregion countdown-timer-tests
|
||||||
// ...
|
// ...
|
||||||
it('timer and parent seconds should match', () => {
|
it('timer and parent seconds should match', function () {
|
||||||
const parent = element(by.tagName(parentTag));
|
let parent = element(by.tagName(parentTag));
|
||||||
const message = parent.element(by.tagName('app-countdown-timer')).getText();
|
let message = parent.element(by.tagName('app-countdown-timer')).getText();
|
||||||
browser.sleep(10); // give `seconds` a chance to catchup with `message`
|
browser.sleep(10); // give `seconds` a chance to catchup with `message`
|
||||||
const seconds = parent.element(by.className('seconds')).getText();
|
let seconds = parent.element(by.className('seconds')).getText();
|
||||||
expect(message).toContain(seconds);
|
expect(message).toContain(seconds);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should stop the countdown', () => {
|
it('should stop the countdown', function () {
|
||||||
const parent = element(by.tagName(parentTag));
|
let parent = element(by.tagName(parentTag));
|
||||||
const stopButton = parent.all(by.tagName('button')).get(1);
|
let stopButton = parent.all(by.tagName('button')).get(1);
|
||||||
|
|
||||||
stopButton.click().then(() => {
|
stopButton.click().then(function() {
|
||||||
const message = parent.element(by.tagName('app-countdown-timer')).getText();
|
let message = parent.element(by.tagName('app-countdown-timer')).getText();
|
||||||
expect(message).toContain('Holding');
|
expect(message).toContain('Holding');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -188,39 +190,39 @@ describe('Component Communication Cookbook Tests', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
describe('Parent and children communicate via a service', () => {
|
describe('Parent and children communicate via a service', function() {
|
||||||
// #docregion bidirectional-service
|
// #docregion bidirectional-service
|
||||||
// ...
|
// ...
|
||||||
it('should announce a mission', () => {
|
it('should announce a mission', function () {
|
||||||
const missionControl = element(by.tagName('app-mission-control'));
|
let missionControl = element(by.tagName('app-mission-control'));
|
||||||
const announceButton = missionControl.all(by.tagName('button')).get(0);
|
let announceButton = missionControl.all(by.tagName('button')).get(0);
|
||||||
announceButton.click().then(() => {
|
announceButton.click().then(function () {
|
||||||
const history = missionControl.all(by.tagName('li'));
|
let history = missionControl.all(by.tagName('li'));
|
||||||
expect(history.count()).toBe(1);
|
expect(history.count()).toBe(1);
|
||||||
expect(history.get(0).getText()).toMatch(/Mission.* announced/);
|
expect(history.get(0).getText()).toMatch(/Mission.* announced/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the mission by Lovell', () => {
|
it('should confirm the mission by Lovell', function () {
|
||||||
testConfirmMission(1, 2, 'Lovell');
|
testConfirmMission(1, 2, 'Lovell');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the mission by Haise', () => {
|
it('should confirm the mission by Haise', function () {
|
||||||
testConfirmMission(3, 3, 'Haise');
|
testConfirmMission(3, 3, 'Haise');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the mission by Swigert', () => {
|
it('should confirm the mission by Swigert', function () {
|
||||||
testConfirmMission(2, 4, 'Swigert');
|
testConfirmMission(2, 4, 'Swigert');
|
||||||
});
|
});
|
||||||
|
|
||||||
function testConfirmMission(buttonIndex: number, expectedLogCount: number, astronaut: string) {
|
function testConfirmMission(buttonIndex: number, expectedLogCount: number, astronaut: string) {
|
||||||
const confirmedLog = ' confirmed the mission';
|
let _confirmedLog = ' confirmed the mission';
|
||||||
const missionControl = element(by.tagName('app-mission-control'));
|
let missionControl = element(by.tagName('app-mission-control'));
|
||||||
const confirmButton = missionControl.all(by.tagName('button')).get(buttonIndex);
|
let confirmButton = missionControl.all(by.tagName('button')).get(buttonIndex);
|
||||||
confirmButton.click().then(() => {
|
confirmButton.click().then(function () {
|
||||||
const history = missionControl.all(by.tagName('li'));
|
let history = missionControl.all(by.tagName('li'));
|
||||||
expect(history.count()).toBe(expectedLogCount);
|
expect(history.count()).toBe(expectedLogCount);
|
||||||
expect(history.get(expectedLogCount - 1).getText()).toBe(astronaut + confirmedLog);
|
expect(history.get(expectedLogCount - 1).getText()).toBe(astronaut + _confirmedLog);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// ...
|
// ...
|
||||||
|
@ -15,7 +15,7 @@ import { VersionParentComponent } from './version-parent.component';
|
|||||||
import { VoterComponent } from './voter.component';
|
import { VoterComponent } from './voter.component';
|
||||||
import { VoteTakerComponent } from './votetaker.component';
|
import { VoteTakerComponent } from './votetaker.component';
|
||||||
|
|
||||||
const directives: any[] = [
|
let directives: any[] = [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
AstronautComponent,
|
AstronautComponent,
|
||||||
CountdownTimerComponent,
|
CountdownTimerComponent,
|
||||||
@ -30,7 +30,7 @@ const directives: any[] = [
|
|||||||
VoteTakerComponent
|
VoteTakerComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
const schemas: any[] = [];
|
let schemas: any[] = [];
|
||||||
|
|
||||||
// Include Countdown examples
|
// Include Countdown examples
|
||||||
// unless in e2e tests which they break.
|
// unless in e2e tests which they break.
|
||||||
@ -49,6 +49,6 @@ if (!/e2e/.test(location.search)) {
|
|||||||
],
|
],
|
||||||
declarations: directives,
|
declarations: directives,
|
||||||
bootstrap: [ AppComponent ],
|
bootstrap: [ AppComponent ],
|
||||||
schemas
|
schemas: schemas
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
@ -12,6 +12,6 @@ import { Hero } from './hero';
|
|||||||
})
|
})
|
||||||
export class HeroChildComponent {
|
export class HeroChildComponent {
|
||||||
@Input() hero: Hero;
|
@Input() hero: Hero;
|
||||||
@Input('master') masterName: string; // tslint:disable-line: no-input-rename
|
@Input('master') masterName: string;
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
@ -34,7 +34,7 @@ export class MissionControlComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
announce() {
|
announce() {
|
||||||
const mission = this.missions[this.nextMission++];
|
let mission = this.missions[this.nextMission++];
|
||||||
this.missionService.announceMission(mission);
|
this.missionService.announceMission(mission);
|
||||||
this.history.push(`Mission "${mission}" announced`);
|
this.history.push(`Mission "${mission}" announced`);
|
||||||
if (this.nextMission >= this.missions.length) { this.nextMission = 0; }
|
if (this.nextMission >= this.missions.length) { this.nextMission = 0; }
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// tslint:disable: variable-name
|
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
@ -7,11 +6,13 @@ import { Component, Input } from '@angular/core';
|
|||||||
template: '<h3>"{{name}}"</h3>'
|
template: '<h3>"{{name}}"</h3>'
|
||||||
})
|
})
|
||||||
export class NameChildComponent {
|
export class NameChildComponent {
|
||||||
|
private _name = '';
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
get name(): string { return this._name; }
|
|
||||||
set name(name: string) {
|
set name(name: string) {
|
||||||
this._name = (name && name.trim()) || '<no name set>';
|
this._name = (name && name.trim()) || '<no name set>';
|
||||||
}
|
}
|
||||||
private _name = '';
|
|
||||||
|
get name(): string { return this._name; }
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
@ -18,14 +18,14 @@ export class VersionChildComponent implements OnChanges {
|
|||||||
changeLog: string[] = [];
|
changeLog: string[] = [];
|
||||||
|
|
||||||
ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
|
ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
|
||||||
const log: string[] = [];
|
let log: string[] = [];
|
||||||
for (const propName in changes) {
|
for (let propName in changes) {
|
||||||
const changedProp = changes[propName];
|
let changedProp = changes[propName];
|
||||||
const to = JSON.stringify(changedProp.currentValue);
|
let to = JSON.stringify(changedProp.currentValue);
|
||||||
if (changedProp.isFirstChange()) {
|
if (changedProp.isFirstChange()) {
|
||||||
log.push(`Initial value of ${propName} set to ${to}`);
|
log.push(`Initial value of ${propName} set to ${to}`);
|
||||||
} else {
|
} else {
|
||||||
const from = JSON.stringify(changedProp.previousValue);
|
let from = JSON.stringify(changedProp.previousValue);
|
||||||
log.push(`${propName} changed from ${from} to ${to}`);
|
log.push(`${propName} changed from ${from} to ${to}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Component Style Tests', () => {
|
describe('Component Style Tests', function () {
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('scopes component styles to component view', () => {
|
it('scopes component styles to component view', function() {
|
||||||
const componentH1 = element(by.css('app-root > h1'));
|
let componentH1 = element(by.css('app-root > h1'));
|
||||||
const externalH1 = element(by.css('body > h1'));
|
let externalH1 = element(by.css('body > h1'));
|
||||||
|
|
||||||
// Note: sometimes webdriver returns the fontWeight as "normal",
|
// Note: sometimes webdriver returns the fontWeight as "normal",
|
||||||
// other times as "400", both of which are equal in CSS terms.
|
// other times as "400", both of which are equal in CSS terms.
|
||||||
@ -17,49 +19,49 @@ describe('Component Style Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('allows styling :host element', () => {
|
it('allows styling :host element', function() {
|
||||||
const host = element(by.css('app-hero-details'));
|
let host = element(by.css('app-hero-details'));
|
||||||
|
|
||||||
expect(host.getCssValue('borderWidth')).toEqual('1px');
|
expect(host.getCssValue('borderWidth')).toEqual('1px');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports :host() in function form', () => {
|
it('supports :host() in function form', function() {
|
||||||
const host = element(by.css('app-hero-details'));
|
let host = element(by.css('app-hero-details'));
|
||||||
|
|
||||||
host.element(by.buttonText('Activate')).click();
|
host.element(by.buttonText('Activate')).click();
|
||||||
expect(host.getCssValue('borderWidth')).toEqual('3px');
|
expect(host.getCssValue('borderWidth')).toEqual('3px');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows conditional :host-context() styling', () => {
|
it('allows conditional :host-context() styling', function() {
|
||||||
const h2 = element(by.css('app-hero-details h2'));
|
let h2 = element(by.css('app-hero-details h2'));
|
||||||
|
|
||||||
expect(h2.getCssValue('backgroundColor')).toEqual('rgba(238, 238, 255, 1)'); // #eeeeff
|
expect(h2.getCssValue('backgroundColor')).toEqual('rgba(238, 238, 255, 1)'); // #eeeeff
|
||||||
});
|
});
|
||||||
|
|
||||||
it('styles both view and content children with /deep/', () => {
|
it('styles both view and content children with /deep/', function() {
|
||||||
const viewH3 = element(by.css('app-hero-team h3'));
|
let viewH3 = element(by.css('app-hero-team h3'));
|
||||||
const contentH3 = element(by.css('app-hero-controls h3'));
|
let contentH3 = element(by.css('app-hero-controls h3'));
|
||||||
|
|
||||||
expect(viewH3.getCssValue('fontStyle')).toEqual('italic');
|
expect(viewH3.getCssValue('fontStyle')).toEqual('italic');
|
||||||
expect(contentH3.getCssValue('fontStyle')).toEqual('italic');
|
expect(contentH3.getCssValue('fontStyle')).toEqual('italic');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('includes styles loaded with CSS @import', () => {
|
it('includes styles loaded with CSS @import', function() {
|
||||||
const host = element(by.css('app-hero-details'));
|
let host = element(by.css('app-hero-details'));
|
||||||
|
|
||||||
expect(host.getCssValue('padding')).toEqual('10px');
|
expect(host.getCssValue('padding')).toEqual('10px');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('processes template inline styles', () => {
|
it('processes template inline styles', function() {
|
||||||
const button = element(by.css('app-hero-controls button'));
|
let button = element(by.css('app-hero-controls button'));
|
||||||
const externalButton = element(by.css('body > button'));
|
let externalButton = element(by.css('body > button'));
|
||||||
expect(button.getCssValue('backgroundColor')).toEqual('rgba(255, 255, 255, 1)'); // #ffffff
|
expect(button.getCssValue('backgroundColor')).toEqual('rgba(255, 255, 255, 1)'); // #ffffff
|
||||||
expect(externalButton.getCssValue('backgroundColor')).not.toEqual('rgba(255, 255, 255, 1)');
|
expect(externalButton.getCssValue('backgroundColor')).not.toEqual('rgba(255, 255, 255, 1)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('processes template <link>s', () => {
|
it('processes template <link>s', function() {
|
||||||
const li = element(by.css('app-hero-team li:first-child'));
|
let li = element(by.css('app-hero-team li:first-child'));
|
||||||
const externalLi = element(by.css('body > ul li'));
|
let externalLi = element(by.css('body > ul li'));
|
||||||
|
|
||||||
expect(li.getCssValue('listStyleType')).toEqual('square');
|
expect(li.getCssValue('listStyleType')).toEqual('square');
|
||||||
expect(externalLi.getCssValue('listStyleType')).not.toEqual('square');
|
expect(externalLi.getCssValue('listStyleType')).not.toEqual('square');
|
||||||
|
@ -1,74 +1,76 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Dependency Injection Cookbook', () => {
|
describe('Dependency Injection Cookbook', function () {
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render Logged in User example', () => {
|
it('should render Logged in User example', function () {
|
||||||
const loggedInUser = element.all(by.xpath('//h3[text()="Logged in user"]')).get(0);
|
let loggedInUser = element.all(by.xpath('//h3[text()="Logged in user"]')).get(0);
|
||||||
expect(loggedInUser).toBeDefined();
|
expect(loggedInUser).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"Bombasto" should be the logged in user', () => {
|
it('"Bombasto" should be the logged in user', function () {
|
||||||
const loggedInUser = element.all(by.xpath('//div[text()="Name: Bombasto"]')).get(0);
|
let loggedInUser = element.all(by.xpath('//div[text()="Name: Bombasto"]')).get(0);
|
||||||
expect(loggedInUser).toBeDefined();
|
expect(loggedInUser).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render sorted heroes', () => {
|
it('should render sorted heroes', function () {
|
||||||
const sortedHeroes = element.all(by.xpath('//h3[text()="Sorted Heroes" and position()=1]')).get(0);
|
let sortedHeroes = element.all(by.xpath('//h3[text()="Sorted Heroes" and position()=1]')).get(0);
|
||||||
expect(sortedHeroes).toBeDefined();
|
expect(sortedHeroes).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Dr Nice should be in sorted heroes', () => {
|
it('Dr Nice should be in sorted heroes', function () {
|
||||||
const sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Dr Nice" and position()=2]')).get(0);
|
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Dr Nice" and position()=2]')).get(0);
|
||||||
expect(sortedHero).toBeDefined();
|
expect(sortedHero).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('RubberMan should be in sorted heroes', () => {
|
it('RubberMan should be in sorted heroes', function () {
|
||||||
const sortedHero = element.all(by.xpath('//sorted-heroes/[text()="RubberMan" and position()=3]')).get(0);
|
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="RubberMan" and position()=3]')).get(0);
|
||||||
expect(sortedHero).toBeDefined();
|
expect(sortedHero).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Magma should be in sorted heroes', () => {
|
it('Magma should be in sorted heroes', function () {
|
||||||
const sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Magma"]')).get(0);
|
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Magma"]')).get(0);
|
||||||
expect(sortedHero).toBeDefined();
|
expect(sortedHero).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render Hero of the Month', () => {
|
it('should render Hero of the Month', function () {
|
||||||
const heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0);
|
let heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0);
|
||||||
expect(heroOfTheMonth).toBeDefined();
|
expect(heroOfTheMonth).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render Hero Bios', () => {
|
it('should render Hero Bios', function () {
|
||||||
const heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0);
|
let heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0);
|
||||||
expect(heroBios).toBeDefined();
|
expect(heroBios).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render Magma\'s description in Hero Bios', () => {
|
it('should render Magma\'s description in Hero Bios', function () {
|
||||||
const magmaText = element.all(by.xpath('//textarea[text()="Hero of all trades"]')).get(0);
|
let magmaText = element.all(by.xpath('//textarea[text()="Hero of all trades"]')).get(0);
|
||||||
expect(magmaText).toBeDefined();
|
expect(magmaText).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render Magma\'s phone in Hero Bios and Contacts', () => {
|
it('should render Magma\'s phone in Hero Bios and Contacts', function () {
|
||||||
const magmaPhone = element.all(by.xpath('//div[text()="Phone #: 555-555-5555"]')).get(0);
|
let magmaPhone = element.all(by.xpath('//div[text()="Phone #: 555-555-5555"]')).get(0);
|
||||||
expect(magmaPhone).toBeDefined();
|
expect(magmaPhone).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render Hero-of-the-Month runner-ups', () => {
|
it('should render Hero-of-the-Month runner-ups', function () {
|
||||||
const runnersUp = element(by.id('rups1')).getText();
|
let runnersUp = element(by.id('rups1')).getText();
|
||||||
expect(runnersUp).toContain('RubberMan, Dr Nice');
|
expect(runnersUp).toContain('RubberMan, Dr Nice');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render DateLogger log entry in Hero-of-the-Month', () => {
|
it('should render DateLogger log entry in Hero-of-the-Month', function () {
|
||||||
const logs = element.all(by.id('logs')).get(0).getText();
|
let logs = element.all(by.id('logs')).get(0).getText();
|
||||||
expect(logs).toContain('INFO: starting up at');
|
expect(logs).toContain('INFO: starting up at');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should highlight Hero Bios and Contacts container when mouseover', () => {
|
it('should highlight Hero Bios and Contacts container when mouseover', function () {
|
||||||
const target = element(by.css('div[appHighlight="yellow"]'));
|
let target = element(by.css('div[appHighlight="yellow"]'));
|
||||||
const yellow = 'rgba(255, 255, 0, 1)';
|
let yellow = 'rgba(255, 255, 0, 1)';
|
||||||
|
|
||||||
expect(target.getCssValue('background-color')).not.toEqual(yellow);
|
expect(target.getCssValue('background-color')).not.toEqual(yellow);
|
||||||
|
|
||||||
@ -79,25 +81,25 @@ describe('Dependency Injection Cookbook', () => {
|
|||||||
browser.wait(() => target.getCssValue('background-color').then(c => c === yellow), 2000);
|
browser.wait(() => target.getCssValue('background-color').then(c => c === yellow), 2000);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('in Parent Finder', () => {
|
describe('in Parent Finder', function () {
|
||||||
const cathy1 = element(by.css('alex cathy'));
|
let cathy1 = element(by.css('alex cathy'));
|
||||||
const craig1 = element(by.css('alex craig'));
|
let craig1 = element(by.css('alex craig'));
|
||||||
const carol1 = element(by.css('alex carol p'));
|
let carol1 = element(by.css('alex carol p'));
|
||||||
const carol2 = element(by.css('barry carol p'));
|
let carol2 = element(by.css('barry carol p'));
|
||||||
|
|
||||||
it('"Cathy" should find "Alex" via the component class', () => {
|
it('"Cathy" should find "Alex" via the component class', function () {
|
||||||
expect(cathy1.getText()).toContain('Found Alex via the component');
|
expect(cathy1.getText()).toContain('Found Alex via the component');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"Craig" should not find "Alex" via the base class', () => {
|
it('"Craig" should not find "Alex" via the base class', function () {
|
||||||
expect(craig1.getText()).toContain('Did not find Alex via the base');
|
expect(craig1.getText()).toContain('Did not find Alex via the base');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"Carol" within "Alex" should have "Alex" parent', () => {
|
it('"Carol" within "Alex" should have "Alex" parent', function () {
|
||||||
expect(carol1.getText()).toContain('Alex');
|
expect(carol1.getText()).toContain('Alex');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"Carol" within "Barry" should have "Barry" parent', () => {
|
it('"Carol" within "Barry" should have "Barry" parent', function () {
|
||||||
expect(carol2.getText()).toContain('Barry');
|
expect(carol2.getText()).toContain('Barry');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -42,11 +42,11 @@ const declarations = [
|
|||||||
ParentFinderComponent,
|
ParentFinderComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
const componentListA = [ AliceComponent, AlexComponent ];
|
const a_components = [AliceComponent, AlexComponent ];
|
||||||
|
|
||||||
const componentListB = [ BarryComponent, BethComponent, BobComponent ];
|
const b_components = [ BarryComponent, BethComponent, BobComponent ];
|
||||||
|
|
||||||
const componentListC = [
|
const c_components = [
|
||||||
CarolComponent, ChrisComponent, CraigComponent,
|
CarolComponent, ChrisComponent, CraigComponent,
|
||||||
CathyComponent
|
CathyComponent
|
||||||
];
|
];
|
||||||
@ -61,9 +61,9 @@ const componentListC = [
|
|||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
declarations,
|
declarations,
|
||||||
componentListA,
|
a_components,
|
||||||
componentListB,
|
b_components,
|
||||||
componentListC,
|
c_components,
|
||||||
StorageComponent,
|
StorageComponent,
|
||||||
],
|
],
|
||||||
bootstrap: [ AppComponent ],
|
bootstrap: [ AppComponent ],
|
||||||
|
@ -3,7 +3,7 @@ import { Hero } from './hero';
|
|||||||
|
|
||||||
export class HeroData {
|
export class HeroData {
|
||||||
createDb() {
|
createDb() {
|
||||||
const heroes = [
|
let heroes = [
|
||||||
new Hero(1, 'Windstorm'),
|
new Hero(1, 'Windstorm'),
|
||||||
new Hero(2, 'Bombasto'),
|
new Hero(2, 'Bombasto'),
|
||||||
new Hero(3, 'Magneta'),
|
new Hero(3, 'Magneta'),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// tslint:disable: component-selector space-before-function-paren
|
/* tslint:disable:no-unused-variable component-selector-name one-line check-open-brace */
|
||||||
|
/* tslint:disable:*/
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component, forwardRef, Optional, SkipSelf } from '@angular/core';
|
import { Component, forwardRef, Optional, SkipSelf } from '@angular/core';
|
||||||
@ -19,7 +20,8 @@ const DifferentParent = Parent;
|
|||||||
// The `parentType` defaults to `Parent` when omitting the second parameter.
|
// The `parentType` defaults to `Parent` when omitting the second parameter.
|
||||||
// #docregion provide-the-parent
|
// #docregion provide-the-parent
|
||||||
export function provideParent
|
export function provideParent
|
||||||
// #enddocregion provide-the-parent
|
// #enddocregion provide-parent, provide-the-parent
|
||||||
|
// #docregion provide-parent
|
||||||
(component: any, parentType?: any) {
|
(component: any, parentType?: any) {
|
||||||
return { provide: parentType || Parent, useExisting: forwardRef(() => component) };
|
return { provide: parentType || Parent, useExisting: forwardRef(() => component) };
|
||||||
}
|
}
|
||||||
|
@ -22,5 +22,5 @@ export function runnersUpFactory(take: number) {
|
|||||||
.join(', ');
|
.join(', ');
|
||||||
// #docregion factory-synopsis
|
// #docregion factory-synopsis
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
// #enddocregion factory-synopsis
|
// #enddocregion factory-synopsis
|
||||||
|
@ -24,7 +24,7 @@ export class UserContextService {
|
|||||||
// #enddocregion ctor, injectables
|
// #enddocregion ctor, injectables
|
||||||
|
|
||||||
loadUser(userId: number) {
|
loadUser(userId: number) {
|
||||||
const user = this.userService.getUserById(userId);
|
let user = this.userService.getUserById(userId);
|
||||||
this.name = user.name;
|
this.name = user.name;
|
||||||
this.role = user.role;
|
this.role = user.role;
|
||||||
|
|
||||||
|
@ -1,196 +1,202 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by, ElementFinder } from 'protractor';
|
import { browser, element, by, ElementFinder } from 'protractor';
|
||||||
|
|
||||||
describe('Dependency Injection Tests', () => {
|
describe('Dependency Injection Tests', function () {
|
||||||
|
|
||||||
let expectedMsg: string;
|
let expectedMsg: string;
|
||||||
let expectedMsgRx: RegExp;
|
let expectedMsgRx: RegExp;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Cars:', () => {
|
describe('Cars:', function() {
|
||||||
|
|
||||||
it('DI car displays as expected', () => {
|
it('DI car displays as expected', function () {
|
||||||
expectedMsg = 'DI car with 4 cylinders and Flintstone tires.';
|
expectedMsg = 'DI car with 4 cylinders and Flintstone tires.';
|
||||||
expect(element(by.css('#di')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#di')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('No DI car displays as expected', () => {
|
it('No DI car displays as expected', function () {
|
||||||
expectedMsg = 'No DI car with 4 cylinders and Flintstone tires.';
|
expectedMsg = 'No DI car with 4 cylinders and Flintstone tires.';
|
||||||
expect(element(by.css('#nodi')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#nodi')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Injector car displays as expected', () => {
|
it('Injector car displays as expected', function () {
|
||||||
expectedMsg = 'Injector car with 4 cylinders and Flintstone tires.';
|
expectedMsg = 'Injector car with 4 cylinders and Flintstone tires.';
|
||||||
expect(element(by.css('#injector')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#injector')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Factory car displays as expected', () => {
|
it('Factory car displays as expected', function () {
|
||||||
expectedMsg = 'Factory car with 4 cylinders and Flintstone tires.';
|
expectedMsg = 'Factory car with 4 cylinders and Flintstone tires.';
|
||||||
expect(element(by.css('#factory')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#factory')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Simple car displays as expected', () => {
|
it('Simple car displays as expected', function () {
|
||||||
expectedMsg = 'Simple car with 4 cylinders and Flintstone tires.';
|
expectedMsg = 'Simple car with 4 cylinders and Flintstone tires.';
|
||||||
expect(element(by.css('#simple')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#simple')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Super car displays as expected', () => {
|
it('Super car displays as expected', function () {
|
||||||
expectedMsg = 'Super car with 12 cylinders and Flintstone tires.';
|
expectedMsg = 'Super car with 12 cylinders and Flintstone tires.';
|
||||||
expect(element(by.css('#super')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#super')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test car displays as expected', () => {
|
it('Test car displays as expected', function () {
|
||||||
expectedMsg = 'Test car with 8 cylinders and YokoGoodStone tires.';
|
expectedMsg = 'Test car with 8 cylinders and YokoGoodStone tires.';
|
||||||
expect(element(by.css('#test')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#test')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Other Injections:', () => {
|
describe('Other Injections:', function() {
|
||||||
it('DI car displays as expected', () => {
|
it('DI car displays as expected', function () {
|
||||||
expectedMsg = 'DI car with 4 cylinders and Flintstone tires.';
|
expectedMsg = 'DI car with 4 cylinders and Flintstone tires.';
|
||||||
expect(element(by.css('#car')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#car')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Hero displays as expected', () => {
|
it('Hero displays as expected', function () {
|
||||||
expectedMsg = 'Dr Nice';
|
expectedMsg = 'Dr Nice';
|
||||||
expect(element(by.css('#hero')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#hero')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Optional injection displays as expected', () => {
|
it('Optional injection displays as expected', function () {
|
||||||
expectedMsg = 'R.O.U.S.\'s? I don\'t think they exist!';
|
expectedMsg = 'R.O.U.S.\'s? I don\'t think they exist!';
|
||||||
expect(element(by.css('#rodent')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#rodent')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Tests:', () => {
|
describe('Tests:', function() {
|
||||||
|
|
||||||
it('Tests display as expected', () => {
|
it('Tests display as expected', function () {
|
||||||
expectedMsgRx = /Tests passed/;
|
expectedMsgRx = /Tests passed/;
|
||||||
expect(element(by.css('#tests')).getText()).toMatch(expectedMsgRx);
|
expect(element(by.css('#tests')).getText()).toMatch(expectedMsgRx);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Provider variations:', () => {
|
describe('Provider variations:', function() {
|
||||||
|
|
||||||
it('P1 (class) displays as expected', () => {
|
it('P1 (class) displays as expected', function () {
|
||||||
expectedMsg = 'Hello from logger provided with Logger class';
|
expectedMsg = 'Hello from logger provided with Logger class';
|
||||||
expect(element(by.css('#p1')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p1')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P3 (provide) displays as expected', () => {
|
it('P3 (provide) displays as expected', function () {
|
||||||
expectedMsg = 'Hello from logger provided with useClass:Logger';
|
expectedMsg = 'Hello from logger provided with useClass:Logger';
|
||||||
expect(element(by.css('#p3')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p3')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P4 (useClass:BetterLogger) displays as expected', () => {
|
it('P4 (useClass:BetterLogger) displays as expected', function () {
|
||||||
expectedMsg = 'Hello from logger provided with useClass:BetterLogger';
|
expectedMsg = 'Hello from logger provided with useClass:BetterLogger';
|
||||||
expect(element(by.css('#p4')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p4')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P5 (useClass:EvenBetterLogger - dependency) displays as expected', () => {
|
it('P5 (useClass:EvenBetterLogger - dependency) displays as expected', function () {
|
||||||
expectedMsg = 'Message to Bob: Hello from EvenBetterlogger';
|
expectedMsg = 'Message to Bob: Hello from EvenBetterlogger';
|
||||||
expect(element(by.css('#p5')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p5')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P6a (no alias) displays as expected', () => {
|
it('P6a (no alias) displays as expected', function () {
|
||||||
expectedMsg = 'Hello OldLogger (but we want NewLogger)';
|
expectedMsg = 'Hello OldLogger (but we want NewLogger)';
|
||||||
expect(element(by.css('#p6a')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p6a')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P6b (alias) displays as expected', () => {
|
it('P6b (alias) displays as expected', function () {
|
||||||
expectedMsg = 'Hello from NewLogger (via aliased OldLogger)';
|
expectedMsg = 'Hello from NewLogger (via aliased OldLogger)';
|
||||||
expect(element(by.css('#p6b')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p6b')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P7 (useValue) displays as expected', () => {
|
it('P7 (useValue) displays as expected', function () {
|
||||||
expectedMsg = 'Silent logger says "Shhhhh!". Provided via "useValue"';
|
expectedMsg = 'Silent logger says "Shhhhh!". Provided via "useValue"';
|
||||||
expect(element(by.css('#p7')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p7')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P8 (useFactory) displays as expected', () => {
|
it('P8 (useFactory) displays as expected', function () {
|
||||||
expectedMsg = 'Hero service injected successfully via heroServiceProvider';
|
expectedMsg = 'Hero service injected successfully via heroServiceProvider';
|
||||||
expect(element(by.css('#p8')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p8')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P9 (InjectionToken) displays as expected', () => {
|
it('P9 (InjectionToken) displays as expected', function () {
|
||||||
expectedMsg = 'APP_CONFIG Application title is Dependency Injection';
|
expectedMsg = 'APP_CONFIG Application title is Dependency Injection';
|
||||||
expect(element(by.css('#p9')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p9')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('P10 (optional dependency) displays as expected', () => {
|
it('P10 (optional dependency) displays as expected', function () {
|
||||||
expectedMsg = 'Optional logger was not available';
|
expectedMsg = 'Optional logger was not available';
|
||||||
expect(element(by.css('#p10')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p10')).getText()).toEqual(expectedMsg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('User/Heroes:', () => {
|
describe('User/Heroes:', function() {
|
||||||
it('User is Bob - unauthorized', () => {
|
it('User is Bob - unauthorized', function () {
|
||||||
expectedMsgRx = /Bob, is not authorized/;
|
expectedMsgRx = /Bob, is not authorized/;
|
||||||
expect(element(by.css('#user')).getText()).toMatch(expectedMsgRx);
|
expect(element(by.css('#user')).getText()).toMatch(expectedMsgRx);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have button', () => {
|
it('should have button', function () {
|
||||||
expect(element.all(by.cssContainingText('button', 'Next User'))
|
expect(element.all(by.cssContainingText('button', 'Next User'))
|
||||||
.get(0).isDisplayed()).toBe(true, '\'Next User\' button should be displayed');
|
.get(0).isDisplayed()).toBe(true, '\'Next User\' button should be displayed');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('unauthorized user should have multiple unauthorized heroes', () => {
|
it('unauthorized user should have multiple unauthorized heroes', function () {
|
||||||
const heroes = element.all(by.css('#unauthorized app-hero-list div'));
|
let heroes = element.all(by.css('#unauthorized app-hero-list div'));
|
||||||
expect(heroes.count()).toBeGreaterThan(0);
|
expect(heroes.count()).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('unauthorized user should have no secret heroes', () => {
|
it('unauthorized user should have no secret heroes', function () {
|
||||||
const heroes = element.all(by.css('#unauthorized app-hero-list div'));
|
let heroes = element.all(by.css('#unauthorized app-hero-list div'));
|
||||||
expect(heroes.count()).toBeGreaterThan(0);
|
expect(heroes.count()).toBeGreaterThan(0);
|
||||||
|
|
||||||
const filteredHeroes = heroes.filter((elem: ElementFinder, index: number) => {
|
let filteredHeroes = heroes.filter((elem: ElementFinder, index: number) => {
|
||||||
return elem.getText().then((text: string) => /secret/.test(text));
|
return elem.getText().then((text: string) => {
|
||||||
|
return /secret/.test(text);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(filteredHeroes.count()).toEqual(0);
|
expect(filteredHeroes.count()).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('unauthorized user should have no authorized heroes listed', () => {
|
it('unauthorized user should have no authorized heroes listed', function () {
|
||||||
expect(element.all(by.css('#authorized app-hero-list div')).count()).toEqual(0);
|
expect(element.all(by.css('#authorized app-hero-list div')).count()).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('after button click', () => {
|
describe('after button click', function() {
|
||||||
|
|
||||||
beforeAll((done: any) => {
|
beforeAll(function (done: any) {
|
||||||
const buttonEle = element.all(by.cssContainingText('button', 'Next User')).get(0);
|
let buttonEle = element.all(by.cssContainingText('button', 'Next User')).get(0);
|
||||||
buttonEle.click().then(done, done);
|
buttonEle.click().then(done, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User is Alice - authorized', () => {
|
it('User is Alice - authorized', function () {
|
||||||
expectedMsgRx = /Alice, is authorized/;
|
expectedMsgRx = /Alice, is authorized/;
|
||||||
expect(element(by.css('#user')).getText()).toMatch(expectedMsgRx);
|
expect(element(by.css('#user')).getText()).toMatch(expectedMsgRx);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('authorized user should have multiple authorized heroes ', () => {
|
it('authorized user should have multiple authorized heroes ', function () {
|
||||||
const 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);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('authorized user should have multiple authorized heroes with tree-shakeable HeroesService', () => {
|
it('authorized user should have multiple authorized heroes with tree-shakeable HeroesService', function () {
|
||||||
const heroes = element.all(by.css('#tspAuthorized app-hero-list div'));
|
let heroes = element.all(by.css('#tspAuthorized app-hero-list div'));
|
||||||
expect(heroes.count()).toBeGreaterThan(0);
|
expect(heroes.count()).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('authorized user should have secret heroes', () => {
|
it('authorized user should have secret heroes', function () {
|
||||||
const 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);
|
||||||
|
|
||||||
const filteredHeroes = heroes.filter((elem: ElementFinder, index: number) => {
|
let filteredHeroes = heroes.filter(function(elem: ElementFinder, index: number) {
|
||||||
return elem.getText().then((text: string) => /secret/.test(text));
|
return elem.getText().then(function(text: string) {
|
||||||
|
return /secret/.test(text);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(filteredHeroes.count()).toBeGreaterThan(0);
|
expect(filteredHeroes.count()).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('authorized user should have no unauthorized heroes listed', () => {
|
it('authorized user should have no unauthorized heroes listed', function () {
|
||||||
expect(element.all(by.css('#unauthorized app-hero-list div')).count()).toEqual(0);
|
expect(element.all(by.css('#unauthorized app-hero-list div')).count()).toEqual(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -7,7 +7,7 @@ import { Car, Engine, Tires } from './car';
|
|||||||
export function simpleCar() {
|
export function simpleCar() {
|
||||||
// #docregion car-ctor-instantiation
|
// #docregion car-ctor-instantiation
|
||||||
// Simple car with 4 cylinders and Flintstone tires.
|
// Simple car with 4 cylinders and Flintstone tires.
|
||||||
const car = new Car(new Engine(), new Tires());
|
let car = new Car(new Engine(), new Tires());
|
||||||
// #enddocregion car-ctor-instantiation
|
// #enddocregion car-ctor-instantiation
|
||||||
car.description = 'Simple';
|
car.description = 'Simple';
|
||||||
return car;
|
return car;
|
||||||
@ -20,12 +20,11 @@ class Engine2 {
|
|||||||
constructor(public cylinders: number) { }
|
constructor(public cylinders: number) { }
|
||||||
}
|
}
|
||||||
// #enddocregion car-ctor-instantiation-with-param
|
// #enddocregion car-ctor-instantiation-with-param
|
||||||
|
|
||||||
export function superCar() {
|
export function superCar() {
|
||||||
// #docregion car-ctor-instantiation-with-param
|
// #docregion car-ctor-instantiation-with-param
|
||||||
// Super car with 12 cylinders and Flintstone tires.
|
// Super car with 12 cylinders and Flintstone tires.
|
||||||
const bigCylinders = 12;
|
let bigCylinders = 12;
|
||||||
const car = new Car(new Engine2(bigCylinders), new Tires());
|
let car = new Car(new Engine2(bigCylinders), new Tires());
|
||||||
// #enddocregion car-ctor-instantiation-with-param
|
// #enddocregion car-ctor-instantiation-with-param
|
||||||
car.description = 'Super';
|
car.description = 'Super';
|
||||||
return car;
|
return car;
|
||||||
@ -40,7 +39,7 @@ class MockTires extends Tires { make = 'YokoGoodStone'; }
|
|||||||
export function testCar() {
|
export function testCar() {
|
||||||
// #docregion car-ctor-instantiation-with-mocks
|
// #docregion car-ctor-instantiation-with-mocks
|
||||||
// Test car with 8 cylinders and YokoGoodStone tires.
|
// Test car with 8 cylinders and YokoGoodStone tires.
|
||||||
const car = new Car(new MockEngine(), new MockTires());
|
let car = new Car(new MockEngine(), new MockTires());
|
||||||
// #enddocregion car-ctor-instantiation-with-mocks
|
// #enddocregion car-ctor-instantiation-with-mocks
|
||||||
car.description = 'Test';
|
car.description = 'Test';
|
||||||
return car;
|
return car;
|
||||||
|
@ -4,7 +4,7 @@ import { Engine, Tires, Car } from './car';
|
|||||||
// BAD pattern!
|
// BAD pattern!
|
||||||
export class CarFactory {
|
export class CarFactory {
|
||||||
createCar() {
|
createCar() {
|
||||||
const car = new Car(this.createEngine(), this.createTires());
|
let car = new Car(this.createEngine(), this.createTires());
|
||||||
car.description = 'Factory';
|
car.description = 'Factory';
|
||||||
return car;
|
return car;
|
||||||
}
|
}
|
||||||
|
@ -26,14 +26,14 @@ export function useInjector() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
// #docregion injector-call
|
// #docregion injector-call
|
||||||
const car = injector.get(Car);
|
let car = injector.get(Car);
|
||||||
// #enddocregion injector-call, injector-create-and-call
|
// #enddocregion injector-call, injector-create-and-call
|
||||||
car.description = 'Injector';
|
car.description = 'Injector';
|
||||||
|
|
||||||
injector = Injector.create({
|
injector = Injector.create({
|
||||||
providers: [{ provide: Logger, deps: [] }]
|
providers: [{ provide: Logger, deps: [] }]
|
||||||
});
|
});
|
||||||
const logger = injector.get(Logger);
|
let logger = injector.get(Logger);
|
||||||
logger.log('Injector car.drive() said: ' + car.drive());
|
logger.log('Injector car.drive() said: ' + car.drive());
|
||||||
return car;
|
return car;
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,9 @@ import { useInjector } from './car-injector';
|
|||||||
providers: [Car, Engine, Tires]
|
providers: [Car, Engine, Tires]
|
||||||
})
|
})
|
||||||
export class CarComponent {
|
export class CarComponent {
|
||||||
factoryCar = (new CarFactory()).createCar();
|
factoryCar = (new CarFactory).createCar();
|
||||||
injectorCar = useInjector();
|
injectorCar = useInjector();
|
||||||
noDiCar = new CarNoDi();
|
noDiCar = new CarNoDi;
|
||||||
simpleCar = simpleCar();
|
simpleCar = simpleCar();
|
||||||
superCar = superCar();
|
superCar = superCar();
|
||||||
testCar = testCar();
|
testCar = testCar();
|
||||||
|
@ -5,7 +5,7 @@ import { Logger } from '../logger.service';
|
|||||||
import { UserService } from '../user.service';
|
import { UserService } from '../user.service';
|
||||||
|
|
||||||
// #docregion factory
|
// #docregion factory
|
||||||
const heroServiceFactory = (logger: Logger, userService: UserService) => {
|
let heroServiceFactory = (logger: Logger, userService: UserService) => {
|
||||||
return new HeroService(logger, userService.user.isAuthorized);
|
return new HeroService(logger, userService.user.isAuthorized);
|
||||||
};
|
};
|
||||||
// #enddocregion factory
|
// #enddocregion factory
|
||||||
|
@ -17,7 +17,7 @@ export class HeroService {
|
|||||||
private isAuthorized: boolean) { }
|
private isAuthorized: boolean) { }
|
||||||
|
|
||||||
getHeroes() {
|
getHeroes() {
|
||||||
const auth = this.isAuthorized ? 'authorized ' : 'unauthorized';
|
let auth = this.isAuthorized ? 'authorized ' : 'unauthorized';
|
||||||
this.logger.log(`Getting heroes for ${auth} user.`);
|
this.logger.log(`Getting heroes for ${auth} user.`);
|
||||||
return HEROES.filter(hero => this.isAuthorized || !hero.isSecret);
|
return HEROES.filter(hero => this.isAuthorized || !hero.isSecret);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ export class InjectorComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get rodent() {
|
get rodent() {
|
||||||
const rousDontExist = `R.O.U.S.'s? I don't think they exist!`;
|
let rousDontExist = `R.O.U.S.'s? I don't think they exist!`;
|
||||||
return this.injector.get(ROUS, rousDontExist);
|
return this.injector.get(ROUS, rousDontExist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ const template = '{{log}}';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-1',
|
selector: 'provider-1',
|
||||||
template,
|
template: template,
|
||||||
// #docregion providers-1, providers-logger
|
// #docregion providers-1, providers-logger
|
||||||
providers: [Logger]
|
providers: [Logger]
|
||||||
// #enddocregion providers-1, providers-logger
|
// #enddocregion providers-1, providers-logger
|
||||||
@ -35,7 +35,7 @@ export class Provider1Component {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-3',
|
selector: 'provider-3',
|
||||||
template,
|
template: template,
|
||||||
providers:
|
providers:
|
||||||
// #docregion providers-3
|
// #docregion providers-3
|
||||||
[{ provide: Logger, useClass: Logger }]
|
[{ provide: Logger, useClass: Logger }]
|
||||||
@ -54,7 +54,7 @@ export class BetterLogger extends Logger {}
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-4',
|
selector: 'provider-4',
|
||||||
template,
|
template: template,
|
||||||
providers:
|
providers:
|
||||||
// #docregion providers-4
|
// #docregion providers-4
|
||||||
[{ provide: Logger, useClass: BetterLogger }]
|
[{ provide: Logger, useClass: BetterLogger }]
|
||||||
@ -76,7 +76,7 @@ export class EvenBetterLogger extends Logger {
|
|||||||
constructor(private userService: UserService) { super(); }
|
constructor(private userService: UserService) { super(); }
|
||||||
|
|
||||||
log(message: string) {
|
log(message: string) {
|
||||||
const name = this.userService.user.name;
|
let name = this.userService.user.name;
|
||||||
super.log(`Message to ${name}: ${message}`);
|
super.log(`Message to ${name}: ${message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ export class EvenBetterLogger extends Logger {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-5',
|
selector: 'provider-5',
|
||||||
template,
|
template: template,
|
||||||
providers:
|
providers:
|
||||||
// #docregion providers-5
|
// #docregion providers-5
|
||||||
[ UserService,
|
[ UserService,
|
||||||
@ -107,12 +107,12 @@ export class OldLogger {
|
|||||||
logs: string[] = [];
|
logs: string[] = [];
|
||||||
log(message: string) {
|
log(message: string) {
|
||||||
throw new Error('Should not call the old logger!');
|
throw new Error('Should not call the old logger!');
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-6a',
|
selector: 'provider-6a',
|
||||||
template,
|
template: template,
|
||||||
providers:
|
providers:
|
||||||
// #docregion providers-6a
|
// #docregion providers-6a
|
||||||
[ NewLogger,
|
[ NewLogger,
|
||||||
@ -135,7 +135,7 @@ export class Provider6aComponent {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-6b',
|
selector: 'provider-6b',
|
||||||
template,
|
template: template,
|
||||||
providers:
|
providers:
|
||||||
// #docregion providers-6b
|
// #docregion providers-6b
|
||||||
[ NewLogger,
|
[ NewLogger,
|
||||||
@ -168,7 +168,7 @@ export const SilentLogger = {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-7',
|
selector: 'provider-7',
|
||||||
template,
|
template: template,
|
||||||
providers:
|
providers:
|
||||||
// #docregion providers-7
|
// #docregion providers-7
|
||||||
[{ provide: Logger, useValue: SilentLogger }]
|
[{ provide: Logger, useValue: SilentLogger }]
|
||||||
@ -186,7 +186,7 @@ export class Provider7Component {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-8',
|
selector: 'provider-8',
|
||||||
template,
|
template: template,
|
||||||
providers: [heroServiceProvider, Logger, UserService]
|
providers: [heroServiceProvider, Logger, UserService]
|
||||||
})
|
})
|
||||||
export class Provider8Component {
|
export class Provider8Component {
|
||||||
@ -202,7 +202,7 @@ export class Provider8Component {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-9',
|
selector: 'provider-9',
|
||||||
template,
|
template: template,
|
||||||
/*
|
/*
|
||||||
// #docregion providers-9-interface
|
// #docregion providers-9-interface
|
||||||
// FAIL! Can't use interface as provider token
|
// FAIL! Can't use interface as provider token
|
||||||
@ -237,11 +237,11 @@ export class Provider9Component implements OnInit {
|
|||||||
import { Optional } from '@angular/core';
|
import { Optional } from '@angular/core';
|
||||||
// #enddocregion import-optional
|
// #enddocregion import-optional
|
||||||
|
|
||||||
const someMessage = 'Hello from the injected logger';
|
let some_message = 'Hello from the injected logger';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'provider-10',
|
selector: 'provider-10',
|
||||||
template,
|
template: template,
|
||||||
providers: [{ provide: Logger, useValue: null }]
|
providers: [{ provide: Logger, useValue: null }]
|
||||||
})
|
})
|
||||||
export class Provider10Component implements OnInit {
|
export class Provider10Component implements OnInit {
|
||||||
@ -249,7 +249,7 @@ export class Provider10Component implements OnInit {
|
|||||||
// #docregion provider-10-ctor
|
// #docregion provider-10-ctor
|
||||||
constructor(@Optional() private logger?: Logger) {
|
constructor(@Optional() private logger?: Logger) {
|
||||||
if (this.logger) {
|
if (this.logger) {
|
||||||
this.logger.log(someMessage);
|
this.logger.log(some_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion provider-10-ctor
|
// #enddocregion provider-10-ctor
|
||||||
|
@ -43,7 +43,7 @@ var testResults: {pass: string; message: string};
|
|||||||
|
|
||||||
function expect(actual: any) {
|
function expect(actual: any) {
|
||||||
return {
|
return {
|
||||||
toEqual: (expected: any) => {
|
toEqual: function(expected: any){
|
||||||
testResults = actual === expected ?
|
testResults = actual === expected ?
|
||||||
{pass: 'passed', message: testName} :
|
{pass: 'passed', message: testName} :
|
||||||
{pass: 'failed', message: `${testName}; expected ${actual} to equal ${expected}.`};
|
{pass: 'failed', message: `${testName}; expected ${actual} to equal ${expected}.`};
|
||||||
|
@ -8,8 +8,8 @@ export class User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get the user; don't 'new' it.
|
// TODO: get the user; don't 'new' it.
|
||||||
const alice = new User('Alice', true);
|
let alice = new User('Alice', true);
|
||||||
const bob = new User('Bob', false);
|
let bob = new User('Bob', false);
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
@ -1,27 +1,29 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Displaying Data Tests', () => {
|
describe('Displaying Data Tests', function () {
|
||||||
const title = 'Tour of Heroes';
|
let _title = 'Tour of Heroes';
|
||||||
const defaultHero = 'Windstorm';
|
let _defaultHero = 'Windstorm';
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display correct title: ' + title, () => {
|
it('should display correct title: ' + _title, function () {
|
||||||
expect(element(by.css('h1')).getText()).toEqual(title);
|
expect(element(by.css('h1')).getText()).toEqual(_title);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have correct default hero: ' + defaultHero, () => {
|
it('should have correct default hero: ' + _defaultHero, function () {
|
||||||
expect(element(by.css('h2')).getText()).toContain(defaultHero);
|
expect(element(by.css('h2')).getText()).toContain(_defaultHero);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have heroes', () => {
|
it('should have heroes', function () {
|
||||||
const heroEls = element.all(by.css('li'));
|
let heroEls = element.all(by.css('li'));
|
||||||
expect(heroEls.count()).not.toBe(0, 'should have heroes');
|
expect(heroEls.count()).not.toBe(0, 'should have heroes');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display "there are many heroes!"', () => {
|
it('should display "there are many heroes!"', function () {
|
||||||
expect(element(by.css('ul ~ p')).getText()).toContain('There are many heroes!');
|
expect(element(by.css('ul ~ p')).getText()).toContain('There are many heroes!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Docs Style Guide', () => {
|
describe('Docs Style Guide', function () {
|
||||||
const title = 'Authors Style Guide Sample';
|
let _title = 'Authors Style Guide Sample';
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display correct title: ' + title, () => {
|
it('should display correct title: ' + _title, function () {
|
||||||
expect(element(by.css('h1')).getText()).toEqual(title);
|
expect(element(by.css('h1')).getText()).toEqual(_title);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
/* tslint:disable:quotemark */
|
/* tslint:disable:quotemark */
|
||||||
describe('Dynamic Component Loader', () => {
|
describe('Dynamic Component Loader', function () {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should load ad banner', () => {
|
it('should load ad banner', function () {
|
||||||
const headline = element(by.xpath("//h4[text()='Featured Hero Profile']"));
|
let headline = element(by.xpath("//h4[text()='Featured Hero Profile']"));
|
||||||
const name = element(by.xpath("//h3[text()='Bombasto']"));
|
let name = element(by.xpath("//h3[text()='Bombasto']"));
|
||||||
const bio = element(by.xpath("//p[text()='Brave as they come']"));
|
let bio = element(by.xpath("//p[text()='Brave as they come']"));
|
||||||
|
|
||||||
expect(name).toBeDefined();
|
expect(name).toBeDefined();
|
||||||
expect(headline).toBeDefined();
|
expect(headline).toBeDefined();
|
||||||
|
@ -11,7 +11,7 @@ import { AdComponent } from './ad.component';
|
|||||||
template: `
|
template: `
|
||||||
<div class="ad-banner-example">
|
<div class="ad-banner-example">
|
||||||
<h3>Advertisements</h3>
|
<h3>Advertisements</h3>
|
||||||
<ng-template adHost></ng-template>
|
<ng-template ad-host></ng-template>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
// #enddocregion ad-host
|
// #enddocregion ad-host
|
||||||
@ -43,8 +43,8 @@ export class AdBannerComponent implements OnInit, OnDestroy {
|
|||||||
const viewContainerRef = this.adHost.viewContainerRef;
|
const viewContainerRef = this.adHost.viewContainerRef;
|
||||||
viewContainerRef.clear();
|
viewContainerRef.clear();
|
||||||
|
|
||||||
const componentRef = viewContainerRef.createComponent<AdComponent>(componentFactory);
|
const componentRef = viewContainerRef.createComponent(componentFactory);
|
||||||
componentRef.instance.data = adItem.data;
|
(<AdComponent>componentRef.instance).data = adItem.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAds() {
|
getAds() {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
// tslint:disable: directive-selector
|
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Directive, ViewContainerRef } from '@angular/core';
|
import { Directive, ViewContainerRef } from '@angular/core';
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[adHost]',
|
selector: '[ad-host]',
|
||||||
})
|
})
|
||||||
export class AdDirective {
|
export class AdDirective {
|
||||||
constructor(public viewContainerRef: ViewContainerRef) { }
|
constructor(public viewContainerRef: ViewContainerRef) { }
|
||||||
|
@ -1,25 +1,27 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
/* tslint:disable:quotemark */
|
/* tslint:disable:quotemark */
|
||||||
describe('Dynamic Form', () => {
|
describe('Dynamic Form', function () {
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should submit form', () => {
|
it('should submit form', function () {
|
||||||
const firstNameElement = element.all(by.css('input[id=firstName]')).get(0);
|
let firstNameElement = element.all(by.css('input[id=firstName]')).get(0);
|
||||||
expect(firstNameElement.getAttribute('value')).toEqual('Bombasto');
|
expect(firstNameElement.getAttribute('value')).toEqual('Bombasto');
|
||||||
|
|
||||||
const emailElement = element.all(by.css('input[id=emailAddress]')).get(0);
|
let emailElement = element.all(by.css('input[id=emailAddress]')).get(0);
|
||||||
const email = 'test@test.com';
|
let email = 'test@test.com';
|
||||||
emailElement.sendKeys(email);
|
emailElement.sendKeys(email);
|
||||||
expect(emailElement.getAttribute('value')).toEqual(email);
|
expect(emailElement.getAttribute('value')).toEqual(email);
|
||||||
|
|
||||||
element(by.css('select option[value="solid"]')).click();
|
element(by.css('select option[value="solid"]')).click();
|
||||||
|
|
||||||
const saveButton = element.all(by.css('button')).get(0);
|
let saveButton = element.all(by.css('button')).get(0);
|
||||||
saveButton.click().then(() => {
|
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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -10,14 +10,13 @@ export class QuestionBase<T> {
|
|||||||
options: {key: string, value: string}[];
|
options: {key: string, value: string}[];
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
value?: T;
|
value?: T,
|
||||||
key?: string;
|
key?: string,
|
||||||
label?: string;
|
label?: string,
|
||||||
required?: boolean;
|
required?: boolean,
|
||||||
order?: number;
|
order?: number,
|
||||||
controlType?: string;
|
controlType?: string,
|
||||||
type?: string;
|
type?: string
|
||||||
options?: {key: string, value: string}[];
|
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.value = options.value;
|
this.value = options.value;
|
||||||
this.key = options.key || '';
|
this.key = options.key || '';
|
||||||
@ -26,6 +25,5 @@ export class QuestionBase<T> {
|
|||||||
this.order = options.order === undefined ? 1 : options.order;
|
this.order = options.order === undefined ? 1 : options.order;
|
||||||
this.controlType = options.controlType || '';
|
this.controlType = options.controlType || '';
|
||||||
this.type = options.type || '';
|
this.type = options.type || '';
|
||||||
this.options = options.options || [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ export class QuestionControlService {
|
|||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
toFormGroup(questions: QuestionBase<string>[] ) {
|
toFormGroup(questions: QuestionBase<string>[] ) {
|
||||||
const group: any = {};
|
let group: any = {};
|
||||||
|
|
||||||
questions.forEach(question => {
|
questions.forEach(question => {
|
||||||
group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
|
group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
|
||||||
|
@ -3,4 +3,10 @@ import { QuestionBase } from './question-base';
|
|||||||
|
|
||||||
export class DropdownQuestion extends QuestionBase<string> {
|
export class DropdownQuestion extends QuestionBase<string> {
|
||||||
controlType = 'dropdown';
|
controlType = 'dropdown';
|
||||||
|
options: {key: string, value: string}[] = [];
|
||||||
|
|
||||||
|
constructor(options: {} = {}) {
|
||||||
|
super(options);
|
||||||
|
this.options = options['options'] || [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,4 +3,10 @@ import { QuestionBase } from './question-base';
|
|||||||
|
|
||||||
export class TextboxQuestion extends QuestionBase<string> {
|
export class TextboxQuestion extends QuestionBase<string> {
|
||||||
controlType = 'textbox';
|
controlType = 'textbox';
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
constructor(options: {} = {}) {
|
||||||
|
super(options);
|
||||||
|
this.type = options['type'] || '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ export class QuestionService {
|
|||||||
// TODO: get from a remote source of question metadata
|
// TODO: get from a remote source of question metadata
|
||||||
getQuestions() {
|
getQuestions() {
|
||||||
|
|
||||||
const questions: QuestionBase<string>[] = [
|
let questions: QuestionBase<string>[] = [
|
||||||
|
|
||||||
new DropdownQuestion({
|
new DropdownQuestion({
|
||||||
key: 'brave',
|
key: 'brave',
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, by, element, ElementFinder, ExpectedConditions as EC } from 'protractor';
|
import { browser, by, element, ElementFinder, ExpectedConditions as EC } from 'protractor';
|
||||||
|
|
||||||
/* tslint:disable:quotemark */
|
/* tslint:disable:quotemark */
|
||||||
@ -14,7 +16,7 @@ describe('Elements', () => {
|
|||||||
const waitForText = (elem: ElementFinder) => {
|
const waitForText = (elem: ElementFinder) => {
|
||||||
// Waiting for the element to have some text, makes the tests less flaky.
|
// Waiting for the element to have some text, makes the tests less flaky.
|
||||||
browser.wait(async () => /\S/.test(await elem.getText()), 5000);
|
browser.wait(async () => /\S/.test(await elem.getText()), 5000);
|
||||||
};
|
}
|
||||||
|
|
||||||
beforeEach(() => browser.get(''));
|
beforeEach(() => browser.get(''));
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
// tslint:disable: variable-name
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
// #docregion
|
|
||||||
import { Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';
|
|
||||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -9,6 +7,9 @@ import { animate, state, style, transition, trigger } from '@angular/animations'
|
|||||||
<span>Popup: {{message}}</span>
|
<span>Popup: {{message}}</span>
|
||||||
<button (click)="closed.next()">✖</button>
|
<button (click)="closed.next()">✖</button>
|
||||||
`,
|
`,
|
||||||
|
host: {
|
||||||
|
'[@state]': 'state',
|
||||||
|
},
|
||||||
animations: [
|
animations: [
|
||||||
trigger('state', [
|
trigger('state', [
|
||||||
state('opened', style({transform: 'translateY(0%)'})),
|
state('opened', style({transform: 'translateY(0%)'})),
|
||||||
@ -38,16 +39,15 @@ import { animate, state, style, transition, trigger } from '@angular/animations'
|
|||||||
`]
|
`]
|
||||||
})
|
})
|
||||||
export class PopupComponent {
|
export class PopupComponent {
|
||||||
@HostBinding('@state')
|
|
||||||
state: 'opened' | 'closed' = 'closed';
|
state: 'opened' | 'closed' = 'closed';
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
get message(): string { return this._message; }
|
|
||||||
set message(message: string) {
|
set message(message: string) {
|
||||||
this._message = message;
|
this._message = message;
|
||||||
this.state = 'opened';
|
this.state = 'opened';
|
||||||
}
|
}
|
||||||
private _message: string;
|
get message(): string { return this._message; }
|
||||||
|
_message: string;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
closed = new EventEmitter();
|
closed = new EventEmitter();
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
import { browser, element, by } from 'protractor';
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
describe('Event binding example', () => {
|
import { browser, element, by, protractor } from 'protractor';
|
||||||
|
|
||||||
beforeEach(() => {
|
describe('Event binding example', function () {
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
const saveButton = element.all(by.css('button')).get(0);
|
let saveButton = element.all(by.css('button')).get(0);
|
||||||
const onSaveButton = element.all(by.css('button')).get(1);
|
let onSaveButton = element.all(by.css('button')).get(1);
|
||||||
const myClick = element.all(by.css('button')).get(2);
|
let myClick = element.all(by.css('button')).get(2);
|
||||||
const deleteButton = element.all(by.css('button')).get(3);
|
let deleteButton = element.all(by.css('button')).get(3);
|
||||||
const saveNoProp = element.all(by.css('button')).get(4);
|
let saveNoProp = element.all(by.css('button')).get(4);
|
||||||
const saveProp = element.all(by.css('button')).get(5);
|
let saveProp = element.all(by.css('button')).get(5);
|
||||||
|
|
||||||
|
|
||||||
it('should display Event Binding with Angular', () => {
|
it('should display Event Binding with Angular', function () {
|
||||||
expect(element(by.css('h1')).getText()).toEqual('Event Binding');
|
expect(element(by.css('h1')).getText()).toEqual('Event Binding');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display 6 buttons', () => {
|
it('should display 6 buttons', function() {
|
||||||
expect(saveButton.getText()).toBe('Save');
|
expect(saveButton.getText()).toBe('Save');
|
||||||
expect(onSaveButton.getText()).toBe('on-click Save');
|
expect(onSaveButton.getText()).toBe('on-click Save');
|
||||||
expect(myClick.getText()).toBe('click with myClick');
|
expect(myClick.getText()).toBe('click with myClick');
|
||||||
@ -27,23 +29,24 @@ describe('Event binding example', () => {
|
|||||||
expect(saveProp.getText()).toBe('Save with propagation');
|
expect(saveProp.getText()).toBe('Save with propagation');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support user input', () => {
|
it('should support user input', function () {
|
||||||
const input = element(by.css('input'));
|
let input = element(by.css('input'));
|
||||||
const bindingResult = element.all(by.css('h4')).get(1);
|
let bindingResult = element.all(by.css('h4')).get(1);
|
||||||
expect(bindingResult.getText()).toEqual('Result: teapot');
|
expect(bindingResult.getText()).toEqual('Result: teapot');
|
||||||
input.sendKeys('abc');
|
input.sendKeys('abc');
|
||||||
expect(bindingResult.getText()).toEqual('Result: teapotabc');
|
expect(bindingResult.getText()).toEqual('Result: teapotabc');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide the item img', async () => {
|
it('should hide the item img', async () => {
|
||||||
|
let deleteButton = element.all(by.css('button')).get(3);
|
||||||
await deleteButton.click();
|
await deleteButton.click();
|
||||||
browser.switchTo().alert().accept();
|
browser.switchTo().alert().accept();
|
||||||
expect(element.all(by.css('img')).get(0).getCssValue('display')).toEqual('none');
|
expect(element.all(by.css('img')).get(0).getCssValue('display')).toEqual('none');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show two alerts', async () => {
|
it('should show two alerts', async () => {
|
||||||
const parentDiv = element.all(by.css('.parent-div'));
|
let parentDiv = element.all(by.css('.parent-div'));
|
||||||
const childDiv = element.all(by.css('div > div')).get(1);
|
let childDiv = element.all(by.css('div > div')).get(1);
|
||||||
await parentDiv.click();
|
await parentDiv.click();
|
||||||
browser.switchTo().alert().accept();
|
browser.switchTo().alert().accept();
|
||||||
expect(childDiv.getText()).toEqual('Click me too! (child)');
|
expect(childDiv.getText()).toEqual('Click me too! (child)');
|
||||||
|
@ -12,7 +12,7 @@ export class AppComponent {
|
|||||||
clickMessage = '';
|
clickMessage = '';
|
||||||
|
|
||||||
onSave(event?: KeyboardEvent) {
|
onSave(event?: KeyboardEvent) {
|
||||||
const evtMsg = event ? ' Event target is ' + (event.target as HTMLElement).textContent : '';
|
const evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).textContent : '';
|
||||||
alert('Saved.' + evtMsg);
|
alert('Saved.' + evtMsg);
|
||||||
if (event) { event.stopPropagation(); }
|
if (event) { event.stopPropagation(); }
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ export class AppComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onClickMe(event?: KeyboardEvent) {
|
onClickMe(event?: KeyboardEvent) {
|
||||||
const evtMsg = event ? ' Event target class is ' + (event.target as HTMLElement).className : '';
|
const evtMsg = event ? ' Event target class is ' + (<HTMLElement>event.target).className : '';
|
||||||
alert('Click me.' + evtMsg);
|
alert('Click me.' + evtMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// tslint:disable: directive-selector
|
/* tslint:disable use-output-property-decorator directive-class-suffix */
|
||||||
import { Directive, ElementRef, EventEmitter, Output } from '@angular/core';
|
import { Directive, ElementRef, EventEmitter, Output } from '@angular/core';
|
||||||
|
|
||||||
@Directive({selector: '[myClick]'})
|
@Directive({selector: '[myClick]'})
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
'use strict'; // necessary for node!
|
||||||
|
|
||||||
import { browser, element, by, protractor, ElementFinder, ElementArrayFinder } from 'protractor';
|
import { browser, element, by, protractor, ElementFinder, ElementArrayFinder } from 'protractor';
|
||||||
|
|
||||||
// THESE TESTS ARE INCOMPLETE
|
// THESE TESTS ARE INCOMPLETE
|
||||||
describe('Form Validation Tests', () => {
|
describe('Form Validation Tests', function () {
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -50,11 +52,11 @@ let page: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function getPage(sectionTag: string) {
|
function getPage(sectionTag: string) {
|
||||||
const section = element(by.css(sectionTag));
|
let section = element(by.css(sectionTag));
|
||||||
const buttons = section.all(by.css('button'));
|
let buttons = section.all(by.css('button'));
|
||||||
|
|
||||||
page = {
|
page = {
|
||||||
section,
|
section: section,
|
||||||
form: section.element(by.css('form')),
|
form: section.element(by.css('form')),
|
||||||
title: section.element(by.css('h1')),
|
title: section.element(by.css('h1')),
|
||||||
nameInput: section.element(by.css('#name')),
|
nameInput: section.element(by.css('#name')),
|
||||||
@ -71,31 +73,31 @@ function getPage(sectionTag: string) {
|
|||||||
|
|
||||||
function tests(title: string) {
|
function tests(title: string) {
|
||||||
|
|
||||||
it('should display correct title', () => {
|
it('should display correct title', function () {
|
||||||
expect(page.title.getText()).toContain(title);
|
expect(page.title.getText()).toContain(title);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not display submitted message before submit', () => {
|
it('should not display submitted message before submit', function () {
|
||||||
expect(page.heroSubmitted.isElementPresent(by.css('p'))).toBe(false);
|
expect(page.heroSubmitted.isElementPresent(by.css('p'))).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have form buttons', () => {
|
it('should have form buttons', function () {
|
||||||
expect(page.heroFormButtons.count()).toEqual(2);
|
expect(page.heroFormButtons.count()).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have error at start', () => {
|
it('should have error at start', function () {
|
||||||
expectFormIsInvalid();
|
expectFormIsInvalid();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('showForm', () => {
|
// it('showForm', function () {
|
||||||
// page.form.getInnerHtml().then(html => console.log(html));
|
// page.form.getInnerHtml().then(html => console.log(html));
|
||||||
// });
|
// });
|
||||||
|
|
||||||
it('should have disabled submit button', () => {
|
it('should have disabled submit button', function () {
|
||||||
expect(page.heroFormButtons.get(0).isEnabled()).toBe(false);
|
expect(page.heroFormButtons.get(0).isEnabled()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resetting name to valid name should clear errors', () => {
|
it('resetting name to valid name should clear errors', function () {
|
||||||
const ele = page.nameInput;
|
const ele = page.nameInput;
|
||||||
expect(ele.isPresent()).toBe(true, 'nameInput should exist');
|
expect(ele.isPresent()).toBe(true, 'nameInput should exist');
|
||||||
ele.clear();
|
ele.clear();
|
||||||
@ -103,7 +105,7 @@ function tests(title: string) {
|
|||||||
expectFormIsValid();
|
expectFormIsValid();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should produce "required" error after clearing name', () => {
|
it('should produce "required" error after clearing name', function () {
|
||||||
page.nameInput.clear();
|
page.nameInput.clear();
|
||||||
// page.alterEgoInput.click(); // to blur ... didn't work
|
// page.alterEgoInput.click(); // to blur ... didn't work
|
||||||
page.nameInput.sendKeys('x', protractor.Key.BACK_SPACE); // ugh!
|
page.nameInput.sendKeys('x', protractor.Key.BACK_SPACE); // ugh!
|
||||||
@ -111,37 +113,37 @@ function tests(title: string) {
|
|||||||
expect(page.errorMessages.get(0).getText()).toContain('required');
|
expect(page.errorMessages.get(0).getText()).toContain('required');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should produce "at least 4 characters" error when name="x"', () => {
|
it('should produce "at least 4 characters" error when name="x"', function () {
|
||||||
page.nameInput.clear();
|
page.nameInput.clear();
|
||||||
page.nameInput.sendKeys('x'); // too short
|
page.nameInput.sendKeys('x'); // too short
|
||||||
expectFormIsInvalid();
|
expectFormIsInvalid();
|
||||||
expect(page.errorMessages.get(0).getText()).toContain('at least 4 characters');
|
expect(page.errorMessages.get(0).getText()).toContain('at least 4 characters');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resetting name to valid name again should clear errors', () => {
|
it('resetting name to valid name again should clear errors', function () {
|
||||||
page.nameInput.sendKeys(testName);
|
page.nameInput.sendKeys(testName);
|
||||||
expectFormIsValid();
|
expectFormIsValid();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have enabled submit button', () => {
|
it('should have enabled submit button', function () {
|
||||||
const submitBtn = page.heroFormButtons.get(0);
|
const submitBtn = page.heroFormButtons.get(0);
|
||||||
expect(submitBtn.isEnabled()).toBe(true);
|
expect(submitBtn.isEnabled()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide form after submit', () => {
|
it('should hide form after submit', function () {
|
||||||
page.heroFormButtons.get(0).click();
|
page.heroFormButtons.get(0).click();
|
||||||
expect(page.heroFormButtons.get(0).isDisplayed()).toBe(false);
|
expect(page.heroFormButtons.get(0).isDisplayed()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('submitted form should be displayed', () => {
|
it('submitted form should be displayed', function () {
|
||||||
expect(page.heroSubmitted.isElementPresent(by.css('p'))).toBe(true);
|
expect(page.heroSubmitted.isElementPresent(by.css('p'))).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('submitted form should have new hero name', () => {
|
it('submitted form should have new hero name', function () {
|
||||||
expect(page.heroSubmitted.getText()).toContain(testName);
|
expect(page.heroSubmitted.getText()).toContain(testName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clicking edit button should reveal form again', () => {
|
it('clicking edit button should reveal form again', function () {
|
||||||
const newFormBtn = page.heroSubmitted.element(by.css('button'));
|
const newFormBtn = page.heroSubmitted.element(by.css('button'));
|
||||||
newFormBtn.click();
|
newFormBtn.click();
|
||||||
expect(page.heroSubmitted.isElementPresent(by.css('p')))
|
expect(page.heroSubmitted.isElementPresent(by.css('p')))
|
||||||
@ -160,7 +162,7 @@ function expectFormIsInvalid() {
|
|||||||
|
|
||||||
function triggerAlterEgoValidation() {
|
function triggerAlterEgoValidation() {
|
||||||
// alterEgo has updateOn set to 'blur', click outside of the input to trigger the blur event
|
// alterEgo has updateOn set to 'blur', click outside of the input to trigger the blur event
|
||||||
element(by.css('app-root')).click();
|
element(by.css('app-root')).click()
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForAlterEgoValidation() {
|
function waitForAlterEgoValidation() {
|
||||||
@ -171,7 +173,7 @@ function waitForAlterEgoValidation() {
|
|||||||
function bobTests() {
|
function bobTests() {
|
||||||
const emsg = 'Name cannot be Bob.';
|
const emsg = 'Name cannot be Bob.';
|
||||||
|
|
||||||
it('should produce "no bob" error after setting name to "Bobby"', () => {
|
it('should produce "no bob" error after setting name to "Bobby"', function () {
|
||||||
// Re-populate select element
|
// Re-populate select element
|
||||||
page.powerSelect.click();
|
page.powerSelect.click();
|
||||||
page.powerOption.click();
|
page.powerOption.click();
|
||||||
@ -182,7 +184,7 @@ function bobTests() {
|
|||||||
expect(page.errorMessages.get(0).getText()).toBe(emsg);
|
expect(page.errorMessages.get(0).getText()).toBe(emsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be ok again with valid name', () => {
|
it('should be ok again with valid name', function () {
|
||||||
page.nameInput.clear();
|
page.nameInput.clear();
|
||||||
page.nameInput.sendKeys(testName);
|
page.nameInput.sendKeys(testName);
|
||||||
expectFormIsValid();
|
expectFormIsValid();
|
||||||
@ -192,7 +194,7 @@ function bobTests() {
|
|||||||
function asyncValidationTests() {
|
function asyncValidationTests() {
|
||||||
const emsg = 'Alter ego is already taken.';
|
const emsg = 'Alter ego is already taken.';
|
||||||
|
|
||||||
it(`should produce "${emsg}" error after setting alterEgo to Eric`, () => {
|
it(`should produce "${emsg}" error after setting alterEgo to Eric`, function () {
|
||||||
page.alterEgoInput.clear();
|
page.alterEgoInput.clear();
|
||||||
page.alterEgoInput.sendKeys('Eric');
|
page.alterEgoInput.sendKeys('Eric');
|
||||||
|
|
||||||
@ -203,7 +205,7 @@ function asyncValidationTests() {
|
|||||||
expect(page.alterEgoErrors.getText()).toBe(emsg);
|
expect(page.alterEgoErrors.getText()).toBe(emsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be ok again with different values', () => {
|
it('should be ok again with different values', function () {
|
||||||
page.alterEgoInput.clear();
|
page.alterEgoInput.clear();
|
||||||
page.alterEgoInput.sendKeys('John');
|
page.alterEgoInput.sendKeys('John');
|
||||||
|
|
||||||
@ -218,7 +220,7 @@ function asyncValidationTests() {
|
|||||||
function crossValidationTests() {
|
function crossValidationTests() {
|
||||||
const emsg = 'Name cannot match alter ego.';
|
const emsg = 'Name cannot match alter ego.';
|
||||||
|
|
||||||
it(`should produce "${emsg}" error after setting name and alter ego to the same value`, () => {
|
it(`should produce "${emsg}" error after setting name and alter ego to the same value`, function () {
|
||||||
page.nameInput.clear();
|
page.nameInput.clear();
|
||||||
page.nameInput.sendKeys('Batman');
|
page.nameInput.sendKeys('Batman');
|
||||||
|
|
||||||
@ -232,7 +234,7 @@ function crossValidationTests() {
|
|||||||
expect(page.crossValidationErrorMessage.getText()).toBe(emsg);
|
expect(page.crossValidationErrorMessage.getText()).toBe(emsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be ok again with different values', () => {
|
it('should be ok again with different values', function () {
|
||||||
page.nameInput.clear();
|
page.nameInput.clear();
|
||||||
page.nameInput.sendKeys('Batman');
|
page.nameInput.sendKeys('Batman');
|
||||||
|
|
||||||
|
@ -22,13 +22,13 @@ export class HeroFormReactiveComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// #docregion custom-validator
|
// #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) // <-- Here's how you pass in the custom validator.
|
||||||
]),
|
]),
|
||||||
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)
|
||||||
});
|
});
|
||||||
// #enddocregion custom-validator
|
// #enddocregion custom-validator
|
||||||
|
|
||||||
|
@ -22,16 +22,16 @@ export class HeroFormReactiveComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// #docregion async-validation
|
// #docregion async-validation
|
||||||
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)
|
forbiddenNameValidator(/bob/i)
|
||||||
]),
|
]),
|
||||||
alterEgo: new FormControl(this.hero.alterEgo, {
|
'alterEgo': new FormControl(this.hero.alterEgo, {
|
||||||
asyncValidators: [this.alterEgoValidator.validate.bind(this.alterEgoValidator)],
|
asyncValidators: [this.alterEgoValidator.validate.bind(this.alterEgoValidator)],
|
||||||
updateOn: 'blur'
|
updateOn: 'blur'
|
||||||
}),
|
}),
|
||||||
power: new FormControl(this.hero.power, Validators.required)
|
'power': new FormControl(this.hero.power, Validators.required)
|
||||||
});
|
});
|
||||||
// #enddocregion async-validation
|
// #enddocregion async-validation
|
||||||
}
|
}
|
||||||
|
@ -21,16 +21,16 @@ export class HeroFormReactiveComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
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)
|
forbiddenNameValidator(/bob/i)
|
||||||
]),
|
]),
|
||||||
alterEgo: new FormControl(this.hero.alterEgo, {
|
'alterEgo': new FormControl(this.hero.alterEgo, {
|
||||||
asyncValidators: [this.alterEgoValidator.validate.bind(this.alterEgoValidator)],
|
asyncValidators: [this.alterEgoValidator.validate.bind(this.alterEgoValidator)],
|
||||||
updateOn: 'blur'
|
updateOn: 'blur'
|
||||||
}),
|
}),
|
||||||
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
|
}, { validators: identityRevealedValidator }); // <-- add custom validator at the FormGroup level
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { AbstractControl, NG_VALIDATORS, Validator, ValidatorFn, Validators } fr
|
|||||||
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
||||||
return (control: AbstractControl): {[key: string]: any} | null => {
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// #enddocregion custom-validator
|
// #enddocregion custom-validator
|
||||||
|
@ -8,7 +8,7 @@ export const identityRevealedValidator: ValidatorFn = (control: FormGroup): Vali
|
|||||||
const name = control.get('name');
|
const name = control.get('name');
|
||||||
const alterEgo = control.get('alterEgo');
|
const alterEgo = control.get('alterEgo');
|
||||||
|
|
||||||
return name && alterEgo && name.value === alterEgo.value ? { identityRevealed: true } : null;
|
return name && alterEgo && name.value === alterEgo.value ? { 'identityRevealed': true } : null;
|
||||||
};
|
};
|
||||||
// #enddocregion cross-validation-validator
|
// #enddocregion cross-validation-validator
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ export const identityRevealedValidator: ValidatorFn = (control: FormGroup): Vali
|
|||||||
})
|
})
|
||||||
export class IdentityRevealedValidatorDirective implements Validator {
|
export class IdentityRevealedValidatorDirective implements Validator {
|
||||||
validate(control: AbstractControl): ValidationErrors {
|
validate(control: AbstractControl): ValidationErrors {
|
||||||
return identityRevealedValidator(control);
|
return identityRevealedValidator(control)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion cross-validation-directive
|
// #enddocregion cross-validation-directive
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Forms Overview Tests', () => {
|
describe('Forms Overview Tests', function () {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export function createNewEvent(eventName: string, bubbles = false, cancelable = false) {
|
export function createNewEvent(eventName: string, bubbles = false, cancelable = false) {
|
||||||
const evt = document.createEvent('CustomEvent');
|
let evt = document.createEvent('CustomEvent');
|
||||||
evt.initCustomEvent(eventName, bubbles, cancelable, null);
|
evt.initCustomEvent(eventName, bubbles, cancelable, null);
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
@ -1,60 +1,60 @@
|
|||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Forms Tests', () => {
|
describe('Forms Tests', function () {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display correct title', () => {
|
it('should display correct title', function () {
|
||||||
expect(element.all(by.css('h1')).get(0).getText()).toEqual('Hero Form');
|
expect(element.all(by.css('h1')).get(0).getText()).toEqual('Hero Form');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should not display message before submit', () => {
|
it('should not display message before submit', function () {
|
||||||
const ele = element(by.css('h2'));
|
let ele = element(by.css('h2'));
|
||||||
expect(ele.isDisplayed()).toBe(false);
|
expect(ele.isDisplayed()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide form after submit', () => {
|
it('should hide form after submit', function () {
|
||||||
const ele = element.all(by.css('h1')).get(0);
|
let ele = element.all(by.css('h1')).get(0);
|
||||||
expect(ele.isDisplayed()).toBe(true);
|
expect(ele.isDisplayed()).toBe(true);
|
||||||
const b = element.all(by.css('button[type=submit]')).get(0);
|
let b = element.all(by.css('button[type=submit]')).get(0);
|
||||||
b.click().then(() => {
|
b.click().then(function() {
|
||||||
expect(ele.isDisplayed()).toBe(false);
|
expect(ele.isDisplayed()).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display message after submit', () => {
|
it('should display message after submit', function () {
|
||||||
const b = element.all(by.css('button[type=submit]')).get(0);
|
let b = element.all(by.css('button[type=submit]')).get(0);
|
||||||
b.click().then(() => {
|
b.click().then(function() {
|
||||||
expect(element(by.css('h2')).getText()).toContain('You submitted the following');
|
expect(element(by.css('h2')).getText()).toContain('You submitted the following');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide form after submit', () => {
|
it('should hide form after submit', function () {
|
||||||
const alterEgoEle = element.all(by.css('input[name=alterEgo]')).get(0);
|
let alterEgoEle = element.all(by.css('input[name=alterEgo]')).get(0);
|
||||||
expect(alterEgoEle.isDisplayed()).toBe(true);
|
expect(alterEgoEle.isDisplayed()).toBe(true);
|
||||||
const submitButtonEle = element.all(by.css('button[type=submit]')).get(0);
|
let submitButtonEle = element.all(by.css('button[type=submit]')).get(0);
|
||||||
submitButtonEle.click().then(() => {
|
submitButtonEle.click().then(function() {
|
||||||
expect(alterEgoEle.isDisplayed()).toBe(false);
|
expect(alterEgoEle.isDisplayed()).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reflect submitted data after submit', () => {
|
it('should reflect submitted data after submit', function () {
|
||||||
const test = 'testing 1 2 3';
|
let test = 'testing 1 2 3';
|
||||||
let newValue: string;
|
let newValue: string;
|
||||||
const alterEgoEle = element.all(by.css('input[name=alterEgo]')).get(0);
|
let alterEgoEle = element.all(by.css('input[name=alterEgo]')).get(0);
|
||||||
alterEgoEle.getAttribute('value').then((value: string) => {
|
alterEgoEle.getAttribute('value').then(function(value: string) {
|
||||||
alterEgoEle.sendKeys(test);
|
alterEgoEle.sendKeys(test);
|
||||||
newValue = value + test;
|
newValue = value + test;
|
||||||
expect(alterEgoEle.getAttribute('value')).toEqual(newValue);
|
expect(alterEgoEle.getAttribute('value')).toEqual(newValue);
|
||||||
const b = element.all(by.css('button[type=submit]')).get(0);
|
let b = element.all(by.css('button[type=submit]')).get(0);
|
||||||
return b.click();
|
return b.click();
|
||||||
}).then(() => {
|
}).then(function() {
|
||||||
const alterEgoTextEle = element(by.cssContainingText('div', 'Alter Ego'));
|
let alterEgoTextEle = element(by.cssContainingText('div', 'Alter Ego'));
|
||||||
expect(alterEgoTextEle.isPresent()).toBe(true, 'cannot locate "Alter Ego" label');
|
expect(alterEgoTextEle.isPresent()).toBe(true, 'cannot locate "Alter Ego" label');
|
||||||
const divEle = element(by.cssContainingText('div', newValue));
|
let divEle = element(by.cssContainingText('div', newValue));
|
||||||
expect(divEle.isPresent()).toBe(true, 'cannot locate div with this text: ' + newValue);
|
expect(divEle.isPresent()).toBe(true, 'cannot locate div with this text: ' + newValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -35,7 +35,7 @@ export class HeroFormComponent {
|
|||||||
|
|
||||||
skyDog(): Hero {
|
skyDog(): Hero {
|
||||||
// #docregion SkyDog
|
// #docregion SkyDog
|
||||||
const myHero = new Hero(42, 'SkyDog',
|
let myHero = new Hero(42, 'SkyDog',
|
||||||
'Fetch any object at any distance',
|
'Fetch any object at any distance',
|
||||||
'Leslie Rollover');
|
'Leslie Rollover');
|
||||||
console.log('My hero is called ' + myHero.name); // "My hero is called SkyDog"
|
console.log('My hero is called ' + myHero.name); // "My hero is called SkyDog"
|
||||||
@ -48,9 +48,9 @@ export class HeroFormComponent {
|
|||||||
// Reveal in html:
|
// Reveal in html:
|
||||||
// Name via form.controls = {{showFormControls(heroForm)}}
|
// Name via form.controls = {{showFormControls(heroForm)}}
|
||||||
showFormControls(form: any) {
|
showFormControls(form: any) {
|
||||||
return form && form.controls.name &&
|
return form && form.controls['name'] &&
|
||||||
// #docregion form-controls
|
// #docregion form-controls
|
||||||
form.controls.name.value; // Dr. IQ
|
form.controls['name'].value; // Dr. IQ
|
||||||
// #enddocregion form-controls
|
// #enddocregion form-controls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
describe('Getting Started V0', () => {
|
describe('Getting Started V0', () => {
|
||||||
beforeEach(() => browser.get('/'));
|
beforeEach(() => {
|
||||||
|
return browser.get('/');
|
||||||
|
});
|
||||||
|
|
||||||
it('should display "My Store" in the top bar', async() => {
|
it('should display "My Store" in the top bar', async() => {
|
||||||
const title = await element(by.css('app-root app-top-bar h1')).getText();
|
const title = await element(by.css('app-root app-top-bar h1')).getText();
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, element, by, ExpectedConditions as EC, logging, ElementFinder, ElementArrayFinder } from 'protractor';
|
import { browser, element, by, ExpectedConditions as EC, logging, ElementFinder, ElementArrayFinder } from 'protractor';
|
||||||
|
|
||||||
describe('Getting Started', () => {
|
describe('Getting Started', () => {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
import { browser, by, element } from 'protractor';
|
import { browser, by, element } from 'protractor';
|
||||||
|
|
||||||
describe('Hierarchical dependency injection', () => {
|
describe('Hierarchical dependency injection', () => {
|
||||||
@ -7,7 +9,7 @@ describe('Hierarchical dependency injection', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Heroes Scenario', () => {
|
describe('Heroes Scenario', () => {
|
||||||
const page = {
|
let page = {
|
||||||
heroName: '',
|
heroName: '',
|
||||||
income: '',
|
income: '',
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// tslint:disable: no-output-native
|
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { HeroTaxReturn } from './hero';
|
import { HeroTaxReturn } from './hero';
|
||||||
@ -31,9 +30,9 @@ export class HeroTaxReturnComponent {
|
|||||||
onCanceled() {
|
onCanceled() {
|
||||||
this.flashMessage('Canceled');
|
this.flashMessage('Canceled');
|
||||||
this.heroTaxReturnService.restoreTaxReturn();
|
this.heroTaxReturnService.restoreTaxReturn();
|
||||||
}
|
};
|
||||||
|
|
||||||
onClose() { this.close.emit(); }
|
onClose() { this.close.emit(); };
|
||||||
|
|
||||||
onSaved() {
|
onSaved() {
|
||||||
this.flashMessage('Saved');
|
this.flashMessage('Saved');
|
||||||
|
@ -24,11 +24,11 @@ const page = {
|
|||||||
uploadMessage: element(by.css('app-uploader p'))
|
uploadMessage: element(by.css('app-uploader p'))
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkLogForMessage = (message: string) => {
|
let checkLogForMessage = (message: string) => {
|
||||||
expect(page.logList.getText()).toContain(message);
|
expect(page.logList.getText()).toContain(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Http Tests', () => {
|
describe('Http Tests', function() {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
@ -40,8 +40,8 @@ export class ConfigComponent {
|
|||||||
this.configService.getConfig_1()
|
this.configService.getConfig_1()
|
||||||
// #docregion v1, v1_callback
|
// #docregion v1, v1_callback
|
||||||
.subscribe((data: Config) => this.config = {
|
.subscribe((data: Config) => this.config = {
|
||||||
heroesUrl: data.heroesUrl,
|
heroesUrl: data['heroesUrl'],
|
||||||
textfile: data.textfile
|
textfile: data['textfile']
|
||||||
});
|
});
|
||||||
// #enddocregion v1_callback
|
// #enddocregion v1_callback
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import { HttpErrorHandler, HandleError } from '../http-error-handler.service';
|
|||||||
const httpOptions = {
|
const httpOptions = {
|
||||||
headers: new HttpHeaders({
|
headers: new HttpHeaders({
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Authorization: 'my-auth-token'
|
'Authorization': 'my-auth-token'
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
// #enddocregion http-options
|
// #enddocregion http-options
|
||||||
|
@ -15,10 +15,8 @@ export class HttpErrorHandler {
|
|||||||
constructor(private messageService: MessageService) { }
|
constructor(private messageService: MessageService) { }
|
||||||
|
|
||||||
/** Create curried handleError function that already knows the service name */
|
/** Create curried handleError function that already knows the service name */
|
||||||
createHandleError = (serviceName = '') => {
|
createHandleError = (serviceName = '') => <T>
|
||||||
return <T>(operation = 'operation', result = {} as T) =>
|
(operation = 'operation', result = {} as T) => this.handleError(serviceName, operation, result);
|
||||||
this.handleError(serviceName, operation, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a function that handles Http operation failures.
|
* Returns a function that handles Http operation failures.
|
||||||
|
@ -12,7 +12,7 @@ export interface RequestCacheEntry {
|
|||||||
// #docregion request-cache
|
// #docregion request-cache
|
||||||
export abstract class RequestCache {
|
export abstract class RequestCache {
|
||||||
abstract get(req: HttpRequest<any>): HttpResponse<any> | undefined;
|
abstract get(req: HttpRequest<any>): HttpResponse<any> | undefined;
|
||||||
abstract put(req: HttpRequest<any>, response: HttpResponse<any>): void;
|
abstract put(req: HttpRequest<any>, response: HttpResponse<any>): void
|
||||||
}
|
}
|
||||||
// #enddocregion request-cache
|
// #enddocregion request-cache
|
||||||
|
|
||||||
@ -44,8 +44,8 @@ export class RequestCacheWithMap implements RequestCache {
|
|||||||
const url = req.urlWithParams;
|
const url = req.urlWithParams;
|
||||||
this.messenger.add(`Caching response from "${url}".`);
|
this.messenger.add(`Caching response from "${url}".`);
|
||||||
|
|
||||||
const newEntry = { url, response, lastRead: Date.now() };
|
const entry = { url, response, lastRead: Date.now() };
|
||||||
this.cache.set(url, newEntry);
|
this.cache.set(url, entry);
|
||||||
|
|
||||||
// remove expired cache entries
|
// remove expired cache entries
|
||||||
const expired = Date.now() - maxAge;
|
const expired = Date.now() - maxAge;
|
||||||
|
@ -23,12 +23,12 @@ bootstrap();
|
|||||||
|
|
||||||
//
|
//
|
||||||
function bootstrap () {
|
function bootstrap () {
|
||||||
if ((window as any).jasmineRef) {
|
if (window['jasmineRef']) {
|
||||||
location.reload();
|
location.reload();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
window.onload(undefined);
|
window.onload(undefined);
|
||||||
(window as any).jasmineRef = jasmine.getEnv();
|
window['jasmineRef'] = jasmine.getEnv();
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
// First, initialize the Angular testing environment.
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
import jasmineRequire from 'jasmine-core/lib/jasmine-core/jasmine.js';
|
import jasmineRequire from 'jasmine-core/lib/jasmine-core/jasmine.js';
|
||||||
|
|
||||||
(window as any).jasmineRequire = jasmineRequire;
|
window['jasmineRequire'] = jasmineRequire;
|
||||||
|
@ -73,7 +73,7 @@ describe('HttpClient testing', () => {
|
|||||||
|
|
||||||
// Make an HTTP GET request with specific header
|
// Make an HTTP GET request with specific header
|
||||||
httpClient.get<Data>(testUrl, {
|
httpClient.get<Data>(testUrl, {
|
||||||
headers: new HttpHeaders({Authorization: 'my-auth-token'})
|
headers: new HttpHeaders({'Authorization': 'my-auth-token'})
|
||||||
})
|
})
|
||||||
.subscribe(data =>
|
.subscribe(data =>
|
||||||
expect(data).toEqual(testData)
|
expect(data).toEqual(testData)
|
||||||
@ -83,14 +83,14 @@ describe('HttpClient testing', () => {
|
|||||||
// #docregion predicate
|
// #docregion predicate
|
||||||
// Expect one request with an authorization header
|
// Expect one request with an authorization header
|
||||||
const req = httpTestingController.expectOne(
|
const req = httpTestingController.expectOne(
|
||||||
request => request.headers.has('Authorization')
|
req => req.headers.has('Authorization')
|
||||||
);
|
);
|
||||||
// #enddocregion predicate
|
// #enddocregion predicate
|
||||||
req.flush(testData);
|
req.flush(testData);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can test multiple requests', () => {
|
it('can test multiple requests', () => {
|
||||||
const testData: Data[] = [
|
let testData: Data[] = [
|
||||||
{ name: 'bob' }, { name: 'carol' },
|
{ name: 'bob' }, { name: 'carol' },
|
||||||
{ name: 'ted' }, { name: 'alice' }
|
{ name: 'ted' }, { name: 'alice' }
|
||||||
];
|
];
|
||||||
|
@ -2,35 +2,35 @@ import { browser, element, by } from 'protractor';
|
|||||||
|
|
||||||
describe('i18n E2E Tests', () => {
|
describe('i18n E2E Tests', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(function () {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display i18n translated welcome: Bonjour !', () => {
|
it('should display i18n translated welcome: Bonjour !', function () {
|
||||||
expect(element(by.css('h1')).getText()).toEqual('Bonjour i18n !');
|
expect(element(by.css('h1')).getText()).toEqual('Bonjour i18n !');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display the node texts without elements', () => {
|
it('should display the node texts without elements', function () {
|
||||||
expect(element(by.css('app-root')).getText()).toContain(`Je n'affiche aucun élément`);
|
expect(element(by.css('app-root')).getText()).toContain(`Je n'affiche aucun élément`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display the translated title attribute', () => {
|
it('should display the translated title attribute', function () {
|
||||||
const title = element(by.css('img')).getAttribute('title');
|
const title = element(by.css('img')).getAttribute('title');
|
||||||
expect(title).toBe(`Logo d'Angular`);
|
expect(title).toBe(`Logo d'Angular`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display the ICU plural expression', () => {
|
it('should display the ICU plural expression', function () {
|
||||||
expect(element.all(by.css('span')).get(0).getText()).toBe(`Mis à jour à l'instant`);
|
expect(element.all(by.css('span')).get(0).getText()).toBe(`Mis à jour à l'instant`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display the ICU select expression', () => {
|
it('should display the ICU select expression', function () {
|
||||||
const selectIcuExp = element.all(by.css('span')).get(1);
|
const selectIcuExp = element.all(by.css('span')).get(1);
|
||||||
expect(selectIcuExp.getText()).toBe(`L'auteur est une femme`);
|
expect(selectIcuExp.getText()).toBe(`L'auteur est une femme`);
|
||||||
element.all(by.css('button')).get(2).click();
|
element.all(by.css('button')).get(2).click();
|
||||||
expect(selectIcuExp.getText()).toBe(`L'auteur est un homme`);
|
expect(selectIcuExp.getText()).toBe(`L'auteur est un homme`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display the nested expression', () => {
|
it('should display the nested expression', function() {
|
||||||
const nestedExp = element.all(by.css('span')).get(2);
|
const nestedExp = element.all(by.css('span')).get(2);
|
||||||
const incBtn = element.all(by.css('button')).get(0);
|
const incBtn = element.all(by.css('button')).get(0);
|
||||||
expect(nestedExp.getText()).toBe(`Mis à jour: à l'instant`);
|
expect(nestedExp.getText()).toBe(`Mis à jour: à l'instant`);
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
import { browser, element, by } from 'protractor';
|
||||||
import { logging } from 'selenium-webdriver';
|
import { logging } from 'selenium-webdriver';
|
||||||
|
|
||||||
describe('Inputs and Outputs', () => {
|
describe('Inputs and Outputs', function () {
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => browser.get(''));
|
beforeEach(() => {
|
||||||
|
browser.get('');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// helper function used to test what's logged to the console
|
// helper function used to test what's logged to the console
|
||||||
@ -13,48 +17,51 @@ describe('Inputs and Outputs', () => {
|
|||||||
.manage()
|
.manage()
|
||||||
.logs()
|
.logs()
|
||||||
.get(logging.Type.BROWSER);
|
.get(logging.Type.BROWSER);
|
||||||
const messages = logs.filter(({ message }) => message.indexOf(contents) !== -1);
|
const message = logs.filter(({ message }) =>
|
||||||
expect(messages.length).toBeGreaterThan(0);
|
message.indexOf(contents) !== -1 ? true : false
|
||||||
|
);
|
||||||
|
console.log(message);
|
||||||
|
expect(message.length).toBeGreaterThan(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should have title Inputs and Outputs', () => {
|
it('should have title Inputs and Outputs', function () {
|
||||||
const title = element.all(by.css('h1')).get(0);
|
let title = element.all(by.css('h1')).get(0);
|
||||||
expect(title.getText()).toEqual('Inputs and Outputs');
|
expect(title.getText()).toEqual('Inputs and Outputs');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add 123 to the parent list', async () => {
|
it('should add 123 to the parent list', async () => {
|
||||||
const addToParentButton = element.all(by.css('button')).get(0);
|
let addToParentButton = element.all(by.css('button')).get(0);
|
||||||
const addToListInput = element.all(by.css('input')).get(0);
|
let addToListInput = element.all(by.css('input')).get(0);
|
||||||
const addedItem = element.all(by.css('li')).get(4);
|
let addedItem = element.all(by.css('li')).get(4);
|
||||||
await addToListInput.sendKeys('123');
|
await addToListInput.sendKeys('123');
|
||||||
await addToParentButton.click();
|
await addToParentButton.click();
|
||||||
expect(addedItem.getText()).toEqual('123');
|
expect(addedItem.getText()).toEqual('123');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete item', async () => {
|
it('should delete item', async () => {
|
||||||
const deleteButton = element.all(by.css('button')).get(1);
|
let deleteButton = element.all(by.css('button')).get(1);
|
||||||
const contents = 'Child';
|
const contents = 'Child';
|
||||||
await deleteButton.click();
|
await deleteButton.click();
|
||||||
await logChecker(deleteButton, contents);
|
await logChecker(deleteButton, contents);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log buy the item', async () => {
|
it('should log buy the item', async () => {
|
||||||
const buyButton = element.all(by.css('button')).get(2);
|
let buyButton = element.all(by.css('button')).get(2);
|
||||||
const contents = 'Child';
|
const contents = 'Child';
|
||||||
await buyButton.click();
|
await buyButton.click();
|
||||||
await logChecker(buyButton, contents);
|
await logChecker(buyButton, contents);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save item for later', async () => {
|
it('should save item for later', async () => {
|
||||||
const saveButton = element.all(by.css('button')).get(3);
|
let saveButton = element.all(by.css('button')).get(3);
|
||||||
const contents = 'Child';
|
const contents = 'Child';
|
||||||
await saveButton.click();
|
await saveButton.click();
|
||||||
await logChecker(saveButton, contents);
|
await logChecker(saveButton, contents);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add item to wishlist', async () => {
|
it('should add item to wishlist', async () => {
|
||||||
const addToParentButton = element.all(by.css('button')).get(4);
|
let addToParentButton = element.all(by.css('button')).get(4);
|
||||||
const addedItem = element.all(by.css('li')).get(6);
|
let addedItem = element.all(by.css('li')).get(6);
|
||||||
await addToParentButton.click();
|
await addToParentButton.click();
|
||||||
expect(addedItem.getText()).toEqual('Television');
|
expect(addedItem.getText()).toEqual('Television');
|
||||||
});
|
});
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user