Compare commits
507 Commits
Author | SHA1 | Date | |
---|---|---|---|
1f0c1f3ff2 | |||
a86a41210f | |||
20c44a6240 | |||
0feb560136 | |||
f4d06445a3 | |||
6c1ab479ee | |||
f7997256fc | |||
dc9da17f37 | |||
99c41d6db0 | |||
1aae94a421 | |||
f0f319b1d6 | |||
454e073918 | |||
76d64331bd | |||
6855396449 | |||
0b96908225 | |||
65f52f3761 | |||
9ce55d08f8 | |||
765c1c5b17 | |||
ccfa3426f7 | |||
83379fa0bb | |||
2ffd44ad96 | |||
4a84842bbb | |||
daa715a1ca | |||
31bce80771 | |||
711e4d4cc2 | |||
fdc5941fe7 | |||
ae10a541bf | |||
b797913d10 | |||
1465372a0e | |||
a33cb2d39b | |||
1202d17b4c | |||
d837828317 | |||
dc210bc75b | |||
75ead94ed5 | |||
6ac0042aef | |||
3eee53603c | |||
5c94fa97c1 | |||
468f4a3f9e | |||
a2393bef02 | |||
5bd1c7bbf7 | |||
19313f7dad | |||
4e2500278c | |||
2c4cfa6f2c | |||
c8f0c3b637 | |||
cf4883240b | |||
6f3157fe6d | |||
12d8af50dd | |||
94fc8463cc | |||
87b9f08d3b | |||
1c8f1799d4 | |||
d98d0dbf17 | |||
7e56222afb | |||
2ed66acdd9 | |||
fa073bafbd | |||
363f14c893 | |||
a9edbc3a4e | |||
e62fa67440 | |||
57236f1e11 | |||
14ffecdf09 | |||
9ae3e1199d | |||
947f542185 | |||
353195c9c5 | |||
72505dfd6f | |||
a63f634592 | |||
18d08a3857 | |||
c4234577db | |||
4830d664da | |||
e26879ad1d | |||
c5c3113f00 | |||
178a78f9ed | |||
7de7871dd9 | |||
784cf46a93 | |||
ba9e63a278 | |||
83231f2174 | |||
62e3196849 | |||
127a06c031 | |||
d4e00ee5a1 | |||
6db8e7eb8f | |||
ee1ef8512f | |||
efef04487c | |||
74d8b2308b | |||
7543e5925e | |||
5ca8ba3be9 | |||
3f70e3df3b | |||
0b68189051 | |||
b811212013 | |||
4d0b831d09 | |||
2cf6b809ae | |||
639fab2c14 | |||
0912be47ff | |||
9548c7cb94 | |||
de5449380f | |||
5ffa4f12e5 | |||
9022091dc6 | |||
74878984b2 | |||
6a6fbc3890 | |||
cb888afd0c | |||
48cf61cf45 | |||
d808333047 | |||
f872b69d3b | |||
9cca82ed70 | |||
e3d33958d2 | |||
4de546eef5 | |||
719ca5283b | |||
3813f54bec | |||
92590693e6 | |||
ef9da2f619 | |||
23f380d6b9 | |||
92b97f7d60 | |||
d12ef0c0a7 | |||
4827dbe308 | |||
04cd4187ce | |||
bb5e455ab2 | |||
96787f2e40 | |||
4f1b7a4a6a | |||
d113bfa14f | |||
a8aa2caeb6 | |||
f20c725406 | |||
caafd7e0a3 | |||
f59f5a2ab3 | |||
b91b3d7462 | |||
a235daee71 | |||
77218d6974 | |||
928dc8f263 | |||
468aeb454a | |||
b9dd2b45af | |||
2ab32c870f | |||
53897d4a84 | |||
efe1713371 | |||
24b9e12383 | |||
ad3fbe1ea0 | |||
f0ce3c2ce5 | |||
ae989b8cb7 | |||
edcc8b8acf | |||
790af88288 | |||
6eef7dbdbe | |||
ba1dfd0cf3 | |||
b37071c22f | |||
b6cba54821 | |||
451e7e2364 | |||
99b63b677e | |||
00b9de56f5 | |||
4423ab5109 | |||
0fc0d9bb3d | |||
00cc02fb0c | |||
0783d482a7 | |||
6cce05e2c5 | |||
bf446cb2d5 | |||
04fd90e32a | |||
be06a44861 | |||
d4a14697ec | |||
35e0d8311b | |||
964d8679b3 | |||
6cbde69e8f | |||
6da2a28dc0 | |||
fbdd282e7c | |||
d1b3af697c | |||
dcf1dcb757 | |||
c6e5225ec3 | |||
3361f59a4f | |||
7e9d5f5e82 | |||
654868f584 | |||
b6c042d0a3 | |||
4becc1bc95 | |||
5bddeea559 | |||
65337fb8b8 | |||
4abd60361a | |||
9d13ee0052 | |||
be1a83337e | |||
0be3792b5c | |||
4edd5fc694 | |||
c88ba02d83 | |||
8719ccdcfb | |||
36083c7c3c | |||
44c350236c | |||
8a85c31667 | |||
293557c80b | |||
e61f094a19 | |||
244f736e47 | |||
9307bc063f | |||
64453e42ff | |||
9e755f30f0 | |||
d0e024ec2d | |||
a576852ad9 | |||
4573a9997b | |||
4af10c6bb0 | |||
eabeb574cf | |||
a297fa9ecd | |||
ea51b62786 | |||
701016d6c4 | |||
e5317d5eaf | |||
389ff894ee | |||
d6417f02af | |||
a239decc91 | |||
a11542ab6f | |||
723fb492ce | |||
971c6f8d3b | |||
e8efd67e71 | |||
75370107c2 | |||
48ae3a0639 | |||
b6d0e215f9 | |||
5ea51b21fd | |||
ebb473368c | |||
7ff9050c25 | |||
ec0c6b3dcc | |||
e92d53f157 | |||
2dbed5e8f5 | |||
a0342763b8 | |||
0d747337a3 | |||
decacd5f74 | |||
c8c2272a9f | |||
e5f459d32b | |||
901b980b8e | |||
186373300a | |||
f30307a2de | |||
166a4553dc | |||
465215b11c | |||
a0eed742b4 | |||
4775f63847 | |||
304816e573 | |||
d70cf76962 | |||
3800455c6f | |||
c635123fc8 | |||
15e1bfc026 | |||
9b961a410a | |||
420c73c722 | |||
62930aac7b | |||
d7433316b0 | |||
c440165384 | |||
0ce96f1d78 | |||
d3deaf9a99 | |||
5c88a9fcfe | |||
0bd7517c73 | |||
d669429bd2 | |||
6a9b2c9a67 | |||
0f389fa5ae | |||
2a27f69522 | |||
180a32894e | |||
00724dcdbb | |||
cc71116ba6 | |||
ddfcf082ca | |||
c7e4f5eb4d | |||
b3fe9017f7 | |||
d3a77ea91a | |||
1b5a931d63 | |||
d840503d35 | |||
b49a734f0d | |||
695f83529d | |||
f898c9ab57 | |||
5337e138e3 | |||
e33047454f | |||
858fa45556 | |||
b97211ee2b | |||
25d4238371 | |||
7743c43529 | |||
54883cb477 | |||
91cef8cfc7 | |||
d40bcce84e | |||
7a18fb2448 | |||
ec39bdcc15 | |||
b7070b0ad6 | |||
aa94cd505c | |||
cc6ccf28a6 | |||
e1071615c6 | |||
8bd5374cfd | |||
b9b9cc2ba8 | |||
a6e10ef869 | |||
9724169bf4 | |||
c0ed57db76 | |||
0bd50e2e50 | |||
0ceb27041f | |||
ec2affe104 | |||
c590e8ca7a | |||
254b9ea44c | |||
2a53f47159 | |||
722d9397b0 | |||
03de31a78e | |||
b22c5a953d | |||
24222e0c1f | |||
95f45e8070 | |||
18be33a9d1 | |||
a22d4f6c98 | |||
5ae8473c6b | |||
fd7c39e3cf | |||
d85d91df66 | |||
15930d21c7 | |||
61a7f98b98 | |||
c3c7bf6509 | |||
b2e7ce47ec | |||
94e518e3c7 | |||
0fa5ac8d0d | |||
f2fca3e243 | |||
5bab49828d | |||
db4e93d0ca | |||
479a59be43 | |||
52aab63dd9 | |||
506beeddc1 | |||
0075078179 | |||
bb7edc52aa | |||
ed2b0e945e | |||
da159bde83 | |||
06a9809e32 | |||
1e4fb74ec8 | |||
797c306306 | |||
972fc06135 | |||
a9117061d0 | |||
fe1d9bacc3 | |||
08b8b51486 | |||
1d4af3f734 | |||
609d81c65e | |||
af30efddc5 | |||
15115f6179 | |||
eec9b6bbb5 | |||
45fd77ead1 | |||
f16587e9b7 | |||
4f9991534e | |||
51a0ed2222 | |||
a5ea100e7c | |||
0429c7f5e9 | |||
1756cced4a | |||
793a001d7c | |||
5c3774cfe6 | |||
12266b2042 | |||
e385abc83c | |||
933cbfb828 | |||
c5e725111d | |||
93993864b1 | |||
26f49151e7 | |||
4b3f9ac739 | |||
80604d3a76 | |||
e615a10371 | |||
c8f2ca2349 | |||
a67afcc932 | |||
fd7698253e | |||
32de025dce | |||
a4e1768a74 | |||
b336871303 | |||
92fa6399f7 | |||
3992341d34 | |||
8c559ef104 | |||
0bac2b062c | |||
58d028178f | |||
e06512b22f | |||
603b0944d5 | |||
918e628f9b | |||
468cf69c55 | |||
c8f3fa9f3e | |||
78136cc3a7 | |||
66724fd159 | |||
8e7f9033a3 | |||
c8f9092364 | |||
bc995835b9 | |||
1bfa908ab3 | |||
2479f7d7ef | |||
333b8679ad | |||
5da621d3dd | |||
cbed582a1a | |||
d5aa6b5bd6 | |||
33eee43263 | |||
72053b0f27 | |||
d20ef47b16 | |||
bdc05aef64 | |||
798d959bee | |||
3570aaa363 | |||
421b6a97d6 | |||
b28a5f6eef | |||
52ab9397a0 | |||
b99e539b0e | |||
fd2ef74a31 | |||
cbc25bbf31 | |||
7385b2cf25 | |||
0daa48800e | |||
ffa4e11db1 | |||
41a41e741d | |||
c5384aee58 | |||
b02c950aac | |||
2eaa304aba | |||
9faf2e4a96 | |||
0e7a89a391 | |||
af4269471d | |||
915a6c17b9 | |||
93b32d3023 | |||
bd82b34f79 | |||
c626e90ab0 | |||
c6bbb0d8e5 | |||
f48a065db0 | |||
aeb6d0d0f7 | |||
655c9e386b | |||
2ad20b953f | |||
7059eaf2d2 | |||
939fda410f | |||
35ab6acab3 | |||
f4ee067cb8 | |||
068e28381d | |||
dff52ecb11 | |||
56af303dc3 | |||
136596ddb4 | |||
e515c913d9 | |||
31eaf78035 | |||
b0d680daa0 | |||
93cbef26c7 | |||
e2b221b8fa | |||
7a33c456d3 | |||
61db817eed | |||
4894220acf | |||
74b7a8eaf5 | |||
bfa55162de | |||
776f991c1a | |||
d9d1a1e682 | |||
867ff14a4a | |||
879457ca05 | |||
efbe4ad28a | |||
64f72c0600 | |||
81c05bfa01 | |||
56abcf088d | |||
6818432cd0 | |||
79bfb037df | |||
0fce20d79d | |||
9f486c31d2 | |||
d36066dd6c | |||
a631b99c69 | |||
78211c42ea | |||
5ff5a11509 | |||
e80047e897 | |||
eee5eeae76 | |||
c3ce1903b6 | |||
21da0346c7 | |||
af2d74fde9 | |||
8de62a9811 | |||
26e28453d6 | |||
8ea30b662f | |||
cb0a2a055d | |||
14ae3c0a21 | |||
90cae34c05 | |||
7bb35889fa | |||
03a3c753bb | |||
74b1464dff | |||
ff523c9ec9 | |||
392ef93c2b | |||
29dcb5bf68 | |||
de594ca221 | |||
3545a49a79 | |||
f4681b6e40 | |||
fb16557381 | |||
61c9da5542 | |||
dbb1eb0ffe | |||
002b81c0b0 | |||
beb3f19dc0 | |||
e8f3c47b03 | |||
c58e6ba13a | |||
61e5ab4703 | |||
10385c27da | |||
0ab244f39e | |||
eafa5260db | |||
15cffa210c | |||
df8e45a193 | |||
bb8744db94 | |||
43bad87ae1 | |||
c3b297a318 | |||
6ea232eb3c | |||
0baab0f3db | |||
e53b686375 | |||
5c28af0e74 | |||
60adc35d30 | |||
024cc3b84a | |||
ac17142001 | |||
8d7066223f | |||
0cb3c04128 | |||
2649794e65 | |||
bf426c5f0d | |||
aa6b9f0382 | |||
822b420a11 | |||
294c6297d7 | |||
58fc65d198 | |||
b6bd8d7572 | |||
b08168bb90 | |||
407fa42679 | |||
aef432384a | |||
fb70083339 | |||
c9c2408176 | |||
e066bddfe9 | |||
447a600477 | |||
70f9bfff43 | |||
57c02b044c | |||
6defe962c8 | |||
267bcb3e9c | |||
b0b66881b4 | |||
9ff8d78bcd | |||
563b707497 | |||
5357e643b3 | |||
f71d132f7c | |||
ba3edda230 | |||
0767d37c07 | |||
8ba24578bc | |||
133a97ad67 | |||
4e67a3ab3f | |||
377f0010fc | |||
6e09129e4c | |||
d80e51a6b1 | |||
feb66b00da | |||
cb19eac105 | |||
6e0564ade6 | |||
05eeb7d279 | |||
2ce5fa3cce | |||
e140cdcb34 | |||
14b2db1d43 | |||
2afc7e982e |
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.
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
3.2.0
|
2.1.1
|
||||||
# [NB: this comment has to be after the first line, see https://github.com/bazelbuild/bazelisk/issues/117]
|
# [NB: this comment has to be after the first line, see https://github.com/bazelbuild/bazelisk/issues/117]
|
||||||
# When updating the Bazel version you also need to update the RBE toolchains version in package.bzl
|
# When updating the Bazel version you also need to update the RBE toolchains version in package.bzl
|
||||||
|
@ -19,12 +19,4 @@ build --local_ram_resources=14336
|
|||||||
|
|
||||||
# All build executed remotely should be done using our RBE configuration.
|
# All build executed remotely should be done using our RBE configuration.
|
||||||
build:remote --google_default_credentials
|
build:remote --google_default_credentials
|
||||||
|
|
||||||
# Upload to GCP's Build Status viewer to allow for us to have better viewing of execution/build
|
|
||||||
# logs. This is only done on CI as the BES (GCP's Build Status viewer) API requires credentials
|
|
||||||
# from service accounts, rather than end user accounts.
|
|
||||||
build:remote --bes_backend=buildeventservice.googleapis.com
|
|
||||||
build:remote --bes_timeout=30s
|
|
||||||
build:remote --bes_results_url="https://source.cloud.google.com/results/invocations/"
|
|
||||||
|
|
||||||
build --config=remote
|
build --config=remote
|
||||||
|
@ -22,17 +22,17 @@ version: 2.1
|
|||||||
# **NOTE 1 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
|
# **NOTE 1 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
|
||||||
# **NOTE 2 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
|
# **NOTE 2 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
|
||||||
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
|
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
|
||||||
var_3: &cache_key v7-angular-node-12-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
|
var_3: &cache_key v6-angular-node-12-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
|
||||||
# We invalidate the cache if the Bazel version changes because otherwise the `bazelisk` cache
|
# We invalidate the cache if the Bazel version changes because otherwise the `bazelisk` cache
|
||||||
# folder will contain all previously used versions and ultimately cause the cache restoring to
|
# folder will contain all previously used versions and ultimately cause the cache restoring to
|
||||||
# be slower due to its growing size.
|
# be slower due to its growing size.
|
||||||
var_4: &cache_key_fallback v7-angular-node-12-{{ checksum ".bazelversion" }}
|
var_4: &cache_key_fallback v6-angular-node-12-{{ checksum ".bazelversion" }}
|
||||||
var_3_win: &cache_key_win v7-angular-win-node-12-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
|
var_3_win: &cache_key_win v6-angular-win-node-12-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
|
||||||
var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelversion" }}
|
var_4_win: &cache_key_win_fallback v6-angular-win-node-12-{{ checksum ".bazelversion" }}
|
||||||
|
|
||||||
# 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 v7-angular-components-f428c00465dfcf8a020237f22532480eedbd2cb6
|
var_5: &components_repo_unit_tests_cache_key v7-angular-components-caad0b54ed41949f0ee529c152508749875bc9af
|
||||||
var_6: &components_repo_unit_tests_cache_key_fallback v7-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
|
||||||
@ -67,6 +67,9 @@ var_10: &only_on_master
|
|||||||
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
|
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
|
||||||
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
|
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
|
||||||
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
|
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
|
||||||
|
# **NOTE 3**: If you change the version of the `*-browsers` docker image, make sure the
|
||||||
|
# `--versions.chrome` arg in `integration/bazel-schematics/test.sh` specifies a
|
||||||
|
# ChromeDriver version that is compatible with the Chrome version in the image.
|
||||||
executors:
|
executors:
|
||||||
default-executor:
|
default-executor:
|
||||||
parameters:
|
parameters:
|
||||||
@ -117,7 +120,7 @@ commands:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
# Install GTK+ graphical user interface (libgtk-3-0), advanced linux sound architecture (libasound2)
|
# Install GTK+ graphical user interface (libgtk-3-0), advanced linux sound architecture (libasound2)
|
||||||
# and network security service libraries (libnss3) & X11 Screen Saver extension library (libssx1)
|
# and network security service libraries (libnss3) & X11 Screen Saver extension library (libssx1)
|
||||||
# which are dependencies of chrome & needed for karma & protractor headless chrome tests.
|
# which are dependendies of chrome & needed for karma & protractor headless chrome tests.
|
||||||
# This is a very small install which takes around 7s in comparing to using the full
|
# This is a very small install which takes around 7s in comparing to using the full
|
||||||
# circleci/node:x.x.x-browsers image.
|
# circleci/node:x.x.x-browsers image.
|
||||||
sudo apt-get -y install libgtk-3-0 libasound2 libnss3 libxss1
|
sudo apt-get -y install libgtk-3-0 libasound2 libnss3 libxss1
|
||||||
@ -160,7 +163,7 @@ commands:
|
|||||||
description: Sets up a domain that resolves to the local host.
|
description: Sets up a domain that resolves to the local host.
|
||||||
steps:
|
steps:
|
||||||
- run:
|
- run:
|
||||||
name: Preparing environment for running tests on Sauce Labs.
|
name: Preparing environment for running tests on Saucelabs.
|
||||||
command: |
|
command: |
|
||||||
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
|
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
|
||||||
# the tunnel. We do this because devices are sometimes not able to properly resolve
|
# the tunnel. We do this because devices are sometimes not able to properly resolve
|
||||||
@ -172,13 +175,13 @@ commands:
|
|||||||
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
|
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
|
||||||
- run:
|
- run:
|
||||||
# Sets up a local domain in the machine's host file that resolves to the local
|
# Sets up a local domain in the machine's host file that resolves to the local
|
||||||
# host. This domain is helpful in Sauce Labs tests where devices are not able to
|
# host. This domain is helpful in Saucelabs tests where devices are not able to
|
||||||
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
|
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
|
||||||
name: Setting up alias domain for local host.
|
name: Setting up alias domain for local host.
|
||||||
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
|
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
|
||||||
|
|
||||||
# Normally this would be an individual job instead of a command.
|
# Normally this would be an individual job instead of a command.
|
||||||
# But startup and setup time for each individual windows job are high enough to discourage
|
# But startup and setup time for each invidual windows job are high enough to discourage
|
||||||
# many small jobs, so instead we use a command for setup unless the gain becomes significant.
|
# many small jobs, so instead we use a command for setup unless the gain becomes significant.
|
||||||
setup_win:
|
setup_win:
|
||||||
description: Setup windows node environment
|
description: Setup windows node environment
|
||||||
@ -596,8 +599,8 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Decrypt github credentials
|
name: Decrypt github credentials
|
||||||
# We need ensure that the same default digest is used for encoding and decoding with
|
# We need ensure that the same default digest is used for encoding and decoding with
|
||||||
# OpenSSL. OpenSSL versions might have different default digests which can cause
|
# openssl. Openssl versions might have different default digests which can cause
|
||||||
# decryption failures based on the installed OpenSSL version. https://stackoverflow.com/a/39641378/4317734
|
# decryption failures based on the installed openssl version. https://stackoverflow.com/a/39641378/4317734
|
||||||
command: 'openssl aes-256-cbc -d -in .circleci/github_token -md md5 -k "${KEY}" -out ~/.git_credentials'
|
command: 'openssl aes-256-cbc -d -in .circleci/github_token -md md5 -k "${KEY}" -out ~/.git_credentials'
|
||||||
- run: ./scripts/ci/publish-build-artifacts.sh
|
- run: ./scripts/ci/publish-build-artifacts.sh
|
||||||
|
|
||||||
|
@ -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 "f428c00465dfcf8a020237f22532480eedbd2cb6"
|
setPublicVar COMPONENTS_REPO_COMMIT "caad0b54ed41949f0ee529c152508749875bc9af"
|
||||||
|
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
|
@ -60,12 +60,11 @@ if (require.resolve === module) {
|
|||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
function _main(args) {
|
function _main(args) {
|
||||||
triggerWebhook(...args)
|
triggerWebhook(...args).
|
||||||
.then(
|
then(({statusCode, responseText}) => (200 <= statusCode && statusCode < 400) ?
|
||||||
({statusCode, responseText}) => (200 <= statusCode && statusCode < 400) ?
|
|
||||||
console.log(`Status: ${statusCode}\n${responseText}`) :
|
console.log(`Status: ${statusCode}\n${responseText}`) :
|
||||||
Promise.reject(new Error(`Request failed (status: ${statusCode}): ${responseText}`)))
|
Promise.reject(new Error(`Request failed (status: ${statusCode}): ${responseText}`))).
|
||||||
.catch(err => {
|
catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
@ -78,12 +77,15 @@ function postJson(url, data) {
|
|||||||
const statusCode = res.statusCode || -1;
|
const statusCode = res.statusCode || -1;
|
||||||
let responseText = '';
|
let responseText = '';
|
||||||
|
|
||||||
res.on('error', reject)
|
res.
|
||||||
.on('data', d => responseText += d)
|
on('error', reject).
|
||||||
.on('end', () => resolve({statusCode, responseText}));
|
on('data', d => responseText += d).
|
||||||
|
on('end', () => resolve({statusCode, responseText}));
|
||||||
};
|
};
|
||||||
|
|
||||||
request(url, opts, onResponse).on('error', reject).end(JSON.stringify(data));
|
request(url, opts, onResponse).
|
||||||
|
on('error', reject).
|
||||||
|
end(JSON.stringify(data));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
2
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
@ -32,7 +32,7 @@ Existing issues often contain information about workarounds, resolution, or prog
|
|||||||
|
|
||||||
## 🔬 Minimal Reproduction
|
## 🔬 Minimal Reproduction
|
||||||
<!--
|
<!--
|
||||||
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-ivy
|
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-issue-repro2
|
||||||
-->
|
-->
|
||||||
<!-- ✍️--> https://stackblitz.com/...
|
<!-- ✍️--> https://stackblitz.com/...
|
||||||
|
|
||||||
|
6
.github/angular-robot.yml
vendored
6
.github/angular-robot.yml
vendored
@ -154,12 +154,6 @@ triage:
|
|||||||
-
|
-
|
||||||
- "type: RFC / Discussion / question"
|
- "type: RFC / Discussion / question"
|
||||||
- "comp: *"
|
- "comp: *"
|
||||||
-
|
|
||||||
- "type: confusing"
|
|
||||||
- "comp: *"
|
|
||||||
-
|
|
||||||
- "type: use-case"
|
|
||||||
- "comp: *"
|
|
||||||
|
|
||||||
# options for the triage PR plugin
|
# options for the triage PR plugin
|
||||||
triagePR:
|
triagePR:
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -42,6 +42,3 @@ yarn-error.log
|
|||||||
|
|
||||||
.notes.md
|
.notes.md
|
||||||
baseline.json
|
baseline.json
|
||||||
|
|
||||||
# Ignore .history for the xyz.local-history VSCode extension
|
|
||||||
.history
|
|
||||||
|
145
.gitmessage
145
.gitmessage
@ -1,145 +0,0 @@
|
|||||||
<type>(<scope>): <summary>
|
|
||||||
|
|
||||||
<Describe the motivation behind this change - explain WHY you are making this change. Wrap all lines
|
|
||||||
at 100 characters.>
|
|
||||||
|
|
||||||
Fixes #<issue number>
|
|
||||||
|
|
||||||
# ────────────────────────────────────────── 100 chars ────────────────────────────────────────────┤
|
|
||||||
|
|
||||||
|
|
||||||
# Example Commit Messages
|
|
||||||
# =======================
|
|
||||||
|
|
||||||
|
|
||||||
# ─── Example: Simple refactor ────────────────────────────────────────────────────────────────────┤
|
|
||||||
# refactor(core): rename refreshDynamicEmbeddedViews to refreshEmbeddedViews
|
|
||||||
#
|
|
||||||
# Improve code readability. The original name no longer matches how the function is used.
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
||||||
|
|
||||||
|
|
||||||
# ─── Example: Simple docs change ─────────────────────────────────────────────────────────────────┤
|
|
||||||
# docs: clarify the service limitation in providers.md guide
|
|
||||||
#
|
|
||||||
# Fixes #36332
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
||||||
|
|
||||||
|
|
||||||
# ─── Example: A bug fix ──────────────────────────────────────────────────────────────────────────┤
|
|
||||||
# fix(ngcc): ensure lockfile is removed when `analyzeFn` fails
|
|
||||||
#
|
|
||||||
# Previously an error thrown in the `analyzeFn` would cause the ngcc process to exit immediately
|
|
||||||
# without removing the lockfile, and potentially before the unlocker process had been successfully
|
|
||||||
# spawned resulting in the lockfile being orphaned and left behind.
|
|
||||||
#
|
|
||||||
# Now we catch these errors and remove the lockfile as needed.
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
||||||
|
|
||||||
|
|
||||||
# ─── Example: Breaking change ────────────────────────────────────────────────────────────────────┤
|
|
||||||
# feat(bazel): simplify ng_package by dropping esm5 and fesm5
|
|
||||||
#
|
|
||||||
# esm5 and fesm5 distributions are no longer needed and have been deprecated in the past.
|
|
||||||
#
|
|
||||||
# https://v9.angular.io/guide/deprecations#esm5-and-fesm5-code-formats-in-angular-npm-packages
|
|
||||||
#
|
|
||||||
# This commit modifies ng_package to no longer distribute these two formats in npm packages built by
|
|
||||||
# ng_package (e.g. @angular/core).
|
|
||||||
#
|
|
||||||
# This commit intentionally doesn't fully clean up the ng_package rule to remove all traces of esm5
|
|
||||||
# and fems5 build artifacts as that is a bigger cleanup and currently we are narrowing down the
|
|
||||||
# scope of this change to the MVP needed for v10, which in this case is 'do not put esm5 and fesm5'
|
|
||||||
# into the npm packages.
|
|
||||||
#
|
|
||||||
# More cleanup to follow: https://angular-team.atlassian.net/browse/FW-2143
|
|
||||||
#
|
|
||||||
# BREAKING CHANGE: esm5 and fesm5 format is no longer distributed in Angular's npm packages e.g.
|
|
||||||
# @angular/core
|
|
||||||
#
|
|
||||||
# Angular CLI will automatically downlevel the code to es5 if differential loading is enabled in the
|
|
||||||
# Angular project, so no action is required from Angular CLI users.
|
|
||||||
#
|
|
||||||
# If you are not using Angular CLI to build your application or library, and you need to be able to
|
|
||||||
# build es5 artifacts, then you will need to downlevel the distributed Angular code to es5 on your
|
|
||||||
# own.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Fixes #1234
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Angular Commit Message Format
|
|
||||||
# =============================
|
|
||||||
#
|
|
||||||
# The full specification of the Angular Commit Message Format can be found at
|
|
||||||
# https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
|
|
||||||
#
|
|
||||||
# The following is an excerpt of the specification with the most commonly needed info.
|
|
||||||
#
|
|
||||||
# Each commit message consists of a *header*, a *body*, and a *footer*.
|
|
||||||
#
|
|
||||||
# <header>
|
|
||||||
# <BLANK LINE>
|
|
||||||
# <body>
|
|
||||||
# <BLANK LINE>
|
|
||||||
# <footer>
|
|
||||||
#
|
|
||||||
# The header is mandatory.
|
|
||||||
#
|
|
||||||
# The body is mandatory for all commits except for those of scope "docs". When the body is required
|
|
||||||
# it must be at least 20 characters long.
|
|
||||||
#
|
|
||||||
# The footer is optional.
|
|
||||||
#
|
|
||||||
# Any line of the commit message cannot be longer than 100 characters.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Commit Message Header
|
|
||||||
# ---------------------
|
|
||||||
#
|
|
||||||
# <type>(<scope>): <short summary>
|
|
||||||
# │ │ │
|
|
||||||
# │ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
|
|
||||||
# │ │
|
|
||||||
# │ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
|
||||||
# │ elements|forms|http|language-service|localize|platform-browser|
|
|
||||||
# │ platform-browser-dynamic|platform-server|platform-webworker|
|
|
||||||
# │ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
|
|
||||||
# │ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
|
|
||||||
# │ https://github.com/angular/angular/blob/master/CONTRIBUTING.md#scope
|
|
||||||
# │
|
|
||||||
# └─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
|
|
||||||
# https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Commit Message Body
|
|
||||||
# ---------------------
|
|
||||||
#
|
|
||||||
# Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
|
|
||||||
#
|
|
||||||
# Explain the motivation for the change in the commit message body. This commit message should
|
|
||||||
# explain WHY you are making the change. You can include a comparison of the previous behavior with
|
|
||||||
# the new behavior in order to illustrate the impact of the change.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Commit Message Footer
|
|
||||||
# ---------------------
|
|
||||||
#
|
|
||||||
# The footer can contain information about breaking changes and is also the place to reference
|
|
||||||
# GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
|
|
||||||
#
|
|
||||||
# ```
|
|
||||||
# BREAKING CHANGE: <breaking change summary>
|
|
||||||
# <BLANK LINE>
|
|
||||||
# <breaking change description + migration instructions>
|
|
||||||
# <BLANK LINE>
|
|
||||||
# <BLANK LINE>
|
|
||||||
# Fixes #<issue number>
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of
|
|
||||||
# the breaking change, a blank line, and a detailed description of the breaking change that also
|
|
||||||
# includes migration instructions.
|
|
||||||
#
|
|
123
.ng-dev-config.ts
Normal file
123
.ng-dev-config.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import {MergeConfig} from './dev-infra/pr/merge/config';
|
||||||
|
|
||||||
|
// The configuration for `ng-dev commit-message` commands.
|
||||||
|
const commitMessage = {
|
||||||
|
'maxLength': 120,
|
||||||
|
'minBodyLength': 100,
|
||||||
|
'types': [
|
||||||
|
'build',
|
||||||
|
'ci',
|
||||||
|
'docs',
|
||||||
|
'feat',
|
||||||
|
'fix',
|
||||||
|
'perf',
|
||||||
|
'refactor',
|
||||||
|
'release',
|
||||||
|
'style',
|
||||||
|
'test',
|
||||||
|
],
|
||||||
|
'scopes': [
|
||||||
|
'animations',
|
||||||
|
'bazel',
|
||||||
|
'benchpress',
|
||||||
|
'changelog',
|
||||||
|
'common',
|
||||||
|
'compiler',
|
||||||
|
'compiler-cli',
|
||||||
|
'core',
|
||||||
|
'dev-infra',
|
||||||
|
'docs-infra',
|
||||||
|
'elements',
|
||||||
|
'forms',
|
||||||
|
'http',
|
||||||
|
'language-service',
|
||||||
|
'localize',
|
||||||
|
'ngcc',
|
||||||
|
'packaging',
|
||||||
|
'platform-browser',
|
||||||
|
'platform-browser-dynamic',
|
||||||
|
'platform-server',
|
||||||
|
'platform-webworker',
|
||||||
|
'platform-webworker-dynamic',
|
||||||
|
'router',
|
||||||
|
'service-worker',
|
||||||
|
'upgrade',
|
||||||
|
've',
|
||||||
|
'zone.js',
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// The configuration for `ng-dev format` commands.
|
||||||
|
const format = {
|
||||||
|
'clang-format': {
|
||||||
|
'matchers': [
|
||||||
|
'dev-infra/**/*.{js,ts}',
|
||||||
|
'packages/**/*.{js,ts}',
|
||||||
|
'!packages/zone.js',
|
||||||
|
'!packages/common/locales/**/*.{js,ts}',
|
||||||
|
'!packages/common/src/i18n/available_locales.ts',
|
||||||
|
'!packages/common/src/i18n/currencies.ts',
|
||||||
|
'!packages/common/src/i18n/locale_en.ts',
|
||||||
|
'modules/benchmarks/**/*.{js,ts}',
|
||||||
|
'modules/playground/**/*.{js,ts}',
|
||||||
|
'tools/**/*.{js,ts}',
|
||||||
|
'!tools/gulp-tasks/cldr/extract.js',
|
||||||
|
'!tools/public_api_guard/**/*.d.ts',
|
||||||
|
'!tools/ts-api-guardian/test/fixtures/**',
|
||||||
|
'*.{js,ts}',
|
||||||
|
'!**/node_modules/**',
|
||||||
|
'!**/dist/**',
|
||||||
|
'!**/built/**',
|
||||||
|
'!shims_for_IE.js',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'buildifier': true
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Github metadata information for `ng-dev` commands. */
|
||||||
|
const github = {
|
||||||
|
owner: 'angular',
|
||||||
|
name: 'angular',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Configuration for the `ng-dev pr merge` command. The command can be used
|
||||||
|
// for merging upstream pull requests into branches based on a PR target label.
|
||||||
|
const merge = () => {
|
||||||
|
// TODO: resume dynamically determining patch branch
|
||||||
|
const patch = '10.0.x';
|
||||||
|
const config: MergeConfig = {
|
||||||
|
githubApiMerge: false,
|
||||||
|
claSignedLabel: 'cla: yes',
|
||||||
|
mergeReadyLabel: /^PR action: merge(-assistance)?/,
|
||||||
|
commitMessageFixupLabel: 'commit message fixup',
|
||||||
|
labels: [
|
||||||
|
{
|
||||||
|
pattern: 'PR target: master-only',
|
||||||
|
branches: ['master'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: 'PR target: patch-only',
|
||||||
|
branches: [patch],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: 'PR target: master & patch',
|
||||||
|
branches: ['master', patch],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
requiredBaseCommits: {
|
||||||
|
// PRs that target either `master` or the patch branch, need to be rebased
|
||||||
|
// on top of the latest commit message validation fix.
|
||||||
|
'master': '4341743b4a6d7e23c6f944aa9e34166b701369a1',
|
||||||
|
[patch]: '2a53f471592f424538802907aca1f60f1177a86d'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return config;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Export function to build ng-dev configuration object.
|
||||||
|
module.exports = {
|
||||||
|
commitMessage,
|
||||||
|
format,
|
||||||
|
github,
|
||||||
|
merge,
|
||||||
|
};
|
@ -1,52 +0,0 @@
|
|||||||
import {CommitMessageConfig} from '../dev-infra/commit-message/config';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The configuration for `ng-dev commit-message` commands.
|
|
||||||
*/
|
|
||||||
export const commitMessage: CommitMessageConfig = {
|
|
||||||
maxLineLength: 120,
|
|
||||||
minBodyLength: 20,
|
|
||||||
minBodyLengthTypeExcludes: ['docs'],
|
|
||||||
types: [
|
|
||||||
'build',
|
|
||||||
'ci',
|
|
||||||
'docs',
|
|
||||||
'feat',
|
|
||||||
'fix',
|
|
||||||
'perf',
|
|
||||||
'refactor',
|
|
||||||
'release',
|
|
||||||
'style',
|
|
||||||
'test',
|
|
||||||
],
|
|
||||||
scopes: [
|
|
||||||
'animations',
|
|
||||||
'bazel',
|
|
||||||
'benchpress',
|
|
||||||
'changelog',
|
|
||||||
'common',
|
|
||||||
'compiler',
|
|
||||||
'compiler-cli',
|
|
||||||
'core',
|
|
||||||
'dev-infra',
|
|
||||||
'docs-infra',
|
|
||||||
'elements',
|
|
||||||
'forms',
|
|
||||||
'http',
|
|
||||||
'language-service',
|
|
||||||
'localize',
|
|
||||||
'migrations',
|
|
||||||
'ngcc',
|
|
||||||
'packaging',
|
|
||||||
'platform-browser',
|
|
||||||
'platform-browser-dynamic',
|
|
||||||
'platform-server',
|
|
||||||
'platform-webworker',
|
|
||||||
'platform-webworker-dynamic',
|
|
||||||
'router',
|
|
||||||
'service-worker',
|
|
||||||
'upgrade',
|
|
||||||
've',
|
|
||||||
'zone.js',
|
|
||||||
]
|
|
||||||
};
|
|
@ -1,11 +0,0 @@
|
|||||||
import {commitMessage} from './commit-message';
|
|
||||||
import {format} from './format';
|
|
||||||
import {github} from './github';
|
|
||||||
import {merge} from './merge';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
commitMessage,
|
|
||||||
format,
|
|
||||||
github,
|
|
||||||
merge,
|
|
||||||
};
|
|
@ -1,22 +0,0 @@
|
|||||||
import {FormatConfig} from '../dev-infra/format/config';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration for the `ng-dev format` command.
|
|
||||||
*/
|
|
||||||
export const format: FormatConfig = {
|
|
||||||
'clang-format': {
|
|
||||||
'matchers': [
|
|
||||||
'**/*.{js,ts}',
|
|
||||||
// TODO: burn down format failures and remove aio and integration exceptions.
|
|
||||||
'!aio/**',
|
|
||||||
'!integration/**',
|
|
||||||
// Both third_party and .yarn are directories containing copied code which should
|
|
||||||
// not be modified.
|
|
||||||
'!third_party/**',
|
|
||||||
'!.yarn/**',
|
|
||||||
// Do not format d.ts files as they are generated
|
|
||||||
'!**/*.d.ts',
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'buildifier': true
|
|
||||||
};
|
|
@ -1,15 +0,0 @@
|
|||||||
# The file is inert unless it's explicitly included into the local git config via:
|
|
||||||
#
|
|
||||||
# ```
|
|
||||||
# git config --add include.path '../.ng-dev/gitconfig'
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# Calling that command will append the following into `.git/config` of the current git workspace
|
|
||||||
# (i.e. $GIT_DIR, typically `angular/.git/config`):
|
|
||||||
#
|
|
||||||
# ```
|
|
||||||
# [include]
|
|
||||||
# path = ../.ng-dev/gitconfig
|
|
||||||
# ```
|
|
||||||
[commit]
|
|
||||||
template = .gitmessage
|
|
@ -1,11 +0,0 @@
|
|||||||
import {GithubConfig} from '../dev-infra/utils/config';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Github configuration for the `ng-dev` command. This repository is used as
|
|
||||||
* remote for the merge script and other utilities like `ng-dev pr rebase`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const github: GithubConfig = {
|
|
||||||
owner: 'angular',
|
|
||||||
name: 'angular'
|
|
||||||
};
|
|
@ -1,38 +0,0 @@
|
|||||||
import {MergeConfig} from '../dev-infra/pr/merge/config';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
|
|
||||||
* are respected by the merge script (e.g. the target labels).
|
|
||||||
*/
|
|
||||||
export const merge = (): MergeConfig => {
|
|
||||||
// TODO: resume dynamically determining patch branch
|
|
||||||
const patch = '10.0.x';
|
|
||||||
return {
|
|
||||||
githubApiMerge: false,
|
|
||||||
claSignedLabel: 'cla: yes',
|
|
||||||
mergeReadyLabel: /^PR action: merge(-assistance)?/,
|
|
||||||
caretakerNoteLabel: 'PR action: merge-assistance',
|
|
||||||
commitMessageFixupLabel: 'commit message fixup',
|
|
||||||
labels: [
|
|
||||||
{
|
|
||||||
pattern: 'PR target: master-only',
|
|
||||||
branches: ['master'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: 'PR target: patch-only',
|
|
||||||
branches: [patch],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: 'PR target: master & patch',
|
|
||||||
branches: ['master', patch],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
requiredBaseCommits: {
|
|
||||||
// PRs that target either `master` or the patch branch, need to be rebased
|
|
||||||
// on top of the latest commit message validation fix.
|
|
||||||
// These SHAs are the commits that update the required license text in the header.
|
|
||||||
'master': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
|
|
||||||
[patch]: '27b95ba64a5d99757f4042073fd1860e20e3ed24'
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
320
.pullapprove.yml
320
.pullapprove.yml
@ -34,8 +34,41 @@
|
|||||||
####################################################################################
|
####################################################################################
|
||||||
# GitHub usernames
|
# GitHub usernames
|
||||||
####################################################################################
|
####################################################################################
|
||||||
# See reviewer list under `required-minimum-review` group. Team member names and
|
# aikidave - Dave Shevitz
|
||||||
# usernames are managed there.
|
# 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
|
||||||
|
# matsko - Matias Niemela
|
||||||
|
# mgechev - Minko Gechev
|
||||||
|
# mhevery - Miško Hevery
|
||||||
|
# michaelprentice - Michael Prentice
|
||||||
|
# mmalerba - Miles Malerba
|
||||||
|
# petebacondarwin - Pete Bacon Darwin
|
||||||
|
# pkozlowski-opensource - Pawel Kozlowski
|
||||||
|
# robwormald - Rob Wormald
|
||||||
|
# StephenFluin - Stephen Fluin
|
||||||
|
|
||||||
|
|
||||||
####################################################################################
|
####################################################################################
|
||||||
@ -47,8 +80,8 @@
|
|||||||
# Used for approving minor changes, large-scale refactorings, and in emergency situations.
|
# Used for approving minor changes, large-scale refactorings, and in emergency situations.
|
||||||
#
|
#
|
||||||
# IgorMinar
|
# IgorMinar
|
||||||
# jelbourn
|
|
||||||
# josephperrott
|
# josephperrott
|
||||||
|
# kara
|
||||||
# mhevery
|
# mhevery
|
||||||
#
|
#
|
||||||
# =========================================================
|
# =========================================================
|
||||||
@ -67,35 +100,8 @@ 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
|
1: &can-be-global-approved "\"global-approvers\" not in groups.approved"
|
||||||
# - `global-approvers`
|
2: &can-be-global-docs-approved "\"global-docs-approvers\" not in groups.approved"
|
||||||
# - `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-docs-approved: &can-be-global-docs-approved "\"global-docs-approvers\" not in groups.approved"
|
|
||||||
defaults: &defaults
|
|
||||||
reviews:
|
|
||||||
# Authors provide their approval implicitly, this approval allows for a reviewer
|
|
||||||
# from a group not to need a review specifically for an area of the repository
|
|
||||||
# they own. This is coupled with the `required-minimum-review` group which requires
|
|
||||||
# that all PRs are reviewed by at least one team member who is not the author of
|
|
||||||
# the PR.
|
|
||||||
author_value: 1
|
|
||||||
|
|
||||||
# turn on 'draft' support
|
# turn on 'draft' support
|
||||||
# https://docs.pullapprove.com/config/github-api-version/
|
# https://docs.pullapprove.com/config/github-api-version/
|
||||||
@ -115,54 +121,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
|
||||||
#
|
#
|
||||||
@ -203,7 +161,6 @@ groups:
|
|||||||
# Framework: Animations
|
# Framework: Animations
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-animations:
|
fw-animations:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -221,16 +178,13 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- crisbeto
|
- matsko
|
||||||
- IgorMinar
|
|
||||||
- jelbourn
|
|
||||||
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Framework: Compiler
|
# Framework: Compiler
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-compiler:
|
fw-compiler:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -249,13 +203,13 @@ groups:
|
|||||||
- alxhub
|
- alxhub
|
||||||
- AndrewKushnir
|
- AndrewKushnir
|
||||||
- JoostK
|
- JoostK
|
||||||
|
- kara
|
||||||
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Framework: Compiler / ngcc
|
# Framework: Compiler / ngcc
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-ngcc:
|
fw-ngcc:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -272,7 +226,6 @@ groups:
|
|||||||
# Framework: Migrations
|
# Framework: Migrations
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-migrations:
|
fw-migrations:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -282,13 +235,13 @@ groups:
|
|||||||
- alxhub
|
- alxhub
|
||||||
- crisbeto
|
- crisbeto
|
||||||
- devversion
|
- devversion
|
||||||
|
- kara
|
||||||
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Framework: Core
|
# Framework: Core
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-core:
|
fw-core:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -362,38 +315,26 @@ groups:
|
|||||||
'aio/content/guide/ngmodule-vs-jsmodule.md',
|
'aio/content/guide/ngmodule-vs-jsmodule.md',
|
||||||
'aio/content/guide/module-types.md',
|
'aio/content/guide/module-types.md',
|
||||||
'aio/content/guide/template-syntax.md',
|
'aio/content/guide/template-syntax.md',
|
||||||
'aio/content/guide/built-in-template-functions.md',
|
|
||||||
'aio/content/examples/built-in-template-functions/**',
|
'aio/content/examples/built-in-template-functions/**',
|
||||||
'aio/content/guide/event-binding.md',
|
|
||||||
'aio/content/examples/event-binding/**',
|
'aio/content/examples/event-binding/**',
|
||||||
'aio/content/guide/interpolation.md',
|
|
||||||
'aio/content/examples/interpolation/**',
|
'aio/content/examples/interpolation/**',
|
||||||
'aio/content/examples/template-syntax/**',
|
'aio/content/examples/template-syntax/**',
|
||||||
'aio/content/images/guide/template-syntax/**',
|
'aio/content/images/guide/template-syntax/**',
|
||||||
'aio/content/guide/binding-syntax.md',
|
|
||||||
'aio/content/examples/binding-syntax/**',
|
'aio/content/examples/binding-syntax/**',
|
||||||
'aio/content/guide/property-binding.md',
|
|
||||||
'aio/content/examples/property-binding/**',
|
'aio/content/examples/property-binding/**',
|
||||||
'aio/content/guide/attribute-binding.md',
|
|
||||||
'aio/content/examples/attribute-binding/**',
|
'aio/content/examples/attribute-binding/**',
|
||||||
'aio/content/guide/two-way-binding.md',
|
|
||||||
'aio/content/examples/two-way-binding/**',
|
'aio/content/examples/two-way-binding/**',
|
||||||
'aio/content/guide/built-in-directives.md',
|
|
||||||
'aio/content/examples/built-in-directives/**',
|
'aio/content/examples/built-in-directives/**',
|
||||||
'aio/content/images/guide/built-in-directives/**',
|
'aio/content/images/guide/built-in-directives/**',
|
||||||
'aio/content/guide/template-reference-variables.md',
|
|
||||||
'aio/content/examples/template-reference-variables/**',
|
'aio/content/examples/template-reference-variables/**',
|
||||||
'aio/content/guide/inputs-outputs.md',
|
|
||||||
'aio/content/examples/inputs-outputs/**',
|
'aio/content/examples/inputs-outputs/**',
|
||||||
'aio/content/images/guide/inputs-outputs/**',
|
'aio/content/images/guide/inputs-outputs/**',
|
||||||
'aio/content/guide/template-expression-operators.md',
|
|
||||||
'aio/content/examples/template-expression-operators/**',
|
'aio/content/examples/template-expression-operators/**',
|
||||||
'aio/content/guide/pipes.md',
|
'aio/content/guide/pipes.md',
|
||||||
'aio/content/examples/pipes/**',
|
'aio/content/examples/pipes/**',
|
||||||
'aio/content/images/guide/pipes/**',
|
'aio/content/images/guide/pipes/**',
|
||||||
'aio/content/guide/providers.md',
|
'aio/content/guide/providers.md',
|
||||||
'aio/content/examples/providers/**',
|
'aio/content/examples/providers/**',
|
||||||
'aio/content/images/guide/providers/**',
|
|
||||||
'aio/content/guide/singleton-services.md',
|
'aio/content/guide/singleton-services.md',
|
||||||
'aio/content/guide/set-document-title.md',
|
'aio/content/guide/set-document-title.md',
|
||||||
'aio/content/examples/set-document-title/**',
|
'aio/content/examples/set-document-title/**',
|
||||||
@ -401,9 +342,7 @@ groups:
|
|||||||
'aio/content/guide/sharing-ngmodules.md',
|
'aio/content/guide/sharing-ngmodules.md',
|
||||||
'aio/content/guide/structural-directives.md',
|
'aio/content/guide/structural-directives.md',
|
||||||
'aio/content/examples/structural-directives/**',
|
'aio/content/examples/structural-directives/**',
|
||||||
'aio/content/guide/svg-in-templates.md',
|
|
||||||
'aio/content/images/guide/structural-directives/**',
|
'aio/content/images/guide/structural-directives/**',
|
||||||
'aio/content/guide/template-statements.md',
|
|
||||||
'aio/content/guide/user-input.md',
|
'aio/content/guide/user-input.md',
|
||||||
'aio/content/examples/user-input/**',
|
'aio/content/examples/user-input/**',
|
||||||
'aio/content/images/guide/user-input/**'
|
'aio/content/images/guide/user-input/**'
|
||||||
@ -413,7 +352,7 @@ groups:
|
|||||||
- alxhub
|
- alxhub
|
||||||
- AndrewKushnir
|
- AndrewKushnir
|
||||||
- atscott
|
- atscott
|
||||||
- ~kara # do not request reviews from Kara, but allow her to approve PRs
|
- kara
|
||||||
- mhevery
|
- mhevery
|
||||||
- pkozlowski-opensource
|
- pkozlowski-opensource
|
||||||
|
|
||||||
@ -422,13 +361,13 @@ groups:
|
|||||||
# Framework: Http
|
# Framework: Http
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-http:
|
fw-http:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
'packages/common/http/**',
|
'packages/common/http/**',
|
||||||
|
'packages/http/**',
|
||||||
'packages/examples/http/**',
|
'packages/examples/http/**',
|
||||||
'aio/content/guide/http.md',
|
'aio/content/guide/http.md',
|
||||||
'aio/content/examples/http/**',
|
'aio/content/examples/http/**',
|
||||||
@ -444,7 +383,6 @@ groups:
|
|||||||
# Framework: Elements
|
# Framework: Elements
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-elements:
|
fw-elements:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -465,7 +403,6 @@ groups:
|
|||||||
# Framework: Forms
|
# Framework: Forms
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-forms:
|
fw-forms:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -498,7 +435,6 @@ groups:
|
|||||||
# Framework: i18n
|
# Framework: i18n
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-i18n:
|
fw-i18n:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -532,7 +468,6 @@ groups:
|
|||||||
# Framework: Platform Server
|
# Framework: Platform Server
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-platform-server:
|
fw-platform-server:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -552,7 +487,6 @@ groups:
|
|||||||
# Framework: Router
|
# Framework: Router
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-router:
|
fw-router:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -561,9 +495,6 @@ groups:
|
|||||||
'packages/router/**',
|
'packages/router/**',
|
||||||
'packages/examples/router/**',
|
'packages/examples/router/**',
|
||||||
'aio/content/guide/router.md',
|
'aio/content/guide/router.md',
|
||||||
'aio/content/guide/router-tutorial.md',
|
|
||||||
'aio/content/guide/router-tutorial-toh.md',
|
|
||||||
'aio/content/examples/router-tutorial/**',
|
|
||||||
'aio/content/examples/router/**',
|
'aio/content/examples/router/**',
|
||||||
'aio/content/images/guide/router/**'
|
'aio/content/images/guide/router/**'
|
||||||
])
|
])
|
||||||
@ -576,7 +507,6 @@ groups:
|
|||||||
# Framework: Service Worker
|
# Framework: Service Worker
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-service-worker:
|
fw-service-worker:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -604,7 +534,6 @@ groups:
|
|||||||
# Framework: Upgrade
|
# Framework: Upgrade
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-upgrade:
|
fw-upgrade:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -635,7 +564,6 @@ groups:
|
|||||||
# Framework: Testing
|
# Framework: Testing
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-testing:
|
fw-testing:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -643,14 +571,6 @@ groups:
|
|||||||
contains_any_globs(files.exclude('packages/compiler-cli/**'), [
|
contains_any_globs(files.exclude('packages/compiler-cli/**'), [
|
||||||
'**/testing/**',
|
'**/testing/**',
|
||||||
'aio/content/guide/testing.md',
|
'aio/content/guide/testing.md',
|
||||||
'aio/content/guide/test-debugging.md',
|
|
||||||
'aio/content/guide/testing-attribute-directives.md',
|
|
||||||
'aio/content/guide/testing-code-coverage.md',
|
|
||||||
'aio/content/guide/testing-components-basics.md',
|
|
||||||
'aio/content/guide/testing-components-scenarios.md',
|
|
||||||
'aio/content/guide/testing-pipes.md',
|
|
||||||
'aio/content/guide/testing-services.md',
|
|
||||||
'aio/content/guide/testing-utility-apis.md',
|
|
||||||
'aio/content/examples/testing/**',
|
'aio/content/examples/testing/**',
|
||||||
'aio/content/images/guide/testing/**'
|
'aio/content/images/guide/testing/**'
|
||||||
])
|
])
|
||||||
@ -658,6 +578,7 @@ groups:
|
|||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
- AndrewKushnir
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
|
- kara
|
||||||
- pkozlowski-opensource
|
- pkozlowski-opensource
|
||||||
|
|
||||||
|
|
||||||
@ -665,7 +586,6 @@ groups:
|
|||||||
# Framework: Benchmarks
|
# Framework: Benchmarks
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-benchmarks:
|
fw-benchmarks:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- >
|
- >
|
||||||
@ -675,6 +595,7 @@ groups:
|
|||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
|
- kara
|
||||||
- pkozlowski-opensource
|
- pkozlowski-opensource
|
||||||
|
|
||||||
|
|
||||||
@ -682,7 +603,6 @@ groups:
|
|||||||
# Framework: Playground
|
# Framework: Playground
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-playground:
|
fw-playground:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- >
|
- >
|
||||||
@ -692,15 +612,13 @@ groups:
|
|||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- jelbourn
|
- kara
|
||||||
- pkozlowski-opensource
|
|
||||||
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Framework: Security
|
# Framework: Security
|
||||||
# =========================================================
|
# =========================================================
|
||||||
fw-security:
|
fw-security:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -718,25 +636,18 @@ groups:
|
|||||||
users:
|
users:
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- mhevery
|
- mhevery
|
||||||
- jelbourn
|
|
||||||
- pkozlowski-opensource
|
|
||||||
reviews:
|
|
||||||
request: -1 # request reviews from everyone
|
|
||||||
required: 2 # require at least 2 approvals
|
|
||||||
reviewed_for: required
|
|
||||||
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Bazel
|
# Bazel
|
||||||
# =========================================================
|
# =========================================================
|
||||||
bazel:
|
bazel:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
'packages/bazel/**',
|
'packages/bazel/**',
|
||||||
|
'aio/content/guide/bazel.md'
|
||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
@ -749,7 +660,6 @@ groups:
|
|||||||
# Language Service
|
# Language Service
|
||||||
# =========================================================
|
# =========================================================
|
||||||
language-service:
|
language-service:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -769,7 +679,6 @@ groups:
|
|||||||
# zone.js
|
# zone.js
|
||||||
# =========================================================
|
# =========================================================
|
||||||
zone-js:
|
zone-js:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -788,7 +697,6 @@ groups:
|
|||||||
# Benchpress
|
# Benchpress
|
||||||
# =========================================================
|
# =========================================================
|
||||||
benchpress:
|
benchpress:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -799,14 +707,12 @@ groups:
|
|||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- alxhub
|
- alxhub
|
||||||
- josephperrott
|
|
||||||
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Integration Tests
|
# Integration Tests
|
||||||
# =========================================================
|
# =========================================================
|
||||||
integration-tests:
|
integration-tests:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- >
|
- >
|
||||||
@ -817,6 +723,7 @@ groups:
|
|||||||
users:
|
users:
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- josephperrott
|
- josephperrott
|
||||||
|
- kara
|
||||||
- mhevery
|
- mhevery
|
||||||
|
|
||||||
|
|
||||||
@ -824,7 +731,6 @@ groups:
|
|||||||
# Docs: Gettings Started & Tutorial
|
# Docs: Gettings Started & Tutorial
|
||||||
# =========================================================
|
# =========================================================
|
||||||
docs-getting-started-and-tutorial:
|
docs-getting-started-and-tutorial:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -857,7 +763,6 @@ groups:
|
|||||||
# Docs: Marketing
|
# Docs: Marketing
|
||||||
# =========================================================
|
# =========================================================
|
||||||
docs-marketing:
|
docs-marketing:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -880,7 +785,6 @@ groups:
|
|||||||
# Docs: Observables
|
# Docs: Observables
|
||||||
# =========================================================
|
# =========================================================
|
||||||
docs-observables:
|
docs-observables:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -906,7 +810,6 @@ groups:
|
|||||||
# Docs: Packaging, Tooling, Releasing
|
# Docs: Packaging, Tooling, Releasing
|
||||||
# =========================================================
|
# =========================================================
|
||||||
docs-packaging-and-releasing:
|
docs-packaging-and-releasing:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -926,47 +829,20 @@ groups:
|
|||||||
'aio/content/guide/migration-localize.md',
|
'aio/content/guide/migration-localize.md',
|
||||||
'aio/content/guide/migration-module-with-providers.md',
|
'aio/content/guide/migration-module-with-providers.md',
|
||||||
'aio/content/guide/static-query-migration.md',
|
'aio/content/guide/static-query-migration.md',
|
||||||
'aio/content/guide/updating-to-version-10.md',
|
'aio/content/guide/updating-to-version-9.md',
|
||||||
'aio/content/guide/ivy-compatibility.md',
|
'aio/content/guide/ivy-compatibility.md',
|
||||||
'aio/content/guide/ivy-compatibility-examples.md'
|
'aio/content/guide/ivy-compatibility-examples.md'
|
||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- jelbourn
|
- kara
|
||||||
|
|
||||||
|
|
||||||
# =========================================================
|
|
||||||
# Tooling: Compiler API shared with Angular CLI
|
|
||||||
#
|
|
||||||
# Changing this API might break Angular CLI, so we require
|
|
||||||
# the CLI team to approve changes here.
|
|
||||||
# =========================================================
|
|
||||||
tooling-cli-shared-api:
|
|
||||||
conditions:
|
|
||||||
- *can-be-global-approved
|
|
||||||
- *can-be-global-docs-approved
|
|
||||||
- >
|
|
||||||
contains_any_globs(files, [
|
|
||||||
'packages/compiler-cli/src/tooling.ts'
|
|
||||||
])
|
|
||||||
reviewers:
|
|
||||||
users:
|
|
||||||
- alan-agius4
|
|
||||||
- clydin
|
|
||||||
- kyliau
|
|
||||||
- IgorMinar
|
|
||||||
reviews:
|
|
||||||
request: -1 # request reviews from everyone
|
|
||||||
required: 2 # require at least 2 approvals
|
|
||||||
reviewed_for: required
|
|
||||||
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Docs: CLI
|
# Docs: CLI
|
||||||
# =========================================================
|
# =========================================================
|
||||||
docs-cli:
|
docs-cli:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -983,12 +859,8 @@ groups:
|
|||||||
'aio/content/images/guide/deployment/**',
|
'aio/content/images/guide/deployment/**',
|
||||||
'aio/content/guide/file-structure.md',
|
'aio/content/guide/file-structure.md',
|
||||||
'aio/content/guide/ivy.md',
|
'aio/content/guide/ivy.md',
|
||||||
'aio/content/guide/strict-mode.md',
|
|
||||||
'aio/content/guide/web-worker.md',
|
'aio/content/guide/web-worker.md',
|
||||||
'aio/content/guide/workspace-config.md',
|
'aio/content/guide/workspace-config.md',
|
||||||
'aio/content/guide/migration-solution-style-tsconfig.md',
|
|
||||||
'aio/content/guide/migration-update-module-and-target-compiler-options.md',
|
|
||||||
'aio/content/guide/migration-update-libraries-tslib.md',
|
|
||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
@ -1001,7 +873,6 @@ groups:
|
|||||||
# Docs: CLI Libraries
|
# Docs: CLI Libraries
|
||||||
# =========================================================
|
# =========================================================
|
||||||
docs-libraries:
|
docs-libraries:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -1022,7 +893,6 @@ groups:
|
|||||||
# Docs: Schematics
|
# Docs: Schematics
|
||||||
# =========================================================
|
# =========================================================
|
||||||
docs-schematics:
|
docs-schematics:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -1045,7 +915,6 @@ groups:
|
|||||||
# Docs-infra
|
# Docs-infra
|
||||||
# =========================================================
|
# =========================================================
|
||||||
docs-infra:
|
docs-infra:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
@ -1075,16 +944,14 @@ groups:
|
|||||||
# Dev-infra
|
# Dev-infra
|
||||||
# =========================================================
|
# =========================================================
|
||||||
dev-infra:
|
dev-infra:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- >
|
- >
|
||||||
contains_any_globs(files.exclude("CHANGELOG.md").exclude("packages/compiler-cli/**/BUILD.bazel"), [
|
contains_any_globs(files.exclude("CHANGELOG.md"), [
|
||||||
'*',
|
'*',
|
||||||
'.circleci/**',
|
'.circleci/**',
|
||||||
'.devcontainer/**',
|
'.devcontainer/**',
|
||||||
'.github/**',
|
'.github/**',
|
||||||
'.ng-dev/**',
|
|
||||||
'.vscode/**',
|
'.vscode/**',
|
||||||
'.yarn/**',
|
'.yarn/**',
|
||||||
'dev-infra/**',
|
'dev-infra/**',
|
||||||
@ -1100,6 +967,8 @@ groups:
|
|||||||
'docs/TOOLS.md',
|
'docs/TOOLS.md',
|
||||||
'docs/TRIAGE_AND_LABELS.md',
|
'docs/TRIAGE_AND_LABELS.md',
|
||||||
'goldens/*',
|
'goldens/*',
|
||||||
|
'modules/e2e_util/e2e_util.ts',
|
||||||
|
'modules/e2e_util/perf_util.ts',
|
||||||
'modules/*',
|
'modules/*',
|
||||||
'packages/*',
|
'packages/*',
|
||||||
'packages/examples/test-utils/**',
|
'packages/examples/test-utils/**',
|
||||||
@ -1107,10 +976,15 @@ groups:
|
|||||||
'packages/examples/*',
|
'packages/examples/*',
|
||||||
'scripts/**',
|
'scripts/**',
|
||||||
'third_party/**',
|
'third_party/**',
|
||||||
|
'tools/brotli-cli/**',
|
||||||
|
'tools/browsers/**',
|
||||||
'tools/build/**',
|
'tools/build/**',
|
||||||
'tools/circular_dependency_test/**',
|
'tools/circular_dependency_test/**',
|
||||||
'tools/contributing-stats/**',
|
'tools/contributing-stats/**',
|
||||||
|
'tools/components/**',
|
||||||
'tools/gulp-tasks/**',
|
'tools/gulp-tasks/**',
|
||||||
|
'tools/ng_rollup_bundle/**',
|
||||||
|
'tools/ngcontainer/**',
|
||||||
'tools/npm/**',
|
'tools/npm/**',
|
||||||
'tools/npm_integration_test/**',
|
'tools/npm_integration_test/**',
|
||||||
'tools/rxjs/**',
|
'tools/rxjs/**',
|
||||||
@ -1140,10 +1014,7 @@ groups:
|
|||||||
# Public API
|
# Public API
|
||||||
# =========================================================
|
# =========================================================
|
||||||
public-api:
|
public-api:
|
||||||
<<: *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, [
|
||||||
@ -1157,27 +1028,15 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- alxhub
|
- kara
|
||||||
- atscott
|
|
||||||
- jelbourn
|
|
||||||
- petebacondarwin
|
|
||||||
- pkozlowski-opensource
|
|
||||||
reviews:
|
|
||||||
request: 4 # Request reviews from four people
|
|
||||||
required: 3 # Require that three people approve
|
|
||||||
reviewed_for: required
|
|
||||||
|
|
||||||
|
|
||||||
# ================================================
|
# ================================================
|
||||||
# Size tracking
|
# Size tracking
|
||||||
# ================================================
|
# ================================================
|
||||||
size-tracking:
|
size-tracking:
|
||||||
<<: *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, [
|
||||||
@ -1185,27 +1044,15 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- alxhub
|
- kara
|
||||||
- atscott
|
|
||||||
- jelbourn
|
|
||||||
- petebacondarwin
|
|
||||||
- pkozlowski-opensource
|
|
||||||
reviews:
|
|
||||||
request: 4 # Request reviews from four people
|
|
||||||
required: 2 # Require that two people approve
|
|
||||||
reviewed_for: required
|
|
||||||
|
|
||||||
|
|
||||||
# ================================================
|
# ================================================
|
||||||
# Circular dependencies
|
# Circular dependencies
|
||||||
# ================================================
|
# ================================================
|
||||||
circular-dependencies:
|
circular-dependencies:
|
||||||
<<: *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, [
|
||||||
@ -1213,13 +1060,9 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- alxhub
|
- josephperrott
|
||||||
- atscott
|
- kara
|
||||||
- jelbourn
|
|
||||||
- petebacondarwin
|
|
||||||
- pkozlowski-opensource
|
|
||||||
|
|
||||||
|
|
||||||
####################################################################################
|
####################################################################################
|
||||||
@ -1230,7 +1073,6 @@ groups:
|
|||||||
# Code Ownership
|
# Code Ownership
|
||||||
# =========================================================
|
# =========================================================
|
||||||
code-ownership:
|
code-ownership:
|
||||||
<<: *defaults
|
|
||||||
conditions:
|
conditions:
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- >
|
- >
|
||||||
@ -1239,43 +1081,19 @@ groups:
|
|||||||
])
|
])
|
||||||
reviewers:
|
reviewers:
|
||||||
users:
|
users:
|
||||||
- AndrewKushnir
|
|
||||||
- IgorMinar
|
- IgorMinar
|
||||||
- alxhub
|
|
||||||
- atscott
|
|
||||||
- jelbourn
|
|
||||||
- josephperrott
|
|
||||||
- mhevery
|
|
||||||
|
|
||||||
|
|
||||||
# ====================================================
|
# ====================================================
|
||||||
# Catch all for if no groups match the code change
|
# Catch all for if no groups match the code change
|
||||||
# ====================================================
|
# ====================================================
|
||||||
fallback:
|
fallback:
|
||||||
<<: *defaults
|
|
||||||
# A group is considered to be `active` for a PR if at least one of group's
|
|
||||||
# conditions matches the PR.
|
|
||||||
#
|
|
||||||
# The PullApprove CI check should fail if a PR has no `active` groups, as
|
|
||||||
# this indicates the PR is modifying a file that has no owner.
|
|
||||||
#
|
|
||||||
# This is enforced through the pullapprove verification check done
|
|
||||||
# as part of the CircleCI lint job. Failures in this lint job should be
|
|
||||||
# fixed as part of the PR. This can be done by updating the
|
|
||||||
# `.pullapprove.yml` file cover the unmatched path.
|
|
||||||
# The pullapprove verification script is part of the ng-dev tool and can be
|
|
||||||
# run locally with the command: `yarn -s ng-dev pullapprove verify`
|
|
||||||
#
|
|
||||||
# For cases in which the verification check fails to ensure coverage, this
|
|
||||||
# group will be active. The expectation is that this should be remedied
|
|
||||||
# before merging the PR as described above. In an emergency situation
|
|
||||||
# `global-approvers` can still approve PRs that match this `fallback` rule,
|
|
||||||
# but that should be an exception and not an expectation.
|
|
||||||
conditions:
|
conditions:
|
||||||
- *no-groups-above-this-active
|
|
||||||
# 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
|
|
||||||
# approval has been provided. To ensure we don't activate the fallback group in such cases,
|
|
||||||
# ensure that no explicit global approval has been provided.
|
|
||||||
- *can-be-global-approved
|
- *can-be-global-approved
|
||||||
- *can-be-global-docs-approved
|
# Groups which are found to have matching conditions are `active`
|
||||||
|
# according to PullApprove. If no groups are matched and considered
|
||||||
|
# active, we still want to have a review occur.
|
||||||
|
- len(groups.active) == 0
|
||||||
|
reviewers:
|
||||||
|
users:
|
||||||
|
- IgorMinar
|
||||||
|
1
.vscode/recommended-settings.json
vendored
1
.vscode/recommended-settings.json
vendored
@ -26,7 +26,6 @@
|
|||||||
"**/bazel-out": true,
|
"**/bazel-out": true,
|
||||||
"**/dist": true,
|
"**/dist": true,
|
||||||
"**/aio/src/generated": true,
|
"**/aio/src/generated": true,
|
||||||
".history": true,
|
|
||||||
},
|
},
|
||||||
"git.ignoreLimitWarning": true,
|
"git.ignoreLimitWarning": true,
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package(default_visibility = ["//visibility:public"])
|
|||||||
|
|
||||||
exports_files([
|
exports_files([
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
|
"protractor-perf.conf.js",
|
||||||
"karma-js.conf.js",
|
"karma-js.conf.js",
|
||||||
"browser-providers.conf.js",
|
"browser-providers.conf.js",
|
||||||
"scripts/ci/track-payload-size.sh",
|
"scripts/ci/track-payload-size.sh",
|
||||||
@ -24,7 +25,7 @@ filegroup(
|
|||||||
"//packages/zone.js/dist:zone-testing.js",
|
"//packages/zone.js/dist:zone-testing.js",
|
||||||
"//packages/zone.js/dist:task-tracking.js",
|
"//packages/zone.js/dist:task-tracking.js",
|
||||||
"//:test-events.js",
|
"//:test-events.js",
|
||||||
"//:third_party/shims_for_IE.js",
|
"//: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.
|
||||||
"@npm//:node_modules/systemjs/dist/system.src.js",
|
"@npm//:node_modules/systemjs/dist/system.src.js",
|
||||||
"@npm//:node_modules/reflect-metadata/Reflect.js",
|
"@npm//:node_modules/reflect-metadata/Reflect.js",
|
||||||
|
535
CHANGELOG.md
535
CHANGELOG.md
@ -1,447 +1,33 @@
|
|||||||
<a name="10.0.8"></a>
|
<a name="9.1.12"></a>
|
||||||
## 10.0.8 (2020-08-04)
|
## [9.1.12](https://github.com/angular/angular/compare/9.1.11...9.1.12) (2020-07-08)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### 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))
|
* **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)
|
||||||
* **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>
|
<a name="9.1.11"></a>
|
||||||
## 10.0.7 (2020-07-30)
|
## [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
|
### 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))
|
* **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//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//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//github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts/issues/L158) [#36141](https://github.com/angular/angular/issues/36141)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<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>
|
|
||||||
## 10.0.4 (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)) ([b76a2dc](https://github.com/angular/angular/commit/b76a2dc))
|
|
||||||
* **compiler:** check more cases for pipe usage inside host bindings ([#37883](https://github.com/angular/angular/issues/37883)) ([a94383f](https://github.com/angular/angular/commit/a94383f)), closes [#34655](https://github.com/angular/angular/issues/34655) [#37610](https://github.com/angular/angular/issues/37610)
|
|
||||||
* **language-service:** non-existent module format in package output ([#37778](https://github.com/angular/angular/issues/37778)) ([12f1773](https://github.com/angular/angular/commit/12f1773))
|
|
||||||
* **language-service:** remove completion for string ([#37983](https://github.com/angular/angular/issues/37983)) ([387e838](https://github.com/angular/angular/commit/387e838))
|
|
||||||
* **ngcc:** report a warning if ngcc tries to use a solution-style tsconfig ([#38003](https://github.com/angular/angular/issues/38003)) ([e3b8010](https://github.com/angular/angular/commit/e3b8010)), closes [#36386](https://github.com/angular/angular/issues/36386)
|
|
||||||
* **service-worker:** correctly handle relative base href ([#37922](https://github.com/angular/angular/issues/37922)) ([b186db7](https://github.com/angular/angular/commit/b186db7)), 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)) ([dc42c97](https://github.com/angular/angular/commit/dc42c97)), closes [#30505](https://github.com/angular/angular/issues/30505)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **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.0.3"></a>
|
|
||||||
## 10.0.3 (2020-07-08)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **core:** handle spaces after `select` and `plural` ICU keywords ([#37866](https://github.com/angular/angular/issues/37866)) ([790bb94](https://github.com/angular/angular/commit/790bb94))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.2"></a>
|
|
||||||
## [10.0.2](https://github.com/angular/angular/compare/10.0.1...10.0.2) (2020-06-30)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **core:** determine required DOMParser feature availability ([#36578](https://github.com/angular/angular/issues/36578)) ([#37783](https://github.com/angular/angular/issues/37783)) ([12a71bc](https://github.com/angular/angular/commit/12a71bc))
|
|
||||||
* **core:** do not trigger CSP alert/report in Firefox and Chrome ([#36578](https://github.com/angular/angular/issues/36578)) ([#37783](https://github.com/angular/angular/issues/37783)) ([b0b7248](https://github.com/angular/angular/commit/b0b7248)), closes [#25214](https://github.com/angular/angular/issues/25214)
|
|
||||||
* **core:** don't consider inherited NG_ELEMENT_ID during DI ([#37574](https://github.com/angular/angular/issues/37574)) ([64b0ae9](https://github.com/angular/angular/commit/64b0ae9)), closes [#36235](https://github.com/angular/angular/issues/36235)
|
|
||||||
* **core:** error when invoking callbacks registered via ViewRef.onDestroy ([#37543](https://github.com/angular/angular/issues/37543)) ([75b119e](https://github.com/angular/angular/commit/75b119e)), closes [#36213](https://github.com/angular/angular/issues/36213)
|
|
||||||
* **core:** error when invoking callbacks registered via ViewRef.onDestroy ([#37543](https://github.com/angular/angular/issues/37543)) ([#37783](https://github.com/angular/angular/issues/37783)) ([df2cd37](https://github.com/angular/angular/commit/df2cd37)), closes [#36213](https://github.com/angular/angular/issues/36213)
|
|
||||||
* **core:** fake_async_fallback should have the same logic with fake-async ([#37680](https://github.com/angular/angular/issues/37680)) ([7a91b23](https://github.com/angular/angular/commit/7a91b23))
|
|
||||||
* **elements:** fire custom element output events during component initialization ([#37570](https://github.com/angular/angular/issues/37570)) ([89e16ed](https://github.com/angular/angular/commit/89e16ed)), closes [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L167-L170](https://github.com//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//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//github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts/issues/L158) [#36141](https://github.com/angular/angular/issues/36141)
|
|
||||||
* **language-service:** incorrect autocomplete results on unknown symbol ([#37518](https://github.com/angular/angular/issues/37518)) ([7c0b25f](https://github.com/angular/angular/commit/7c0b25f))
|
|
||||||
* **ngcc:** ensure lockfile is removed when analyzeFn fails ([#37739](https://github.com/angular/angular/issues/37739)) ([1a1f99a](https://github.com/angular/angular/commit/1a1f99a))
|
|
||||||
* **ngcc:** prevent including JavaScript sources outside of the package ([#37596](https://github.com/angular/angular/issues/37596)) ([4b90b6a](https://github.com/angular/angular/commit/4b90b6a)), closes [#37508](https://github.com/angular/angular/issues/37508)
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
||||||
* **compiler-cli:** fix memory leak in retained incremental state ([#37835](https://github.com/angular/angular/issues/37835)) ([57a518a](https://github.com/angular/angular/commit/57a518a))
|
* **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="10.0.1"></a>
|
|
||||||
## [10.0.1](https://github.com/angular/angular/compare/10.0.0...10.0.1) (2020-06-26)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **core:** cleanup DOM elements when root view is removed ([#37600](https://github.com/angular/angular/issues/37600)) ([64f2ffa](https://github.com/angular/angular/commit/64f2ffa)), closes [#36449](https://github.com/angular/angular/issues/36449)
|
|
||||||
* **forms:** change error message ([#37643](https://github.com/angular/angular/issues/37643)) ([c5bc2e7](https://github.com/angular/angular/commit/c5bc2e7))
|
|
||||||
* **forms:** correct usage of `selectedOptions` ([#37620](https://github.com/angular/angular/issues/37620)) ([dfb58c4](https://github.com/angular/angular/commit/dfb58c4)), closes [#37433](https://github.com/angular/angular/issues/37433)
|
|
||||||
* **http:** avoid abort a request when fetch operation is completed ([#37367](https://github.com/angular/angular/issues/37367)) ([a5d5f67](https://github.com/angular/angular/commit/a5d5f67))
|
|
||||||
* **language-service:** reinstate getExternalFiles() ([#37750](https://github.com/angular/angular/issues/37750)) ([ad6680f](https://github.com/angular/angular/commit/ad6680f))
|
|
||||||
* **migrations:** do not incorrectly add todo for @Injectable or @Pipe ([#37732](https://github.com/angular/angular/issues/37732)) ([13020b9](https://github.com/angular/angular/commit/13020b9)), closes [#37726](https://github.com/angular/angular/issues/37726)
|
|
||||||
* **router:** `RouterLinkActive` should run CD when setting `isActive` ([#21411](https://github.com/angular/angular/issues/21411)) ([a8ea817](https://github.com/angular/angular/commit/a8ea817)), closes [#15943](https://github.com/angular/angular/issues/15943) [#19934](https://github.com/angular/angular/issues/19934)
|
|
||||||
* **router:** add null support for RouterLink directive ([#32616](https://github.com/angular/angular/issues/32616)) ([69948ce](https://github.com/angular/angular/commit/69948ce))
|
|
||||||
* **router:** fix error when calling ParamMap.get function ([#31599](https://github.com/angular/angular/issues/31599)) ([3190ccf](https://github.com/angular/angular/commit/3190ccf))
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
|
|
||||||
* **compiler-cli:** fix regressions in incremental program reuse ([#37690](https://github.com/angular/angular/issues/37690)) ([96b96fb](https://github.com/angular/angular/commit/96b96fb))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.0"></a>
|
|
||||||
# [10.0.0](https://github.com/angular/angular/compare/10.0.0-rc.6...10.0.0) (2020-06-24)
|
|
||||||
|
|
||||||
### Release Highlights & Update instructions
|
|
||||||
To learn about the release highlights and our CLI-powered automated update workflow for your projects please check out the [v10 release announcement](https://blog.angular.io/version-10-of-angular-now-available-78960babd41).
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **bazel:** expose explicit mapping from closure to devmode files ([#36262](https://github.com/angular/angular/issues/36262)) ([ba796bb](https://github.com/angular/angular/commit/ba796bb))
|
|
||||||
* **bazel:** simplify ng_package by dropping esm5 and fesm5 ([#36944](https://github.com/angular/angular/issues/36944)) ([9dbb30f](https://github.com/angular/angular/commit/9dbb30f))
|
|
||||||
* **compiler-cli:** report error if undecorated class with Angular features is discovered ([#36921](https://github.com/angular/angular/issues/36921)) ([4c92cf4](https://github.com/angular/angular/commit/4c92cf4))
|
|
||||||
* **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([d714b95](https://github.com/angular/angular/commit/d714b95))
|
|
||||||
* **compiler:** add dependency info and ng-content selectors to metadata ([#35695](https://github.com/angular/angular/issues/35695)) ([32ce8b1](https://github.com/angular/angular/commit/32ce8b1))
|
|
||||||
* **compiler:** add name spans for property reads and method calls ([#36826](https://github.com/angular/angular/issues/36826)) ([eb34aa5](https://github.com/angular/angular/commit/eb34aa5))
|
|
||||||
* **core** make generic mandatory for ModuleWithProviders ([#36892](https://github.com/angular/angular/issues/36892)) ([20cc3ab](https://github.com/angular/angular/commit/20cc3ab))
|
|
||||||
* **core** update to tslib 2.0 and move to direct dependencies ([#37198](https://github.com/angular/angular/pull/37198)), closes [#37188](https://github.com/angular/angular/issues/37188)
|
|
||||||
* **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([c24ad56](https://github.com/angular/angular/commit/c24ad56))
|
|
||||||
* **core:** undecorated-classes-with-decorated-fields migration should handle classes with lifecycle hooks ([#36921](https://github.com/angular/angular/issues/36921)) ([c6ecdc9](https://github.com/angular/angular/commit/c6ecdc9))
|
|
||||||
* **language-service:** Remove HTML entities autocompletion ([#37515](https://github.com/angular/angular/issues/37515)) ([67bd88b](https://github.com/angular/angular/commit/67bd88b))
|
|
||||||
* **language-service:** TS references from template items ([#37437](https://github.com/angular/angular/issues/37437)) ([bf2cb6f](https://github.com/angular/angular/commit/bf2cb6f))
|
|
||||||
* **language-service:** [ivy] Parse Angular compiler options ([#36922](https://github.com/angular/angular/issues/36922)) ([dbd0f8e](https://github.com/angular/angular/commit/dbd0f8e))
|
|
||||||
* **language-service:** [ivy] wrap ngtsc to handle typecheck files ([#36930](https://github.com/angular/angular/issues/36930)) ([1142c37](https://github.com/angular/angular/commit/1142c37))
|
|
||||||
* **localize:** support merging multiple translation files ([#36792](https://github.com/angular/angular/issues/36792)) ([72f534f](https://github.com/angular/angular/commit/72f534f))
|
|
||||||
* **ngcc:** allow async locking timeouts to be configured ([#36838](https://github.com/angular/angular/issues/36838)) ([38f805c](https://github.com/angular/angular/commit/38f805c))
|
|
||||||
* **ngcc:** implement a program-based entry-point finder ([#37075](https://github.com/angular/angular/issues/37075)) ([f3ccd29](https://github.com/angular/angular/commit/f3ccd29))
|
|
||||||
* **ngcc:** support for new APF where `module` points to esm2015 output ([#36944](https://github.com/angular/angular/issues/36944)) ([c98a4d6](https://github.com/angular/angular/commit/c98a4d6))
|
|
||||||
* **ngcc:** support marking an in-progress task as unprocessed ([#36626](https://github.com/angular/angular/issues/36626)) ([4665c35](https://github.com/angular/angular/commit/4665c35))
|
|
||||||
* **ngcc:** support reverting a file written by `FileWriter` ([#36626](https://github.com/angular/angular/issues/36626)) ([772ccf0](https://github.com/angular/angular/commit/772ccf0))
|
|
||||||
* **platform-server:** use absolute URLs from Location for HTTP ([#37071](https://github.com/angular/angular/issues/37071)) ([9edea0b](https://github.com/angular/angular/commit/9edea0b))
|
|
||||||
* **router:** allow CanLoad guard to return UrlTree ([#36610](https://github.com/angular/angular/issues/36610)) ([00e6cb1](https://github.com/angular/angular/commit/00e6cb1)), closes [#26521](https://github.com/angular/angular/issues/26521) [#28306](https://github.com/angular/angular/issues/28306)
|
|
||||||
* **service-worker:** include `CacheQueryOptions` options in ngsw-config ([#34663](https://github.com/angular/angular/issues/34663)) ([dc9f4b9](https://github.com/angular/angular/commit/dc9f4b9)), closes [#28443](https://github.com/angular/angular/issues/28443)
|
|
||||||
* **service-worker:** support timeout in `registerWhenStable` SW registration strategy ([#35870](https://github.com/angular/angular/issues/35870)) ([00efacf](https://github.com/angular/angular/commit/00efacf)), closes [#34464](https://github.com/angular/angular/issues/34464)
|
|
||||||
* **service-worker:** use `ignoreVary: true` when retrieving responses from cache ([#34663](https://github.com/angular/angular/issues/34663)) ([ee35e22](https://github.com/angular/angular/commit/ee35e22)), closes [#36638](https://github.com/angular/angular/issues/36638)
|
|
||||||
* remove TypeScript 3.6 and 3.7 support ([#36329](https://github.com/angular/angular/issues/36329)) ([fbd281c](https://github.com/angular/angular/commit/fbd281c))
|
|
||||||
* remove support for TypeScript 3.8 ([#37129](https://github.com/angular/angular/issues/37129)) ([6466fb2](https://github.com/angular/angular/commit/6466fb2))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bazel:** ng_package rule should update "package.json" of ts_library targets ([#36944](https://github.com/angular/angular/issues/36944)) ([d5293d2](https://github.com/angular/angular/commit/d5293d2))
|
|
||||||
* **common:** `locales/global/*.js` are not ES5 compliant ([#36342](https://github.com/angular/angular/issues/36342)) ([078b0be](https://github.com/angular/angular/commit/078b0be)), closes [angular/angular-cli#16394](https://github.com/angular/angular-cli/issues/16394)
|
|
||||||
* **common:** format day-periods that cross midnight ([#36611](https://github.com/angular/angular/issues/36611)) ([c6e5fc4](https://github.com/angular/angular/commit/c6e5fc4)), closes [#36566](https://github.com/angular/angular/issues/36566)
|
|
||||||
* **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([d783519](https://github.com/angular/angular/commit/d783519)), closes [#35743](https://github.com/angular/angular/issues/35743)
|
|
||||||
* **common:** prevent duplicate URL change notifications ([#37404](https://github.com/angular/angular/issues/37404)) ([fff424a](https://github.com/angular/angular/commit/fff424a))
|
|
||||||
* **common:** prevent duplicate URL change notifications ([#37459](https://github.com/angular/angular/issues/37459)) ([0864726](https://github.com/angular/angular/commit/0864726))
|
|
||||||
* **compiler-cli:** `isCaseSensitive()` returns correct value ([#36859](https://github.com/angular/angular/issues/36859)) ([fc4741f](https://github.com/angular/angular/commit/fc4741f))
|
|
||||||
* **compiler-cli:** compute the correct target output for `$localize` messages ([#36989](https://github.com/angular/angular/issues/36989)) ([4e1b5e4](https://github.com/angular/angular/commit/4e1b5e4))
|
|
||||||
* **compiler-cli:** don't try to tag non-ts files as shims ([#36987](https://github.com/angular/angular/issues/36987)) ([42d1091](https://github.com/angular/angular/commit/42d1091))
|
|
||||||
* **compiler-cli:** downlevel angular decorators to static properties ([#37382](https://github.com/angular/angular/issues/37382)) ([323651b](https://github.com/angular/angular/commit/323651b)), closes [#30586](https://github.com/angular/angular/issues/30586) [#30106](https://github.com/angular/angular/issues/30106) [#30586](https://github.com/angular/angular/issues/30586) [#30141](https://github.com/angular/angular/issues/30141)
|
|
||||||
* **compiler-cli:** ensure LogicalFileSystem handles case-sensitivity ([#36859](https://github.com/angular/angular/issues/36859)) ([53a8459](https://github.com/angular/angular/commit/53a8459))
|
|
||||||
* **compiler-cli:** ensure LogicalFileSystem maintains case in paths ([#37008](https://github.com/angular/angular/issues/37008)) ([3dfc770](https://github.com/angular/angular/commit/3dfc770)), closes [#36992](https://github.com/angular/angular/issues/36992) [#36993](https://github.com/angular/angular/issues/36993) [#37000](https://github.com/angular/angular/issues/37000)
|
|
||||||
* **compiler-cli:** ensure `MockFileSystem` handles case-sensitivity ([#36859](https://github.com/angular/angular/issues/36859)) ([26eacd4](https://github.com/angular/angular/commit/26eacd4))
|
|
||||||
* **compiler-cli:** ensure `getRootDirs()` handles case-sensitivity ([#36859](https://github.com/angular/angular/issues/36859)) ([3f3e9b7](https://github.com/angular/angular/commit/3f3e9b7))
|
|
||||||
* **compiler-cli:** fix bug tracking indirect NgModule dependencies ([#36211](https://github.com/angular/angular/issues/36211)) ([bab90a7](https://github.com/angular/angular/commit/bab90a7))
|
|
||||||
* **compiler-cli:** fix case-sensitivity issues in NgtscCompilerHost ([#36859](https://github.com/angular/angular/issues/36859)) ([0ec0ff3](https://github.com/angular/angular/commit/0ec0ff3))
|
|
||||||
* **compiler-cli:** normalize mock Windows file paths correctly ([#36859](https://github.com/angular/angular/issues/36859)) ([b682bd1](https://github.com/angular/angular/commit/b682bd1))
|
|
||||||
* **compiler-cli:** pass real source spans where they are empty ([#31805](https://github.com/angular/angular/issues/31805)) ([e893c5a](https://github.com/angular/angular/commit/e893c5a))
|
|
||||||
* **compiler-cli:** use CompilerHost to ensure canonical file paths ([#36859](https://github.com/angular/angular/issues/36859)) ([a10c126](https://github.com/angular/angular/commit/a10c126))
|
|
||||||
* **compiler-cli:** use ModuleWithProviders type if static eval fails ([#37126](https://github.com/angular/angular/issues/37126)) ([305b5a3](https://github.com/angular/angular/commit/305b5a3))
|
|
||||||
* **compiler:** avoid generating i18n attributes in plain form ([#36422](https://github.com/angular/angular/issues/36422)) ([88b0985](https://github.com/angular/angular/commit/88b0985))
|
|
||||||
* **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:** 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:** 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:** unable to resolve destructuring variable declarations ([#37497](https://github.com/angular/angular/issues/37497)) ([df10597](https://github.com/angular/angular/commit/df10597)), closes [#36917](https://github.com/angular/angular/issues/36917)
|
|
||||||
* **core:** Host classes should not be fed back into `@Input` ([#35889](https://github.com/angular/angular/issues/35889)) ([cda2530](https://github.com/angular/angular/commit/cda2530)), closes [#35383](https://github.com/angular/angular/issues/35383)
|
|
||||||
* **core:** Refresh transplanted views at insertion point only ([#35968](https://github.com/angular/angular/issues/35968)) ([1786586](https://github.com/angular/angular/commit/1786586)), closes [#35400](https://github.com/angular/angular/issues/35400) [#21324](https://github.com/angular/angular/issues/21324)
|
|
||||||
* **core:** attempt to recover from user errors during creation ([#36381](https://github.com/angular/angular/issues/36381)) ([3d82aa7](https://github.com/angular/angular/commit/3d82aa7)), closes [#31221](https://github.com/angular/angular/issues/31221)
|
|
||||||
* **core:** avoid migration error when non-existent symbol is imported ([#36367](https://github.com/angular/angular/issues/36367)) ([d43c306](https://github.com/angular/angular/commit/d43c306)), closes [#36346](https://github.com/angular/angular/issues/36346)
|
|
||||||
* **core:** correct "development mode" console message ([#36571](https://github.com/angular/angular/issues/36571)) ([8d8e419](https://github.com/angular/angular/commit/8d8e419)), closes [#36570](https://github.com/angular/angular/issues/36570)
|
|
||||||
* **core:** disable tsickle pass when producing APF packages ([#37221](https://github.com/angular/angular/issues/37221)) ([a1001f2](https://github.com/angular/angular/commit/a1001f2))
|
|
||||||
* **core:** do not use unbound attributes as inputs to structural directives ([#36441](https://github.com/angular/angular/issues/36441)) ([acf6075](https://github.com/angular/angular/commit/acf6075))
|
|
||||||
* **core:** handle empty translations correctly ([#36499](https://github.com/angular/angular/issues/36499)) ([b1f1d3f](https://github.com/angular/angular/commit/b1f1d3f)), closes [#36476](https://github.com/angular/angular/issues/36476)
|
|
||||||
* **core:** handle pluralize functions that expect a number ([#36901](https://github.com/angular/angular/issues/36901)) ([2ff4b35](https://github.com/angular/angular/commit/2ff4b35)), closes [#36888](https://github.com/angular/angular/issues/36888)
|
|
||||||
* **core:** handle synthetic props in Directive host bindings correctly ([#35568](https://github.com/angular/angular/issues/35568)) ([f27deea](https://github.com/angular/angular/commit/f27deea)), closes [#35501](https://github.com/angular/angular/issues/35501)
|
|
||||||
* **core:** infinite loop if injectable using inheritance has a custom decorator ([#37022](https://github.com/angular/angular/issues/37022)) ([bc54936](https://github.com/angular/angular/commit/bc54936)), closes [#35733](https://github.com/angular/angular/issues/35733)
|
|
||||||
* **core:** inheritance delegate ctor regex updated to work on minified code ([#36962](https://github.com/angular/angular/issues/36962)) ([ea971f7](https://github.com/angular/angular/commit/ea971f7))
|
|
||||||
* **core:** log error instead of warning for unknown properties and elements ([#36399](https://github.com/angular/angular/issues/36399)) ([9d9d46f](https://github.com/angular/angular/commit/9d9d46f)), closes [#35699](https://github.com/angular/angular/issues/35699)
|
|
||||||
* **core:** missing-injectable migration should not migrate `@NgModule` classes ([#36369](https://github.com/angular/angular/issues/36369)) ([28995db](https://github.com/angular/angular/commit/28995db)), closes [#35700](https://github.com/angular/angular/issues/35700)
|
|
||||||
* **core:** ngOnDestroy on multi providers called with incorrect context ([#35840](https://github.com/angular/angular/issues/35840)) ([95fc3d4](https://github.com/angular/angular/commit/95fc3d4)), closes [#35231](https://github.com/angular/angular/issues/35231)
|
|
||||||
* **core:** pipes injecting viewProviders when used on a component host node ([#36512](https://github.com/angular/angular/issues/36512)) ([81d23b3](https://github.com/angular/angular/commit/81d23b3)), closes [#36146](https://github.com/angular/angular/issues/36146)
|
|
||||||
* **core:** prevent unknown property check for AOT-compiled components ([#36072](https://github.com/angular/angular/issues/36072)) ([4a9f0be](https://github.com/angular/angular/commit/4a9f0be)), closes [#35945](https://github.com/angular/angular/issues/35945)
|
|
||||||
* **core:** properly get root nodes from embedded views with <ng-content> ([#36051](https://github.com/angular/angular/issues/36051)) ([e30e132](https://github.com/angular/angular/commit/e30e132)), closes [#35967](https://github.com/angular/angular/issues/35967)
|
|
||||||
* **core:** properly identify modules affected by overrides in TestBed ([#36649](https://github.com/angular/angular/issues/36649)) ([942b986](https://github.com/angular/angular/commit/942b986)), closes [#36619](https://github.com/angular/angular/issues/36619)
|
|
||||||
* **core:** reenable decorator downleveling for Angular npm packages ([#37317](https://github.com/angular/angular/issues/37317)) ([d16a7f3](https://github.com/angular/angular/commit/d16a7f3)), closes [#37221](https://github.com/angular/angular/issues/37221) [#37221](https://github.com/angular/angular/issues/37221)
|
|
||||||
* **core:** run `APP_INITIALIZER`s before accessing `LOCALE_ID` token in Ivy TestBed ([#36237](https://github.com/angular/angular/issues/36237)) ([1649743](https://github.com/angular/angular/commit/1649743)), closes [#36230](https://github.com/angular/angular/issues/36230)
|
|
||||||
* **core:** should fake a top event task when coalescing events to prevent draining microTaskQueue too early. ([#36841](https://github.com/angular/angular/issues/36841)) ([9b8eb42](https://github.com/angular/angular/commit/9b8eb42)), closes [#36839](https://github.com/angular/angular/issues/36839)
|
|
||||||
* **core:** undecorated-classes-with-decorated-fields migration does not decorate derived classes ([#35339](https://github.com/angular/angular/issues/35339)) ([32eafef](https://github.com/angular/angular/commit/32eafef)), closes [#34376](https://github.com/angular/angular/issues/34376)
|
|
||||||
* **core:** undecorated-classes-with-decorated-fields migration should avoid error if base class has no value declaration ([#36543](https://github.com/angular/angular/issues/36543)) ([ca67748](https://github.com/angular/angular/commit/ca67748)), closes [#36522](https://github.com/angular/angular/issues/36522)
|
|
||||||
* **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([0ce8ad3](https://github.com/angular/angular/commit/0ce8ad3))
|
|
||||||
* **elements:** capture input properties set before upgrading the element ([#36114](https://github.com/angular/angular/issues/36114)) ([2fc5ae5](https://github.com/angular/angular/commit/2fc5ae5)), closes [#30848](https://github.com/angular/angular/issues/30848) [#31416](https://github.com/angular/angular/issues/31416)
|
|
||||||
* **elements:** correctly handle getting/setting properties before connecting the element ([#36114](https://github.com/angular/angular/issues/36114)) ([327980b](https://github.com/angular/angular/commit/327980b)), closes [#30848](https://github.com/angular/angular/issues/30848)
|
|
||||||
* **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([9ba46d9](https://github.com/angular/angular/commit/9ba46d9))
|
|
||||||
* **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([b14ac96](https://github.com/angular/angular/commit/b14ac96)), closes [#36130](https://github.com/angular/angular/issues/36130)
|
|
||||||
* **elements:** do not break when the constructor of an Angular Element is not called ([#36114](https://github.com/angular/angular/issues/36114)) ([89b44d1](https://github.com/angular/angular/commit/89b44d1))
|
|
||||||
* **elements:** fire custom element output events during component initialization ([#36161](https://github.com/angular/angular/issues/36161)) ([e9bff5f](https://github.com/angular/angular/commit/e9bff5f)), closes [#36141](https://github.com/angular/angular/issues/36141)
|
|
||||||
* **forms:** handle numeric values properly in the validator ([#36157](https://github.com/angular/angular/issues/36157)) ([88a235d](https://github.com/angular/angular/commit/88a235d)), closes [#35591](https://github.com/angular/angular/issues/35591)
|
|
||||||
* **forms:** number input fires valueChanges twice ([#36087](https://github.com/angular/angular/issues/36087)) ([97d6d90](https://github.com/angular/angular/commit/97d6d90)), closes [#12540](https://github.com/angular/angular/issues/12540)
|
|
||||||
* **language-service:** Improve signature selection by finding exact match ([#37494](https://github.com/angular/angular/issues/37494)) ([e97a2d4](https://github.com/angular/angular/commit/e97a2d4))
|
|
||||||
* **language-service:** Recover from error in analyzing Ng Modules ([#37108](https://github.com/angular/angular/issues/37108)) ([2c1f35e](https://github.com/angular/angular/commit/2c1f35e))
|
|
||||||
* **language-service:** disable update the `[@angular](https://github.com/angular)/core` module ([#36783](https://github.com/angular/angular/issues/36783)) ([dd049ca](https://github.com/angular/angular/commit/dd049ca))
|
|
||||||
* **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([fe2b692](https://github.com/angular/angular/commit/fe2b692)), closes [#36191](https://github.com/angular/angular/issues/36191)
|
|
||||||
* **language-service:** properly evaluate types in comparable expressions ([#36529](https://github.com/angular/angular/issues/36529)) ([8be0972](https://github.com/angular/angular/commit/8be0972))
|
|
||||||
* **language-service:** use empty statement as parent of type node ([#36989](https://github.com/angular/angular/issues/36989)) ([a32cbed](https://github.com/angular/angular/commit/a32cbed))
|
|
||||||
* **language-service:** use the `HtmlAst` to get the span of HTML tag ([#36371](https://github.com/angular/angular/issues/36371)) ([81195a2](https://github.com/angular/angular/commit/81195a2))
|
|
||||||
* **language-service:** wrong completions in conditional operator ([#37505](https://github.com/angular/angular/issues/37505)) ([32020f9](https://github.com/angular/angular/commit/32020f9))
|
|
||||||
* **localize:** allow ICU expansion case to start with any character except `}` ([#36123](https://github.com/angular/angular/issues/36123)) ([fced8ee](https://github.com/angular/angular/commit/fced8ee)), closes [#31586](https://github.com/angular/angular/issues/31586)
|
|
||||||
* **localize:** ensure `getLocation()` works ([#36853](https://github.com/angular/angular/issues/36853)) ([70b25a3](https://github.com/angular/angular/commit/70b25a3))
|
|
||||||
* **localize:** include legacy ids when describing messages ([#36761](https://github.com/angular/angular/issues/36761)) ([47f9867](https://github.com/angular/angular/commit/47f9867))
|
|
||||||
* **ngcc:** `viaModule` should be `null` for local imports ([#36989](https://github.com/angular/angular/issues/36989)) ([d268d2a](https://github.com/angular/angular/commit/d268d2a))
|
|
||||||
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([76a8cd5](https://github.com/angular/angular/commit/76a8cd5)), closes [36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414#issuecomment-609644282)
|
|
||||||
* **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([326240e](https://github.com/angular/angular/commit/326240e))
|
|
||||||
* **ngcc:** capture dynamic import expressions as well as declarations ([#37075](https://github.com/angular/angular/issues/37075)) ([5c0bdae](https://github.com/angular/angular/commit/5c0bdae))
|
|
||||||
* **ngcc:** correctly detect external files from nested `node_modules/` ([#36559](https://github.com/angular/angular/issues/36559)) ([6ab43d7](https://github.com/angular/angular/commit/6ab43d7)), closes [#36526](https://github.com/angular/angular/issues/36526)
|
|
||||||
* **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([ca25c95](https://github.com/angular/angular/commit/ca25c95)), closes [#36089](https://github.com/angular/angular/issues/36089)
|
|
||||||
* **ngcc:** correctly get config for packages in nested `node_modules/` ([#37040](https://github.com/angular/angular/issues/37040)) ([9ade1c3](https://github.com/angular/angular/commit/9ade1c3))
|
|
||||||
* **ngcc:** correctly get config for sub-entry-points when primary entry-point is ignored ([#37040](https://github.com/angular/angular/issues/37040)) ([bf57776](https://github.com/angular/angular/commit/bf57776))
|
|
||||||
* **ngcc:** correctly identify relative Windows-style import paths ([#36372](https://github.com/angular/angular/issues/36372)) ([aecf9de](https://github.com/angular/angular/commit/aecf9de))
|
|
||||||
* **ngcc:** correctly identify the package path of secondary entry-points ([#36249](https://github.com/angular/angular/issues/36249)) ([995cd15](https://github.com/angular/angular/commit/995cd15)), closes [#35747](https://github.com/angular/angular/issues/35747)
|
|
||||||
* **ngcc:** correctly retrieve a package's version from its `package.json` ([#37040](https://github.com/angular/angular/issues/37040)) ([11c0402](https://github.com/angular/angular/commit/11c0402))
|
|
||||||
* **ngcc:** detect non-emitted, non-imported TypeScript helpers ([#36418](https://github.com/angular/angular/issues/36418)) ([5fa7b8b](https://github.com/angular/angular/commit/5fa7b8b))
|
|
||||||
* **ngcc:** display output from the unlocker process on Windows ([#36569](https://github.com/angular/angular/issues/36569)) ([e041ac6](https://github.com/angular/angular/commit/e041ac6))
|
|
||||||
* **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([cabf997](https://github.com/angular/angular/commit/cabf997)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596#issuecomment-250890218)
|
|
||||||
* **ngcc:** do not inline source-maps for non-inline typings source-maps ([#37363](https://github.com/angular/angular/issues/37363)) ([b4e26b5](https://github.com/angular/angular/commit/b4e26b5)), closes [#37324](https://github.com/angular/angular/issues/37324)
|
|
||||||
* **ngcc:** do not run in parallel mode if there are less than 3 CPU cores ([#36626](https://github.com/angular/angular/issues/36626)) ([4c63241](https://github.com/angular/angular/commit/4c63241))
|
|
||||||
* **ngcc:** do not scan import expressions in d.ts files ([#37503](https://github.com/angular/angular/issues/37503)) ([8248307](https://github.com/angular/angular/commit/8248307))
|
|
||||||
* **ngcc:** do not spawn more processes than intended in parallel mode ([#36280](https://github.com/angular/angular/issues/36280)) ([5cee709](https://github.com/angular/angular/commit/5cee709)), closes [#35719](https://github.com/angular/angular/issues/35719) [#36278](https://github.com/angular/angular/issues/36278)
|
|
||||||
* **ngcc:** do not spawn unlocker processes on cluster workers ([#36569](https://github.com/angular/angular/issues/36569)) ([66effde](https://github.com/angular/angular/commit/66effde)), closes [#35861](https://github.com/angular/angular/issues/35861)
|
|
||||||
* **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([0c2ed4c](https://github.com/angular/angular/commit/0c2ed4c)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860#issuecomment-614694269)
|
|
||||||
* **ngcc:** do not warn if `paths` mapping does not exist ([#36525](https://github.com/angular/angular/issues/36525)) ([717df13](https://github.com/angular/angular/commit/717df13)), closes [#36518](https://github.com/angular/angular/issues/36518)
|
|
||||||
* **ngcc:** do not write entry-point manifest outside node_modules ([#36299](https://github.com/angular/angular/issues/36299)) ([c6dd900](https://github.com/angular/angular/commit/c6dd900)), closes [#36296](https://github.com/angular/angular/issues/36296)
|
|
||||||
* **ngcc:** don't crash on cyclic source-map references ([#36452](https://github.com/angular/angular/issues/36452)) ([ee70a18](https://github.com/angular/angular/commit/ee70a18)), closes [#35727](https://github.com/angular/angular/issues/35727) [#35757](https://github.com/angular/angular/issues/35757)
|
|
||||||
* **ngcc:** ensure reflection hosts can handle TS 3.9 IIFE wrapped classes ([#36989](https://github.com/angular/angular/issues/36989)) ([d7440c4](https://github.com/angular/angular/commit/d7440c4))
|
|
||||||
* **ngcc:** ensure rendering formatters work with IIFE wrapped classes ([#36989](https://github.com/angular/angular/issues/36989)) ([c8ee390](https://github.com/angular/angular/commit/c8ee390))
|
|
||||||
* **ngcc:** ensure that more dependencies are found by `EsmDependencyHost` ([#37075](https://github.com/angular/angular/issues/37075)) ([c6872c0](https://github.com/angular/angular/commit/c6872c0))
|
|
||||||
* **ngcc:** find decorated constructor params on IIFE wrapped classes ([#37436](https://github.com/angular/angular/issues/37436)) ([2cb3b66](https://github.com/angular/angular/commit/2cb3b66)), closes [#37330](https://github.com/angular/angular/issues/37330)
|
|
||||||
* **ngcc:** force ngcc to exit on error ([#36622](https://github.com/angular/angular/issues/36622)) ([663b768](https://github.com/angular/angular/commit/663b768)), closes [#36616](https://github.com/angular/angular/issues/36616)
|
|
||||||
* **ngcc:** give up re-spawning crashed worker process after 3 attempts ([#36626](https://github.com/angular/angular/issues/36626)) ([793cb32](https://github.com/angular/angular/commit/793cb32))
|
|
||||||
* **ngcc:** handle `ENOMEM` errors in worker processes ([#36626](https://github.com/angular/angular/issues/36626)) ([4779c4b](https://github.com/angular/angular/commit/4779c4b))
|
|
||||||
* **ngcc:** handle bad path mappings when finding entry-points ([#36331](https://github.com/angular/angular/issues/36331)) ([cc4b813](https://github.com/angular/angular/commit/cc4b813)), closes [#36313](https://github.com/angular/angular/issues/36313) [#36283](https://github.com/angular/angular/issues/36283)
|
|
||||||
* **ngcc:** handle entry-points within container folders ([#36305](https://github.com/angular/angular/issues/36305)) ([38ad1d9](https://github.com/angular/angular/commit/38ad1d9)), closes [#35756](https://github.com/angular/angular/issues/35756) [#36216](https://github.com/angular/angular/issues/36216)
|
|
||||||
* **ngcc:** identifier ModuleWithProviders functions in IIFE wrapped classes ([#37206](https://github.com/angular/angular/issues/37206)) ([97e1399](https://github.com/angular/angular/commit/97e1399)), closes [#37189](https://github.com/angular/angular/issues/37189)
|
|
||||||
* **ngcc:** provide a unique exit code for timeouts ([#36838](https://github.com/angular/angular/issues/36838)) ([d805526](https://github.com/angular/angular/commit/d805526))
|
|
||||||
* **ngcc:** recognize enum declarations emitted in JavaScript ([#36550](https://github.com/angular/angular/issues/36550)) ([89c5890](https://github.com/angular/angular/commit/89c5890)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
|
||||||
* **ngcc:** sniff `main` property for ESM5 format ([#36396](https://github.com/angular/angular/issues/36396)) ([2463548](https://github.com/angular/angular/commit/2463548)), closes [#35788](https://github.com/angular/angular/issues/35788)
|
|
||||||
* **ngcc:** support ModuleWithProviders functions that delegate ([#36948](https://github.com/angular/angular/issues/36948)) ([fafa50d](https://github.com/angular/angular/commit/fafa50d)), closes [#36892](https://github.com/angular/angular/issues/36892)
|
|
||||||
* **ngcc:** support TS 3.9 wrapped ES2015 classes ([#36884](https://github.com/angular/angular/issues/36884)) ([db4c59d](https://github.com/angular/angular/commit/db4c59d))
|
|
||||||
* **ngcc:** support `defineProperty()` re-exports in CommonJS and UMD ([#36989](https://github.com/angular/angular/issues/36989)) ([91092f6](https://github.com/angular/angular/commit/91092f6))
|
|
||||||
* **ngcc:** support ignoring deep-imports via package config ([#36423](https://github.com/angular/angular/issues/36423)) ([f9fb833](https://github.com/angular/angular/commit/f9fb833)), closes [#35750](https://github.com/angular/angular/issues/35750)
|
|
||||||
* **ngcc:** support recovering when a worker process crashes ([#36626](https://github.com/angular/angular/issues/36626)) ([966598c](https://github.com/angular/angular/commit/966598c)), closes [#36278](https://github.com/angular/angular/issues/36278)
|
|
||||||
* **ngcc:** support simple `browser` property in entry-points ([#36396](https://github.com/angular/angular/issues/36396)) ([6b3aa60](https://github.com/angular/angular/commit/6b3aa60)), closes [#36062](https://github.com/angular/angular/issues/36062)
|
|
||||||
* **ngcc:** use annotateForClosureCompiler option ([#36652](https://github.com/angular/angular/issues/36652)) ([eca8d11](https://github.com/angular/angular/commit/eca8d11)), closes [#36618](https://github.com/angular/angular/issues/36618)
|
|
||||||
* **ngcc:** use path-mappings from tsconfig in dependency resolution ([#36180](https://github.com/angular/angular/issues/36180)) ([380de1e](https://github.com/angular/angular/commit/380de1e)), closes [#36119](https://github.com/angular/angular/issues/36119)
|
|
||||||
* **ngcc:** use preserve whitespaces from tsconfig if provided ([#36189](https://github.com/angular/angular/issues/36189)) ([b8e9a30](https://github.com/angular/angular/commit/b8e9a30)), closes [#35871](https://github.com/angular/angular/issues/35871)
|
|
||||||
* **platform-server:** correctly handle absolute relative URLs ([#37341](https://github.com/angular/angular/issues/37341)) ([420d1c3](https://github.com/angular/angular/commit/420d1c3)), closes [#37314](https://github.com/angular/angular/issues/37314)
|
|
||||||
* **platform-server:** update `xhr2` dependency ([#36366](https://github.com/angular/angular/issues/36366)) ([b59bc0e](https://github.com/angular/angular/commit/b59bc0e)), closes [#36358](https://github.com/angular/angular/issues/36358)
|
|
||||||
* **router:** Fix relative link generation from empty path components ([#37446](https://github.com/angular/angular/issues/37446)) ([585e3f6](https://github.com/angular/angular/commit/585e3f6)), closes [#26243](https://github.com/angular/angular/issues/26243) [#13011](https://github.com/angular/angular/issues/13011) [#35687](https://github.com/angular/angular/issues/35687)
|
|
||||||
* **router:** allow UrlMatcher to return null ([#36402](https://github.com/angular/angular/issues/36402)) ([568e9df](https://github.com/angular/angular/commit/568e9df)), closes [#29824](https://github.com/angular/angular/issues/29824)
|
|
||||||
* **router:** cancel navigation when at least one resolver completes with no "next" emission ([#24621](https://github.com/angular/angular/issues/24621)) ([d9c4840](https://github.com/angular/angular/commit/d9c4840)), closes [#24195](https://github.com/angular/angular/issues/24195)
|
|
||||||
* **router:** fix navigation ignoring logic to compare to the browser url ([#37408](https://github.com/angular/angular/issues/37408)) ([5db2e79](https://github.com/angular/angular/commit/5db2e79)), closes [#16710](https://github.com/angular/angular/issues/16710) [#13586](https://github.com/angular/angular/issues/13586)
|
|
||||||
* **router:** pass correct component to canDeactivate checks when using two or more sibling router-outlets ([#36302](https://github.com/angular/angular/issues/36302)) ([80e6c07](https://github.com/angular/angular/commit/80e6c07)), closes [#34614](https://github.com/angular/angular/issues/34614)
|
|
||||||
* **router:** state data missing in routerLink ([#36462](https://github.com/angular/angular/issues/36462)) ([e0415db](https://github.com/angular/angular/commit/e0415db)), closes [#33173](https://github.com/angular/angular/issues/33173)
|
|
||||||
* **router:** update type for routerLink to include null and undefined ([#37018](https://github.com/angular/angular/issues/37018)) ([ef9f8df](https://github.com/angular/angular/commit/ef9f8df)), closes [#13380](https://github.com/angular/angular/issues/13380) [#36544](https://github.com/angular/angular/issues/36544)
|
|
||||||
* **service-worker:** Don't stay locked in EXISTING_CLIENTS_ONLY if corrupted data ([#37453](https://github.com/angular/angular/issues/37453)) ([6f93847](https://github.com/angular/angular/commit/6f93847)), closes [#31109](https://github.com/angular/angular/issues/31109) [#31865](https://github.com/angular/angular/issues/31865)
|
|
||||||
* **service-worker:** by default register the SW after 30s even the app never stabilizes ([#35870](https://github.com/angular/angular/issues/35870)) ([29e8a64](https://github.com/angular/angular/commit/29e8a64)), closes [#34464](https://github.com/angular/angular/issues/34464)
|
|
||||||
* **service-worker:** prevent SW registration strategies from affecting app stabilization ([#35870](https://github.com/angular/angular/issues/35870)) ([2d7c95f](https://github.com/angular/angular/commit/2d7c95f))
|
|
||||||
* **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([0cc53fb](https://github.com/angular/angular/commit/0cc53fb)), closes [#36492](https://github.com/angular/angular/issues/36492)
|
|
||||||
* add aikidave as reviewer for DOCS: Marketing ([#37014](https://github.com/angular/angular/issues/37014)) ([286fbf4](https://github.com/angular/angular/commit/286fbf4))
|
|
||||||
|
|
||||||
|
|
||||||
### Code Refactoring
|
|
||||||
|
|
||||||
* **common:** remove WrappedValue from AsyncPipe ([#36633](https://github.com/angular/angular/issues/36633)) ([49be32c](https://github.com/angular/angular/commit/49be32c)), closes [#29927](https://github.com/angular/angular/issues/29927)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
|
|
||||||
* **compiler-cli:** perform template type-checking incrementally ([#36211](https://github.com/angular/angular/issues/36211)) ([ecffc35](https://github.com/angular/angular/commit/ecffc35))
|
|
||||||
* **compiler-cli:** split Ivy template type-checking into multiple files ([#36211](https://github.com/angular/angular/issues/36211)) ([b861e9c](https://github.com/angular/angular/commit/b861e9c))
|
|
||||||
* **core:** avoid pulling in jit-specific code in aot bundles ([#37372](https://github.com/angular/angular/issues/37372)) ([#37514](https://github.com/angular/angular/issues/37514)) ([6114cd2](https://github.com/angular/angular/commit/6114cd2)), closes [#29083](https://github.com/angular/angular/issues/29083)
|
|
||||||
* **forms:** optimize internal method _anyControls in FormGroup ([#32534](https://github.com/angular/angular/issues/32534)) ([6c7467a](https://github.com/angular/angular/commit/6c7467a))
|
|
||||||
* **ngcc:** allow immediately reporting a stale lock file ([#37250](https://github.com/angular/angular/issues/37250)) ([930d204](https://github.com/angular/angular/commit/930d204))
|
|
||||||
* **ngcc:** cache parsed tsconfig between runs ([#37417](https://github.com/angular/angular/issues/37417)) ([f9daa13](https://github.com/angular/angular/commit/f9daa13)), closes [#36882](https://github.com/angular/angular/issues/36882)
|
|
||||||
* **ngcc:** only compute basePaths in TargetedEntryPointFinder when needed ([#36881](https://github.com/angular/angular/issues/36881)) ([ec6b9cc](https://github.com/angular/angular/commit/ec6b9cc)), closes [#36874](https://github.com/angular/angular/issues/36874)
|
|
||||||
* **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([3bedfda](https://github.com/angular/angular/commit/3bedfda))
|
|
||||||
* **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([a185efb](https://github.com/angular/angular/commit/a185efb)), closes [#issuecomment-608401834](https://github.com/angular/angular#issuecomment-608401834)
|
|
||||||
* **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([ec0ce60](https://github.com/angular/angular/commit/ec0ce60))
|
|
||||||
* **ngcc:** speed up the `getBasePaths()` computation ([#36881](https://github.com/angular/angular/issues/36881)) ([e037840](https://github.com/angular/angular/commit/e037840))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### Dependency updates
|
|
||||||
@angular/compiler-cli now requires:
|
|
||||||
- TypeScript 3.9
|
|
||||||
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* TypeScript 3.6, 3.7 and 3.8 are no longer supported, please update to TypeScript 3.9.
|
|
||||||
* **core:** Angular npm packages no longer contain jsdoc comments
|
|
||||||
to support Closure Compiler's advanced optimizations
|
|
||||||
|
|
||||||
The support for Closure Compiler in Angular packages has been
|
|
||||||
experimental and broken for quite some time.
|
|
||||||
|
|
||||||
As of TS3.9, Closure is unusable with the JavaScript emit. Please follow
|
|
||||||
https://github.com/microsoft/TypeScript/issues/38374 for more
|
|
||||||
information and updates.
|
|
||||||
|
|
||||||
If you used Closure Compiler with Angular in the past, you will likely
|
|
||||||
be better off consuming Angular packages built from sources directly
|
|
||||||
rather than consuming the version we publish on npm,
|
|
||||||
which is primarily optimized for Webpack/Rollup + Terser build pipeline.
|
|
||||||
|
|
||||||
As a temporary workaround, you might consider using your current build
|
|
||||||
pipeline with Closure flag `--compilation_level=SIMPLE`. This flag
|
|
||||||
will ensure that your build pipeline produces buildable and
|
|
||||||
runnable artifacts, at the cost of increased payload size due to
|
|
||||||
advanced optimizations being disabled.
|
|
||||||
|
|
||||||
If you were affected by this change, please help us understand your
|
|
||||||
needs by leaving a comment on https://github.com/angular/angular/issues/37234.
|
|
||||||
|
|
||||||
* **core:** make generic mandatory for ModuleWithProviders
|
|
||||||
|
|
||||||
A generic type parameter has always been required for the `ModuleWithProviders` pattern to work with Ivy, but prior to this commit, View Engine allowed the generic type to be omitted (though support was officially deprecated).
|
|
||||||
If you're using `ModuleWithProviders` without a generic type in your application code, a v10 migration will update your code for you.
|
|
||||||
|
|
||||||
However, if you are using View Engine and also depending on a library that omits the generic type, you will now get a build time error similar to:
|
|
||||||
|
|
||||||
```
|
|
||||||
error TS2314: Generic type 'ModuleWithProviders<T>' requires 1 type argument(s).
|
|
||||||
```
|
|
||||||
|
|
||||||
In this case, ngcc won't help you (because it's Ivy-only) and the migration only covers application code.
|
|
||||||
You should contact the library author to fix their library to provide a type parameter when they use this class.
|
|
||||||
|
|
||||||
As a workaround, we suggest setting `skipLibChecks` to false in your tsconfig or updating your app to use Ivy.
|
|
||||||
|
|
||||||
* **forms:** Number inputs no longer listen to the `change` event.
|
|
||||||
|
|
||||||
Tests which trigger `change` events need to be updated to trigger `input` events instead.
|
|
||||||
|
|
||||||
The `change` event was in place to support IE9, as we found that `input` events were not fired with backspace or cut actions. If you need to maintain IE9 support, you will need to add a change event listener to number inputs and call the `onChange` method of `NumberValueAccessor` manually.
|
|
||||||
|
|
||||||
Lastly, old versions of WebDriver would synthetically trigger the `change` event on `WebElement.clear` and `WebElement.sendKeys`. If you are using an old version of WebDriver, you may need to update tests to ensure `input` events are triggered. For example, you could use `element.sendKeys(Keys.chord(Keys.CONTROL, "a"), Keys.BACK_SPACE);` in place of `element.clear()`.
|
|
||||||
* **forms:** The `minLength` and `maxLength` validators now verify that the form control's value has a
|
|
||||||
numeric `length` property, and only validate for length if that's the case.
|
|
||||||
|
|
||||||
Previously, falsey values without the length property (such as `0` or
|
|
||||||
`false` values) were triggering validation errors. If your code relies on
|
|
||||||
the old behavior, you can include other validators such as [min][1] or
|
|
||||||
[requiredTrue][2] to the list of validators for a particular field.
|
|
||||||
|
|
||||||
[1]: https://angular.io/api/forms/Validators#min
|
|
||||||
[2]: https://angular.io/api/forms/Validators#requiredTrue
|
|
||||||
* **bazel:** esm5 and fesm5 format is no longer distributed in
|
|
||||||
Angular's npm packages e.g. @angular/core
|
|
||||||
|
|
||||||
If you are not using Angular CLI to build your application or library,
|
|
||||||
and you need to be able to build es5 artifacts, then you will need to
|
|
||||||
downlevel the distributed Angular code to es5 on your own.
|
|
||||||
|
|
||||||
Angular CLI will automatically downlevel the code to es5 if differential
|
|
||||||
loading is enabled in the Angular project, so no action is required from
|
|
||||||
Angular CLI users.
|
|
||||||
|
|
||||||
* **core:** Warnings about unknown elements are now logged as errors. This won't break your app, but it may trip up tools that expect nothing to be logged via `console.error`.
|
|
||||||
* **router:** Any resolver which return EMPTY will cancel navigation.
|
|
||||||
If you want to allow the navigation to continue, you will need to update the resolvers to emit
|
|
||||||
some value, (i.e. defaultIfEmpty(...), of(...), etc).
|
|
||||||
* **service-worker:** Previously, [Vary](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary)
|
|
||||||
headers would be taken into account when retrieving resources from the
|
|
||||||
cache, completely preventing the retrieval of cached assets (due to
|
|
||||||
ServiceWorker implementation details) and leading to unpredictable
|
|
||||||
behavior due to inconsistent/buggy implementations in different
|
|
||||||
browsers.
|
|
||||||
|
|
||||||
Now, `Vary` headers are ignored when retrieving resources from the
|
|
||||||
ServiceWorker caches, which can result in resources being retrieved even
|
|
||||||
when their headers are different. If your application needs to
|
|
||||||
differentiate its responses based on request headers, please make sure
|
|
||||||
the Angular ServiceWorker is [configured](https://angular.io/guide/service-worker-config)
|
|
||||||
to avoid caching the affected resources.
|
|
||||||
* **common:** This change could result in ExpressionChangedAfterItHasBeenChecked errors that
|
|
||||||
were not detected before. The error could previously have gone undetected
|
|
||||||
because two WrappedValues are considered "equal" in all cases for the purposes
|
|
||||||
of the check, even if their respective unwrapped values are not.
|
|
||||||
|
|
||||||
Additionally, `[val]=(observable | async).someProperty` will no longer
|
|
||||||
trigger change detection if the value of `someProperty` is identical to
|
|
||||||
the value in the previous emit. If you need to force change detection,
|
|
||||||
either update the binding to use an object whose reference changes or
|
|
||||||
subscribe to the observable and call markForCheck as needed.
|
|
||||||
|
|
||||||
* **common:** format day-periods that cross midnight
|
|
||||||
|
|
||||||
When formatting a time with the `b` or `B` format codes, the rendered
|
|
||||||
string was not correctly handling day periods that spanned midnight.
|
|
||||||
Instead the logic was falling back to the default case of `AM`.
|
|
||||||
|
|
||||||
Now the logic has been updated so that it matches times that are within
|
|
||||||
a day period that spans midnight, so it will now render the correct
|
|
||||||
output, such as `at night` in the case of English.
|
|
||||||
|
|
||||||
Applications that are using either `formatDate()` or `DatePipe` and any
|
|
||||||
of the `b` or `B` format codes will be affected by this change.
|
|
||||||
|
|
||||||
* **router:** UrlMatcher's type now reflects that it could always return
|
|
||||||
null.
|
|
||||||
|
|
||||||
If you implemented your own Router or Recognizer class, please update it to
|
|
||||||
handle matcher returning null.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -453,7 +39,7 @@ This release contains a re-submit of the following 3 commits with fixes for TS 3
|
|||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **elements:** capture input properties set before upgrading the element ([#36114](https://github.com/angular/angular/issues/36114)) ([#37226](https://github.com/angular/angular/issues/37226)) ([a33cb2d](https://github.com/angular/angular/commit/a33cb2d)), closes [#30848](https://github.com/angular/angular/issues/30848) [#31416](https://github.com/angular/angular/issues/31416)
|
* **elements:** capture input properties set before upgrading the element ([#36114](https://github.com/angular/angular/issues/36114)) ([#37226](https://github.com/angular/angular/issues/37226)) ([a33cb2d](https://github.com/angular/angular/commit/a33cb2d)), closes [#30848](https://github.com/angular/angular/issues/30848) [#31416](https://github.com/angular/angular/issues/31416)
|
||||||
* **elements:** correctly handle getting/setting properties before connecting the element ([#36114](https://github.com/angular/angular/issues/36114)) ([#37226](https://github.com/angular/angular/issues/37226)) ([6ac0042](https://github.com/angular/angular/commit/6ac0042)), closes [/github.com/angular/angular/pull/31416/files#r300326698](https://github.com/angular/angular/pull/31416/files/issues/r300326698)
|
* **elements:** correctly handle getting/setting properties before connecting the element ([#36114](https://github.com/angular/angular/issues/36114)) ([#37226](https://github.com/angular/angular/issues/37226)) ([6ac0042](https://github.com/angular/angular/commit/6ac0042)), closes [/github.com/angular/angular/pull/31416/files#r300326698](https://github.com//github.com/angular/angular/pull/31416/files/issues/r300326698)
|
||||||
* **elements:** do not break when the constructor of an Angular Element is not called ([#36114](https://github.com/angular/angular/issues/36114)) ([#37226](https://github.com/angular/angular/issues/37226)) ([1465372](https://github.com/angular/angular/commit/1465372))
|
* **elements:** do not break when the constructor of an Angular Element is not called ([#36114](https://github.com/angular/angular/issues/36114)) ([#37226](https://github.com/angular/angular/issues/37226)) ([1465372](https://github.com/angular/angular/commit/1465372))
|
||||||
|
|
||||||
|
|
||||||
@ -467,7 +53,7 @@ This release contains a re-submit of the following 3 commits with fixes for TS 3
|
|||||||
* **core:** Host classes should not be fed back into `@Input` ([#35889](https://github.com/angular/angular/issues/35889)) ([f872b69](https://github.com/angular/angular/commit/f872b69)), closes [#35383](https://github.com/angular/angular/issues/35383)
|
* **core:** Host classes should not be fed back into `@Input` ([#35889](https://github.com/angular/angular/issues/35889)) ([f872b69](https://github.com/angular/angular/commit/f872b69)), closes [#35383](https://github.com/angular/angular/issues/35383)
|
||||||
* **core:** inheritance delegate ctor regex updated to work on minified code ([#36962](https://github.com/angular/angular/issues/36962)) ([e3d3395](https://github.com/angular/angular/commit/e3d3395))
|
* **core:** inheritance delegate ctor regex updated to work on minified code ([#36962](https://github.com/angular/angular/issues/36962)) ([e3d3395](https://github.com/angular/angular/commit/e3d3395))
|
||||||
* **elements:** capture input properties set before upgrading the element ([#36114](https://github.com/angular/angular/issues/36114)) ([1c8f179](https://github.com/angular/angular/commit/1c8f179)), closes [#30848](https://github.com/angular/angular/issues/30848) [#31416](https://github.com/angular/angular/issues/31416)
|
* **elements:** capture input properties set before upgrading the element ([#36114](https://github.com/angular/angular/issues/36114)) ([1c8f179](https://github.com/angular/angular/commit/1c8f179)), closes [#30848](https://github.com/angular/angular/issues/30848) [#31416](https://github.com/angular/angular/issues/31416)
|
||||||
* **elements:** correctly handle getting/setting properties before connecting the element ([#36114](https://github.com/angular/angular/issues/36114)) ([363f14c](https://github.com/angular/angular/commit/363f14c)), closes [/github.com/angular/angular/pull/31416/files#r300326698](https://github.com/angular/angular/pull/31416/files/issues/r300326698)
|
* **elements:** correctly handle getting/setting properties before connecting the element ([#36114](https://github.com/angular/angular/issues/36114)) ([363f14c](https://github.com/angular/angular/commit/363f14c)), closes [/github.com/angular/angular/pull/31416/files#r300326698](https://github.com//github.com/angular/angular/pull/31416/files/issues/r300326698)
|
||||||
* **elements:** do not break when the constructor of an Angular Element is not called ([#36114](https://github.com/angular/angular/issues/36114)) ([87b9f08](https://github.com/angular/angular/commit/87b9f08))
|
* **elements:** do not break when the constructor of an Angular Element is not called ([#36114](https://github.com/angular/angular/issues/36114)) ([87b9f08](https://github.com/angular/angular/commit/87b9f08))
|
||||||
* **router:** update type for routerLink to include null and undefined ([#37018](https://github.com/angular/angular/issues/37018)) ([7de7871](https://github.com/angular/angular/commit/7de7871)), closes [#13380](https://github.com/angular/angular/issues/13380) [#36544](https://github.com/angular/angular/issues/36544)
|
* **router:** update type for routerLink to include null and undefined ([#37018](https://github.com/angular/angular/issues/37018)) ([7de7871](https://github.com/angular/angular/commit/7de7871)), closes [#13380](https://github.com/angular/angular/issues/13380) [#36544](https://github.com/angular/angular/issues/36544)
|
||||||
|
|
||||||
@ -486,6 +72,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)
|
||||||
|
|
||||||
@ -531,6 +118,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)
|
||||||
|
|
||||||
@ -545,8 +133,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//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//github.com/angular/angular-cli/issues/16860/issues/issuecomment-614694269)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -566,11 +154,15 @@ This release contains various API docs improvements.
|
|||||||
* **router:** pass correct component to canDeactivate checks when using two or more sibling router-outlets ([#36302](https://github.com/angular/angular/issues/36302)) ([8e7f903](https://github.com/angular/angular/commit/8e7f903)), closes [#34614](https://github.com/angular/angular/issues/34614)
|
* **router:** pass correct component to canDeactivate checks when using two or more sibling router-outlets ([#36302](https://github.com/angular/angular/issues/36302)) ([8e7f903](https://github.com/angular/angular/commit/8e7f903)), closes [#34614](https://github.com/angular/angular/issues/34614)
|
||||||
* **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))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.1"></a>
|
<a name="9.1.1"></a>
|
||||||
## [9.1.1](https://github.com/angular/angular/compare/9.1.0...9.1.1) (2020-04-07)
|
## [9.1.1](https://github.com/angular/angular/compare/9.1.0...9.1.1) (2020-04-07)
|
||||||
|
|
||||||
@ -587,13 +179,13 @@ 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//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))
|
||||||
* **ngcc:** correctly identify the package path of secondary entry-points ([#36249](https://github.com/angular/angular/issues/36249)) ([e53b686](https://github.com/angular/angular/commit/e53b686)), closes [#35747](https://github.com/angular/angular/issues/35747)
|
* **ngcc:** correctly identify the package path of secondary entry-points ([#36249](https://github.com/angular/angular/issues/36249)) ([e53b686](https://github.com/angular/angular/commit/e53b686)), closes [#35747](https://github.com/angular/angular/issues/35747)
|
||||||
* **ngcc:** detect non-emitted, non-imported TypeScript helpers ([#36418](https://github.com/angular/angular/issues/36418)) ([93b32d3](https://github.com/angular/angular/commit/93b32d3))
|
* **ngcc:** detect non-emitted, non-imported TypeScript helpers ([#36418](https://github.com/angular/angular/issues/36418)) ([93b32d3](https://github.com/angular/angular/commit/93b32d3))
|
||||||
* **ngcc:** do not spawn more processes than intended in parallel mode ([#36280](https://github.com/angular/angular/issues/36280)) ([6ea232e](https://github.com/angular/angular/commit/6ea232e)), closes [#35719](https://github.com/angular/angular/issues/35719) [#36278](https://github.com/angular/angular/issues/36278) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/main.ts#L429](https://github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/main.ts/issues/L429) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L108](https://github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L108) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L110](https://github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L110) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L199](https://github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L199)
|
* **ngcc:** do not spawn more processes than intended in parallel mode ([#36280](https://github.com/angular/angular/issues/36280)) ([6ea232e](https://github.com/angular/angular/commit/6ea232e)), closes [#35719](https://github.com/angular/angular/issues/35719) [#36278](https://github.com/angular/angular/issues/36278) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/main.ts#L429](https://github.com//github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/main.ts/issues/L429) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L108](https://github.com//github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L108) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L110](https://github.com//github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L110) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L199](https://github.com//github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L199)
|
||||||
* **ngcc:** do not write entry-point manifest outside node_modules ([#36299](https://github.com/angular/angular/issues/36299)) ([bb8744d](https://github.com/angular/angular/commit/bb8744d)), closes [#36296](https://github.com/angular/angular/issues/36296)
|
* **ngcc:** do not write entry-point manifest outside node_modules ([#36299](https://github.com/angular/angular/issues/36299)) ([bb8744d](https://github.com/angular/angular/commit/bb8744d)), closes [#36296](https://github.com/angular/angular/issues/36296)
|
||||||
* **ngcc:** don't crash on cyclic source-map references ([#36452](https://github.com/angular/angular/issues/36452)) ([56af303](https://github.com/angular/angular/commit/56af303)), closes [#35727](https://github.com/angular/angular/issues/35727) [#35757](https://github.com/angular/angular/issues/35757)
|
* **ngcc:** don't crash on cyclic source-map references ([#36452](https://github.com/angular/angular/issues/36452)) ([56af303](https://github.com/angular/angular/commit/56af303)), closes [#35727](https://github.com/angular/angular/issues/35727) [#35757](https://github.com/angular/angular/issues/35757)
|
||||||
* **ngcc:** handle bad path mappings when finding entry-points ([#36331](https://github.com/angular/angular/issues/36331)) ([7bb3588](https://github.com/angular/angular/commit/7bb3588)), closes [#36313](https://github.com/angular/angular/issues/36313) [#36283](https://github.com/angular/angular/issues/36283)
|
* **ngcc:** handle bad path mappings when finding entry-points ([#36331](https://github.com/angular/angular/issues/36331)) ([7bb3588](https://github.com/angular/angular/commit/7bb3588)), closes [#36313](https://github.com/angular/angular/issues/36313) [#36283](https://github.com/angular/angular/issues/36283)
|
||||||
@ -605,6 +197,7 @@ This release contains various API docs improvements.
|
|||||||
* **router:** state data missing in routerLink ([#36462](https://github.com/angular/angular/issues/36462)) ([0e7a89a](https://github.com/angular/angular/commit/0e7a89a)), closes [#33173](https://github.com/angular/angular/issues/33173)
|
* **router:** state data missing in routerLink ([#36462](https://github.com/angular/angular/issues/36462)) ([0e7a89a](https://github.com/angular/angular/commit/0e7a89a)), closes [#33173](https://github.com/angular/angular/issues/33173)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.0"></a>
|
<a name="9.1.0"></a>
|
||||||
# [9.1.0](https://github.com/angular/angular/compare/9.0.0...9.1.0) (2020-03-25)
|
# [9.1.0](https://github.com/angular/angular/compare/9.0.0...9.1.0) (2020-03-25)
|
||||||
|
|
||||||
@ -763,7 +356,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ngcc:** use path-mappings from tsconfig in dependency resolution ([#36180](https://github.com/angular/angular/issues/36180)) ([6defe96](https://github.com/angular/angular/commit/6defe96)), closes [#36119](https://github.com/angular/angular/issues/36119)
|
* **ngcc:** use path-mappings from tsconfig in dependency resolution ([#36180](https://github.com/angular/angular/issues/36180)) ([6defe96](https://github.com/angular/angular/commit/6defe96)), closes [#36119](https://github.com/angular/angular/issues/36119)
|
||||||
* **ngcc:** use preserve whitespaces from tsconfig if provided ([#36189](https://github.com/angular/angular/issues/36189)) ([aef4323](https://github.com/angular/angular/commit/aef4323)), closes [#35871](https://github.com/angular/angular/issues/35871)
|
* **ngcc:** use preserve whitespaces from tsconfig if provided ([#36189](https://github.com/angular/angular/issues/36189)) ([aef4323](https://github.com/angular/angular/commit/aef4323)), closes [#35871](https://github.com/angular/angular/issues/35871)
|
||||||
* **platform-browser:** add missing peerDependency on `[@angular](https://github.com/angular)/animations` ([#35949](https://github.com/angular/angular/issues/35949)) ([64d6f13](https://github.com/angular/angular/commit/64d6f13)), closes [#35888](https://github.com/angular/angular/issues/35888)
|
* **platform-browser:** add missing peerDependency on `[@angular](https://github.com/angular)/animations` ([#35949](https://github.com/angular/angular/issues/35949)) ([64d6f13](https://github.com/angular/angular/commit/64d6f13)), closes [#35888](https://github.com/angular/angular/issues/35888)
|
||||||
* **router:** removed unused ApplicationRef dependency ([#35642](https://github.com/angular/angular/issues/35642)) ([c839c05](https://github.com/angular/angular/commit/c839c05)), closes [/github.com/angular/angular/commit/5a849829c42330d7e88e83e916e6e36380c97a97#diff-c0baae5e1df628e1a217e8dc38557](https://github.com/angular/angular/commit/5a849829c42330d7e88e83e916e6e36380c97a97/issues/diff-c0baae5e1df628e1a217e8dc38557)
|
* **router:** removed unused ApplicationRef dependency ([#35642](https://github.com/angular/angular/issues/35642)) ([c839c05](https://github.com/angular/angular/commit/c839c05)), closes [/github.com/angular/angular/commit/5a849829c42330d7e88e83e916e6e36380c97a97#diff-c0baae5e1df628e1a217e8dc38557](https://github.com//github.com/angular/angular/commit/5a849829c42330d7e88e83e916e6e36380c97a97/issues/diff-c0baae5e1df628e1a217e8dc38557)
|
||||||
* **router:** state data missing in routerLink ([#33203](https://github.com/angular/angular/issues/33203)) ([de67978](https://github.com/angular/angular/commit/de67978))
|
* **router:** state data missing in routerLink ([#33203](https://github.com/angular/angular/issues/33203)) ([de67978](https://github.com/angular/angular/commit/de67978))
|
||||||
* **service-worker:** treat 503 as offline ([#35595](https://github.com/angular/angular/issues/35595)) ([96cdf03](https://github.com/angular/angular/commit/96cdf03)), closes [#35571](https://github.com/angular/angular/issues/35571)
|
* **service-worker:** treat 503 as offline ([#35595](https://github.com/angular/angular/issues/35595)) ([96cdf03](https://github.com/angular/angular/commit/96cdf03)), closes [#35571](https://github.com/angular/angular/issues/35571)
|
||||||
* fix flaky test cases of passive events ([#35679](https://github.com/angular/angular/issues/35679)) ([8ef29b6](https://github.com/angular/angular/commit/8ef29b6))
|
* fix flaky test cases of passive events ([#35679](https://github.com/angular/angular/issues/35679)) ([8ef29b6](https://github.com/angular/angular/commit/8ef29b6))
|
||||||
@ -898,7 +491,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ngcc:** correctly detect emitted TS helpers in ES5 ([#35191](https://github.com/angular/angular/issues/35191)) ([af4fe3a](https://github.com/angular/angular/commit/af4fe3a))
|
* **ngcc:** correctly detect emitted TS helpers in ES5 ([#35191](https://github.com/angular/angular/issues/35191)) ([af4fe3a](https://github.com/angular/angular/commit/af4fe3a))
|
||||||
* **ngcc:** correctly detect outer aliased class identifiers in ES5 ([#35527](https://github.com/angular/angular/issues/35527)) ([39bd9a7](https://github.com/angular/angular/commit/39bd9a7)), 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)) ([39bd9a7](https://github.com/angular/angular/commit/39bd9a7)), closes [#35399](https://github.com/angular/angular/issues/35399)
|
||||||
* **ngcc:** handle imports in dts files when processing CommonJS ([#35191](https://github.com/angular/angular/issues/35191)) ([12e3db8](https://github.com/angular/angular/commit/12e3db8)), 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)) ([12e3db8](https://github.com/angular/angular/commit/12e3db8)), closes [#34356](https://github.com/angular/angular/issues/34356)
|
||||||
* **router:** removed unused ApplicationRef dependency ([#35642](https://github.com/angular/angular/issues/35642)) ([2f140f5](https://github.com/angular/angular/commit/2f140f5)), closes [/github.com/angular/angular/commit/5a849829c42330d7e88e83e916e6e36380c97a97#diff-c0baae5e1df628e1a217e8dc38557](https://github.com/angular/angular/commit/5a849829c42330d7e88e83e916e6e36380c97a97/issues/diff-c0baae5e1df628e1a217e8dc38557)
|
* **router:** removed unused ApplicationRef dependency ([#35642](https://github.com/angular/angular/issues/35642)) ([2f140f5](https://github.com/angular/angular/commit/2f140f5)), closes [/github.com/angular/angular/commit/5a849829c42330d7e88e83e916e6e36380c97a97#diff-c0baae5e1df628e1a217e8dc38557](https://github.com//github.com/angular/angular/commit/5a849829c42330d7e88e83e916e6e36380c97a97/issues/diff-c0baae5e1df628e1a217e8dc38557)
|
||||||
* **service-worker:** treat 503 as offline ([#35595](https://github.com/angular/angular/issues/35595)) ([64a415b](https://github.com/angular/angular/commit/64a415b)), closes [#35571](https://github.com/angular/angular/issues/35571)
|
* **service-worker:** treat 503 as offline ([#35595](https://github.com/angular/angular/issues/35595)) ([64a415b](https://github.com/angular/angular/commit/64a415b)), closes [#35571](https://github.com/angular/angular/issues/35571)
|
||||||
|
|
||||||
|
|
||||||
@ -975,7 +568,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** support emitting a reference to interface declarations ([#34849](https://github.com/angular/angular/issues/34849)) ([ad9ec52](https://github.com/angular/angular/commit/ad9ec52)), closes [#34021](https://github.com/angular/angular/issues/34021) [#34837](https://github.com/angular/angular/issues/34837)
|
* **ivy:** support emitting a reference to interface declarations ([#34849](https://github.com/angular/angular/issues/34849)) ([ad9ec52](https://github.com/angular/angular/commit/ad9ec52)), closes [#34021](https://github.com/angular/angular/issues/34021) [#34837](https://github.com/angular/angular/issues/34837)
|
||||||
* **ivy:** template type-check errors from TS should not use NG error codes ([#35146](https://github.com/angular/angular/issues/35146)) ([cf3071f](https://github.com/angular/angular/commit/cf3071f))
|
* **ivy:** template type-check errors from TS should not use NG error codes ([#35146](https://github.com/angular/angular/issues/35146)) ([cf3071f](https://github.com/angular/angular/commit/cf3071f))
|
||||||
* **ivy:** host-styling throws assert exception inside *ngFor ([#35133](https://github.com/angular/angular/issues/35133)) ([31e9873](https://github.com/angular/angular/commit/31e9873)), closes [#35118](https://github.com/angular/angular/issues/35118)
|
* **ivy:** host-styling throws assert exception inside *ngFor ([#35133](https://github.com/angular/angular/issues/35133)) ([31e9873](https://github.com/angular/angular/commit/31e9873)), closes [#35118](https://github.com/angular/angular/issues/35118)
|
||||||
* **ngcc:** correctly invalidate cache when moving/removing files/directories ([#35106](https://github.com/angular/angular/issues/35106)) ([22357d4](https://github.com/angular/angular/commit/22357d4)), closes [/github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts#L54](https://github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts/issues/L54) [/github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts#L61](https://github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts/issues/L61) [#35095](https://github.com/angular/angular/issues/35095)
|
* **ngcc:** correctly invalidate cache when moving/removing files/directories ([#35106](https://github.com/angular/angular/issues/35106)) ([22357d4](https://github.com/angular/angular/commit/22357d4)), closes [/github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts#L54](https://github.com//github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts/issues/L54) [/github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts#L61](https://github.com//github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts/issues/L61) [#35095](https://github.com/angular/angular/issues/35095)
|
||||||
* **ngcc:** do not lock if the target is not compiled by Angular ([#35057](https://github.com/angular/angular/issues/35057)) ([c30c518](https://github.com/angular/angular/commit/c30c518)), closes [#35000](https://github.com/angular/angular/issues/35000)
|
* **ngcc:** do not lock if the target is not compiled by Angular ([#35057](https://github.com/angular/angular/issues/35057)) ([c30c518](https://github.com/angular/angular/commit/c30c518)), closes [#35000](https://github.com/angular/angular/issues/35000)
|
||||||
* **compiler-cli:** add `sass` as a valid css preprocessor extension ([#35052](https://github.com/angular/angular/issues/35052)) ([7f96fbb](https://github.com/angular/angular/commit/7f96fbb))
|
* **compiler-cli:** add `sass` as a valid css preprocessor extension ([#35052](https://github.com/angular/angular/issues/35052)) ([7f96fbb](https://github.com/angular/angular/commit/7f96fbb))
|
||||||
* should also allow subclass Promise without Symbol.species ([#34533](https://github.com/angular/angular/issues/34533)) ([0de632a](https://github.com/angular/angular/commit/0de632a))
|
* should also allow subclass Promise without Symbol.species ([#34533](https://github.com/angular/angular/issues/34533)) ([0de632a](https://github.com/angular/angular/commit/0de632a))
|
||||||
@ -985,10 +578,10 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** ensure `DebugNode`/`DebugElement` are tree-shakeable in Ivy ([#35003](https://github.com/angular/angular/issues/35003)) ([23c0147](https://github.com/angular/angular/commit/23c0147)), closes [#30130](https://github.com/angular/angular/issues/30130)
|
* **ivy:** ensure `DebugNode`/`DebugElement` are tree-shakeable in Ivy ([#35003](https://github.com/angular/angular/issues/35003)) ([23c0147](https://github.com/angular/angular/commit/23c0147)), closes [#30130](https://github.com/angular/angular/issues/30130)
|
||||||
* **ivy:** ensure multi providers in ModuleWithProviders are not duplicated ([#34914](https://github.com/angular/angular/issues/34914)) ([4975f89](https://github.com/angular/angular/commit/4975f89))
|
* **ivy:** ensure multi providers in ModuleWithProviders are not duplicated ([#34914](https://github.com/angular/angular/issues/34914)) ([4975f89](https://github.com/angular/angular/commit/4975f89))
|
||||||
* **ivy:** update ViewContainerRef to get the correct parentInjector ([#35013](https://github.com/angular/angular/issues/35013)) ([eaa4a5a](https://github.com/angular/angular/commit/eaa4a5a))
|
* **ivy:** update ViewContainerRef to get the correct parentInjector ([#35013](https://github.com/angular/angular/issues/35013)) ([eaa4a5a](https://github.com/angular/angular/commit/eaa4a5a))
|
||||||
* **language-service:** prune duplicate returned definitions ([#34995](https://github.com/angular/angular/issues/34995)) ([71f5417](https://github.com/angular/angular/commit/71f5417)), closes [/github.com/angular/angular/pull/34847#discussion_r371006680](https://github.com/angular/angular/pull/34847/issues/discussion_r371006680)
|
* **language-service:** prune duplicate returned definitions ([#34995](https://github.com/angular/angular/issues/34995)) ([71f5417](https://github.com/angular/angular/commit/71f5417)), closes [/github.com/angular/angular/pull/34847#discussion_r371006680](https://github.com//github.com/angular/angular/pull/34847/issues/discussion_r371006680)
|
||||||
* **language-service:** remove repeated symbol definitions for structural directive ([#34847](https://github.com/angular/angular/issues/34847)) ([35916d3](https://github.com/angular/angular/commit/35916d3))
|
* **language-service:** remove repeated symbol definitions for structural directive ([#34847](https://github.com/angular/angular/issues/34847)) ([35916d3](https://github.com/angular/angular/commit/35916d3))
|
||||||
* **language-service:** warn, not error, on missing context members ([#35036](https://github.com/angular/angular/issues/35036)) ([0e76821](https://github.com/angular/angular/commit/0e76821))
|
* **language-service:** warn, not error, on missing context members ([#35036](https://github.com/angular/angular/issues/35036)) ([0e76821](https://github.com/angular/angular/commit/0e76821))
|
||||||
* **localize:** re-enable filename in code-frame error messages ([#34994](https://github.com/angular/angular/issues/34994)) ([c7c7b20](https://github.com/angular/angular/commit/c7c7b20)), closes [/github.com/angular/angular/pull/34974/files#r371034476](https://github.com/angular/angular/pull/34974/files/issues/r371034476)
|
* **localize:** re-enable filename in code-frame error messages ([#34994](https://github.com/angular/angular/issues/34994)) ([c7c7b20](https://github.com/angular/angular/commit/c7c7b20)), closes [/github.com/angular/angular/pull/34974/files#r371034476](https://github.com//github.com/angular/angular/pull/34974/files/issues/r371034476)
|
||||||
* **ngcc:** improve lockfile error message ([#35001](https://github.com/angular/angular/issues/35001)) ([1d31c81](https://github.com/angular/angular/commit/1d31c81)), closes [#35000](https://github.com/angular/angular/issues/35000)
|
* **ngcc:** improve lockfile error message ([#35001](https://github.com/angular/angular/issues/35001)) ([1d31c81](https://github.com/angular/angular/commit/1d31c81)), closes [#35000](https://github.com/angular/angular/issues/35000)
|
||||||
* **ivy:** correctly emit component when it's removed from its module ([#34912](https://github.com/angular/angular/issues/34912)) ([adc663e](https://github.com/angular/angular/commit/adc663e)), closes [#34813](https://github.com/angular/angular/issues/34813)
|
* **ivy:** correctly emit component when it's removed from its module ([#34912](https://github.com/angular/angular/issues/34912)) ([adc663e](https://github.com/angular/angular/commit/adc663e)), closes [#34813](https://github.com/angular/angular/issues/34813)
|
||||||
* **ivy:** DebugNode.classes not working on SVG elements ([#34872](https://github.com/angular/angular/issues/34872)) ([7e8aac1](https://github.com/angular/angular/commit/7e8aac1)), closes [#34868](https://github.com/angular/angular/issues/34868)
|
* **ivy:** DebugNode.classes not working on SVG elements ([#34872](https://github.com/angular/angular/issues/34872)) ([7e8aac1](https://github.com/angular/angular/commit/7e8aac1)), closes [#34868](https://github.com/angular/angular/issues/34868)
|
||||||
@ -1011,7 +604,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//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)
|
||||||
@ -1026,19 +619,19 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** ngClass not applying classes with trailing/leading spaces ([#34539](https://github.com/angular/angular/issues/34539)) ([98ed7c6](https://github.com/angular/angular/commit/98ed7c6)), closes [#34476](https://github.com/angular/angular/issues/34476)
|
* **ivy:** ngClass not applying classes with trailing/leading spaces ([#34539](https://github.com/angular/angular/issues/34539)) ([98ed7c6](https://github.com/angular/angular/commit/98ed7c6)), closes [#34476](https://github.com/angular/angular/issues/34476)
|
||||||
* **ivy:** Prevent errors when querying DebugElement roots that were outside angular context ([#34687](https://github.com/angular/angular/issues/34687)) ([f1cdb8f](https://github.com/angular/angular/commit/f1cdb8f))
|
* **ivy:** Prevent errors when querying DebugElement roots that were outside angular context ([#34687](https://github.com/angular/angular/issues/34687)) ([f1cdb8f](https://github.com/angular/angular/commit/f1cdb8f))
|
||||||
* **ivy:** properly bootstrap components with attribute selectors ([#34450](https://github.com/angular/angular/issues/34450)) ([2c0b9ea](https://github.com/angular/angular/commit/2c0b9ea)), closes [#34349](https://github.com/angular/angular/issues/34349)
|
* **ivy:** properly bootstrap components with attribute selectors ([#34450](https://github.com/angular/angular/issues/34450)) ([2c0b9ea](https://github.com/angular/angular/commit/2c0b9ea)), closes [#34349](https://github.com/angular/angular/issues/34349)
|
||||||
* **ivy:** warn instead of throwing for unknown elements ([#34524](https://github.com/angular/angular/issues/34524)) ([d9ae70e](https://github.com/angular/angular/commit/d9ae70e)), closes [/github.com/angular/angular/pull/33419#discussion_r339296216](https://github.com/angular/angular/pull/33419/issues/discussion_r339296216)
|
* **ivy:** warn instead of throwing for unknown elements ([#34524](https://github.com/angular/angular/issues/34524)) ([d9ae70e](https://github.com/angular/angular/commit/d9ae70e)), closes [/github.com/angular/angular/pull/33419#discussion_r339296216](https://github.com//github.com/angular/angular/pull/33419/issues/discussion_r339296216)
|
||||||
* **language-service:** apply suggested change. ([#34564](https://github.com/angular/angular/issues/34564)) ([b3af220](https://github.com/angular/angular/commit/b3af220))
|
* **language-service:** apply suggested change. ([#34564](https://github.com/angular/angular/issues/34564)) ([b3af220](https://github.com/angular/angular/commit/b3af220))
|
||||||
* **language-service:** break the hover/definitions for two-way binding ([#34564](https://github.com/angular/angular/issues/34564)) ([eb5c20c](https://github.com/angular/angular/commit/eb5c20c))
|
* **language-service:** break the hover/definitions for two-way binding ([#34564](https://github.com/angular/angular/issues/34564)) ([eb5c20c](https://github.com/angular/angular/commit/eb5c20c))
|
||||||
* **language-service:** CRLF offset in inline template ([#34737](https://github.com/angular/angular/issues/34737)) ([80315b5](https://github.com/angular/angular/commit/80315b5))
|
* **language-service:** CRLF offset in inline template ([#34737](https://github.com/angular/angular/issues/34737)) ([80315b5](https://github.com/angular/angular/commit/80315b5))
|
||||||
* **language-service:** do not use an i18n parser for templates ([#34531](https://github.com/angular/angular/issues/34531)) ([cb7dcb3](https://github.com/angular/angular/commit/cb7dcb3))
|
* **language-service:** do not use an i18n parser for templates ([#34531](https://github.com/angular/angular/issues/34531)) ([cb7dcb3](https://github.com/angular/angular/commit/cb7dcb3))
|
||||||
* **language-service:** only visit directives ([#34564](https://github.com/angular/angular/issues/34564)) ([76d7aa7](https://github.com/angular/angular/commit/76d7aa7))
|
* **language-service:** only visit directives ([#34564](https://github.com/angular/angular/issues/34564)) ([76d7aa7](https://github.com/angular/angular/commit/76d7aa7))
|
||||||
* **ngcc:** avoid error due to circular dependency in `EsmDependencyHost` ([#34512](https://github.com/angular/angular/issues/34512)) ([7c3172a](https://github.com/angular/angular/commit/7c3172a)), closes [/github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/utils.ts#L10](https://github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/utils.ts/issues/L10) [/github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/esm_dependency_host.ts#L10](https://github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/esm_dependency_host.ts/issues/L10) [/github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/dependency_host.ts#L9](https://github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/dependency_host.ts/issues/L9)
|
* **ngcc:** avoid error due to circular dependency in `EsmDependencyHost` ([#34512](https://github.com/angular/angular/issues/34512)) ([7c3172a](https://github.com/angular/angular/commit/7c3172a)), closes [/github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/utils.ts#L10](https://github.com//github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/utils.ts/issues/L10) [/github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/esm_dependency_host.ts#L10](https://github.com//github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/esm_dependency_host.ts/issues/L10) [/github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/dependency_host.ts#L9](https://github.com//github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/dependency_host.ts/issues/L9)
|
||||||
* **ngcc:** correctly detect dependencies in CommonJS ([#34528](https://github.com/angular/angular/issues/34528)) ([ff02ddf](https://github.com/angular/angular/commit/ff02ddf))
|
* **ngcc:** correctly detect dependencies in CommonJS ([#34528](https://github.com/angular/angular/issues/34528)) ([ff02ddf](https://github.com/angular/angular/commit/ff02ddf))
|
||||||
* **ngcc:** correctly handle inline exports in UMD ([#34512](https://github.com/angular/angular/issues/34512)) ([7bbfccf](https://github.com/angular/angular/commit/7bbfccf))
|
* **ngcc:** correctly handle inline exports in UMD ([#34512](https://github.com/angular/angular/issues/34512)) ([7bbfccf](https://github.com/angular/angular/commit/7bbfccf))
|
||||||
* **ngcc:** don't crash if symbol has no declarations ([#34658](https://github.com/angular/angular/issues/34658)) ([4def99e](https://github.com/angular/angular/commit/4def99e)), closes [/github.com/angular/angular/blob/8d0de89e/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts#L309](https://github.com/angular/angular/blob/8d0de89e/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts/issues/L309) [#34560](https://github.com/angular/angular/issues/34560)
|
* **ngcc:** don't crash if symbol has no declarations ([#34658](https://github.com/angular/angular/issues/34658)) ([4def99e](https://github.com/angular/angular/commit/4def99e)), closes [/github.com/angular/angular/blob/8d0de89e/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts#L309](https://github.com//github.com/angular/angular/blob/8d0de89e/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts/issues/L309) [#34560](https://github.com/angular/angular/issues/34560)
|
||||||
* **ngcc:** handle UMD factories that do not use all params ([#34660](https://github.com/angular/angular/issues/34660)) ([83868be](https://github.com/angular/angular/commit/83868be)), closes [#34653](https://github.com/angular/angular/issues/34653)
|
* **ngcc:** handle UMD factories that do not use all params ([#34660](https://github.com/angular/angular/issues/34660)) ([83868be](https://github.com/angular/angular/commit/83868be)), closes [#34653](https://github.com/angular/angular/issues/34653)
|
||||||
* **ngcc:** insert definitions after statement ([#34677](https://github.com/angular/angular/issues/34677)) ([f295240](https://github.com/angular/angular/commit/f295240)), closes [#34648](https://github.com/angular/angular/issues/34648)
|
* **ngcc:** insert definitions after statement ([#34677](https://github.com/angular/angular/issues/34677)) ([f295240](https://github.com/angular/angular/commit/f295240)), closes [#34648](https://github.com/angular/angular/issues/34648)
|
||||||
* **ngcc:** recognize re-exports with `require()` calls in UMD ([#34512](https://github.com/angular/angular/issues/34512)) ([79be354](https://github.com/angular/angular/commit/79be354)), closes [/github.com/angular/angular/pull/34254/files#r359515373](https://github.com/angular/angular/pull/34254/files/issues/r359515373)
|
* **ngcc:** recognize re-exports with `require()` calls in UMD ([#34512](https://github.com/angular/angular/issues/34512)) ([79be354](https://github.com/angular/angular/commit/79be354)), closes [/github.com/angular/angular/pull/34254/files#r359515373](https://github.com//github.com/angular/angular/pull/34254/files/issues/r359515373)
|
||||||
* **ngcc:** recognize re-exports with imported TS helpers in CommonJS and UMD ([#34527](https://github.com/angular/angular/issues/34527)) ([a88dc17](https://github.com/angular/angular/commit/a88dc17))
|
* **ngcc:** recognize re-exports with imported TS helpers in CommonJS and UMD ([#34527](https://github.com/angular/angular/issues/34527)) ([a88dc17](https://github.com/angular/angular/commit/a88dc17))
|
||||||
* **common:** remove trailing whitespace for CurrencyPipe ([#34642](https://github.com/angular/angular/issues/34642)) ([c42b90b](https://github.com/angular/angular/commit/c42b90b)), closes [#34641](https://github.com/angular/angular/issues/34641)
|
* **common:** remove trailing whitespace for CurrencyPipe ([#34642](https://github.com/angular/angular/issues/34642)) ([c42b90b](https://github.com/angular/angular/commit/c42b90b)), closes [#34641](https://github.com/angular/angular/issues/34641)
|
||||||
* **ivy:** append `advance` instructions before `i18nExp` ([#34436](https://github.com/angular/angular/issues/34436)) ([ba4c31c](https://github.com/angular/angular/commit/ba4c31c))
|
* **ivy:** append `advance` instructions before `i18nExp` ([#34436](https://github.com/angular/angular/issues/34436)) ([ba4c31c](https://github.com/angular/angular/commit/ba4c31c))
|
||||||
@ -1085,7 +678,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** add flag to skip non-exported classes ([#33921](https://github.com/angular/angular/issues/33921)) ([#34340](https://github.com/angular/angular/issues/34340)) ([7ed984b](https://github.com/angular/angular/commit/7ed984b)), closes [#33724](https://github.com/angular/angular/issues/33724)
|
* **ivy:** add flag to skip non-exported classes ([#33921](https://github.com/angular/angular/issues/33921)) ([#34340](https://github.com/angular/angular/issues/34340)) ([7ed984b](https://github.com/angular/angular/commit/7ed984b)), closes [#33724](https://github.com/angular/angular/issues/33724)
|
||||||
* **ivy:** align TestBed.overrideProvider with what happens with providers in TestBed providers array ([#33769](https://github.com/angular/angular/issues/33769)) ([10a33ef](https://github.com/angular/angular/commit/10a33ef))
|
* **ivy:** align TestBed.overrideProvider with what happens with providers in TestBed providers array ([#33769](https://github.com/angular/angular/issues/33769)) ([10a33ef](https://github.com/angular/angular/commit/10a33ef))
|
||||||
* **ivy:** do not invoke change detection for destroyed views ([#34241](https://github.com/angular/angular/issues/34241)) ([24bbcaf](https://github.com/angular/angular/commit/24bbcaf))
|
* **ivy:** do not invoke change detection for destroyed views ([#34241](https://github.com/angular/angular/issues/34241)) ([24bbcaf](https://github.com/angular/angular/commit/24bbcaf))
|
||||||
* **ivy:** handle SafeStyles in [style.prop] correctly ([#34286](https://github.com/angular/angular/issues/34286)) ([b0d5784](https://github.com/angular/angular/commit/b0d5784)), closes [/github.com/angular/angular/blob/master/packages/core/src/render3/styling/bindings.ts#L620](https://github.com/angular/angular/blob/master/packages/core/src/render3/styling/bindings.ts/issues/L620)
|
* **ivy:** handle SafeStyles in [style.prop] correctly ([#34286](https://github.com/angular/angular/issues/34286)) ([b0d5784](https://github.com/angular/angular/commit/b0d5784)), closes [/github.com/angular/angular/blob/master/packages/core/src/render3/styling/bindings.ts#L620](https://github.com//github.com/angular/angular/blob/master/packages/core/src/render3/styling/bindings.ts/issues/L620)
|
||||||
* **ivy:** inherit static coercion members from base classes ([#34296](https://github.com/angular/angular/issues/34296)) ([edfaab6](https://github.com/angular/angular/commit/edfaab6)), closes [#33830](https://github.com/angular/angular/issues/33830)
|
* **ivy:** inherit static coercion members from base classes ([#34296](https://github.com/angular/angular/issues/34296)) ([edfaab6](https://github.com/angular/angular/commit/edfaab6)), closes [#33830](https://github.com/angular/angular/issues/33830)
|
||||||
* **ivy:** properly parenthesize ternary expressions when emitted ([#34221](https://github.com/angular/angular/issues/34221)) ([af36bc6](https://github.com/angular/angular/commit/af36bc6)), closes [#34087](https://github.com/angular/angular/issues/34087)
|
* **ivy:** properly parenthesize ternary expressions when emitted ([#34221](https://github.com/angular/angular/issues/34221)) ([af36bc6](https://github.com/angular/angular/commit/af36bc6)), closes [#34087](https://github.com/angular/angular/issues/34087)
|
||||||
* **ivy:** throw a better error when DI can't inject a ctor param ([#33739](https://github.com/angular/angular/issues/33739)) ([#34340](https://github.com/angular/angular/issues/34340)) ([676aca1](https://github.com/angular/angular/commit/676aca1)), closes [#33637](https://github.com/angular/angular/issues/33637)
|
* **ivy:** throw a better error when DI can't inject a ctor param ([#33739](https://github.com/angular/angular/issues/33739)) ([#34340](https://github.com/angular/angular/issues/34340)) ([676aca1](https://github.com/angular/angular/commit/676aca1)), closes [#33637](https://github.com/angular/angular/issues/33637)
|
||||||
@ -1098,7 +691,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ngcc:** log Angular error codes correctly ([#34014](https://github.com/angular/angular/issues/34014)) ([3cd43c1](https://github.com/angular/angular/commit/3cd43c1))
|
* **ngcc:** log Angular error codes correctly ([#34014](https://github.com/angular/angular/issues/34014)) ([3cd43c1](https://github.com/angular/angular/commit/3cd43c1))
|
||||||
* **ngcc:** report diagnostics from migrations ([#34014](https://github.com/angular/angular/issues/34014)) ([599dcd0](https://github.com/angular/angular/commit/599dcd0))
|
* **ngcc:** report diagnostics from migrations ([#34014](https://github.com/angular/angular/issues/34014)) ([599dcd0](https://github.com/angular/angular/commit/599dcd0))
|
||||||
* **bazel:** don't rely on [@angular](https://github.com/angular)/core being as a depedency to install [@angular](https://github.com/angular)/bazel ([#34181](https://github.com/angular/angular/issues/34181)) ([716fc84](https://github.com/angular/angular/commit/716fc84)), closes [#34164](https://github.com/angular/angular/issues/34164)
|
* **bazel:** don't rely on [@angular](https://github.com/angular)/core being as a depedency to install [@angular](https://github.com/angular)/bazel ([#34181](https://github.com/angular/angular/issues/34181)) ([716fc84](https://github.com/angular/angular/commit/716fc84)), closes [#34164](https://github.com/angular/angular/issues/34164)
|
||||||
* **bazel:** reenable template type checking in ng_module ([#34144](https://github.com/angular/angular/issues/34144)) ([572e731](https://github.com/angular/angular/commit/572e731)), closes [/github.com/angular/angular/blob/168abc6d6f52713383411b14980e104c99bfeef5/packages/compiler-cli/src/ngtsc/program.ts#L430-L434](https://github.com/angular/angular/blob/168abc6d6f52713383411b14980e104c99bfeef5/packages/compiler-cli/src/ngtsc/program.ts/issues/L430-L434)
|
* **bazel:** reenable template type checking in ng_module ([#34144](https://github.com/angular/angular/issues/34144)) ([572e731](https://github.com/angular/angular/commit/572e731)), closes [/github.com/angular/angular/blob/168abc6d6f52713383411b14980e104c99bfeef5/packages/compiler-cli/src/ngtsc/program.ts#L430-L434](https://github.com//github.com/angular/angular/blob/168abc6d6f52713383411b14980e104c99bfeef5/packages/compiler-cli/src/ngtsc/program.ts/issues/L430-L434)
|
||||||
* **common:** reflect input type in NgForOf context ([#33997](https://github.com/angular/angular/issues/33997)) ([b640d38](https://github.com/angular/angular/commit/b640d38))
|
* **common:** reflect input type in NgForOf context ([#33997](https://github.com/angular/angular/issues/33997)) ([b640d38](https://github.com/angular/angular/commit/b640d38))
|
||||||
* **common:** reflect input type in NgIf context ([#33997](https://github.com/angular/angular/issues/33997)) ([7504543](https://github.com/angular/angular/commit/7504543)), closes [#31556](https://github.com/angular/angular/issues/31556)
|
* **common:** reflect input type in NgIf context ([#33997](https://github.com/angular/angular/issues/33997)) ([7504543](https://github.com/angular/angular/commit/7504543)), closes [#31556](https://github.com/angular/angular/issues/31556)
|
||||||
* **compiler:** i18n - trim whitespace from i18n custom ids ([#34154](https://github.com/angular/angular/issues/34154)) ([64317c6](https://github.com/angular/angular/commit/64317c6)), closes [#34147](https://github.com/angular/angular/issues/34147)
|
* **compiler:** i18n - trim whitespace from i18n custom ids ([#34154](https://github.com/angular/angular/issues/34154)) ([64317c6](https://github.com/angular/angular/commit/64317c6)), closes [#34147](https://github.com/angular/angular/issues/34147)
|
||||||
@ -1134,7 +727,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** support inserting a `viewRef` that is already present ([#34052](https://github.com/angular/angular/issues/34052)) ([978b500](https://github.com/angular/angular/commit/978b500)), closes [#33924](https://github.com/angular/angular/issues/33924)
|
* **ivy:** support inserting a `viewRef` that is already present ([#34052](https://github.com/angular/angular/issues/34052)) ([978b500](https://github.com/angular/angular/commit/978b500)), closes [#33924](https://github.com/angular/angular/issues/33924)
|
||||||
* **ivy:** take styles extracted from template into account in JIT mode ([#34017](https://github.com/angular/angular/issues/34017)) ([b659aa3](https://github.com/angular/angular/commit/b659aa3))
|
* **ivy:** take styles extracted from template into account in JIT mode ([#34017](https://github.com/angular/angular/issues/34017)) ([b659aa3](https://github.com/angular/angular/commit/b659aa3))
|
||||||
* **ivy:** track changes across failed builds ([#33971](https://github.com/angular/angular/issues/33971)) ([1ffbde1](https://github.com/angular/angular/commit/1ffbde1)), closes [#32214](https://github.com/angular/angular/issues/32214)
|
* **ivy:** track changes across failed builds ([#33971](https://github.com/angular/angular/issues/33971)) ([1ffbde1](https://github.com/angular/angular/commit/1ffbde1)), closes [#32214](https://github.com/angular/angular/issues/32214)
|
||||||
* **ivy:** wrap functions from "providers" in parentheses in Closure mode ([#33609](https://github.com/angular/angular/issues/33609)) ([fc6ad19](https://github.com/angular/angular/commit/fc6ad19)), closes [/github.com/angular/tsickle/blob/d7974262571c8a17d684e5ba07680e1b1993afdd/src/jsdoc_transformer.ts#L1021](https://github.com/angular/tsickle/blob/d7974262571c8a17d684e5ba07680e1b1993afdd/src/jsdoc_transformer.ts/issues/L1021)
|
* **ivy:** wrap functions from "providers" in parentheses in Closure mode ([#33609](https://github.com/angular/angular/issues/33609)) ([fc6ad19](https://github.com/angular/angular/commit/fc6ad19)), closes [/github.com/angular/tsickle/blob/d7974262571c8a17d684e5ba07680e1b1993afdd/src/jsdoc_transformer.ts#L1021](https://github.com//github.com/angular/tsickle/blob/d7974262571c8a17d684e5ba07680e1b1993afdd/src/jsdoc_transformer.ts/issues/L1021)
|
||||||
* **language-service:** determine index types accessed using dot notation ([#33884](https://github.com/angular/angular/issues/33884)) ([e8ec296](https://github.com/angular/angular/commit/e8ec296)), closes [#29811](https://github.com/angular/angular/issues/29811) [#29811](https://github.com/angular/angular/issues/29811)
|
* **language-service:** determine index types accessed using dot notation ([#33884](https://github.com/angular/angular/issues/33884)) ([e8ec296](https://github.com/angular/angular/commit/e8ec296)), closes [#29811](https://github.com/angular/angular/issues/29811) [#29811](https://github.com/angular/angular/issues/29811)
|
||||||
* **language-service:** fix error of array-index out of bounds exception ([#33928](https://github.com/angular/angular/issues/33928)) ([b05ce85](https://github.com/angular/angular/commit/b05ce85))
|
* **language-service:** fix error of array-index out of bounds exception ([#33928](https://github.com/angular/angular/issues/33928)) ([b05ce85](https://github.com/angular/angular/commit/b05ce85))
|
||||||
* **language-service:** function.bind() should not be an error ([#34041](https://github.com/angular/angular/issues/34041)) ([#34046](https://github.com/angular/angular/issues/34046)) ([d22f3d6](https://github.com/angular/angular/commit/d22f3d6))
|
* **language-service:** function.bind() should not be an error ([#34041](https://github.com/angular/angular/issues/34041)) ([#34046](https://github.com/angular/angular/issues/34046)) ([d22f3d6](https://github.com/angular/angular/commit/d22f3d6))
|
||||||
@ -1142,7 +735,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//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))
|
||||||
@ -1221,7 +814,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//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)
|
||||||
@ -1251,7 +844,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//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))
|
||||||
@ -1265,7 +858,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** use ReflectionHost to check exports when writing an import ([#33192](https://github.com/angular/angular/issues/33192)) ([de44570](https://github.com/angular/angular/commit/de44570))
|
* **ivy:** use ReflectionHost to check exports when writing an import ([#33192](https://github.com/angular/angular/issues/33192)) ([de44570](https://github.com/angular/angular/commit/de44570))
|
||||||
* **language-service:** Increase project/script version in MockHost.reset() ([#33200](https://github.com/angular/angular/issues/33200)) ([43241a5](https://github.com/angular/angular/commit/43241a5))
|
* **language-service:** Increase project/script version in MockHost.reset() ([#33200](https://github.com/angular/angular/issues/33200)) ([43241a5](https://github.com/angular/angular/commit/43241a5))
|
||||||
* **language-service:** reset MockHost after every spec instead of creating new LS ([#33200](https://github.com/angular/angular/issues/33200)) ([11bf767](https://github.com/angular/angular/commit/11bf767))
|
* **language-service:** reset MockHost after every spec instead of creating new LS ([#33200](https://github.com/angular/angular/issues/33200)) ([11bf767](https://github.com/angular/angular/commit/11bf767))
|
||||||
* **ngcc:** avoid warning when reflecting on index signature member ([#33198](https://github.com/angular/angular/issues/33198)) ([78214e7](https://github.com/angular/angular/commit/78214e7)), closes [/github.com/angular/angular/blob/4659cc26e/packages/common/http/src/jsonp.ts#L39](https://github.com/angular/angular/blob/4659cc26e/packages/common/http/src/jsonp.ts/issues/L39)
|
* **ngcc:** avoid warning when reflecting on index signature member ([#33198](https://github.com/angular/angular/issues/33198)) ([78214e7](https://github.com/angular/angular/commit/78214e7)), closes [/github.com/angular/angular/blob/4659cc26e/packages/common/http/src/jsonp.ts#L39](https://github.com//github.com/angular/angular/blob/4659cc26e/packages/common/http/src/jsonp.ts/issues/L39)
|
||||||
* **ngcc:** better detection of end of decorator expression ([#33192](https://github.com/angular/angular/issues/33192)) ([5071083](https://github.com/angular/angular/commit/5071083))
|
* **ngcc:** better detection of end of decorator expression ([#33192](https://github.com/angular/angular/issues/33192)) ([5071083](https://github.com/angular/angular/commit/5071083))
|
||||||
* **ngcc:** Esm5ReflectionHost.getDeclarationOfIdentifier should handle aliased inner declarations ([#33252](https://github.com/angular/angular/issues/33252)) ([bfd07b3](https://github.com/angular/angular/commit/bfd07b3))
|
* **ngcc:** Esm5ReflectionHost.getDeclarationOfIdentifier should handle aliased inner declarations ([#33252](https://github.com/angular/angular/issues/33252)) ([bfd07b3](https://github.com/angular/angular/commit/bfd07b3))
|
||||||
* **ngcc:** report the correct viaModule when reflecting over commonjs ([#33192](https://github.com/angular/angular/issues/33192)) ([afcff73](https://github.com/angular/angular/commit/afcff73))
|
* **ngcc:** report the correct viaModule when reflecting over commonjs ([#33192](https://github.com/angular/angular/issues/33192)) ([afcff73](https://github.com/angular/angular/commit/afcff73))
|
||||||
@ -1284,7 +877,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* google3 sync which requires type hints ([#33108](https://github.com/angular/angular/issues/33108)) ([0c69ec2](https://github.com/angular/angular/commit/0c69ec2))
|
* google3 sync which requires type hints ([#33108](https://github.com/angular/angular/issues/33108)) ([0c69ec2](https://github.com/angular/angular/commit/0c69ec2))
|
||||||
* **ngcc:** rename the executable from `ivy-ngcc` to `ngcc` ([#33140](https://github.com/angular/angular/issues/33140)) ([1a34fbc](https://github.com/angular/angular/commit/1a34fbc))
|
* **ngcc:** rename the executable from `ivy-ngcc` to `ngcc` ([#33140](https://github.com/angular/angular/issues/33140)) ([1a34fbc](https://github.com/angular/angular/commit/1a34fbc))
|
||||||
* **service-worker:** continue serving api requests on cache failure ([#32996](https://github.com/angular/angular/issues/32996)) ([52483bf](https://github.com/angular/angular/commit/52483bf)), closes [#21412](https://github.com/angular/angular/issues/21412)
|
* **service-worker:** continue serving api requests on cache failure ([#32996](https://github.com/angular/angular/issues/32996)) ([52483bf](https://github.com/angular/angular/commit/52483bf)), closes [#21412](https://github.com/angular/angular/issues/21412)
|
||||||
* **common:** expand type for "ngForOf" input to work with strict null checks ([#31371](https://github.com/angular/angular/issues/31371)) ([c1bb886](https://github.com/angular/angular/commit/c1bb886)), closes [#16373](https://github.com/angular/components/pull/16373)
|
* **common:** expand type for "ngForOf" input to work with strict null checks ([#31371](https://github.com/angular/angular/issues/31371)) ([c1bb886](https://github.com/angular/angular/commit/c1bb886)), closes [#16373](https://github.com//github.com/angular/components/pull/16373)
|
||||||
* **core:** ngNoopZone should have the same signature with ngZone ([#32068](https://github.com/angular/angular/issues/32068)) ([3a53e2c](https://github.com/angular/angular/commit/3a53e2c)), closes [#32063](https://github.com/angular/angular/issues/32063)
|
* **core:** ngNoopZone should have the same signature with ngZone ([#32068](https://github.com/angular/angular/issues/32068)) ([3a53e2c](https://github.com/angular/angular/commit/3a53e2c)), closes [#32063](https://github.com/angular/angular/issues/32063)
|
||||||
* **core:** set migration schematic versions to valid semver versions ([#32991](https://github.com/angular/angular/issues/32991)) ([0119f46](https://github.com/angular/angular/commit/0119f46))
|
* **core:** set migration schematic versions to valid semver versions ([#32991](https://github.com/angular/angular/issues/32991)) ([0119f46](https://github.com/angular/angular/commit/0119f46))
|
||||||
* **core:** update migration descriptions with links to AIO documentation ([#32991](https://github.com/angular/angular/issues/32991)) ([f8eca84](https://github.com/angular/angular/commit/f8eca84))
|
* **core:** update migration descriptions with links to AIO documentation ([#32991](https://github.com/angular/angular/issues/32991)) ([f8eca84](https://github.com/angular/angular/commit/f8eca84))
|
||||||
@ -1308,7 +901,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//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))
|
||||||
@ -1417,7 +1010,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//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))
|
||||||
@ -1459,7 +1052,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//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))
|
||||||
@ -1868,7 +1461,7 @@ 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)
|
* **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//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//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//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//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>
|
||||||
@ -1877,7 +1470,7 @@ This release contains various API docs improvements.
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **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)
|
* **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//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//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//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//github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1973,7 +1566,7 @@ This release contains various API docs improvements.
|
|||||||
* **bazel:** do not modify tsconfig.json ([#30984](https://github.com/angular/angular/issues/30984)) ([49307f0](https://github.com/angular/angular/commit/49307f0))
|
* **bazel:** do not modify tsconfig.json ([#30984](https://github.com/angular/angular/issues/30984)) ([49307f0](https://github.com/angular/angular/commit/49307f0))
|
||||||
* **bazel:** Load global stylesheet in dev and prod ([#30879](https://github.com/angular/angular/issues/30879)) ([5a7bcd1](https://github.com/angular/angular/commit/5a7bcd1))
|
* **bazel:** Load global stylesheet in dev and prod ([#30879](https://github.com/angular/angular/issues/30879)) ([5a7bcd1](https://github.com/angular/angular/commit/5a7bcd1))
|
||||||
* **common:** expose the `HttpUploadProgressEvent` interface as public API ([#30852](https://github.com/angular/angular/issues/30852)) ([4e8614b](https://github.com/angular/angular/commit/4e8614b)), closes [#30814](https://github.com/angular/angular/issues/30814)
|
* **common:** expose the `HttpUploadProgressEvent` interface as public API ([#30852](https://github.com/angular/angular/issues/30852)) ([4e8614b](https://github.com/angular/angular/commit/4e8614b)), closes [#30814](https://github.com/angular/angular/issues/30814)
|
||||||
* **core:** TypeScript related migrations should cater for BOM ([#30719](https://github.com/angular/angular/issues/30719)) ([26e3615](https://github.com/angular/angular/commit/26e3615)), closes [/github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts#L72](https://github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts/issues/L72) [#30713](https://github.com/angular/angular/issues/30713)
|
* **core:** TypeScript related migrations should cater for BOM ([#30719](https://github.com/angular/angular/issues/30719)) ([26e3615](https://github.com/angular/angular/commit/26e3615)), closes [/github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts#L72](https://github.com//github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts/issues/L72) [#30713](https://github.com/angular/angular/issues/30713)
|
||||||
* **service-worker:** avoid uncaught rejection warning when registration fails ([#30876](https://github.com/angular/angular/issues/30876)) ([08c38a1](https://github.com/angular/angular/commit/08c38a1))
|
* **service-worker:** avoid uncaught rejection warning when registration fails ([#30876](https://github.com/angular/angular/issues/30876)) ([08c38a1](https://github.com/angular/angular/commit/08c38a1))
|
||||||
|
|
||||||
|
|
||||||
@ -1984,7 +1577,7 @@ This release contains various API docs improvements.
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **core:** TypeScript related migrations should cater for BOM ([#30719](https://github.com/angular/angular/issues/30719)) ([80394ce](https://github.com/angular/angular/commit/80394ce)), closes [/github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts#L72](https://github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts/issues/L72) [#30713](https://github.com/angular/angular/issues/30713)
|
* **core:** TypeScript related migrations should cater for BOM ([#30719](https://github.com/angular/angular/issues/30719)) ([80394ce](https://github.com/angular/angular/commit/80394ce)), closes [/github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts#L72](https://github.com//github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/src/tree/recorder.ts/issues/L72) [#30713](https://github.com/angular/angular/issues/30713)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2137,7 +1730,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **common:** add upgrade sub-package to `ng_package` rule for @angular/common ([#30117](https://github.com/angular/angular/issues/30117)) ([6de4cbd](https://github.com/angular/angular/commit/6de4cbd)), closes [#30055](https://github.com/angular/angular/issues/30055) [#30116](https://github.com/angular/angular/issues/30116)
|
* **common:** add upgrade sub-package to `ng_package` rule for @angular/common ([#30117](https://github.com/angular/angular/issues/30117)) ([6de4cbd](https://github.com/angular/angular/commit/6de4cbd)), closes [#30055](https://github.com/angular/angular/issues/30055) [#30116](https://github.com/angular/angular/issues/30116)
|
||||||
* **common:** adjust `MockPlatformLocation` to set state to new object ([#30055](https://github.com/angular/angular/issues/30055)) ([825efa8](https://github.com/angular/angular/commit/825efa8))
|
* **common:** adjust `MockPlatformLocation` to set state to new object ([#30055](https://github.com/angular/angular/issues/30055)) ([825efa8](https://github.com/angular/angular/commit/825efa8))
|
||||||
* **compiler:** Fix compiler crash due to isSkipSelf of null ([#30075](https://github.com/angular/angular/issues/30075)) ([28fd5ab](https://github.com/angular/angular/commit/28fd5ab))
|
* **compiler:** Fix compiler crash due to isSkipSelf of null ([#30075](https://github.com/angular/angular/issues/30075)) ([28fd5ab](https://github.com/angular/angular/commit/28fd5ab))
|
||||||
* **upgrade:** do not break if `onMicrotaskEmpty` emits while a `$digest` is in progress ([#29794](https://github.com/angular/angular/issues/29794)) ([0ddf2e7](https://github.com/angular/angular/commit/0ddf2e7)), closes [#24680](https://github.com/angular/angular/issues/24680) [/github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts#L12](https://github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts/issues/L12) [#24680](https://github.com/angular/angular/issues/24680)
|
* **upgrade:** do not break if `onMicrotaskEmpty` emits while a `$digest` is in progress ([#29794](https://github.com/angular/angular/issues/29794)) ([0ddf2e7](https://github.com/angular/angular/commit/0ddf2e7)), closes [#24680](https://github.com/angular/angular/issues/24680) [/github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts#L12](https://github.com//github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts/issues/L12) [#24680](https://github.com/angular/angular/issues/24680)
|
||||||
* **bazel:** do not typecheck core schematic files ([#29876](https://github.com/angular/angular/issues/29876)) ([2ba799d](https://github.com/angular/angular/commit/2ba799d))
|
* **bazel:** do not typecheck core schematic files ([#29876](https://github.com/angular/angular/issues/29876)) ([2ba799d](https://github.com/angular/angular/commit/2ba799d))
|
||||||
* **bazel:** restore `ng build --prod` ([#30005](https://github.com/angular/angular/issues/30005)) ([96a8289](https://github.com/angular/angular/commit/96a8289))
|
* **bazel:** restore `ng build --prod` ([#30005](https://github.com/angular/angular/issues/30005)) ([96a8289](https://github.com/angular/angular/commit/96a8289))
|
||||||
* **common:** prevent repeated application of `HttpParams` mutations ([#29045](https://github.com/angular/angular/issues/29045)) ([8e8e89a](https://github.com/angular/angular/commit/8e8e89a)), closes [#20430](https://github.com/angular/angular/issues/20430)
|
* **common:** prevent repeated application of `HttpParams` mutations ([#29045](https://github.com/angular/angular/issues/29045)) ([8e8e89a](https://github.com/angular/angular/commit/8e8e89a)), closes [#20430](https://github.com/angular/angular/issues/20430)
|
||||||
@ -2191,7 +1784,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//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))
|
||||||
@ -2199,7 +1792,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **language-service:** Fix completions for input/output with alias ([#28904](https://github.com/angular/angular/issues/28904)) ([ad4a9bf](https://github.com/angular/angular/commit/ad4a9bf)), closes [#27959](https://github.com/angular/angular/issues/27959)
|
* **language-service:** Fix completions for input/output with alias ([#28904](https://github.com/angular/angular/issues/28904)) ([ad4a9bf](https://github.com/angular/angular/commit/ad4a9bf)), closes [#27959](https://github.com/angular/angular/issues/27959)
|
||||||
* **bazel:** Add postinstall step to generate summaries ([#28850](https://github.com/angular/angular/issues/28850)) ([96b597c](https://github.com/angular/angular/commit/96b597c))
|
* **bazel:** Add postinstall step to generate summaries ([#28850](https://github.com/angular/angular/issues/28850)) ([96b597c](https://github.com/angular/angular/commit/96b597c))
|
||||||
* **bazel:** Schematics should upgrade rxjs to 6.4.0 ([#28841](https://github.com/angular/angular/issues/28841)) ([2d80419](https://github.com/angular/angular/commit/2d80419))
|
* **bazel:** Schematics should upgrade rxjs to 6.4.0 ([#28841](https://github.com/angular/angular/issues/28841)) ([2d80419](https://github.com/angular/angular/commit/2d80419))
|
||||||
* **compiler-cli:** incorrect bundled metadata for static class member call expressions ([#28762](https://github.com/angular/angular/issues/28762)) ([4131715](https://github.com/angular/angular/commit/4131715)), closes [/github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts#L121](https://github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts/issues/L121) [#28741](https://github.com/angular/angular/issues/28741)
|
* **compiler-cli:** incorrect bundled metadata for static class member call expressions ([#28762](https://github.com/angular/angular/issues/28762)) ([4131715](https://github.com/angular/angular/commit/4131715)), closes [/github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts#L121](https://github.com//github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts/issues/L121) [#28741](https://github.com/angular/angular/issues/28741)
|
||||||
* **bazel:** Install angular repo before yarn_install ([#28670](https://github.com/angular/angular/issues/28670)) ([49fb8c3](https://github.com/angular/angular/commit/49fb8c3))
|
* **bazel:** Install angular repo before yarn_install ([#28670](https://github.com/angular/angular/issues/28670)) ([49fb8c3](https://github.com/angular/angular/commit/49fb8c3))
|
||||||
* **bazel:** Turn on strict action env ([#28675](https://github.com/angular/angular/issues/28675)) ([2ea030c](https://github.com/angular/angular/commit/2ea030c))
|
* **bazel:** Turn on strict action env ([#28675](https://github.com/angular/angular/issues/28675)) ([2ea030c](https://github.com/angular/angular/commit/2ea030c))
|
||||||
* **compiler:** ensure that event handlers have the correct source spans ([#28055](https://github.com/angular/angular/issues/28055)) ([cffd862](https://github.com/angular/angular/commit/cffd862))
|
* **compiler:** ensure that event handlers have the correct source spans ([#28055](https://github.com/angular/angular/issues/28055)) ([cffd862](https://github.com/angular/angular/commit/cffd862))
|
||||||
@ -2352,7 +1945,7 @@ For details on how to migrate, please refer to [the deprecations guide](https://
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **upgrade:** do not break if `onMicrotaskEmpty` emits while a `$digest` is in progress ([#29794](https://github.com/angular/angular/issues/29794)) ([#30107](https://github.com/angular/angular/issues/30107)) ([1084c19](https://github.com/angular/angular/commit/1084c19)), closes [#24680](https://github.com/angular/angular/issues/24680) [/github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts#L12](https://github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts/issues/L12) [#24680](https://github.com/angular/angular/issues/24680)
|
* **upgrade:** do not break if `onMicrotaskEmpty` emits while a `$digest` is in progress ([#29794](https://github.com/angular/angular/issues/29794)) ([#30107](https://github.com/angular/angular/issues/30107)) ([1084c19](https://github.com/angular/angular/commit/1084c19)), closes [#24680](https://github.com/angular/angular/issues/24680) [/github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts#L12](https://github.com//github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts/issues/L12) [#24680](https://github.com/angular/angular/issues/24680)
|
||||||
|
|
||||||
|
|
||||||
<a name="7.2.13"></a>
|
<a name="7.2.13"></a>
|
||||||
@ -2406,7 +1999,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//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>
|
||||||
@ -2426,7 +2019,7 @@ This release contains various API docs improvements.
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **compiler-cli:** incorrect bundled metadata for static class member call expressions ([#28762](https://github.com/angular/angular/issues/28762)) ([ab69c31](https://github.com/angular/angular/commit/ab69c31)), closes [/github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts#L121](https://github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts/issues/L121) [#28741](https://github.com/angular/angular/issues/28741)
|
* **compiler-cli:** incorrect bundled metadata for static class member call expressions ([#28762](https://github.com/angular/angular/issues/28762)) ([ab69c31](https://github.com/angular/angular/commit/ab69c31)), closes [/github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts#L121](https://github.com//github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts/issues/L121) [#28741](https://github.com/angular/angular/issues/28741)
|
||||||
|
|
||||||
|
|
||||||
<a name="7.2.5"></a>
|
<a name="7.2.5"></a>
|
||||||
@ -2569,7 +2162,7 @@ This release contains various API docs improvements.
|
|||||||
* **bazel:** emit full node stack traces when Angular compilation crashes ([#27678](https://github.com/angular/angular/issues/27678)) ([522919a](https://github.com/angular/angular/commit/522919a))
|
* **bazel:** emit full node stack traces when Angular compilation crashes ([#27678](https://github.com/angular/angular/issues/27678)) ([522919a](https://github.com/angular/angular/commit/522919a))
|
||||||
* **bazel:** fix major/minor semver check between @angular/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([1cc08b4](https://github.com/angular/angular/commit/1cc08b4))
|
* **bazel:** fix major/minor semver check between @angular/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([1cc08b4](https://github.com/angular/angular/commit/1cc08b4))
|
||||||
* **bazel:** Load http_archive and rules_nodejs dependencies ([#27609](https://github.com/angular/angular/issues/27609)) ([8313ffc](https://github.com/angular/angular/commit/8313ffc))
|
* **bazel:** Load http_archive and rules_nodejs dependencies ([#27609](https://github.com/angular/angular/issues/27609)) ([8313ffc](https://github.com/angular/angular/commit/8313ffc))
|
||||||
* **bazel:** ng_package writes unrelevant definitions to bazel out ([#27519](https://github.com/angular/angular/issues/27519)) ([44dfa60](https://github.com/angular/angular/commit/44dfa60)), closes [/github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts#L105-L124](https://github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts/issues/L105-L124)
|
* **bazel:** ng_package writes unrelevant definitions to bazel out ([#27519](https://github.com/angular/angular/issues/27519)) ([44dfa60](https://github.com/angular/angular/commit/44dfa60)), closes [/github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts#L105-L124](https://github.com//github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts/issues/L105-L124)
|
||||||
* **bazel:** Set module_name and enable ng test ([#27715](https://github.com/angular/angular/issues/27715)) ([85866de](https://github.com/angular/angular/commit/85866de))
|
* **bazel:** Set module_name and enable ng test ([#27715](https://github.com/angular/angular/issues/27715)) ([85866de](https://github.com/angular/angular/commit/85866de))
|
||||||
* **bazel:** fix TS errors in the `schematics/bazel-workspace` files ([#27600](https://github.com/angular/angular/issues/27600)) ([3290fc3](https://github.com/angular/angular/commit/3290fc3))
|
* **bazel:** fix TS errors in the `schematics/bazel-workspace` files ([#27600](https://github.com/angular/angular/issues/27600)) ([3290fc3](https://github.com/angular/angular/commit/3290fc3))
|
||||||
* **bazel:** Read latest versions from latest-versions.ts & use semver check ([#27526](https://github.com/angular/angular/issues/27526)) ([30a3b49](https://github.com/angular/angular/commit/30a3b49))
|
* **bazel:** Read latest versions from latest-versions.ts & use semver check ([#27526](https://github.com/angular/angular/issues/27526)) ([30a3b49](https://github.com/angular/angular/commit/30a3b49))
|
||||||
@ -2609,7 +2202,7 @@ This release contains various API docs improvements.
|
|||||||
* **bazel:** emit full node stack traces when Angular compilation crashes ([#27678](https://github.com/angular/angular/issues/27678)) ([0d8528b](https://github.com/angular/angular/commit/0d8528b))
|
* **bazel:** emit full node stack traces when Angular compilation crashes ([#27678](https://github.com/angular/angular/issues/27678)) ([0d8528b](https://github.com/angular/angular/commit/0d8528b))
|
||||||
* **bazel:** fix major/minor semver check between @angular/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([3ed1e84](https://github.com/angular/angular/commit/3ed1e84))
|
* **bazel:** fix major/minor semver check between @angular/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([3ed1e84](https://github.com/angular/angular/commit/3ed1e84))
|
||||||
* **bazel:** Load http_archive and rules_nodejs dependencies ([#27609](https://github.com/angular/angular/issues/27609)) ([89ace1a](https://github.com/angular/angular/commit/89ace1a))
|
* **bazel:** Load http_archive and rules_nodejs dependencies ([#27609](https://github.com/angular/angular/issues/27609)) ([89ace1a](https://github.com/angular/angular/commit/89ace1a))
|
||||||
* **bazel:** ng_package writes unrelevant definitions to bazel out ([#27519](https://github.com/angular/angular/issues/27519)) ([ef056c5](https://github.com/angular/angular/commit/ef056c5)), closes [/github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts#L105-L124](https://github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts/issues/L105-L124)
|
* **bazel:** ng_package writes unrelevant definitions to bazel out ([#27519](https://github.com/angular/angular/issues/27519)) ([ef056c5](https://github.com/angular/angular/commit/ef056c5)), closes [/github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts#L105-L124](https://github.com//github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts/issues/L105-L124)
|
||||||
* **bazel:** Read latest versions from latest-versions.ts & use semver check ([#27591](https://github.com/angular/angular/issues/27591)) ([93078e3](https://github.com/angular/angular/commit/93078e3))
|
* **bazel:** Read latest versions from latest-versions.ts & use semver check ([#27591](https://github.com/angular/angular/issues/27591)) ([93078e3](https://github.com/angular/angular/commit/93078e3))
|
||||||
* **bazel:** Set module_name and enable ng test ([#27715](https://github.com/angular/angular/issues/27715)) ([183f278](https://github.com/angular/angular/commit/183f278))
|
* **bazel:** Set module_name and enable ng test ([#27715](https://github.com/angular/angular/issues/27715)) ([183f278](https://github.com/angular/angular/commit/183f278))
|
||||||
* **common:** KeyValuePipe should return empty array for empty objects ([#27258](https://github.com/angular/angular/issues/27258)) ([fa3af8b](https://github.com/angular/angular/commit/fa3af8b))
|
* **common:** KeyValuePipe should return empty array for empty objects ([#27258](https://github.com/angular/angular/issues/27258)) ([fa3af8b](https://github.com/angular/angular/commit/fa3af8b))
|
||||||
@ -2638,7 +2231,7 @@ This release contains various API docs improvements.
|
|||||||
* **bazel:** ng_package not generating UMD bundles on windows ([#27200](https://github.com/angular/angular/issues/27200)) ([e476c38](https://github.com/angular/angular/commit/e476c38))
|
* **bazel:** ng_package not generating UMD bundles on windows ([#27200](https://github.com/angular/angular/issues/27200)) ([e476c38](https://github.com/angular/angular/commit/e476c38))
|
||||||
* **bazel:** ng_package should correctly map to source maps in secondary entry-points ([#27313](https://github.com/angular/angular/issues/27313)) ([fc2c23e](https://github.com/angular/angular/commit/fc2c23e)), closes [#25510](https://github.com/angular/angular/issues/25510)
|
* **bazel:** ng_package should correctly map to source maps in secondary entry-points ([#27313](https://github.com/angular/angular/issues/27313)) ([fc2c23e](https://github.com/angular/angular/commit/fc2c23e)), closes [#25510](https://github.com/angular/angular/issues/25510)
|
||||||
* **compiler-cli:** flatModuleIndex files not generated on windows with multiple input files ([#27200](https://github.com/angular/angular/issues/27200)) ([8087b6b](https://github.com/angular/angular/commit/8087b6b))
|
* **compiler-cli:** flatModuleIndex files not generated on windows with multiple input files ([#27200](https://github.com/angular/angular/issues/27200)) ([8087b6b](https://github.com/angular/angular/commit/8087b6b))
|
||||||
* **compiler-cli:** ngtsc shim files not being generated on case-insensitive platforms ([#27466](https://github.com/angular/angular/issues/27466)) ([84f2928](https://github.com/angular/angular/commit/84f2928)), closes [/github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts#L681-L682](https://github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts/issues/L681-L682)
|
* **compiler-cli:** ngtsc shim files not being generated on case-insensitive platforms ([#27466](https://github.com/angular/angular/issues/27466)) ([84f2928](https://github.com/angular/angular/commit/84f2928)), closes [/github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts#L681-L682](https://github.com//github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts/issues/L681-L682)
|
||||||
* **platform-server:** add @angular/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([236ac06](https://github.com/angular/angular/commit/236ac06)), closes [#26154](https://github.com/angular/angular/issues/26154)
|
* **platform-server:** add @angular/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([236ac06](https://github.com/angular/angular/commit/236ac06)), closes [#26154](https://github.com/angular/angular/issues/26154)
|
||||||
|
|
||||||
|
|
||||||
@ -2862,7 +2455,7 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
|||||||
* **compiler:** update compiler to flatten nested template fns ([#24943](https://github.com/angular/angular/issues/24943)) ([fe14f18](https://github.com/angular/angular/commit/fe14f18))
|
* **compiler:** update compiler to flatten nested template fns ([#24943](https://github.com/angular/angular/issues/24943)) ([fe14f18](https://github.com/angular/angular/commit/fe14f18))
|
||||||
* **compiler:** update compiler to generate new slot allocations ([#25607](https://github.com/angular/angular/issues/25607)) ([27e2039](https://github.com/angular/angular/commit/27e2039))
|
* **compiler:** update compiler to generate new slot allocations ([#25607](https://github.com/angular/angular/issues/25607)) ([27e2039](https://github.com/angular/angular/commit/27e2039))
|
||||||
* **core:** In Testability.whenStable update callback, pass more complete ([#25010](https://github.com/angular/angular/issues/25010)) ([16c03c0](https://github.com/angular/angular/commit/16c03c0))
|
* **core:** In Testability.whenStable update callback, pass more complete ([#25010](https://github.com/angular/angular/issues/25010)) ([16c03c0](https://github.com/angular/angular/commit/16c03c0))
|
||||||
* **core:** add missing `peerDependency ` to `@angular/compiler` ([#26033](https://github.com/angular/angular/issues/26033)) ([549de1e](https://github.com/angular/angular/commit/549de1e)), closes [/github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e#diff-58563046c4439699f2e6a89187099a54](https://github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e/issues/diff-58563046c4439699f2e6a89187099a54)
|
* **core:** add missing `peerDependency ` to `@angular/compiler` ([#26033](https://github.com/angular/angular/issues/26033)) ([549de1e](https://github.com/angular/angular/commit/549de1e)), closes [/github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e#diff-58563046c4439699f2e6a89187099a54](https://github.com//github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e/issues/diff-58563046c4439699f2e6a89187099a54)
|
||||||
* **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)
|
* **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)
|
||||||
* **core:** do not clear element content when using shadow dom ([#24861](https://github.com/angular/angular/issues/24861)) ([6e828bb](https://github.com/angular/angular/commit/6e828bb))
|
* **core:** do not clear element content when using shadow dom ([#24861](https://github.com/angular/angular/issues/24861)) ([6e828bb](https://github.com/angular/angular/commit/6e828bb))
|
||||||
* **core:** size regression with closure compiler ([#25531](https://github.com/angular/angular/issues/25531)) ([1f59f2f](https://github.com/angular/angular/commit/1f59f2f))
|
* **core:** size regression with closure compiler ([#25531](https://github.com/angular/angular/issues/25531)) ([1f59f2f](https://github.com/angular/angular/commit/1f59f2f))
|
||||||
|
279
CONTRIBUTING.md
279
CONTRIBUTING.md
@ -1,7 +1,7 @@
|
|||||||
# Contributing to Angular
|
# Contributing to Angular
|
||||||
|
|
||||||
We would love for you to contribute to Angular and help make it even better than it is today!
|
We would love for you to contribute to Angular and help make it even better than it is
|
||||||
As a contributor, here are the guidelines we would like you to follow:
|
today! As a contributor, here are the guidelines we would like you to follow:
|
||||||
|
|
||||||
- [Code of Conduct](#coc)
|
- [Code of Conduct](#coc)
|
||||||
- [Question or Problem?](#question)
|
- [Question or Problem?](#question)
|
||||||
@ -12,17 +12,12 @@ As a contributor, here are the guidelines we would like you to follow:
|
|||||||
- [Commit Message Guidelines](#commit)
|
- [Commit Message Guidelines](#commit)
|
||||||
- [Signing the CLA](#cla)
|
- [Signing the CLA](#cla)
|
||||||
|
|
||||||
|
|
||||||
## <a name="coc"></a> Code of Conduct
|
## <a name="coc"></a> Code of Conduct
|
||||||
|
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc].
|
||||||
Help us keep Angular open and inclusive.
|
|
||||||
Please read and follow our [Code of Conduct][coc].
|
|
||||||
|
|
||||||
|
|
||||||
## <a name="question"></a> Got a Question or Problem?
|
## <a name="question"></a> Got a Question or Problem?
|
||||||
|
|
||||||
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests.
|
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests. You've got much better chances of getting your question answered on [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) where the questions should be tagged with tag `angular`.
|
||||||
Instead, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) to ask support-related questions. When creating a new question on Stack Overflow, make sure to add the `angular` tag.
|
|
||||||
|
|
||||||
Stack Overflow is a much better place to ask questions since:
|
Stack Overflow is a much better place to ask questions since:
|
||||||
|
|
||||||
@ -34,41 +29,33 @@ To save your and our time, we will systematically close all issues that are requ
|
|||||||
|
|
||||||
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter].
|
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter].
|
||||||
|
|
||||||
|
|
||||||
## <a name="issue"></a> Found a Bug?
|
## <a name="issue"></a> Found a Bug?
|
||||||
|
If you find a bug in the source code, you can help us by
|
||||||
If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github].
|
[submitting an issue](#submit-issue) to our [GitHub Repository][github]. Even better, you can
|
||||||
Even better, you can [submit a Pull Request](#submit-pr) with a fix.
|
[submit a Pull Request](#submit-pr) with a fix.
|
||||||
|
|
||||||
|
|
||||||
## <a name="feature"></a> Missing a Feature?
|
## <a name="feature"></a> Missing a Feature?
|
||||||
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.
|
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub
|
||||||
If you would like to *implement* a new feature, please consider the size of the change in order to determine the right steps to proceed:
|
Repository. If you would like to *implement* a new feature, please submit an issue with
|
||||||
|
a proposal for your work first, to be sure that we can use it.
|
||||||
* For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.
|
Please consider what kind of change it is:
|
||||||
This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.
|
|
||||||
|
|
||||||
**Note**: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature.
|
|
||||||
|
|
||||||
|
* For a **Major Feature**, first open an issue and outline your proposal so that it can be
|
||||||
|
discussed. This will also allow us to better coordinate our efforts, prevent duplication of work,
|
||||||
|
and help you to craft the change so that it is successfully accepted into the project.
|
||||||
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
|
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
|
||||||
|
|
||||||
|
|
||||||
## <a name="submit"></a> Submission Guidelines
|
## <a name="submit"></a> Submission Guidelines
|
||||||
|
|
||||||
|
|
||||||
### <a name="submit-issue"></a> Submitting an Issue
|
### <a name="submit-issue"></a> Submitting an Issue
|
||||||
|
|
||||||
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
|
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
|
||||||
|
|
||||||
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it.
|
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs, we will systematically ask you to provide a minimal reproduction. Having a minimal reproducible scenario gives us a wealth of important information without going back & forth to you with additional questions.
|
||||||
In order to reproduce bugs, we require that you provide a minimal reproduction.
|
|
||||||
Having a minimal reproducible scenario gives us a wealth of important information without going back and forth to you with additional questions.
|
|
||||||
|
|
||||||
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem.
|
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem.
|
||||||
|
|
||||||
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs.
|
We will be insisting on a minimal reproduction scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience, users often find coding problems themselves while preparing a minimal reproduction. We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
|
||||||
Often, developers find coding problems themselves while preparing a minimal reproduction.
|
|
||||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
|
|
||||||
|
|
||||||
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
|
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
|
||||||
|
|
||||||
@ -76,51 +63,42 @@ You can file new issues by selecting from our [new issue templates](https://gith
|
|||||||
|
|
||||||
|
|
||||||
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
|
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
|
||||||
|
|
||||||
Before you submit your Pull Request (PR) consider the following guidelines:
|
Before you submit your Pull Request (PR) consider the following guidelines:
|
||||||
|
|
||||||
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission.
|
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR
|
||||||
You don't want to duplicate existing efforts.
|
that relates to your submission. You don't want to duplicate effort.
|
||||||
|
1. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
|
||||||
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
|
|
||||||
Discussing the design up front helps to ensure that we're ready to accept your work.
|
Discussing the design up front helps to ensure that we're ready to accept your work.
|
||||||
|
1. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
|
||||||
3. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
|
We cannot accept code without this. Make sure you sign with the primary email address of the Git identity that has been granted access to the Angular repository.
|
||||||
We cannot accept code without a signed CLA.
|
1. Fork the angular/angular repo.
|
||||||
Make sure you author all contributed Git commits with email address associated with your CLA signature.
|
1. Make your changes in a new git branch:
|
||||||
|
|
||||||
4. Fork the angular/angular repo.
|
|
||||||
|
|
||||||
5. Make your changes in a new git branch:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git checkout -b my-fix-branch master
|
git checkout -b my-fix-branch master
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Create your patch, **including appropriate test cases**.
|
1. Create your patch, **including appropriate test cases**.
|
||||||
|
1. Follow our [Coding Rules](#rules).
|
||||||
7. Follow our [Coding Rules](#rules).
|
1. Run the full Angular test suite, as described in the [developer documentation][dev-doc],
|
||||||
|
and ensure that all tests pass.
|
||||||
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
|
1. Commit your changes using a descriptive commit message that follows our
|
||||||
|
[commit message conventions](#commit). Adherence to these conventions
|
||||||
9. Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit).
|
is necessary because release notes are automatically generated from these messages.
|
||||||
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git commit -a
|
git commit -a
|
||||||
```
|
```
|
||||||
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
||||||
|
|
||||||
10. Push your branch to GitHub:
|
1. Push your branch to GitHub:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git push origin my-fix-branch
|
git push origin my-fix-branch
|
||||||
```
|
```
|
||||||
|
|
||||||
11. In GitHub, send a pull request to `angular:master`.
|
1. In GitHub, send a pull request to `angular:master`.
|
||||||
|
* If we suggest changes then:
|
||||||
If we ask for changes via code reviews then:
|
|
||||||
|
|
||||||
* Make the required updates.
|
* Make the required updates.
|
||||||
* Re-run the Angular test suites to ensure tests are still passing.
|
* Re-run the Angular test suites to ensure tests are still passing.
|
||||||
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
|
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
|
||||||
@ -132,10 +110,10 @@ Before you submit your Pull Request (PR) consider the following guidelines:
|
|||||||
|
|
||||||
That's it! Thank you for your contribution!
|
That's it! Thank you for your contribution!
|
||||||
|
|
||||||
|
|
||||||
#### After your pull request is merged
|
#### After your pull request is merged
|
||||||
|
|
||||||
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:
|
After your pull request is merged, you can safely delete your branch and pull the changes
|
||||||
|
from the main (upstream) repository:
|
||||||
|
|
||||||
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
|
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
|
||||||
|
|
||||||
@ -161,66 +139,55 @@ After your pull request is merged, you can safely delete your branch and pull th
|
|||||||
git pull --ff upstream master
|
git pull --ff upstream master
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## <a name="rules"></a> Coding Rules
|
## <a name="rules"></a> Coding Rules
|
||||||
To ensure consistency throughout the source code, keep these rules in mind as you are working:
|
To ensure consistency throughout the source code, keep these rules in mind as you are working:
|
||||||
|
|
||||||
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
|
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
|
||||||
* All public API methods **must be documented**.
|
* All public API methods **must be documented**. (Details TBC).
|
||||||
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
|
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at
|
||||||
|
**100 characters**. An automated formatter is available, see
|
||||||
|
[DEVELOPER.md](docs/DEVELOPER.md#clang-format).
|
||||||
|
|
||||||
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
|
## <a name="commit"></a> Commit Message Guidelines
|
||||||
|
|
||||||
|
We have very precise rules over how our git commit messages can be formatted. This leads to **more
|
||||||
|
readable messages** that are easy to follow when looking through the **project history**. But also,
|
||||||
|
we use the git commit messages to **generate the Angular change log**.
|
||||||
|
|
||||||
## <a name="commit"></a> Commit Message Format
|
### Commit Message Format
|
||||||
|
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
|
||||||
*This specification is inspired and supersedes the [AngularJS commit message format][commit-message-format].*
|
format that includes a **type**, a **scope** and a **subject**:
|
||||||
|
|
||||||
We have very precise rules over how our Git commit messages must be formatted.
|
|
||||||
This format leads to **easier to read commit history**.
|
|
||||||
|
|
||||||
Each commit message consists of a **header**, a **body**, and a **footer**.
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
<header>
|
<type>(<scope>): <subject>
|
||||||
<BLANK LINE>
|
<BLANK LINE>
|
||||||
<body>
|
<body>
|
||||||
<BLANK LINE>
|
<BLANK LINE>
|
||||||
<footer>
|
<footer>
|
||||||
```
|
```
|
||||||
|
|
||||||
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format.
|
The **header** is mandatory and the **scope** of the header is optional.
|
||||||
|
|
||||||
The `body` is mandatory for all commits except for those of scope "docs".
|
Any line of the commit message cannot be longer than 100 characters! This allows the message to be easier
|
||||||
When the body is required it must be at least 20 characters long.
|
to read on GitHub as well as in various git tools.
|
||||||
|
|
||||||
The `footer` is optional.
|
The footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.
|
||||||
|
|
||||||
Any line of the commit message cannot be longer than 100 characters.
|
Samples: (even more [samples](https://github.com/angular/angular/commits/master))
|
||||||
|
|
||||||
|
|
||||||
#### <a href="commit-header"></a>Commit Message Header
|
|
||||||
|
|
||||||
```
|
```
|
||||||
<type>(<scope>): <short summary>
|
docs(changelog): update changelog to beta.5
|
||||||
│ │ │
|
```
|
||||||
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
|
```
|
||||||
│ │
|
fix(release): need to depend on latest rxjs and zone.js
|
||||||
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
|
||||||
│ elements|forms|http|language-service|localize|platform-browser|
|
The version in our package.json gets copied to the one we publish, and users need the latest of these.
|
||||||
│ platform-browser-dynamic|platform-server|platform-webworker|
|
|
||||||
│ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
|
|
||||||
│ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
|
|
||||||
│
|
|
||||||
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.
|
### Revert
|
||||||
|
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
|
||||||
|
|
||||||
##### Type
|
|
||||||
|
|
||||||
|
### Type
|
||||||
Must be one of the following:
|
Must be one of the following:
|
||||||
|
|
||||||
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
||||||
@ -233,95 +200,66 @@ Must be one of the following:
|
|||||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
||||||
* **test**: Adding missing tests or correcting existing tests
|
* **test**: Adding missing tests or correcting existing tests
|
||||||
|
|
||||||
|
### Scope
|
||||||
##### Scope
|
|
||||||
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
|
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
|
||||||
|
|
||||||
The following is the list of supported scopes:
|
The following is the list of supported scopes:
|
||||||
|
|
||||||
* `animations`
|
* **animations**
|
||||||
* `bazel`
|
* **bazel**
|
||||||
* `benchpress`
|
* **benchpress**
|
||||||
* `common`
|
* **common**
|
||||||
* `compiler`
|
* **compiler**
|
||||||
* `compiler-cli`
|
* **compiler-cli**
|
||||||
* `core`
|
* **core**
|
||||||
* `elements`
|
* **elements**
|
||||||
* `forms`
|
* **forms**
|
||||||
* `http`
|
* **http**
|
||||||
* `language-service`
|
* **language-service**
|
||||||
* `localize`
|
* **localize**
|
||||||
* `platform-browser`
|
* **platform-browser**
|
||||||
* `platform-browser-dynamic`
|
* **platform-browser-dynamic**
|
||||||
* `platform-server`
|
* **platform-server**
|
||||||
* `platform-webworker`
|
* **platform-webworker**
|
||||||
* `platform-webworker-dynamic`
|
* **platform-webworker-dynamic**
|
||||||
* `router`
|
* **router**
|
||||||
* `service-worker`
|
* **service-worker**
|
||||||
* `upgrade`
|
* **upgrade**
|
||||||
* `zone.js`
|
* **zone.js**
|
||||||
|
|
||||||
There are currently a few exceptions to the "use package name" rule:
|
There are currently a few exceptions to the "use package name" rule:
|
||||||
|
|
||||||
* `packaging`: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
|
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g.
|
||||||
|
public path changes, package.json changes done to all packages, d.ts file/format changes, changes
|
||||||
|
to bundles, etc.
|
||||||
|
* **changelog**: used for updating the release notes in CHANGELOG.md
|
||||||
|
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
|
||||||
|
repo
|
||||||
|
* **dev-infra**: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra
|
||||||
|
* **ngcc**: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
|
||||||
|
* **ve**: used for changes specific to ViewEngine (legacy compiler/renderer).
|
||||||
|
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
|
||||||
|
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
|
||||||
|
specific package (e.g. `docs: fix typo in tutorial`).
|
||||||
|
|
||||||
* `changelog`: used for updating the release notes in CHANGELOG.md
|
### Subject
|
||||||
|
The subject contains a succinct description of the change:
|
||||||
* `dev-infra`: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra
|
|
||||||
|
|
||||||
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
|
|
||||||
|
|
||||||
* `migrations`: used for changes to the `ng update` migrations.
|
|
||||||
|
|
||||||
* `ngcc`: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
|
|
||||||
|
|
||||||
* `ve`: used for changes specific to ViewEngine (legacy compiler/renderer).
|
|
||||||
|
|
||||||
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a specific package (e.g. `docs: fix typo in tutorial`).
|
|
||||||
|
|
||||||
|
|
||||||
##### Summary
|
|
||||||
|
|
||||||
Use the summary field to provide a succinct description of the change:
|
|
||||||
|
|
||||||
* use the imperative, present tense: "change" not "changed" nor "changes"
|
* use the imperative, present tense: "change" not "changed" nor "changes"
|
||||||
* don't capitalize the first letter
|
* don't capitalize the first letter
|
||||||
* no dot (.) at the end
|
* no dot (.) at the end
|
||||||
|
|
||||||
|
### Body
|
||||||
|
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
|
||||||
|
The body should include the motivation for the change and contrast this with previous behavior.
|
||||||
|
|
||||||
#### Commit Message Body
|
### Footer
|
||||||
|
The footer should contain any information about **Breaking Changes** and is also the place to
|
||||||
|
reference GitHub issues that this commit **Closes**.
|
||||||
|
|
||||||
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
|
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
|
||||||
|
|
||||||
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change.
|
|
||||||
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
|
|
||||||
|
|
||||||
|
|
||||||
#### Commit Message Footer
|
|
||||||
|
|
||||||
The footer can contain information about breaking changes and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
|
|
||||||
|
|
||||||
```
|
|
||||||
BREAKING CHANGE: <breaking change summary>
|
|
||||||
<BLANK LINE>
|
|
||||||
<breaking change description + migration instructions>
|
|
||||||
<BLANK LINE>
|
|
||||||
<BLANK LINE>
|
|
||||||
Fixes #<issue number>
|
|
||||||
```
|
|
||||||
|
|
||||||
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
|
|
||||||
|
|
||||||
|
|
||||||
### Revert commits
|
|
||||||
|
|
||||||
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
|
|
||||||
|
|
||||||
The content of the commit message body should contain:
|
|
||||||
|
|
||||||
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`,
|
|
||||||
- a clear description of the reason for reverting the commit message.
|
|
||||||
|
|
||||||
|
A detailed explanation can be found in this [document][commit-message-format].
|
||||||
|
|
||||||
## <a name="cla"></a> Signing the CLA
|
## <a name="cla"></a> Signing the CLA
|
||||||
|
|
||||||
@ -332,17 +270,18 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise
|
|||||||
* For corporations, we'll need you to
|
* For corporations, we'll need you to
|
||||||
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
|
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
|
||||||
|
|
||||||
If you have more than one GitHub accounts, or multiple email addresses associated with a single GitHub account, you must sign the CLA using the primary email address of the GitHub account used to author Git commits and send pull requests.
|
<hr>
|
||||||
|
|
||||||
The following documents can help you sort out issues with GitHub accounts and multiple email addresses:
|
If you have more than one Git identity, you must make sure that you sign the CLA using the primary email address associated with the ID that has been granted access to the Angular repository. Git identities can be associated with more than one email address, and only one is primary. Here are some links to help you sort out multiple Git identities and email addresses:
|
||||||
|
|
||||||
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
|
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
|
||||||
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
|
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
|
||||||
* https://help.github.com/articles/about-commit-email-addresses/
|
* https://help.github.com/articles/about-commit-email-addresses/
|
||||||
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
|
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
|
||||||
|
|
||||||
|
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
[angular-group]: https://groups.google.com/forum/#!forum/angular
|
[angular-group]: https://groups.google.com/forum/#!forum/angular
|
||||||
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
|
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
|
||||||
|
15
WORKSPACE
15
WORKSPACE
@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
|||||||
# Fetch rules_nodejs so we can install our npm dependencies
|
# Fetch rules_nodejs so we can install our npm dependencies
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "build_bazel_rules_nodejs",
|
name = "build_bazel_rules_nodejs",
|
||||||
sha256 = "84abf7ac4234a70924628baa9a73a5a5cbad944c4358cf9abdb4aab29c9a5b77",
|
sha256 = "f9e7b9f42ae202cc2d2ce6d698ccb49a9f7f7ea572a78fd451696d03ef2ee116",
|
||||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.7.0/rules_nodejs-1.7.0.tar.gz"],
|
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.6.0/rules_nodejs-1.6.0.tar.gz"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check the rules_nodejs version and download npm dependencies
|
# Check the rules_nodejs version and download npm dependencies
|
||||||
@ -17,7 +17,7 @@ http_archive(
|
|||||||
# assert on that.
|
# assert on that.
|
||||||
load("@build_bazel_rules_nodejs//:index.bzl", "check_rules_nodejs_version", "node_repositories", "yarn_install")
|
load("@build_bazel_rules_nodejs//:index.bzl", "check_rules_nodejs_version", "node_repositories", "yarn_install")
|
||||||
|
|
||||||
check_rules_nodejs_version(minimum_version_string = "1.7.0")
|
check_rules_nodejs_version(minimum_version_string = "1.6.0")
|
||||||
|
|
||||||
# Setup the Node.js toolchain
|
# Setup the Node.js toolchain
|
||||||
node_repositories(
|
node_repositories(
|
||||||
@ -64,7 +64,7 @@ load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories"
|
|||||||
|
|
||||||
web_test_repositories()
|
web_test_repositories()
|
||||||
|
|
||||||
load("//dev-infra/browsers:browser_repositories.bzl", "browser_repositories")
|
load("//tools/browsers:browser_repositories.bzl", "browser_repositories")
|
||||||
|
|
||||||
browser_repositories()
|
browser_repositories()
|
||||||
|
|
||||||
@ -91,18 +91,17 @@ rbe_autoconfig(
|
|||||||
# Need to specify a base container digest in order to ensure that we can use the checked-in
|
# Need to specify a base container digest in order to ensure that we can use the checked-in
|
||||||
# platform configurations for the "ubuntu16_04" image. Otherwise the autoconfig rule would
|
# platform configurations for the "ubuntu16_04" image. Otherwise the autoconfig rule would
|
||||||
# need to pull the image and run it in order determine the toolchain configuration. See:
|
# need to pull the image and run it in order determine the toolchain configuration. See:
|
||||||
# https://github.com/bazelbuild/bazel-toolchains/blob/3.2.0/configs/ubuntu16_04_clang/versions.bzl
|
# https://github.com/bazelbuild/bazel-toolchains/blob/1.1.2/configs/ubuntu16_04_clang/versions.bzl
|
||||||
base_container_digest = "sha256:5e750dd878df9fcf4e185c6f52b9826090f6e532b097f286913a428290622332",
|
base_container_digest = "sha256:1ab40405810effefa0b2f45824d6d608634ccddbf06366760c341ef6fbead011",
|
||||||
# Note that if you change the `digest`, you might also need to update the
|
# Note that if you change the `digest`, you might also need to update the
|
||||||
# `base_container_digest` to make sure marketplace.gcr.io/google/rbe-ubuntu16-04-webtest:<digest>
|
# `base_container_digest` to make sure marketplace.gcr.io/google/rbe-ubuntu16-04-webtest:<digest>
|
||||||
# and marketplace.gcr.io/google/rbe-ubuntu16-04:<base_container_digest> have
|
# and marketplace.gcr.io/google/rbe-ubuntu16-04:<base_container_digest> have
|
||||||
# the same Clang and JDK installed. Clang is needed because of the dependency on
|
# the same Clang and JDK installed. Clang is needed because of the dependency on
|
||||||
# @com_google_protobuf. Java is needed for the Bazel's test executor Java tool.
|
# @com_google_protobuf. Java is needed for the Bazel's test executor Java tool.
|
||||||
digest = "sha256:f743114235a43355bf8324e2ba0fa6a597236fe06f7bc99aaa9ac703631c306b",
|
digest = "sha256:0b8fa87db4b8e5366717a7164342a029d1348d2feea7ecc4b18c780bc2507059",
|
||||||
env = clang_env(),
|
env = clang_env(),
|
||||||
registry = "marketplace.gcr.io",
|
registry = "marketplace.gcr.io",
|
||||||
# We can't use the default "ubuntu16_04" RBE image provided by the autoconfig because we need
|
# We can't use the default "ubuntu16_04" RBE image provided by the autoconfig because we need
|
||||||
# a specific Linux kernel that comes with "libx11" in order to run headless browser tests.
|
# a specific Linux kernel that comes with "libx11" in order to run headless browser tests.
|
||||||
repository = "google/rbe-ubuntu16-04-webtest",
|
repository = "google/rbe-ubuntu16-04-webtest",
|
||||||
use_checked_in_confs = "Force",
|
|
||||||
)
|
)
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles/main.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
"budgets": [
|
"budgets": [
|
||||||
@ -158,7 +158,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles/main.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# CLI Overview and Command Reference
|
# CLI Overview and Command Reference
|
||||||
|
|
||||||
The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications directly from a command shell.
|
The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications. You can use the tool directly in a command shell, or indirectly through an interactive UI such as [Angular Console](https://angularconsole.com).
|
||||||
|
|
||||||
## Installing Angular CLI
|
## Installing Angular CLI
|
||||||
|
|
||||||
@ -109,3 +109,9 @@ Options that specify files can be given as absolute paths, or as paths relative
|
|||||||
The [ng generate](cli/generate) and [ng add](cli/add) commands take as an argument the artifact or library to be generated or added to the current project.
|
The [ng generate](cli/generate) and [ng add](cli/add) commands take as an argument the artifact or library to be generated or added to the current project.
|
||||||
In addition to any general options, each artifact or library defines its own options in a *schematic*.
|
In addition to any general options, each artifact or library defines its own options in a *schematic*.
|
||||||
Schematic options are supplied to the command in the same format as immediate command options.
|
Schematic options are supplied to the command in the same format as immediate command options.
|
||||||
|
|
||||||
|
|
||||||
|
### Building with Bazel
|
||||||
|
|
||||||
|
Optionally, you can configure the Angular CLI to use [Bazel](https://docs.bazel.build) as the build tool. For more information, see [Building with Bazel](guide/bazel).
|
||||||
|
|
||||||
|
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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -200,4 +200,13 @@
|
|||||||
(ngModelChange)="model.name = $event">
|
(ngModelChange)="model.name = $event">
|
||||||
TODO: remove this: {{model.name}}
|
TODO: remove this: {{model.name}}
|
||||||
<!-- #enddocregion ngModel-3-->
|
<!-- #enddocregion ngModel-3-->
|
||||||
|
<hr>
|
||||||
|
<!-- #docregion ngModelName-2 -->
|
||||||
|
<input type="text" class="form-control" id="name"
|
||||||
|
required
|
||||||
|
[(ngModel)]="model.name" name="name"
|
||||||
|
#spy>
|
||||||
|
<br>TODO: remove this: {{spy.className}}
|
||||||
|
<!-- #enddocregion ngModelName-2 -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -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('');
|
||||||
});
|
});
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user