Compare commits
465 Commits
Author | SHA1 | Date | |
---|---|---|---|
769c132d22 | |||
ee65d0d4ab | |||
cd48a5383d | |||
0323affe18 | |||
b793aa3f85 | |||
4382ceae02 | |||
9a81e52eac | |||
903aef07f4 | |||
7f15c014d3 | |||
546299b6f2 | |||
a593b3f877 | |||
2bb4263a26 | |||
0c4430b384 | |||
c68826059c | |||
1cdffbdc2e | |||
00f44ee6d4 | |||
dcfde77de5 | |||
4994527e71 | |||
69eb46ad97 | |||
6e190b1a3f | |||
2b1820dfea | |||
9af4dcc442 | |||
16ba4ae2a7 | |||
cd95db482d | |||
e5cbc9b22b | |||
cd2a2f7989 | |||
8031e58410 | |||
508db0f467 | |||
57047acf17 | |||
3e992e18eb | |||
d801941266 | |||
4dc066b979 | |||
71c1446def | |||
ca14509bfe | |||
19fe45dfdc | |||
42b7f8525b | |||
7f1c5f6248 | |||
7089c20ce5 | |||
b9609020f6 | |||
ea0f031995 | |||
2e1fc36c4e | |||
47c486860e | |||
77ee22eb6e | |||
8c0c689338 | |||
f971f83f06 | |||
895b0454f8 | |||
8febb5ac55 | |||
7d6d4c436c | |||
c15b223001 | |||
1423cc0ad2 | |||
e483078d6f | |||
29481a17b1 | |||
09b374c92c | |||
3f6b279033 | |||
b4c77d551b | |||
588a3ed79d | |||
9e33dc3e6a | |||
0930820748 | |||
96ff4971f2 | |||
c9b9be6c2e | |||
736afea5f1 | |||
a14dc2d7a4 | |||
a357daeaf7 | |||
ec4dced523 | |||
69786c2814 | |||
50bcaa6f5b | |||
6bf8e37827 | |||
91f2b1e4d7 | |||
c7075fe710 | |||
e2e0be4ac6 | |||
f6864cce91 | |||
ef038e8060 | |||
3580a6c986 | |||
67e9812c14 | |||
61b08629fd | |||
d727561c5e | |||
39ecc7b5b6 | |||
23f0a04387 | |||
e884c0cd7b | |||
ab72e06cde | |||
5218f5a401 | |||
e8b00ec404 | |||
94b0e8f288 | |||
157b948e6b | |||
7b9d62b2ed | |||
e4eed73591 | |||
a52123f538 | |||
15193fce98 | |||
572a5e4bd3 | |||
601fae944d | |||
d46f1f28e2 | |||
a2df6031ad | |||
542b7cd925 | |||
ce1b741255 | |||
4a1b4f17ae | |||
7ea8985500 | |||
eefae6d96d | |||
9f430f0ad9 | |||
60b5bf7b99 | |||
7671c73655 | |||
6d7a4ff45e | |||
cfa6ab1910 | |||
2f930a5d44 | |||
886df3e604 | |||
72900eccaf | |||
d9b1136ba4 | |||
97fc5f662e | |||
3ad67e5ef6 | |||
baec8abc75 | |||
1e3c015d89 | |||
9419165079 | |||
1f749fead5 | |||
3d60f6de5f | |||
8aefbfe7bc | |||
2d12af3589 | |||
57bef7306c | |||
c09a879b69 | |||
95d7144aba | |||
29d2986454 | |||
4a73dfc500 | |||
ac3e91bc2e | |||
516956905d | |||
81e8eeb0d8 | |||
cfae2c27cb | |||
f4be046d04 | |||
7081e39a78 | |||
5d5bb58e5a | |||
f65fa3aa1c | |||
dbbfab3ee8 | |||
b87ae8e5f9 | |||
8b1d28ff48 | |||
463e967abb | |||
71b8bbef95 | |||
a2cf677714 | |||
9e1ce318a8 | |||
a00c2a9210 | |||
a677d8b330 | |||
7fe89ba4ea | |||
a8af83bf36 | |||
c75e16aae8 | |||
1affcc63c0 | |||
34395aeea1 | |||
f64de2e9f3 | |||
86ad77c1b1 | |||
d5c815f1f2 | |||
32c6d5313a | |||
388c1a3638 | |||
334a3ba125 | |||
fd1d161844 | |||
280ea13342 | |||
3b1e539bab | |||
8e57965e3c | |||
761bb0aafd | |||
1b881b6ba2 | |||
f03d724fea | |||
cf8d934ba9 | |||
67f4852acb | |||
08f6a64893 | |||
ee49bbebc7 | |||
da78b02d71 | |||
d787925841 | |||
4e6efb361d | |||
aa371335dc | |||
090b6d92da | |||
a5cbfa2aab | |||
e8ed37a0e7 | |||
e5cbebef0d | |||
654ec1570a | |||
728d903a67 | |||
495f8e1bc6 | |||
d778a65447 | |||
e8dbba417d | |||
00c145f14c | |||
8c4c9858a2 | |||
caf3a53385 | |||
6ba1cd4365 | |||
bb18cba253 | |||
5abb9360d8 | |||
16c59aecf1 | |||
47d1216f6b | |||
5e614bfda8 | |||
efecf36eb5 | |||
b68d29791f | |||
136cd097c8 | |||
7be198a8e3 | |||
b4ee74667b | |||
67444e70ab | |||
09e55eabf3 | |||
1c838eb976 | |||
24ec9e57ad | |||
190330a612 | |||
9417086f6c | |||
535ff0564a | |||
e8c8ec7075 | |||
03d2813c20 | |||
fb5b2a89cd | |||
ea495d958f | |||
2edb87e7f8 | |||
903d28fe86 | |||
6945f7978e | |||
27afe01910 | |||
36b6110e7d | |||
24a1e146da | |||
2256920292 | |||
2a25ac2ac9 | |||
56693339c2 | |||
c976b88dcf | |||
3e08794abf | |||
b598e884f6 | |||
cf916a03d3 | |||
ee6498f37e | |||
1a0b2ff4fb | |||
dfb331cd18 | |||
11c926ce47 | |||
a0119b1144 | |||
c938fb4619 | |||
2f49a23d64 | |||
c6eaaf5b3d | |||
5e38ec8acc | |||
0cd5964f67 | |||
f3938a6a2b | |||
3baa74449c | |||
df4e97c81e | |||
d629f2c6a8 | |||
6ee47d5e76 | |||
9226b421e8 | |||
b06847f43d | |||
a54a752147 | |||
d00a2e8920 | |||
86981b395d | |||
feec963106 | |||
09fc669b4f | |||
cb339b87f3 | |||
fdcf877f83 | |||
5b5b9897c9 | |||
0e7365724e | |||
4ef1a3cd97 | |||
38b5ed05ea | |||
642c015f23 | |||
0977d95802 | |||
d374787db6 | |||
a634deb885 | |||
bcbd7ed8f0 | |||
f7de2be3f3 | |||
1e97d511c7 | |||
7e1e00c21e | |||
481f4b7412 | |||
4bc0084e5a | |||
b6864494a1 | |||
0021437ee1 | |||
d91ecd2c8b | |||
d0018e6bf6 | |||
587ca854cc | |||
8b9f03d9fa | |||
40f1f94fe0 | |||
2270467d60 | |||
8efda5b353 | |||
7b7f2d9c1b | |||
c469e25cf2 | |||
a21cde2960 | |||
9b774348b3 | |||
ce219ccfa2 | |||
53bbb01047 | |||
c6741bf36a | |||
cc06bf50f3 | |||
21e78ad022 | |||
05e855092b | |||
2817764433 | |||
145639d0f8 | |||
3eb327b67b | |||
be6af26dc1 | |||
637e81e9bb | |||
abc3cbb33f | |||
27eb8f2723 | |||
81671cea9a | |||
843fc7df9f | |||
cfe4732e41 | |||
48cabb44c7 | |||
9d0db2fe4b | |||
069146e7f3 | |||
fc895ba189 | |||
9a51528072 | |||
7fc38d4947 | |||
b1f84ec78f | |||
f351e8a5b1 | |||
ff2c342356 | |||
01b05b3f7c | |||
3b78f9eb0f | |||
f6ca619343 | |||
ab69c31fc5 | |||
38de40c9ec | |||
53352c40c3 | |||
dd3cab6eb1 | |||
ea1a3d3603 | |||
cf1b436010 | |||
cdcbb53a2d | |||
db2db6e7f5 | |||
1df6b16263 | |||
f4871212b7 | |||
2a23eca917 | |||
b5da4c6676 | |||
b8c2f3b93f | |||
75cf86e70f | |||
bf25165354 | |||
a2ba4448da | |||
ac6b2b4dc3 | |||
b6dffa9763 | |||
54b57def58 | |||
e2b3cc8118 | |||
5e701a2c88 | |||
27a3df146d | |||
8cce7efbb2 | |||
d225c3a6e3 | |||
b23582d57e | |||
d3c6e512a3 | |||
a873fab10c | |||
ecef0dd65e | |||
1cc74eaece | |||
e2b3be87cb | |||
3ca6c928f9 | |||
5933d16f3e | |||
0f839bcfd0 | |||
edda94edfa | |||
b5e36eaa3e | |||
08a1f51704 | |||
9690e36f78 | |||
68e741227b | |||
50a2327520 | |||
b07346c8e3 | |||
8e95849751 | |||
cd143f67af | |||
dd85351162 | |||
c1c68889de | |||
866f4be782 | |||
80e4019c83 | |||
d9f3316021 | |||
424a3b95aa | |||
7e883c2319 | |||
6a7fd70ddf | |||
73f9db53c2 | |||
2bf526bbfb | |||
8bd7d5befc | |||
aa163bea93 | |||
2f73c554c9 | |||
fb2d15fda1 | |||
018507fa02 | |||
95bb72d322 | |||
ce6e6c3f81 | |||
e4b1bdbfa0 | |||
6477c9e04a | |||
3f380b3b78 | |||
c4c0e9dbc5 | |||
4ddf57c58d | |||
624f01c311 | |||
6a713521e3 | |||
57a5ba3438 | |||
1b6fb5bc19 | |||
bd9da268c1 | |||
1e58a2194f | |||
da81c9cb54 | |||
ef6d26d4fa | |||
13bc1cd853 | |||
1fa1379318 | |||
d9efacc07e | |||
47f5b5f2d4 | |||
019fe77f64 | |||
a0e3a8e0f7 | |||
8908156eae | |||
2ee265fb1f | |||
116512b06d | |||
1d841973eb | |||
3694e1a38c | |||
88d8813ccc | |||
49bfb63442 | |||
48848c9ca4 | |||
a1f1ea993d | |||
be8a403bc9 | |||
c378402af4 | |||
91ce8c17ff | |||
786be967fd | |||
e88d5e0df2 | |||
f39f01e00b | |||
ce750e6f5b | |||
beba944843 | |||
50981cbb1f | |||
76e40eed35 | |||
d491a20f3b | |||
74c202a5cd | |||
483e8d28ec | |||
a6fd118f79 | |||
fe6e76c1e7 | |||
de560019f2 | |||
52ed53d071 | |||
5b72d4d676 | |||
c1aa1bf872 | |||
dad1bc7ca3 | |||
2109c30afe | |||
874919a25b | |||
c64e666755 | |||
1da403d8f3 | |||
60c5ebd46a | |||
b71d1987cd | |||
e6325eb9ef | |||
114519ab6a | |||
a9a095d44a | |||
5f9d574d4d | |||
baeb446392 | |||
0d1bfdc505 | |||
fa130e9445 | |||
194710fc1d | |||
6ae5e2b32a | |||
d85d396c26 | |||
1a25144297 | |||
449da8c18e | |||
0f37ed1060 | |||
5c85b4f1e9 | |||
22bc6ef22a | |||
bf928d1c9e | |||
d11c2f915b | |||
98c99e5073 | |||
2c63108faa | |||
0ff48a1266 | |||
ea2a3f8335 | |||
cbed4851a3 | |||
7c157780a9 | |||
cc1b2a5373 | |||
5076185fc8 | |||
65375f4c21 | |||
068a6070dc | |||
47e9761a01 | |||
bef52d20b5 | |||
fe50710021 | |||
71b66fb862 | |||
8db05b408e | |||
351610ca8d | |||
ef78e33560 | |||
12b8a6e351 | |||
260ac20e92 | |||
aed48e00d2 | |||
a9d46e4952 | |||
2f19ad9b46 | |||
81678e62db | |||
cf82fbceba | |||
1d67cb0ce1 | |||
318bd83a6e | |||
f767c22b31 | |||
8346a6dca2 | |||
6397885e74 | |||
8cee56e8c5 | |||
a1b9995731 | |||
35f7ff047a | |||
4ad691a33d | |||
c5af3f8617 | |||
bc1032866c | |||
63e6d1a896 | |||
cb9fd9b4d7 | |||
d5dca0764c | |||
bcd1a09dec | |||
898c0134e7 | |||
763d2150cc | |||
beacbfcb8e | |||
f72319cf6e | |||
5877b3f702 | |||
cf310ba1fa | |||
c2d2953ee4 |
@ -1,4 +1,6 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
|
aio/content
|
||||||
aio/node_modules
|
aio/node_modules
|
||||||
aio/tools/examples/shared/node_modules
|
aio/tools/examples/shared/node_modules
|
||||||
|
integration/bazel
|
||||||
|
25
.bazelrc
25
.bazelrc
@ -1,5 +1,3 @@
|
|||||||
# Load any settings specific to the current user
|
|
||||||
try-import .bazelrc.user
|
|
||||||
################################
|
################################
|
||||||
# Settings for Angular team members only
|
# Settings for Angular team members only
|
||||||
################################
|
################################
|
||||||
@ -35,13 +33,24 @@ test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test
|
|||||||
# See https://github.com/bazelbuild/bazel/issues/4603
|
# See https://github.com/bazelbuild/bazel/issues/4603
|
||||||
build --symlink_prefix=dist/
|
build --symlink_prefix=dist/
|
||||||
|
|
||||||
# Performance: avoid stat'ing input files
|
# Disable watchfs as it causes tests to be flaky on Windows
|
||||||
build --watchfs
|
# https://github.com/angular/angular/issues/29541
|
||||||
|
build --nowatchfs
|
||||||
|
|
||||||
# Turn off legacy external runfiles
|
# Turn off legacy external runfiles
|
||||||
run --nolegacy_external_runfiles
|
run --nolegacy_external_runfiles
|
||||||
test --nolegacy_external_runfiles
|
test --nolegacy_external_runfiles
|
||||||
|
|
||||||
|
# Turn on --incompatible_strict_action_env which was on by default
|
||||||
|
# in Bazel 0.21.0 but turned off again in 0.22.0. Follow
|
||||||
|
# https://github.com/bazelbuild/bazel/issues/7026 for more details.
|
||||||
|
# This flag is needed to so that the bazel cache is not invalidated
|
||||||
|
# when running bazel via `yarn bazel`.
|
||||||
|
# See https://github.com/angular/angular/issues/27514.
|
||||||
|
build --incompatible_strict_action_env
|
||||||
|
run --incompatible_strict_action_env
|
||||||
|
test --incompatible_strict_action_env
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
# Release support #
|
# Release support #
|
||||||
# Turn on these settings with #
|
# Turn on these settings with #
|
||||||
@ -49,7 +58,9 @@ test --nolegacy_external_runfiles
|
|||||||
###############################
|
###############################
|
||||||
|
|
||||||
# Releases should always be stamped with version control info
|
# Releases should always be stamped with version control info
|
||||||
build:release --workspace_status_command=./tools/bazel_stamp_vars.sh
|
# This command assumes node on the path and is a workaround for
|
||||||
|
# https://github.com/bazelbuild/bazel/issues/4802
|
||||||
|
build:release --workspace_status_command="node ./tools/bazel_stamp_vars.js"
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
# Output #
|
# Output #
|
||||||
@ -107,3 +118,7 @@ build:remote --remote_instance_name=projects/internal-200822/instances/default_i
|
|||||||
# Do not accept remote cache.
|
# Do not accept remote cache.
|
||||||
# We need to understand the security risks of using prior build artifacts.
|
# We need to understand the security risks of using prior build artifacts.
|
||||||
build:remote --remote_accept_cached=false
|
build:remote --remote_accept_cached=false
|
||||||
|
|
||||||
|
# Load any settings specific to the current user. Needs to be last statement in this
|
||||||
|
# config, as the user configuration should be able to overwrite flags from this file.
|
||||||
|
try-import .bazelrc.user
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
|
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
|
||||||
# See documentation in /docs/BAZEL.md
|
# See documentation in /docs/BAZEL.md
|
||||||
|
|
||||||
|
# Save downloaded repositories in a location that can be cached by CircleCI. This helps us
|
||||||
|
# speeding up the analysis time significantly with Bazel managed node dependencies on the CI.
|
||||||
|
build --repository_cache=/home/circleci/bazel_repository_cache
|
||||||
|
|
||||||
# Don't be spammy in the logs
|
# Don't be spammy in the logs
|
||||||
# TODO(gmagolan): Hide progress again once build performance improves
|
# TODO(gmagolan): Hide progress again once build performance improves
|
||||||
# Presently, CircleCI can timeout during bazel test ... with the following
|
# Presently, CircleCI can timeout during bazel test ... with the following
|
||||||
|
@ -11,16 +11,43 @@
|
|||||||
# needed for jobs that run tests without Bazel. Bazel runs tests with browsers that will be
|
# needed for jobs that run tests without Bazel. Bazel runs tests with browsers that will be
|
||||||
# fetched by the Webtesting rules. Therefore for jobs that run tests with Bazel, we don't need a
|
# fetched by the Webtesting rules. Therefore for jobs that run tests with Bazel, we don't need a
|
||||||
# docker image with browsers pre-installed.
|
# docker image with browsers pre-installed.
|
||||||
# **NOTE**: If you change the version of the docker images, also change the `cache_key` suffix.
|
# **NOTE 1**: If you change the version of the `*-browsers` docker image, make sure the
|
||||||
|
# `CI_CHROMEDRIVER_VERSION_ARG` env var (in `.circleci/env.sh`) points to a ChromeDriver
|
||||||
|
# version that is compatible with the Chrome version in the image.
|
||||||
|
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
|
||||||
var_1: &default_docker_image circleci/node:10.12
|
var_1: &default_docker_image circleci/node:10.12
|
||||||
var_2: &browsers_docker_image circleci/node:10.12-browsers
|
var_2: &browsers_docker_image circleci/node:10.12-browsers
|
||||||
var_3: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-node-10.12
|
# We don't want to include the current branch name in the cache key because that would prevent
|
||||||
|
# PRs from being able to restore the cache since the branch names are always different for PRs.
|
||||||
|
# The cache key should only consist of dynamic values that change whenever something in the
|
||||||
|
# cache changes. For example:
|
||||||
|
# 1) yarn lock file changes --> cached "node_modules" are different.
|
||||||
|
# 2) bazel repository definitions change --> cached bazel repositories are different.
|
||||||
|
# **NOTE 1 **: If you change the cache key prefix, also sync the restore_cache fallback to match.
|
||||||
|
# **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.
|
||||||
|
var_3: &cache_key v3-angular-node-10.12-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
|
||||||
|
|
||||||
# Define common ENV vars
|
# Initializes the CI environment by setting up common environment variables.
|
||||||
var_4: &define_env_vars
|
var_4: &init_environment
|
||||||
run:
|
run:
|
||||||
name: Define environment variables
|
name: Initializing environment (setting up variables, overwriting Yarn)
|
||||||
command: ./.circleci/env.sh
|
# Overwrite the yarn installed in the docker container with our own version.
|
||||||
|
command: |
|
||||||
|
./.circleci/env.sh
|
||||||
|
ourYarn=$(realpath ./third_party/github.com/yarnpkg/yarn/releases/download/v1.13.0/bin/yarn.js)
|
||||||
|
sudo chmod a+x $ourYarn
|
||||||
|
sudo ln -fs $ourYarn /usr/local/bin/yarn
|
||||||
|
echo "Yarn version: $(yarn --version)"
|
||||||
|
|
||||||
|
# Add GitHub to known hosts.
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
# use git+ssh instead of https
|
||||||
|
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
|
||||||
|
git config --global gc.auto 0 || true
|
||||||
|
|
||||||
|
|
||||||
var_5: &setup_bazel_remote_execution
|
var_5: &setup_bazel_remote_execution
|
||||||
run:
|
run:
|
||||||
@ -36,33 +63,94 @@ var_6: &job_defaults
|
|||||||
docker:
|
docker:
|
||||||
- image: *default_docker_image
|
- image: *default_docker_image
|
||||||
|
|
||||||
# After checkout, rebase on top of master.
|
# After checkout, rebase on top of target branch.
|
||||||
# Similar to travis behavior, but not quite the same.
|
|
||||||
# See https://discuss.circleci.com/t/1662
|
|
||||||
var_7: &post_checkout
|
var_7: &post_checkout
|
||||||
post: git pull --ff-only origin "refs/pull/${CI_PULL_REQUEST//*pull\//}/merge"
|
run:
|
||||||
|
name: Rebase PR on target branch
|
||||||
|
command: >
|
||||||
|
if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then
|
||||||
|
# User is required for rebase.
|
||||||
|
git config user.name "angular-ci"
|
||||||
|
git config user.email "angular-ci"
|
||||||
|
# Rebase PR on top of target branch.
|
||||||
|
node tools/rebase-pr.js angular/angular ${CIRCLE_PR_NUMBER}
|
||||||
|
else
|
||||||
|
echo "This build is not over a PR, nothing to do."
|
||||||
|
fi
|
||||||
|
|
||||||
var_8: &yarn_install
|
var_8: &yarn_install
|
||||||
run:
|
run:
|
||||||
name: Running Yarn install
|
name: Running Yarn install
|
||||||
command: yarn install --frozen-lockfile --non-interactive
|
command: |
|
||||||
|
# Yarn's requests sometimes take more than 10mins to complete.
|
||||||
|
# Print something to stdout, to prevent CircleCI from failing due to not output.
|
||||||
|
while true; do sleep 60; echo "[`date`] Keeping alive..."; done &
|
||||||
|
KEEP_ALIVE_PID=$!
|
||||||
|
yarn install --frozen-lockfile --non-interactive
|
||||||
|
kill $KEEP_ALIVE_PID
|
||||||
|
|
||||||
var_9: &setup_circleci_bazel_config
|
var_9: &setup_circleci_bazel_config
|
||||||
run:
|
run:
|
||||||
name: Setting up CircleCI bazel configuration
|
name: Setting up CircleCI bazel configuration
|
||||||
command: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
command: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||||
|
|
||||||
|
var_10: &restore_cache
|
||||||
|
restore_cache:
|
||||||
|
keys:
|
||||||
|
- *cache_key
|
||||||
|
# This fallback should be the cache_key without variables.
|
||||||
|
- v3-angular-node-10.12-
|
||||||
|
|
||||||
|
# Branch filter that can be specified for jobs that should only run on publish branches
|
||||||
|
# (e.g. master or the patch branch)
|
||||||
|
var_12: &publish_branches_filter
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
# e.g. 7.0.x, 7.1.x, etc.
|
||||||
|
- /\d+\.\d+\.x/
|
||||||
|
|
||||||
|
# Workspace initially persisted by the `install` job, and then enhanced by `test_aio` and
|
||||||
|
# `build-npm-packages`.
|
||||||
|
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
|
||||||
|
# https://circleci.com/blog/deep-diving-into-circleci-workspaces/
|
||||||
|
var_13: &attach_workspace
|
||||||
|
attach_workspace:
|
||||||
|
at: ~/
|
||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
jobs:
|
jobs:
|
||||||
|
setup:
|
||||||
|
<<: *job_defaults
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- *post_checkout
|
||||||
|
# This cache is saved in the build-npm-packages so that Bazel cache is also included.
|
||||||
|
- *restore_cache
|
||||||
|
- *init_environment
|
||||||
|
- *yarn_install
|
||||||
|
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
|
||||||
|
# Make the bazel directories and add a file to them if they don't exist already so that
|
||||||
|
# persist_to_workspace does not fail.
|
||||||
|
- run: |
|
||||||
|
if [ ! -d ~/bazel_repository_cache ]; then
|
||||||
|
mkdir ~/bazel_repository_cache
|
||||||
|
touch ~/bazel_repository_cache/MARKER
|
||||||
|
fi
|
||||||
|
# Persist any changes at this point to be reused by further jobs.
|
||||||
|
# **NOTE 1 **: Folders persisted here should be kept in sync with `var_13: &attach_workspace`.
|
||||||
|
# **NOTE 2 **: To add new content to the workspace, always persist on the same root.
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: ~/
|
||||||
|
paths:
|
||||||
|
- ./ng
|
||||||
|
- ./bazel_repository_cache
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *yarn_install
|
|
||||||
|
|
||||||
- run: 'yarn bazel:format -mode=check ||
|
- run: 'yarn bazel:format -mode=check ||
|
||||||
(echo "BUILD files not formatted. Please run ''yarn bazel:format''" ; exit 1)'
|
(echo "BUILD files not formatted. Please run ''yarn bazel:format''" ; exit 1)'
|
||||||
@ -70,45 +158,28 @@ jobs:
|
|||||||
- run: 'yarn bazel:lint ||
|
- run: 'yarn bazel:lint ||
|
||||||
(echo -e "\n.bzl files have lint errors. Please run ''yarn bazel:lint-fix''"; exit 1)'
|
(echo -e "\n.bzl files have lint errors. Please run ''yarn bazel:lint-fix''"; exit 1)'
|
||||||
|
|
||||||
- run: ./node_modules/.bin/gulp lint
|
- run: yarn gulp lint
|
||||||
|
|
||||||
test:
|
test:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *setup_circleci_bazel_config
|
- *setup_circleci_bazel_config
|
||||||
- *yarn_install
|
|
||||||
|
|
||||||
# Setup remote execution and run RBE-compatible tests.
|
# Setup remote execution and run RBE-compatible tests.
|
||||||
- *setup_bazel_remote_execution
|
- *setup_bazel_remote_execution
|
||||||
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-local
|
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
|
||||||
# Now run RBE incompatible tests locally.
|
|
||||||
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
|
||||||
- run: yarn bazel test //... --build_tag_filters=-ivy-only,local --test_tag_filters=-ivy-only,local
|
|
||||||
|
|
||||||
- save_cache:
|
|
||||||
key: *cache_key
|
|
||||||
paths:
|
|
||||||
- "node_modules"
|
|
||||||
- "~/bazel_repository_cache"
|
|
||||||
|
|
||||||
# Temporary job to test what will happen when we flip the Ivy flag to true
|
# Temporary job to test what will happen when we flip the Ivy flag to true
|
||||||
test_ivy_aot:
|
test_ivy_aot:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *setup_circleci_bazel_config
|
- *setup_circleci_bazel_config
|
||||||
- *yarn_install
|
|
||||||
- *setup_bazel_remote_execution
|
- *setup_bazel_remote_execution
|
||||||
|
|
||||||
# We need to explicitly specify the --symlink_prefix option because otherwise we would
|
# We need to explicitly specify the --symlink_prefix option because otherwise we would
|
||||||
@ -141,11 +212,8 @@ jobs:
|
|||||||
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
|
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
|
||||||
- image: *browsers_docker_image
|
- image: *browsers_docker_image
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
# Build aio
|
# Build aio
|
||||||
- run: yarn --cwd aio build --progress=false
|
- run: yarn --cwd aio build --progress=false
|
||||||
# Lint the code
|
# Lint the code
|
||||||
@ -157,9 +225,9 @@ jobs:
|
|||||||
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
|
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
|
||||||
- run: yarn --cwd aio payload-size
|
- run: yarn --cwd aio payload-size
|
||||||
# Run unit tests
|
# Run unit tests
|
||||||
- run: yarn --cwd aio test --watch=false
|
- run: yarn --cwd aio test --progress=false --watch=false
|
||||||
# Run e2e tests
|
# Run e2e tests
|
||||||
- run: yarn --cwd aio e2e
|
- run: yarn --cwd aio e2e --configuration=ci
|
||||||
# Run unit tests for Firebase redirects
|
# Run unit tests for Firebase redirects
|
||||||
- run: yarn --cwd aio redirects-test
|
- run: yarn --cwd aio redirects-test
|
||||||
|
|
||||||
@ -169,11 +237,8 @@ jobs:
|
|||||||
# Needed because before deploying the deploy-production script runs the PWA score tests.
|
# Needed because before deploying the deploy-production script runs the PWA score tests.
|
||||||
- image: *browsers_docker_image
|
- image: *browsers_docker_image
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
# Deploy angular.io to production (if necessary)
|
# Deploy angular.io to production (if necessary)
|
||||||
- run: setPublicVar CI_STABLE_BRANCH "$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')"
|
- run: setPublicVar CI_STABLE_BRANCH "$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')"
|
||||||
- run: yarn --cwd aio deploy-production
|
- run: yarn --cwd aio deploy-production
|
||||||
@ -184,33 +249,31 @@ jobs:
|
|||||||
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
|
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
|
||||||
- image: *browsers_docker_image
|
- image: *browsers_docker_image
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- attach_workspace:
|
|
||||||
at: dist
|
|
||||||
- *define_env_vars
|
|
||||||
# Build aio (with local Angular packages)
|
# Build aio (with local Angular packages)
|
||||||
- run: yarn --cwd aio build-local --progress=false
|
- run: yarn --cwd aio build-local --progress=false
|
||||||
# Run PWA-score tests
|
# Run PWA-score tests
|
||||||
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
|
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
|
||||||
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
|
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
|
||||||
# Run unit tests
|
# Run unit tests
|
||||||
- run: yarn --cwd aio test --watch=false
|
- run: yarn --cwd aio test --progress=false --watch=false
|
||||||
# Run e2e tests
|
# Run e2e tests
|
||||||
- run: yarn --cwd aio e2e
|
- run: yarn --cwd aio e2e --configuration=ci
|
||||||
|
|
||||||
|
test_aio_local_ivy:
|
||||||
|
<<: *job_defaults
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *init_environment
|
||||||
|
# Build aio with Ivy (using local Angular packages)
|
||||||
|
- run: yarn --cwd aio build-with-ivy --progress=false
|
||||||
|
|
||||||
test_aio_tools:
|
test_aio_tools:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- attach_workspace:
|
|
||||||
at: dist
|
|
||||||
- *define_env_vars
|
|
||||||
# Install
|
# Install
|
||||||
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
|
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
|
||||||
- run: yarn --cwd aio extract-cli-command-docs
|
- run: yarn --cwd aio extract-cli-command-docs
|
||||||
@ -223,23 +286,43 @@ jobs:
|
|||||||
docker:
|
docker:
|
||||||
# Needed because the example e2e tests depend on Chrome.
|
# Needed because the example e2e tests depend on Chrome.
|
||||||
- image: *browsers_docker_image
|
- image: *browsers_docker_image
|
||||||
parallelism: 3
|
parallelism: 4
|
||||||
|
resource_class: xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- attach_workspace:
|
|
||||||
at: dist
|
|
||||||
- *define_env_vars
|
|
||||||
# Install root
|
|
||||||
- *yarn_install
|
|
||||||
# Install aio
|
# Install aio
|
||||||
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
|
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
|
||||||
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
|
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
|
||||||
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
|
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
|
||||||
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
|
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
|
||||||
- run: yarn --cwd aio example-e2e --setup --local --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
|
- run: yarn --cwd aio example-e2e --setup --local --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
|
||||||
|
|
||||||
|
test_docs_examples_ivy:
|
||||||
|
<<: *job_defaults
|
||||||
|
docker:
|
||||||
|
# Needed because the example e2e tests depend on Chrome.
|
||||||
|
- image: *browsers_docker_image
|
||||||
|
resource_class: xlarge
|
||||||
|
# We increase the parallelism here to five while the "test_docs_examples" job runs with
|
||||||
|
# a parallelism of four. This is necessary because this job also need to run NGCC which
|
||||||
|
# takes up more time and we don't want these jobs to impact the overall CI turnaround.
|
||||||
|
parallelism: 5
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *init_environment
|
||||||
|
# Install aio
|
||||||
|
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
|
||||||
|
# Rename the Ivy packages dist folder to "dist/packages-dist" as the AIO
|
||||||
|
# package installer picks up the locally built packages from that location.
|
||||||
|
# *Note*: We could also adjust the packages installer, but given we won't have
|
||||||
|
# two different folders of Angular distributions in the future, we should keep
|
||||||
|
# the packages installer unchanged.
|
||||||
|
- run: mv dist/packages-dist-ivy-aot dist/packages-dist
|
||||||
|
# Run examples tests with ivy. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
|
||||||
|
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
|
||||||
|
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
|
||||||
|
- run: yarn --cwd aio example-e2e --setup --local --ivy --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
|
||||||
|
|
||||||
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
|
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
|
||||||
aio_preview:
|
aio_preview:
|
||||||
@ -247,12 +330,8 @@ jobs:
|
|||||||
environment:
|
environment:
|
||||||
AIO_SNAPSHOT_ARTIFACT_PATH: &aio_preview_artifact_path 'aio/tmp/snapshot.tgz'
|
AIO_SNAPSHOT_ARTIFACT_PATH: &aio_preview_artifact_path 'aio/tmp/snapshot.tgz'
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *yarn_install
|
|
||||||
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CI_PULL_REQUEST $CI_COMMIT
|
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CI_PULL_REQUEST $CI_COMMIT
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: *aio_preview_artifact_path
|
path: *aio_preview_artifact_path
|
||||||
@ -268,45 +347,64 @@ jobs:
|
|||||||
# Needed because the test-preview script runs e2e tests and the PWA score test with Chrome.
|
# Needed because the test-preview script runs e2e tests and the PWA score test with Chrome.
|
||||||
- image: *browsers_docker_image
|
- image: *browsers_docker_image
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- run: yarn install --cwd aio --frozen-lockfile --non-interactive
|
|
||||||
- run:
|
- run:
|
||||||
name: Wait for preview and run tests
|
name: Wait for preview and run tests
|
||||||
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
|
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
|
||||||
|
|
||||||
# This job exists only for backwards-compatibility with old scripts and tests
|
|
||||||
# that rely on the pre-Bazel dist/packages-dist layout.
|
# The `build-npm-packages` tasks exist for backwards-compatibility with old scripts and
|
||||||
# It duplicates some work with the job above: we build the bazel packages
|
# tests that rely on the pre-Bazel `dist/packages-dist` output structure (build.sh).
|
||||||
# twice. Even though we have a remote cache, these jobs will typically run in
|
# Having multiple jobs that independently build in this manner duplicates some work; we build
|
||||||
# parallel so up-to-date outputs will not be available at the time the build
|
# the bazel packages more than once. Even though we have a remote cache, these jobs will
|
||||||
|
# typically run in parallel so up-to-date outputs will not be available at the time the build
|
||||||
# starts.
|
# starts.
|
||||||
# No new jobs should depend on this one.
|
|
||||||
build-packages-dist:
|
# Build the view engine npm packages. No new jobs should depend on this.
|
||||||
|
build-npm-packages:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *setup_circleci_bazel_config
|
- *setup_circleci_bazel_config
|
||||||
- *yarn_install
|
|
||||||
- *setup_bazel_remote_execution
|
- *setup_bazel_remote_execution
|
||||||
|
|
||||||
- run: scripts/build-packages-dist.sh
|
- run: scripts/build-packages-dist.sh
|
||||||
|
|
||||||
# Save the npm packages from //packages/... for other workflow jobs to read
|
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||||
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
|
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: dist
|
root: ~/
|
||||||
paths:
|
paths:
|
||||||
- packages-dist
|
- ng/dist/packages-dist
|
||||||
- packages-dist-ivy-aot
|
|
||||||
|
# Save dependencies and bazel repository cache to use on subsequent runs.
|
||||||
|
- save_cache:
|
||||||
|
key: *cache_key
|
||||||
|
paths:
|
||||||
|
- "node_modules"
|
||||||
|
- "aio/node_modules"
|
||||||
|
- "~/bazel_repository_cache"
|
||||||
|
|
||||||
|
# Build the ivy npm packages.
|
||||||
|
build-ivy-npm-packages:
|
||||||
|
<<: *job_defaults
|
||||||
|
resource_class: xlarge
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *init_environment
|
||||||
|
- *setup_circleci_bazel_config
|
||||||
|
- *setup_bazel_remote_execution
|
||||||
|
|
||||||
|
- run: scripts/build-ivy-npm-packages.sh
|
||||||
|
|
||||||
|
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: ~/
|
||||||
|
paths:
|
||||||
|
- ng/dist/packages-dist-ivy-aot
|
||||||
|
|
||||||
# We run the integration tests outside of Bazel for now.
|
# We run the integration tests outside of Bazel for now.
|
||||||
# They are a separate workflow job so that they can be easily re-run.
|
# They are a separate workflow job so that they can be easily re-run.
|
||||||
@ -325,13 +423,8 @@ jobs:
|
|||||||
# on a 4G worker so we use a larger machine here too.
|
# on a 4G worker so we use a larger machine here too.
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- attach_workspace:
|
|
||||||
at: dist
|
|
||||||
- *define_env_vars
|
|
||||||
# Runs the integration tests in parallel across multiple CircleCI container instances. The
|
# Runs the integration tests in parallel across multiple CircleCI container instances. The
|
||||||
# amount of container nodes for this job is controlled by the "parallelism" option.
|
# amount of container nodes for this job is controlled by the "parallelism" option.
|
||||||
- run: ./integration/run_tests.sh ${CIRCLE_NODE_INDEX} ${CIRCLE_NODE_TOTAL}
|
- run: ./integration/run_tests.sh ${CIRCLE_NODE_INDEX} ${CIRCLE_NODE_TOTAL}
|
||||||
@ -341,21 +434,20 @@ jobs:
|
|||||||
publish_snapshot:
|
publish_snapshot:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
|
||||||
<<: *post_checkout
|
|
||||||
- *define_env_vars
|
|
||||||
# See below - ideally this job should not trigger for non-upstream builds.
|
# See below - ideally this job should not trigger for non-upstream builds.
|
||||||
# But since it does, we have to check this condition.
|
# But since it does, we have to check this condition.
|
||||||
- run:
|
- run:
|
||||||
name: Skip this job for Pull Requests and Fork builds
|
name: Skip this job for Pull Requests and Fork builds
|
||||||
# Note, `|| true` on the end makes this step always exit 0
|
# Note: Using `CIRCLE_*` env variables (instead of those defined in `env.sh` so that this
|
||||||
command: '[[
|
# step can be run before `init_environment`.
|
||||||
"$CI_PULL_REQUEST" != "false"
|
command: >
|
||||||
|| "$CI_REPO_OWNER" != "angular"
|
if [[ -n "${CIRCLE_PR_NUMBER}" ]] ||
|
||||||
|| "$CI_REPO_NAME" != "angular"
|
[[ "$CIRCLE_PROJECT_USERNAME" != "angular" ]] ||
|
||||||
]] && circleci step halt || true'
|
[[ "$CIRCLE_PROJECT_REPONAME" != "angular" ]]; then
|
||||||
- attach_workspace:
|
circleci step halt
|
||||||
at: dist
|
fi
|
||||||
|
- *attach_workspace
|
||||||
|
- *init_environment
|
||||||
# CircleCI has a config setting to force SSH for all github connections
|
# CircleCI has a config setting to force SSH for all github connections
|
||||||
# This is not compatible with our mechanism of using a Personal Access Token
|
# This is not compatible with our mechanism of using a Personal Access Token
|
||||||
# Clear the global setting
|
# Clear the global setting
|
||||||
@ -372,35 +464,18 @@ jobs:
|
|||||||
# which does not load the browser through the Bazel webtesting rules.
|
# which does not load the browser through the Bazel webtesting rules.
|
||||||
- image: *browsers_docker_image
|
- image: *browsers_docker_image
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- run:
|
- run:
|
||||||
name: Run tests against the deployed apps
|
name: Run tests against the deployed apps
|
||||||
command: ./aio/scripts/test-production.sh $CI_AIO_MIN_PWA_SCORE
|
command: ./aio/scripts/test-production.sh $CI_AIO_MIN_PWA_SCORE
|
||||||
- run:
|
- run:
|
||||||
name: Notify caretaker about failure
|
name: Notify caretaker about failure
|
||||||
command: 'curl --request POST --header "Content-Type: application/json" --data "{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}" $CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL'
|
# `$SLACK_CARETAKER_WEBHOOK_URL` is a secret env var defined in CircleCI project settings.
|
||||||
|
# The URL comes from https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
|
||||||
|
command: 'curl --request POST --header "Content-Type: application/json" --data "{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}" $SLACK_CARETAKER_WEBHOOK_URL'
|
||||||
when: on_fail
|
when: on_fail
|
||||||
|
|
||||||
legacy-unit-tests-local:
|
|
||||||
<<: *job_defaults
|
|
||||||
docker:
|
|
||||||
- image: *browsers_docker_image
|
|
||||||
steps:
|
|
||||||
- checkout:
|
|
||||||
<<: *post_checkout
|
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *yarn_install
|
|
||||||
- run: yarn tsc -p packages
|
|
||||||
- run: yarn tsc -p packages/examples
|
|
||||||
- run: yarn tsc -p modules
|
|
||||||
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=ChromeNoSandbox
|
|
||||||
|
|
||||||
legacy-unit-tests-saucelabs:
|
legacy-unit-tests-saucelabs:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
|
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
|
||||||
@ -408,12 +483,8 @@ jobs:
|
|||||||
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
|
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *yarn_install
|
|
||||||
- run:
|
- run:
|
||||||
name: Preparing environment for running tests on Saucelabs.
|
name: Preparing environment for running tests on Saucelabs.
|
||||||
command: |
|
command: |
|
||||||
@ -424,7 +495,6 @@ jobs:
|
|||||||
command: ./scripts/saucelabs/start-tunnel.sh
|
command: ./scripts/saucelabs/start-tunnel.sh
|
||||||
background: true
|
background: true
|
||||||
- run: yarn tsc -p packages
|
- run: yarn tsc -p packages
|
||||||
- run: yarn tsc -p packages/examples
|
|
||||||
- run: yarn tsc -p modules
|
- run: yarn tsc -p modules
|
||||||
# Waits for the Saucelabs tunnel to be ready. This ensures that we don't run tests
|
# Waits for the Saucelabs tunnel to be ready. This ensures that we don't run tests
|
||||||
# too early without Saucelabs not being ready.
|
# too early without Saucelabs not being ready.
|
||||||
@ -432,43 +502,11 @@ jobs:
|
|||||||
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=${KARMA_JS_BROWSERS}
|
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=${KARMA_JS_BROWSERS}
|
||||||
- run: ./scripts/saucelabs/stop-tunnel.sh
|
- run: ./scripts/saucelabs/stop-tunnel.sh
|
||||||
|
|
||||||
legacy-e2e-tests:
|
|
||||||
<<: *job_defaults
|
|
||||||
docker:
|
|
||||||
- image: *browsers_docker_image
|
|
||||||
steps:
|
|
||||||
- checkout:
|
|
||||||
<<: *post_checkout
|
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *setup_circleci_bazel_config
|
|
||||||
- *yarn_install
|
|
||||||
- *setup_bazel_remote_execution
|
|
||||||
- attach_workspace:
|
|
||||||
at: dist
|
|
||||||
# Build the e2e tests using the existing Bazel "packages-dist" output that has been
|
|
||||||
# attached to this job. This avoids multiple rebuilds across various CI jobs.
|
|
||||||
- run: ./scripts/build-e2e-tests.sh --use-existing-packages-dist
|
|
||||||
- run:
|
|
||||||
name: Starting servers for e2e tests
|
|
||||||
command: yarn gulp serve serve-examples
|
|
||||||
background: true
|
|
||||||
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-e2e.conf.js --bundles=true
|
|
||||||
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-examples-e2e.conf.js --bundles=true
|
|
||||||
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-perf.conf.js --bundles=true --dryrun
|
|
||||||
|
|
||||||
legacy-misc-tests:
|
legacy-misc-tests:
|
||||||
<<: *job_defaults
|
<<: *job_defaults
|
||||||
steps:
|
steps:
|
||||||
- checkout:
|
- *attach_workspace
|
||||||
<<: *post_checkout
|
- *init_environment
|
||||||
- restore_cache:
|
|
||||||
key: *cache_key
|
|
||||||
- *define_env_vars
|
|
||||||
- *yarn_install
|
|
||||||
- attach_workspace:
|
|
||||||
at: dist
|
|
||||||
- run: yarn gulp check-cycle
|
- run: yarn gulp check-cycle
|
||||||
# TODO: disabled because the Bazel packages-dist does not seem to have map files for
|
# TODO: disabled because the Bazel packages-dist does not seem to have map files for
|
||||||
# the ESM5/ES2015 output. See: https://github.com/angular/angular/issues/27966
|
# the ESM5/ES2015 output. See: https://github.com/angular/angular/issues/27966
|
||||||
@ -478,32 +516,49 @@ workflows:
|
|||||||
version: 2
|
version: 2
|
||||||
default_workflow:
|
default_workflow:
|
||||||
jobs:
|
jobs:
|
||||||
- lint
|
- setup
|
||||||
- test
|
- lint:
|
||||||
- test_ivy_aot
|
requires:
|
||||||
- build-packages-dist
|
- setup
|
||||||
- test_aio
|
- test:
|
||||||
- legacy-unit-tests-local
|
requires:
|
||||||
- legacy-unit-tests-saucelabs
|
- setup
|
||||||
|
- test_ivy_aot:
|
||||||
|
requires:
|
||||||
|
- setup
|
||||||
|
- build-npm-packages:
|
||||||
|
requires:
|
||||||
|
- setup
|
||||||
|
- test_aio:
|
||||||
|
requires:
|
||||||
|
- setup
|
||||||
|
- legacy-unit-tests-saucelabs:
|
||||||
|
requires:
|
||||||
|
- setup
|
||||||
- deploy_aio:
|
- deploy_aio:
|
||||||
requires:
|
requires:
|
||||||
- test_aio
|
- test_aio
|
||||||
- legacy-e2e-tests:
|
|
||||||
requires:
|
|
||||||
- build-packages-dist
|
|
||||||
- legacy-misc-tests:
|
- legacy-misc-tests:
|
||||||
requires:
|
requires:
|
||||||
- build-packages-dist
|
- build-npm-packages
|
||||||
- test_aio_local:
|
- test_aio_local:
|
||||||
requires:
|
requires:
|
||||||
- build-packages-dist
|
- build-npm-packages
|
||||||
|
# - test_aio_local_ivy:
|
||||||
|
# requires:
|
||||||
|
# - build-npm-packages
|
||||||
- test_aio_tools:
|
- test_aio_tools:
|
||||||
requires:
|
requires:
|
||||||
- build-packages-dist
|
- build-npm-packages
|
||||||
- test_docs_examples:
|
- test_docs_examples:
|
||||||
requires:
|
requires:
|
||||||
- build-packages-dist
|
- build-npm-packages
|
||||||
|
# - test_docs_examples_ivy:
|
||||||
|
# requires:
|
||||||
|
# - build-ivy-npm-packages
|
||||||
- aio_preview:
|
- aio_preview:
|
||||||
|
requires:
|
||||||
|
- setup
|
||||||
# Only run on PR builds. (There can be no previews for non-PR builds.)
|
# Only run on PR builds. (There can be no previews for non-PR builds.)
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
@ -513,7 +568,7 @@ workflows:
|
|||||||
- aio_preview
|
- aio_preview
|
||||||
- integration_test:
|
- integration_test:
|
||||||
requires:
|
requires:
|
||||||
- build-packages-dist
|
- build-npm-packages
|
||||||
- publish_snapshot:
|
- publish_snapshot:
|
||||||
# Note: no filters on this job because we want it to run for all upstream branches
|
# Note: no filters on this job because we want it to run for all upstream branches
|
||||||
# We'd really like to filter out pull requests here, but not yet available:
|
# We'd really like to filter out pull requests here, but not yet available:
|
||||||
@ -526,21 +581,21 @@ workflows:
|
|||||||
- integration_test
|
- integration_test
|
||||||
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
|
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
|
||||||
- test_aio_local
|
- test_aio_local
|
||||||
|
# - test_aio_local_ivy
|
||||||
- test_docs_examples
|
- test_docs_examples
|
||||||
|
# - test_docs_examples_ivy
|
||||||
# Get the artifacts to publish from the build-packages-dist job
|
# Get the artifacts to publish from the build-packages-dist job
|
||||||
# since the publishing script expects the legacy outputs layout.
|
# since the publishing script expects the legacy outputs layout.
|
||||||
- build-packages-dist
|
- build-npm-packages
|
||||||
- legacy-e2e-tests
|
|
||||||
- legacy-misc-tests
|
|
||||||
- legacy-unit-tests-local
|
|
||||||
- legacy-unit-tests-saucelabs
|
- legacy-unit-tests-saucelabs
|
||||||
|
- legacy-misc-tests
|
||||||
|
|
||||||
aio_monitoring:
|
aio_monitoring:
|
||||||
jobs:
|
jobs:
|
||||||
- aio_monitoring
|
- aio_monitoring
|
||||||
triggers:
|
triggers:
|
||||||
- schedule:
|
- schedule:
|
||||||
|
# Runs AIO monitoring job at 00:00AM every day.
|
||||||
cron: "0 0 * * *"
|
cron: "0 0 * * *"
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#
|
#
|
||||||
# Usage: `setPublicVar <name> <value>`
|
# Usage: `setPublicVar <name> <value>`
|
||||||
function setPublicVar() {
|
function setPublicVar() {
|
||||||
setSecretVar $1 $2;
|
setSecretVar $1 "$2";
|
||||||
echo "$1=$2";
|
echo "$1=$2";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
readonly envHelpersPath="`dirname $0`/env-helpers.inc.sh";
|
readonly projectDir=$(realpath "$(dirname ${BASH_SOURCE[0]})/..")
|
||||||
readonly getCommitRangePath="`dirname $0`/get-commit-range.js";
|
readonly envHelpersPath="$projectDir/.circleci/env-helpers.inc.sh";
|
||||||
|
readonly getCommitRangePath="$projectDir/.circleci/get-commit-range.js";
|
||||||
|
|
||||||
# Load helpers and make them available everywhere (through `$BASH_ENV`).
|
# Load helpers and make them available everywhere (through `$BASH_ENV`).
|
||||||
source $envHelpersPath;
|
source $envHelpersPath;
|
||||||
@ -14,10 +15,15 @@ echo "source $envHelpersPath;" >> $BASH_ENV;
|
|||||||
####################################################################################################
|
####################################################################################################
|
||||||
# See https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables for more info.
|
# See https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables for more info.
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
setPublicVar PROJECT_ROOT "$(pwd)";
|
setPublicVar PROJECT_ROOT "$projectDir";
|
||||||
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
|
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
|
||||||
# This is the branch being built; e.g. `pull/12345` for PR builds.
|
# This is the branch being built; e.g. `pull/12345` for PR builds.
|
||||||
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
|
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
|
||||||
|
# ChromeDriver version compatible with the Chrome version included in the docker image used in
|
||||||
|
# `.circleci/config.yml`. See http://chromedriver.chromium.org/downloads for a list of versions.
|
||||||
|
# This variable is intended to be passed as an arg to the `webdriver-manager update` command (e.g.
|
||||||
|
# `"postinstall": "webdriver-manager update $CI_CHROMEDRIVER_VERSION_ARG"`).
|
||||||
|
setPublicVar CI_CHROMEDRIVER_VERSION_ARG "--versions.chrome 2.45";
|
||||||
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
|
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
|
||||||
# `CI_COMMIT_RANGE` will only be available when `CIRCLE_COMPARE_URL` is also available (or can be
|
# `CI_COMMIT_RANGE` will only be available when `CIRCLE_COMPARE_URL` is also available (or can be
|
||||||
# retrieved via `get-compare-url.js`), i.e. on push builds (a.k.a. non-PR, non-scheduled builds and
|
# retrieved via `get-compare-url.js`), i.e. on push builds (a.k.a. non-PR, non-scheduled builds and
|
||||||
@ -33,8 +39,6 @@ setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
|
|||||||
####################################################################################################
|
####################################################################################################
|
||||||
setSecretVar CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN "$AIO_DEPLOY_TOKEN";
|
setSecretVar CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN "$AIO_DEPLOY_TOKEN";
|
||||||
setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
|
setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
|
||||||
# Defined in https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
|
|
||||||
setSecretVar CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL "$SLACK_CARETAKER_WEBHOOK_URL";
|
|
||||||
|
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
@ -50,6 +54,7 @@ else
|
|||||||
setPublicVar SAUCE_USERNAME "angular-ci";
|
setPublicVar SAUCE_USERNAME "angular-ci";
|
||||||
setSecretVar SAUCE_ACCESS_KEY "9b988f434ff8-fbca-8aa4-4ae3-35442987";
|
setSecretVar SAUCE_ACCESS_KEY "9b988f434ff8-fbca-8aa4-4ae3-35442987";
|
||||||
fi
|
fi
|
||||||
|
setPublicVar SAUCE_LOG_FILE /tmp/angular/sauce-connect.log
|
||||||
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
|
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
|
||||||
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
|
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
|
||||||
setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX}"
|
setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX}"
|
||||||
|
@ -141,7 +141,7 @@ function getJson(url) {
|
|||||||
const opts = {headers: {Accept: 'application/json'}};
|
const opts = {headers: {Accept: 'application/json'}};
|
||||||
const onResponse = res => {
|
const onResponse = res => {
|
||||||
const statusCode = res.statusCode || -1;
|
const statusCode = res.statusCode || -1;
|
||||||
const isSuccess = (200 <= statusCode) && (statusCode <= 400);
|
const isSuccess = (200 <= statusCode) && (statusCode < 400);
|
||||||
let responseText = '';
|
let responseText = '';
|
||||||
|
|
||||||
res.
|
res.
|
||||||
|
115
.github/CODEOWNERS
vendored
115
.github/CODEOWNERS
vendored
@ -39,12 +39,14 @@
|
|||||||
# (just to make this file easier to understand)
|
# (just to make this file easier to understand)
|
||||||
# ================================================
|
# ================================================
|
||||||
|
|
||||||
|
# alan-agius4 - Alan Agius
|
||||||
# alexeagle - Alex Eagle
|
# alexeagle - Alex Eagle
|
||||||
# alxhub - Alex Rickabaugh
|
# alxhub - Alex Rickabaugh
|
||||||
# AndrewKushnir - Andrew Kushnir
|
# AndrewKushnir - Andrew Kushnir
|
||||||
# andrewseguin - Andrew Seguin
|
# andrewseguin - Andrew Seguin
|
||||||
# benlesh - Ben Lesh
|
# benlesh - Ben Lesh
|
||||||
# brandonroberts - Brandon Roberts
|
# brandonroberts - Brandon Roberts
|
||||||
|
# devversion - Paul Gschwendtner
|
||||||
# filipesilva - Filipe Silva
|
# filipesilva - Filipe Silva
|
||||||
# gkalpak - George Kalpakas
|
# gkalpak - George Kalpakas
|
||||||
# hansl - Hans Larsen
|
# hansl - Hans Larsen
|
||||||
@ -54,6 +56,7 @@
|
|||||||
# kara - Kara Erickson
|
# kara - Kara Erickson
|
||||||
# kyliau - Keen Yee Liau
|
# kyliau - Keen Yee Liau
|
||||||
# matsko - Matias Niemelä
|
# matsko - Matias Niemelä
|
||||||
|
# mgechev - Minko Gechev
|
||||||
# mhevery - Misko Hevery
|
# mhevery - Misko Hevery
|
||||||
# ocombe - Olivier Combe
|
# ocombe - Olivier Combe
|
||||||
# petebacondarwin - Pete Bacon Darwin
|
# petebacondarwin - Pete Bacon Darwin
|
||||||
@ -85,6 +88,7 @@
|
|||||||
# - IgorMinar
|
# - IgorMinar
|
||||||
# - kara
|
# - kara
|
||||||
# - mhevery
|
# - mhevery
|
||||||
|
# - alexeagle
|
||||||
|
|
||||||
|
|
||||||
# ===========================================================
|
# ===========================================================
|
||||||
@ -113,6 +117,7 @@
|
|||||||
# - alexeagle
|
# - alexeagle
|
||||||
# - kyliau
|
# - kyliau
|
||||||
# - IgorMinar
|
# - IgorMinar
|
||||||
|
# - mgechev
|
||||||
|
|
||||||
|
|
||||||
# ===========================================================
|
# ===========================================================
|
||||||
@ -122,6 +127,7 @@
|
|||||||
# - alexeagle
|
# - alexeagle
|
||||||
# - filipesilva
|
# - filipesilva
|
||||||
# - hansl
|
# - hansl
|
||||||
|
# - mgechev
|
||||||
|
|
||||||
|
|
||||||
# ===========================================================
|
# ===========================================================
|
||||||
@ -290,6 +296,17 @@
|
|||||||
# - IgorMinar
|
# - IgorMinar
|
||||||
|
|
||||||
|
|
||||||
|
# ===========================================================
|
||||||
|
# @angular/tools-docs-libraries
|
||||||
|
# ===========================================================
|
||||||
|
#
|
||||||
|
# - alan-agius4
|
||||||
|
# - alexeagle
|
||||||
|
# - hansl
|
||||||
|
# - IgorMinar
|
||||||
|
# - mgechev
|
||||||
|
|
||||||
|
|
||||||
# ===========================================================
|
# ===========================================================
|
||||||
# @angular/fw-docs-marketing
|
# @angular/fw-docs-marketing
|
||||||
# ===========================================================
|
# ===========================================================
|
||||||
@ -310,6 +327,9 @@
|
|||||||
# ===========================================================
|
# ===========================================================
|
||||||
#
|
#
|
||||||
# - alexeagle
|
# - alexeagle
|
||||||
|
# - devversion
|
||||||
|
# - filipesilva
|
||||||
|
# - gkalpak
|
||||||
# - IgorMinar
|
# - IgorMinar
|
||||||
|
|
||||||
|
|
||||||
@ -344,10 +364,19 @@
|
|||||||
|
|
||||||
/packages/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/packages/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/packages/platform-browser/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/packages/platform-browser/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
/aio/content/guide/animations.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/animations.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/images/guide/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/images/guide/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/complex-animation-sequences.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/reusable-animations.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/route-animations.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/transition-and-triggers.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ================================================
|
# ================================================
|
||||||
@ -378,12 +407,13 @@
|
|||||||
|
|
||||||
|
|
||||||
# ================================================
|
# ================================================
|
||||||
# @angular/compiler-cli/ngtools
|
# Framework/cli integration
|
||||||
#
|
#
|
||||||
# a rule to control API changes between @angular/compiler-cli and @angular/cli
|
# a rule to control API changes between @angular/compiler-cli and @angular/cli
|
||||||
# ================================================
|
# ================================================
|
||||||
|
|
||||||
/packages/compiler-cli/src/ngtools/** @angular/tools-cli @angular/framework-global-approvers
|
/packages/compiler-cli/src/ngtools/** @angular/tools-cli @angular/framework-global-approvers
|
||||||
|
/aio/content/guide/ivy.md @angular/tools-cli @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -402,6 +432,15 @@
|
|||||||
/packages/platform-browser-dynamic/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/packages/platform-browser-dynamic/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/packages/platform-webworker/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/packages/platform-webworker/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/packages/platform-webworker-dynamic/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/packages/platform-webworker-dynamic/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/packages/examples/common/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/architecture-components.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/architecture-modules.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/architecture-next-steps.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/architecture-services.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/architecture.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/architecture/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/images/guide/architecture/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
/aio/content/guide/attribute-directives.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/attribute-directives.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/attribute-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/attribute-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
@ -410,6 +449,8 @@
|
|||||||
/aio/content/guide/bootstrapping.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/bootstrapping.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/bootstrapping/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/bootstrapping/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/cheatsheet.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
/aio/content/guide/component-interaction.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/component-interaction.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/component-interaction/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/component-interaction/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/images/guide/component-interaction/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/images/guide/component-interaction/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
@ -425,7 +466,13 @@
|
|||||||
/aio/content/examples/dependency-injection-in-action/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/dependency-injection-in-action/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/images/guide/dependency-injection-in-action/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/images/guide/dependency-injection-in-action/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
/aio/content/guide/dependency-injection-pattern.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/dependency-injection-navtree.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/dependency-injection-providers.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/displaying-data.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/displaying-data/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/images/guide/displaying-data/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
/aio/content/guide/dynamic-component-loader.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/dynamic-component-loader.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/dynamic-component-loader/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/dynamic-component-loader/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
@ -452,12 +499,9 @@
|
|||||||
/aio/content/images/guide/lifecycle-hooks/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/images/guide/lifecycle-hooks/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
/aio/content/examples/ngcontainer/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/ngcontainer/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/images/guide/ngcontainer/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
|
|
||||||
/aio/content/guide/ngmodules.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/ngmodules.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/ngmodules/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/ngmodules/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/ngmodule/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
/aio/content/images/guide/ngmodule/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
|
|
||||||
/aio/content/guide/ngmodule-api.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/ngmodule-api.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
@ -469,6 +513,9 @@
|
|||||||
/aio/content/guide/module-types.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/module-types.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
/aio/content/guide/template-syntax.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/template-syntax.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/built-in-template-functions/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/event-binding/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/interpolation/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/template-syntax/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/template-syntax/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/images/guide/template-syntax/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/images/guide/template-syntax/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
@ -491,6 +538,10 @@
|
|||||||
/aio/content/examples/structural-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/structural-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/images/guide/structural-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/images/guide/structural-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
/aio/content/guide/user-input.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/user-input/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/images/guide/user-input/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ================================================
|
# ================================================
|
||||||
@ -516,6 +567,7 @@
|
|||||||
/aio/content/guide/elements.md @angular/fw-elements @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/elements.md @angular/fw-elements @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ================================================
|
# ================================================
|
||||||
# @angular/forms
|
# @angular/forms
|
||||||
# ================================================
|
# ================================================
|
||||||
@ -577,6 +629,7 @@
|
|||||||
/packages/service-worker/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/packages/service-worker/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/service-worker-getting-started.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/service-worker-getting-started.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/service-worker-getting-started/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/service-worker-getting-started/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/app-shell.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/service-worker-communications.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/service-worker-communications.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/service-worker-config.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/service-worker-config.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/service-worker-devops.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/service-worker-devops.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
@ -646,6 +699,7 @@ testing/** @angular/fw-test
|
|||||||
/packages/platform-browser/src/security/** @angular/fw-security
|
/packages/platform-browser/src/security/** @angular/fw-security
|
||||||
/aio/content/guide/security.md @angular/fw-security @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/security.md @angular/fw-security @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/security/** @angular/fw-security @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/security/** @angular/fw-security @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/images/guide/security/** @angular/fw-security @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -676,6 +730,14 @@ testing/** @angular/fw-test
|
|||||||
/aio/tests/** @angular/docs-infra @angular/framework-global-approvers
|
/aio/tests/** @angular/docs-infra @angular/framework-global-approvers
|
||||||
/aio/tools/** @angular/docs-infra @angular/framework-global-approvers
|
/aio/tools/** @angular/docs-infra @angular/framework-global-approvers
|
||||||
|
|
||||||
|
# Hidden docs
|
||||||
|
/aio/content/guide/change-log.md @angular/docs-infra @angular/framework-global-approvers
|
||||||
|
/aio/content/guide/docs-style-guide.md @angular/docs-infra @angular/framework-global-approvers
|
||||||
|
/aio/content/examples/docs-style-guide/** @angular/docs-infra @angular/framework-global-approvers
|
||||||
|
/aio/content/images/guide/docs-style-guide/** @angular/docs-infra @angular/framework-global-approvers
|
||||||
|
/aio/content/guide/visual-studio-2015.md @angular/docs-infra @angular/framework-global-approvers
|
||||||
|
/aio/content/examples/visual-studio-2015/** @angular/docs-infra @angular/framework-global-approvers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ================================================
|
# ================================================
|
||||||
@ -683,7 +745,17 @@ testing/** @angular/fw-test
|
|||||||
# ================================================
|
# ================================================
|
||||||
|
|
||||||
/aio/content/guide/quickstart.md @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/quickstart.md @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/cli-quickstart/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/images/guide/cli-quickstart/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/tutorial/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/tutorial/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/images/guide/toh/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/toh-pt0/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/toh-pt1/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/toh-pt2/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/toh-pt3/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/toh-pt4/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/toh-pt5/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/toh-pt6/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -691,17 +763,15 @@ testing/** @angular/fw-test
|
|||||||
# Docs: observables
|
# Docs: observables
|
||||||
# ================================================
|
# ================================================
|
||||||
|
|
||||||
/aio/content/examples/observables/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
/aio/content/images/guide/observables/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
/aio/content/guide/observables.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/observables.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/observables/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/comparing-observables.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/comparing-observables.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/observables-in-angular/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
/aio/content/images/guide/observables-in-angular/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
/aio/content/guide/observables-in-angular.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/observables-in-angular.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/practical-observable-usage/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/observables-in-angular/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/practical-observable-usage.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/practical-observable-usage.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/rx-library/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/practical-observable-usage/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/rx-library.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/rx-library.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/examples/rx-library/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -712,12 +782,25 @@ testing/** @angular/fw-test
|
|||||||
/aio/content/guide/npm-packages.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/npm-packages.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/browser-support.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/browser-support.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/typescript-configuration.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/typescript-configuration.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/setup-systemjs-anatomy.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
|
||||||
/aio/content/guide/setup.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/setup.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/examples/setup/** @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/examples/setup/** @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/build.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/images/guide/build/** @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/deployment.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/deployment.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/file-structure.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/releases.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/releases.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/guide/updating.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/guide/updating.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/workspace-config.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ================================================
|
||||||
|
# Docs: libraries
|
||||||
|
# ================================================
|
||||||
|
|
||||||
|
/aio/content/guide/creating-libraries.md @angular/tools-docs-libraries @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/libraries.md @angular/tools-docs-libraries @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/guide/using-libraries.md @angular/tools-docs-libraries @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -726,6 +809,7 @@ testing/** @angular/fw-test
|
|||||||
# ================================================
|
# ================================================
|
||||||
|
|
||||||
/aio/content/marketing/** @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/marketing/** @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
|
/aio/content/images/bios/** @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/images/marketing/** @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/images/marketing/** @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/navigation.json @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/navigation.json @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
/aio/content/license.md @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
/aio/content/license.md @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||||
@ -739,8 +823,11 @@ testing/** @angular/fw-test
|
|||||||
/* @angular/fw-dev-infra
|
/* @angular/fw-dev-infra
|
||||||
/.buildkite/** @angular/fw-dev-infra
|
/.buildkite/** @angular/fw-dev-infra
|
||||||
/.circleci/** @angular/fw-dev-infra
|
/.circleci/** @angular/fw-dev-infra
|
||||||
|
/.codefresh/** @angular/fw-dev-infra
|
||||||
/.github/** @angular/fw-dev-infra
|
/.github/** @angular/fw-dev-infra
|
||||||
|
/.vscode/** @angular/fw-dev-infra
|
||||||
/docs/BAZEL.md @angular/fw-dev-infra
|
/docs/BAZEL.md @angular/fw-dev-infra
|
||||||
|
/packages/* @angular/fw-dev-infra
|
||||||
/scripts/** @angular/fw-dev-infra
|
/scripts/** @angular/fw-dev-infra
|
||||||
/third_party/** @angular/fw-dev-infra
|
/third_party/** @angular/fw-dev-infra
|
||||||
/tools/** @angular/fw-dev-infra
|
/tools/** @angular/fw-dev-infra
|
||||||
@ -753,6 +840,10 @@ testing/** @angular/fw-test
|
|||||||
# ================================================
|
# ================================================
|
||||||
|
|
||||||
/tools/public_api_guard/** @angular/fw-public-api
|
/tools/public_api_guard/** @angular/fw-public-api
|
||||||
|
/aio/content/guide/glossary.md @angular/fw-public-api
|
||||||
|
/aio/content/guide/styleguide.md @angular/fw-public-api
|
||||||
|
/aio/content/examples/styleguide/** @angular/fw-public-api
|
||||||
|
/aio/content/images/guide/styleguide/** @angular/fw-public-api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
4
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
@ -37,7 +37,9 @@ Please create and share minimal reproduction of the issue starting with this tem
|
|||||||
<!-- ✍️--> https://stackblitz.com/...
|
<!-- ✍️--> https://stackblitz.com/...
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue. Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
|
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue.
|
||||||
|
A good way to make a minimal reproduction is to create a new app via `ng new repro-app` and add the minimum possible code to show the problem.
|
||||||
|
Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
|
||||||
|
|
||||||
Issues that don't have enough info and can't be reproduced will be closed.
|
Issues that don't have enough info and can't be reproduced will be closed.
|
||||||
|
|
||||||
|
7
.github/angular-robot.yml
vendored
7
.github/angular-robot.yml
vendored
@ -56,9 +56,9 @@ merge:
|
|||||||
- "**/.gitkeep"
|
- "**/.gitkeep"
|
||||||
- "**/yarn.lock"
|
- "**/yarn.lock"
|
||||||
- "**/package.json"
|
- "**/package.json"
|
||||||
|
- "**/third_party/**"
|
||||||
- "**/tsconfig-build.json"
|
- "**/tsconfig-build.json"
|
||||||
- "**/tsconfig.json"
|
- "**/tsconfig.json"
|
||||||
- "**/rollup.config.js"
|
|
||||||
- "**/BUILD.bazel"
|
- "**/BUILD.bazel"
|
||||||
- "**/*.md"
|
- "**/*.md"
|
||||||
- "packages/**/integrationtest/**"
|
- "packages/**/integrationtest/**"
|
||||||
@ -103,6 +103,11 @@ merge:
|
|||||||
requiredStatuses:
|
requiredStatuses:
|
||||||
- "ci/circleci: build"
|
- "ci/circleci: build"
|
||||||
- "ci/circleci: lint"
|
- "ci/circleci: lint"
|
||||||
|
- "ci/circleci: publish_snapshot"
|
||||||
|
- "ci/angular: size"
|
||||||
|
- "cla/google"
|
||||||
|
- "google3"
|
||||||
|
|
||||||
|
|
||||||
# the comment that will be added when the merge label is added despite failing checks, leave empty or set to false to disable
|
# the comment that will be added when the merge label is added despite failing checks, leave empty or set to false to disable
|
||||||
# {{MERGE_LABEL}} will be replaced by the value of the mergeLabel option
|
# {{MERGE_LABEL}} will be replaced by the value of the mergeLabel option
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ pubspec.lock
|
|||||||
.idea/
|
.idea/
|
||||||
.settings/
|
.settings/
|
||||||
.vscode/launch.json
|
.vscode/launch.json
|
||||||
|
.vscode/settings.json
|
||||||
*.swo
|
*.swo
|
||||||
modules/.settings
|
modules/.settings
|
||||||
modules/.vscode
|
modules/.vscode
|
||||||
|
23
.vscode/README.md
vendored
Normal file
23
.vscode/README.md
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# VSCode Configuration
|
||||||
|
|
||||||
|
This folder contains opt-in [Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings) and [Extension Recommendations](https://code.visualstudio.com/docs/editor/extension-gallery#_workspace-recommended-extensions) that the Angular team recommends using when working on this repository.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To use the recommended settings follow the steps below:
|
||||||
|
|
||||||
|
- install <https://marketplace.visualstudio.com/items?itemName=xaver.clang-format>
|
||||||
|
- copy `.vscode/recommended-settings.json` to `.vscode/settings.json`
|
||||||
|
- restart the editor
|
||||||
|
|
||||||
|
If you already have your custom workspace settings you should instead manually merge the file content.
|
||||||
|
|
||||||
|
This isn't an automatic process so you will need to repeat it when settings are updated.
|
||||||
|
|
||||||
|
To see the recommended extensions select "Extensions: Show Recommended Extensions" in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).
|
||||||
|
|
||||||
|
## Editing `.vscode/recommended-settings.json`
|
||||||
|
|
||||||
|
If you wish to add extra configuration items please keep in mind any settings you add here will be used by many users.
|
||||||
|
|
||||||
|
Try to keep these settings to things that help facilitate the development process and avoid altering the user workflow whenever possible.
|
12
.vscode/extensions.json
vendored
Normal file
12
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||||
|
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||||
|
|
||||||
|
// List of extensions which should be recommended for users of this workspace.
|
||||||
|
"recommendations": [
|
||||||
|
"devondcarew.bazel-code",
|
||||||
|
"gkalpak.aio-docs-utils",
|
||||||
|
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||||
|
"xaver.clang-format",
|
||||||
|
],
|
||||||
|
}
|
31
.vscode/recommended-settings.json
vendored
Normal file
31
.vscode/recommended-settings.json
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
// Format js and ts files on save with `clang-format.executable`
|
||||||
|
// If `clang-format.executable` is not being used, these two settings should be removed otherwise it will break existing formatting.
|
||||||
|
// You can instead run `yarn gulp format` to manually format your code.
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
},
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
},
|
||||||
|
// Please install https://marketplace.visualstudio.com/items?itemName=xaver.clang-format to take advantage of `clang-format` in VSCode.
|
||||||
|
// (See https://clang.llvm.org/docs/ClangFormat.html for more info `clang-format`.)
|
||||||
|
"clang-format.executable": "${workspaceRoot}/node_modules/.bin/clang-format",
|
||||||
|
// Exclude third party modules and build artifacts from the editor watchers/searches.
|
||||||
|
"files.watcherExclude": {
|
||||||
|
"**/.git/objects/**": true,
|
||||||
|
"**/.git/subtree-cache/**": true,
|
||||||
|
"**/node_modules/**": true,
|
||||||
|
"**/bazel-out/**": true,
|
||||||
|
"**/dist/**": true,
|
||||||
|
"**/aio/src/generated/**": true,
|
||||||
|
},
|
||||||
|
"search.exclude": {
|
||||||
|
"**/node_modules": true,
|
||||||
|
"**/bower_components": true,
|
||||||
|
"**/bazel-out": true,
|
||||||
|
"**/dist": true,
|
||||||
|
"**/aio/src/generated": true,
|
||||||
|
},
|
||||||
|
"git.ignoreLimitWarning": true,
|
||||||
|
}
|
15
.vscode/settings.json
vendored
15
.vscode/settings.json
vendored
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"files.watcherExclude": {
|
|
||||||
"**/.git/objects/**": true,
|
|
||||||
"**/.git/subtree-cache/**": true,
|
|
||||||
"**/node_modules/**": true,
|
|
||||||
"**/bazel-out/**": true,
|
|
||||||
"**/dist/**": true,
|
|
||||||
},
|
|
||||||
"search.exclude": {
|
|
||||||
"**/node_modules": true,
|
|
||||||
"**/bower_components": true,
|
|
||||||
"**/bazel-out": true,
|
|
||||||
"**/dist": true,
|
|
||||||
},
|
|
||||||
}
|
|
52
BUILD.bazel
52
BUILD.bazel
@ -1,21 +1,23 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
load("@build_bazel_rules_nodejs//:defs.bzl", "node_modules_filegroup")
|
|
||||||
|
|
||||||
exports_files([
|
exports_files([
|
||||||
"tsconfig.json",
|
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
"protractor-perf.conf.js",
|
"protractor-perf.conf.js",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "tsconfig.json",
|
||||||
|
actual = "//packages:tsconfig-build.json",
|
||||||
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
name = "web_test_bootstrap_scripts",
|
name = "web_test_bootstrap_scripts",
|
||||||
# do not sort
|
# do not sort
|
||||||
srcs = [
|
srcs = [
|
||||||
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
|
"@npm//node_modules/reflect-metadata:Reflect.js",
|
||||||
"@ngdeps//node_modules/zone.js:dist/zone.js",
|
"@npm//node_modules/zone.js:dist/zone.js",
|
||||||
"@ngdeps//node_modules/zone.js:dist/zone-testing.js",
|
"@npm//node_modules/zone.js:dist/zone-testing.js",
|
||||||
"@ngdeps//node_modules/zone.js:dist/task-tracking.js",
|
"@npm//node_modules/zone.js:dist/task-tracking.js",
|
||||||
"//:test-events.js",
|
"//:test-events.js",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -25,32 +27,14 @@ filegroup(
|
|||||||
srcs = [
|
srcs = [
|
||||||
# We also declare the unminfied AngularJS files since these can be used for
|
# We also declare the unminfied AngularJS files since these can be used for
|
||||||
# local debugging (e.g. see: packages/upgrade/test/common/test_helpers.ts)
|
# local debugging (e.g. see: packages/upgrade/test/common/test_helpers.ts)
|
||||||
"@ngdeps//node_modules/angular:angular.js",
|
"@npm//node_modules/angular:angular.js",
|
||||||
"@ngdeps//node_modules/angular:angular.min.js",
|
"@npm//node_modules/angular:angular.min.js",
|
||||||
"@ngdeps//node_modules/angular-1.5:angular.js",
|
"@npm//node_modules/angular-1.5:angular.js",
|
||||||
"@ngdeps//node_modules/angular-1.5:angular.min.js",
|
"@npm//node_modules/angular-1.5:angular.min.js",
|
||||||
"@ngdeps//node_modules/angular-1.6:angular.js",
|
"@npm//node_modules/angular-1.6:angular.js",
|
||||||
"@ngdeps//node_modules/angular-1.6:angular.min.js",
|
"@npm//node_modules/angular-1.6:angular.min.js",
|
||||||
"@ngdeps//node_modules/angular-mocks:angular-mocks.js",
|
"@npm//node_modules/angular-mocks:angular-mocks.js",
|
||||||
"@ngdeps//node_modules/angular-mocks-1.5:angular-mocks.js",
|
"@npm//node_modules/angular-mocks-1.5:angular-mocks.js",
|
||||||
"@ngdeps//node_modules/angular-mocks-1.6:angular-mocks.js",
|
"@npm//node_modules/angular-mocks-1.6:angular-mocks.js",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
|
|
||||||
|
|
||||||
# A nodejs_binary for @angular/bazel/ngc-wrapped to use by default in
|
|
||||||
# ng_module that depends on @npm//@angular/bazel instead of the
|
|
||||||
# output of the //packages/bazel/src/ngc-wrapped ts_library rule. This
|
|
||||||
# default is for downstream users that depend on the @angular/bazel npm
|
|
||||||
# package. The generated @npm//@angular/bazel/ngc-wrapped target
|
|
||||||
# does not work because it does not have the node `--expose-gc` flag
|
|
||||||
# set which is required to support the call to `global.gc()`.
|
|
||||||
nodejs_binary(
|
|
||||||
name = "@angular/bazel/ngc-wrapped",
|
|
||||||
configuration_env_vars = ["compile"],
|
|
||||||
data = ["@npm//@angular/bazel"],
|
|
||||||
entry_point = "@angular/bazel/src/ngc-wrapped/index.js",
|
|
||||||
install_source_map_support = False,
|
|
||||||
templated_args = ["--node_options=--expose-gc"],
|
|
||||||
)
|
|
||||||
|
136
CHANGELOG.md
136
CHANGELOG.md
@ -1,3 +1,139 @@
|
|||||||
|
<a name="7.2.14"></a>
|
||||||
|
## [7.2.14](https://github.com/angular/angular/compare/7.2.13...7.2.14) (2019-04-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **common:** prevent repeated application of HttpParams mutations ([#29045](https://github.com/angular/angular/issues/29045)) ([ee65d0d](https://github.com/angular/angular/commit/ee65d0d)), closes [#20430](https://github.com/angular/angular/issues/20430)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="7.2.13"></a>
|
||||||
|
## [7.2.13](https://github.com/angular/angular/compare/7.2.12...7.2.13) (2019-04-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **bazel:** use //:tsconfig.json as the default for ng_module ([#29670](https://github.com/angular/angular/issues/29670)) ([#29711](https://github.com/angular/angular/issues/29711)) ([9e33dc3](https://github.com/angular/angular/commit/9e33dc3))
|
||||||
|
* **platform-browser:** insert APP_ID in styles, contentAttr and hostAttr ([#17745](https://github.com/angular/angular/issues/17745)) ([ca14509](https://github.com/angular/angular/commit/ca14509))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="7.2.12"></a>
|
||||||
|
## [7.2.12](https://github.com/angular/angular/compare/7.2.11...7.2.12) (2019-04-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **common:** escape query selector used when anchor scrolling ([#29577](https://github.com/angular/angular/issues/29577)) ([7671c73](https://github.com/angular/angular/commit/7671c73)), closes [#28193](https://github.com/angular/angular/issues/28193)
|
||||||
|
* **router:** adjust setting navigationTransition when a new navigation cancels an existing one ([#29636](https://github.com/angular/angular/issues/29636)) ([e884c0c](https://github.com/angular/angular/commit/e884c0c)), closes [#29389](https://github.com/angular/angular/issues/29389) [#29590](https://github.com/angular/angular/issues/29590)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="7.2.11"></a>
|
||||||
|
## [7.2.11](https://github.com/angular/angular/compare/7.2.10...7.2.11) (2019-03-26)
|
||||||
|
|
||||||
|
This release contains various API docs improvements.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="7.2.10"></a>
|
||||||
|
## [7.2.10](https://github.com/angular/angular/compare/7.2.9...7.2.10) (2019-03-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **compiler-cli:** incorrect metadata bundle for multiple unnamed re-exports ([#29360](https://github.com/angular/angular/issues/29360)) ([cf8d934](https://github.com/angular/angular/commit/cf8d934)), closes [/github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85](https://github.com//github.com/angular/material2/blob/master/tools/package-tools/build-release.ts/issues/L78-L85)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="7.2.9"></a>
|
||||||
|
## [7.2.9](https://github.com/angular/angular/compare/7.2.8...7.2.9) (2019-03-12)
|
||||||
|
|
||||||
|
This release contains various API docs improvements.
|
||||||
|
|
||||||
|
<a name="7.2.8"></a>
|
||||||
|
## [7.2.8](https://github.com/angular/angular/compare/7.2.7...7.2.8) (2019-03-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **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))
|
||||||
|
* **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 [/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>
|
||||||
|
## [7.2.7](https://github.com/angular/angular/compare/7.2.6...7.2.7) (2019-02-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **bazel:** pin browser repositories using [@npm](https://github.com/npm)_bazel_karma//:browser_repositories.bzl in bazel schematics ([#28896](https://github.com/angular/angular/issues/28896)) ([b686449](https://github.com/angular/angular/commit/b686449))
|
||||||
|
* **core:** traverse and sanitize content of unsafe elements ([#28804](https://github.com/angular/angular/issues/28804)) ([fdcf877](https://github.com/angular/angular/commit/fdcf877)), closes [#25879](https://github.com/angular/angular/issues/25879) [#25879](https://github.com/angular/angular/issues/25879) [#26007](https://github.com/angular/angular/issues/26007) [#28427](https://github.com/angular/angular/issues/28427)
|
||||||
|
* **language-service:** Fix completions for input/output with alias ([#28904](https://github.com/angular/angular/issues/28904)) ([d0018e6](https://github.com/angular/angular/commit/d0018e6)), closes [#27959](https://github.com/angular/angular/issues/27959)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="7.2.6"></a>
|
||||||
|
## [7.2.6](https://github.com/angular/angular/compare/7.2.5...7.2.6) (2019-02-20)
|
||||||
|
|
||||||
|
|
||||||
|
### 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//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>
|
||||||
|
## [7.2.5](https://github.com/angular/angular/compare/7.2.4...7.2.5) (2019-02-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **compiler-cli:** diagnostics should respect "newLine" compiler option ([#28550](https://github.com/angular/angular/issues/28550)) ([ce750e6](https://github.com/angular/angular/commit/ce750e6))
|
||||||
|
* **router:** redirect to root url when returned as UrlTree from guard ([#28271](https://github.com/angular/angular/issues/28271)) ([1e58a21](https://github.com/angular/angular/commit/1e58a21)), closes [#27845](https://github.com/angular/angular/issues/27845)
|
||||||
|
* **router:** set href when routerLink is used on an 'area' element ([#28441](https://github.com/angular/angular/issues/28441)) ([d491a20](https://github.com/angular/angular/commit/d491a20)), closes [#28401](https://github.com/angular/angular/issues/28401)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="7.2.4"></a>
|
||||||
|
## [7.2.4](https://github.com/angular/angular/compare/7.2.3...7.2.4) (2019-02-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **bazel:** Bazel builder resolves with require.resolve() ([#28478](https://github.com/angular/angular/issues/28478)) ([d85d396](https://github.com/angular/angular/commit/d85d396))
|
||||||
|
* **bazel:** fix integration test for bazel-schematics ([#28460](https://github.com/angular/angular/issues/28460)) ([449da8c](https://github.com/angular/angular/commit/449da8c))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* pngcrush all pngs ([#28479](https://github.com/angular/angular/issues/28479)) ([1a25144](https://github.com/angular/angular/commit/1a25144)), closes [#18243](https://github.com/angular/angular/issues/18243)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="7.2.3"></a>
|
||||||
|
## [7.2.3](https://github.com/angular/angular/compare/7.2.2...7.2.3) (2019-01-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **bazel:** add [@npm](https://github.com/npm)//tslib dep to e2e ts_library target in bazel-workspace schematic ([#28358](https://github.com/angular/angular/issues/28358)) ([8cee56e](https://github.com/angular/angular/commit/8cee56e))
|
||||||
|
* **bazel:** Bazel-workspace schematics should run in ScopedTree ([#28349](https://github.com/angular/angular/issues/28349)) ([260ac20](https://github.com/angular/angular/commit/260ac20))
|
||||||
|
* **bazel:** Builder should invoke local bazel/iblaze ([#28303](https://github.com/angular/angular/issues/28303)) ([12b8a6e](https://github.com/angular/angular/commit/12b8a6e))
|
||||||
|
* **bazel:** ng-new should run yarn install ([#28381](https://github.com/angular/angular/issues/28381)) ([a9d46e4](https://github.com/angular/angular/commit/a9d46e4))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* yarn version upgrade ([#28360](https://github.com/angular/angular/issues/28360)) ([cc1b2a5](https://github.com/angular/angular/commit/cc1b2a5))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="7.2.2"></a>
|
<a name="7.2.2"></a>
|
||||||
## [7.2.2](https://github.com/angular/angular/compare/7.2.1...7.2.2) (2019-01-22)
|
## [7.2.2](https://github.com/angular/angular/compare/7.2.1...7.2.2) (2019-01-22)
|
||||||
|
|
||||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2014-2018 Google, Inc. http://angular.io
|
Copyright (c) 2010-2019 Google LLC. http://angular.io/license
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
129
WORKSPACE
129
WORKSPACE
@ -1,17 +1,6 @@
|
|||||||
workspace(name = "angular")
|
workspace(name = "angular")
|
||||||
|
|
||||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||||
load(
|
|
||||||
"//packages/bazel:package.bzl",
|
|
||||||
"rules_angular_dependencies",
|
|
||||||
"rules_angular_dev_dependencies",
|
|
||||||
)
|
|
||||||
|
|
||||||
http_archive(
|
|
||||||
name = "io_bazel_rules_go",
|
|
||||||
sha256 = "b7a62250a3a73277ade0ce306d22f122365b513f5402222403e507f2f997d421",
|
|
||||||
url = "https://github.com/bazelbuild/rules_go/releases/download/0.16.3/rules_go-0.16.3.tar.gz",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Uncomment for local bazel rules development
|
# Uncomment for local bazel rules development
|
||||||
#local_repository(
|
#local_repository(
|
||||||
@ -19,59 +8,43 @@ http_archive(
|
|||||||
# path = "../rules_nodejs",
|
# path = "../rules_nodejs",
|
||||||
#)
|
#)
|
||||||
#local_repository(
|
#local_repository(
|
||||||
# name = "build_bazel_rules_typescript",
|
# name = "npm_bazel_typescript",
|
||||||
# path = "../rules_typescript",
|
# path = "../rules_typescript",
|
||||||
#)
|
#)
|
||||||
|
|
||||||
# Angular Bazel users will call this function
|
# Fetch rules_nodejs so we can install our npm dependencies
|
||||||
rules_angular_dependencies()
|
|
||||||
|
|
||||||
# Install transitive deps of rules_nodejs
|
|
||||||
load("@build_bazel_rules_nodejs//:package.bzl", "rules_nodejs_dependencies")
|
|
||||||
|
|
||||||
rules_nodejs_dependencies()
|
|
||||||
|
|
||||||
# These are the dependencies only for us
|
|
||||||
rules_angular_dev_dependencies()
|
|
||||||
|
|
||||||
# Install transitive deps of rules_typescript
|
|
||||||
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
|
|
||||||
|
|
||||||
rules_typescript_dependencies()
|
|
||||||
|
|
||||||
#
|
|
||||||
# Point Bazel to WORKSPACEs that live in subdirectories
|
|
||||||
#
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "rxjs",
|
name = "build_bazel_rules_nodejs",
|
||||||
sha256 = "72b0b4e517f43358f554c125e40e39f67688cd2738a8998b4a266981ed32f403",
|
sha256 = "5c86b055c57e15bf32d9009a15bcd6d8e190c41b1ff2fb18037b75e0012e4e7c",
|
||||||
strip_prefix = "package/src",
|
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.26.0/rules_nodejs-0.26.0.tar.gz"],
|
||||||
url = "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Point to the integration test workspace just so that Bazel doesn't descend into it
|
# Check the bazel version and download npm dependencies
|
||||||
# when expanding the //... pattern
|
|
||||||
local_repository(
|
|
||||||
name = "bazel_integration_test",
|
|
||||||
path = "integration/bazel",
|
|
||||||
)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Load and install our dependencies downloaded above.
|
|
||||||
#
|
|
||||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
||||||
|
load("@build_bazel_rules_nodejs//:package.bzl", "check_rules_nodejs_version")
|
||||||
|
|
||||||
# Bazel version must be at least v0.21.0 because:
|
# Bazel version must be at least v0.21.0 because:
|
||||||
# - 0.21.0 --experimental_strict_action_env flag turned on by default which fixes cache when
|
# - 0.21.0 Using --incompatible_strict_action_env flag fixes cache when running `yarn bazel`
|
||||||
# running `yarn bazel` (see https://github.com/angular/angular/issues/27514#issuecomment-451438271)
|
# (see https://github.com/angular/angular/issues/27514#issuecomment-451438271)
|
||||||
check_bazel_version("0.21.0", """
|
check_bazel_version(
|
||||||
|
message = """
|
||||||
You no longer need to install Bazel on your machine.
|
You no longer need to install Bazel on your machine.
|
||||||
Angular has a dependency on the @bazel/bazel package which supplies it.
|
Angular has a dependency on the @bazel/bazel package which supplies it.
|
||||||
Try running `yarn bazel` instead.
|
Try running `yarn bazel` instead.
|
||||||
(If you did run that, check that you've got a fresh `yarn install`)
|
(If you did run that, check that you've got a fresh `yarn install`)
|
||||||
|
|
||||||
""")
|
""",
|
||||||
|
minimum_bazel_version = "0.21.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
# The NodeJS rules version must be at least v0.15.3 because:
|
||||||
|
# - 0.15.2 Re-introduced the prod_only attribute on yarn_install
|
||||||
|
# - 0.15.3 Includes a fix for the `jasmine_node_test` rule ignoring target tags
|
||||||
|
# - 0.16.8 Supports npm installed bazel workspaces
|
||||||
|
# - 0.26.0 Fix for data files in yarn_install and npm_install
|
||||||
|
check_rules_nodejs_version("0.26.0")
|
||||||
|
|
||||||
|
# Setup the Node.js toolchain
|
||||||
node_repositories(
|
node_repositories(
|
||||||
node_version = "10.9.0",
|
node_version = "10.9.0",
|
||||||
package_json = ["//:package.json"],
|
package_json = ["//:package.json"],
|
||||||
@ -79,41 +52,63 @@ node_repositories(
|
|||||||
yarn_version = "1.12.1",
|
yarn_version = "1.12.1",
|
||||||
)
|
)
|
||||||
|
|
||||||
local_repository(
|
yarn_install(
|
||||||
name = "npm",
|
name = "npm",
|
||||||
path = "tools/npm_workspace",
|
data = [
|
||||||
|
"//:tools/npm/@angular_bazel/index.js",
|
||||||
|
"//:tools/npm/@angular_bazel/package.json",
|
||||||
|
"//:tools/postinstall-patches.js",
|
||||||
|
"//:tools/yarn/check-yarn.js",
|
||||||
|
],
|
||||||
|
package_json = "//:package.json",
|
||||||
|
# Don't install devDependencies, they are large and not used under Bazel
|
||||||
|
prod_only = True,
|
||||||
|
yarn_lock = "//:yarn.lock",
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@io_bazel_rules_go//go:def.bzl", "go_register_toolchains", "go_rules_dependencies")
|
yarn_install(
|
||||||
|
name = "ts-api-guardian_deps",
|
||||||
|
package_json = "@angular//tools/ts-api-guardian:package.json",
|
||||||
|
yarn_lock = "@angular//tools/ts-api-guardian:yarn.lock",
|
||||||
|
)
|
||||||
|
|
||||||
go_rules_dependencies()
|
# Install all bazel dependencies of the @npm npm packages
|
||||||
|
load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
|
||||||
|
|
||||||
go_register_toolchains()
|
install_bazel_dependencies()
|
||||||
|
|
||||||
load("@io_bazel_rules_webtesting//web:repositories.bzl", "browser_repositories", "web_test_repositories")
|
# Load angular dependencies
|
||||||
|
load("//packages/bazel:package.bzl", "rules_angular_dev_dependencies")
|
||||||
|
|
||||||
|
rules_angular_dev_dependencies()
|
||||||
|
|
||||||
|
# Load karma dependencies
|
||||||
|
load("@npm_bazel_karma//:package.bzl", "rules_karma_dependencies")
|
||||||
|
|
||||||
|
rules_karma_dependencies()
|
||||||
|
|
||||||
|
# Setup the rules_webtesting toolchain
|
||||||
|
load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories")
|
||||||
|
|
||||||
web_test_repositories()
|
web_test_repositories()
|
||||||
|
|
||||||
browser_repositories(
|
# Temporary work-around for https://github.com/angular/angular/issues/28681
|
||||||
chromium = True,
|
# TODO(gregmagolan): go back to @io_bazel_rules_webtesting browser_repositories
|
||||||
firefox = True,
|
load("@npm_bazel_karma//:browser_repositories.bzl", "browser_repositories")
|
||||||
)
|
|
||||||
|
|
||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
|
browser_repositories()
|
||||||
|
|
||||||
|
# Setup the rules_typescript tooolchain
|
||||||
|
load("@npm_bazel_typescript//:index.bzl", "ts_setup_workspace")
|
||||||
|
|
||||||
ts_setup_workspace()
|
ts_setup_workspace()
|
||||||
|
|
||||||
load("@angular//:index.bzl", "ng_setup_workspace")
|
# Setup the rules_sass toolchain
|
||||||
|
|
||||||
ng_setup_workspace()
|
|
||||||
|
|
||||||
##################################
|
|
||||||
# Skylark documentation generation
|
|
||||||
|
|
||||||
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
|
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
|
||||||
|
|
||||||
sass_repositories()
|
sass_repositories()
|
||||||
|
|
||||||
|
# Setup the skydoc toolchain
|
||||||
load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
|
load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
|
||||||
|
|
||||||
skydoc_repositories()
|
skydoc_repositories()
|
||||||
|
2
aio/.gitignore
vendored
2
aio/.gitignore
vendored
@ -26,11 +26,13 @@
|
|||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
|
/.firebase/
|
||||||
/.sass-cache
|
/.sass-cache
|
||||||
/connect.lock
|
/connect.lock
|
||||||
/coverage
|
/coverage
|
||||||
/libpeerconnection.log
|
/libpeerconnection.log
|
||||||
debug.log
|
debug.log
|
||||||
|
firebase-debug.log
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
testem.log
|
testem.log
|
||||||
/typings
|
/typings
|
||||||
|
@ -41,16 +41,6 @@ Here are the most important tasks you might need to use:
|
|||||||
- `yarn example-e2e --filter=foo` - limit e2e tests to those containing the word "foo"
|
- `yarn example-e2e --filter=foo` - limit e2e tests to those containing the word "foo"
|
||||||
- `yarn example-e2e --setup --local` - run e2e tests with the local version of Angular contained in the "dist" folder
|
- `yarn example-e2e --setup --local` - run e2e tests with the local version of Angular contained in the "dist" folder
|
||||||
|
|
||||||
## Developing on Windows
|
|
||||||
The `packages/` directory may contain Linux-specific symlinks, which are not recognized by Windows.
|
|
||||||
These unresolved links cause the docs generation process to fail because it cannot locate certain files.
|
|
||||||
|
|
||||||
> Hint: The following steps require administration rights or [Windows Developer Mode](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development) enabled!
|
|
||||||
|
|
||||||
To fix this problem, run `scripts/windows/create-symlinks.sh`. This command creates temporary files where the symlinks used to be. Make sure not to commit those files with your documentation changes.
|
|
||||||
When you are done making and testing your documentation changes, you can restore the original symlinks and delete the temporary files by running `scripts/windows/remove-symlinks.sh`.
|
|
||||||
|
|
||||||
It's necessary to remove the temporary files, because otherwise they're displayed as local changes in your git working copy and certain operations are blocked.
|
|
||||||
|
|
||||||
## Using ServiceWorker locally
|
## Using ServiceWorker locally
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Image metadata and config
|
# Image metadata and config
|
||||||
FROM debian:jessie
|
FROM debian:stretch
|
||||||
|
|
||||||
LABEL name="angular.io PR preview" \
|
LABEL name="angular.io PR preview" \
|
||||||
description="This image implements the PR preview functionality for angular.io." \
|
description="This image implements the PR preview functionality for angular.io." \
|
||||||
@ -26,8 +26,8 @@ ARG AIO_GITHUB_ORGANIZATION=angular
|
|||||||
ARG TEST_AIO_GITHUB_ORGANIZATION=test-org
|
ARG TEST_AIO_GITHUB_ORGANIZATION=test-org
|
||||||
ARG AIO_GITHUB_REPO=angular
|
ARG AIO_GITHUB_REPO=angular
|
||||||
ARG TEST_AIO_GITHUB_REPO=test-repo
|
ARG TEST_AIO_GITHUB_REPO=test-repo
|
||||||
ARG AIO_GITHUB_TEAM_SLUGS=aio-contributors
|
ARG AIO_GITHUB_TEAM_SLUGS=aio-auto-previews,aio-contributors
|
||||||
ARG TEST_AIO_GITHUB_TEAM_SLUGS=aio-contributors
|
ARG TEST_AIO_GITHUB_TEAM_SLUGS=test-team-1,test-team-2
|
||||||
ARG AIO_NGINX_HOSTNAME=$AIO_DOMAIN_NAME
|
ARG AIO_NGINX_HOSTNAME=$AIO_DOMAIN_NAME
|
||||||
ARG TEST_AIO_NGINX_HOSTNAME=$TEST_AIO_DOMAIN_NAME
|
ARG TEST_AIO_NGINX_HOSTNAME=$TEST_AIO_DOMAIN_NAME
|
||||||
ARG AIO_NGINX_PORT_HTTP=80
|
ARG AIO_NGINX_PORT_HTTP=80
|
||||||
@ -40,7 +40,7 @@ ARG AIO_TRUSTED_PR_LABEL="aio: preview"
|
|||||||
ARG TEST_AIO_TRUSTED_PR_LABEL="aio: preview"
|
ARG TEST_AIO_TRUSTED_PR_LABEL="aio: preview"
|
||||||
ARG AIO_PREVIEW_SERVER_HOSTNAME=preview.localhost
|
ARG AIO_PREVIEW_SERVER_HOSTNAME=preview.localhost
|
||||||
ARG TEST_AIO_PREVIEW_SERVER_HOSTNAME=preview.localhost
|
ARG TEST_AIO_PREVIEW_SERVER_HOSTNAME=preview.localhost
|
||||||
ARG AIO_ARTIFACT_MAX_SIZE=20971520
|
ARG AIO_ARTIFACT_MAX_SIZE=26214400
|
||||||
ARG TEST_AIO_ARTIFACT_MAX_SIZE=200
|
ARG TEST_AIO_ARTIFACT_MAX_SIZE=200
|
||||||
ARG AIO_PREVIEW_SERVER_PORT=3000
|
ARG AIO_PREVIEW_SERVER_PORT=3000
|
||||||
ARG TEST_AIO_PREVIEW_SERVER_PORT=3001
|
ARG TEST_AIO_PREVIEW_SERVER_PORT=3001
|
||||||
@ -76,21 +76,20 @@ RUN apt-get update -y && apt-get install -y curl
|
|||||||
RUN curl --silent --show-error --location https://deb.nodesource.com/setup_10.x | bash -
|
RUN curl --silent --show-error --location https://deb.nodesource.com/setup_10.x | bash -
|
||||||
RUN curl --silent --show-error https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
RUN curl --silent --show-error https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
||||||
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
|
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
|
||||||
RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/backports.list
|
RUN echo "deb http://ftp.debian.org/debian stretch-backports main" | tee /etc/apt/sources.list.d/backports.list
|
||||||
|
|
||||||
|
|
||||||
# Install packages
|
# Install packages
|
||||||
RUN apt-get update -y && apt-get install -y \
|
RUN apt-get update -y && apt-get install -y \
|
||||||
chkconfig \
|
cron=3.0pl1-128+deb9u1 \
|
||||||
cron \
|
dnsmasq=2.76-5+deb9u2 \
|
||||||
dnsmasq \
|
nano=2.7.4-1 \
|
||||||
nano \
|
nginx=1.10.3-1+deb9u2 \
|
||||||
nodejs \
|
nodejs=10.15.3-1nodesource1 \
|
||||||
openssl \
|
openssl=1.1.0j-1~deb9u1 \
|
||||||
rsyslog \
|
rsyslog=8.24.0-1 \
|
||||||
yarn
|
yarn=1.15.2-1
|
||||||
RUN apt-get install -t jessie-backports -y nginx
|
RUN yarn global add pm2@3.5.0
|
||||||
RUN yarn global add pm2@2
|
|
||||||
|
|
||||||
|
|
||||||
# Set up log rotation
|
# Set up log rotation
|
||||||
@ -151,8 +150,7 @@ RUN sed -i "s|{{\$AIO_PREVIEW_SERVER_PORT}}|$TEST_AIO_PREVIEW_SERVER_PORT|g" /et
|
|||||||
|
|
||||||
|
|
||||||
# Set up pm2
|
# Set up pm2
|
||||||
RUN pm2 startup systemv -u root > /dev/null
|
RUN pm2 startup --user root > /dev/null
|
||||||
RUN chkconfig pm2-root on
|
|
||||||
|
|
||||||
|
|
||||||
# Set up the shell scripts
|
# Set up the shell scripts
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Imports
|
// Imports
|
||||||
import * as cp from 'child_process';
|
import * as cp from 'child_process';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as http from 'http';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as shell from 'shelljs';
|
import * as shell from 'shelljs';
|
||||||
import {AIO_DOWNLOADS_DIR, HIDDEN_DIR_PREFIX} from '../common/constants';
|
import {AIO_DOWNLOADS_DIR, HIDDEN_DIR_PREFIX} from '../common/constants';
|
||||||
@ -105,18 +104,7 @@ class Helper {
|
|||||||
Object.keys(this.portPerScheme).forEach(scheme => suiteFactory(scheme, this.portPerScheme[scheme]));
|
Object.keys(this.portPerScheme).forEach(scheme => suiteFactory(scheme, this.portPerScheme[scheme]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public verifyResponse(status: number | [number, string], regex: string | RegExp = /^/): VerifyCmdResultFn {
|
public verifyResponse(status: number, regex: string | RegExp = /^/): VerifyCmdResultFn {
|
||||||
let statusCode: number;
|
|
||||||
let statusText: string;
|
|
||||||
|
|
||||||
if (Array.isArray(status)) {
|
|
||||||
statusCode = status[0];
|
|
||||||
statusText = status[1];
|
|
||||||
} else {
|
|
||||||
statusCode = status;
|
|
||||||
statusText = http.STATUS_CODES[statusCode] || 'UNKNOWN_STATUS_CODE';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (result: CmdResult) => {
|
return (result: CmdResult) => {
|
||||||
const [headers, body] = result.stdout.
|
const [headers, body] = result.stdout.
|
||||||
split(/(?:\r?\n){2,}/).
|
split(/(?:\r?\n){2,}/).
|
||||||
@ -131,7 +119,7 @@ class Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect(result.success).toBe(true);
|
expect(result.success).toBe(true);
|
||||||
expect(headers).toContain(`${statusCode} ${statusText}`);
|
expect(headers).toMatch(new RegExp(`HTTP/(?:1\\.1|2) ${status} `));
|
||||||
expect(body).toMatch(regex);
|
expect(body).toMatch(regex);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -259,10 +259,10 @@ describe(`nginx`, () => {
|
|||||||
|
|
||||||
it('should disallow non-GET requests', async () => {
|
it('should disallow non-GET requests', async () => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
h.runCmd(`curl -iLX POST ${baseUrl}/42`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX POST ${baseUrl}/42`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX PUT ${baseUrl}/42`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX PUT ${baseUrl}/42`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX PATCH ${baseUrl}/42`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX PATCH ${baseUrl}/42`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX DELETE ${baseUrl}/42`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX DELETE ${baseUrl}/42`).then(h.verifyResponse(405)),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -295,10 +295,10 @@ describe(`nginx`, () => {
|
|||||||
const url = `${scheme}://${host}/circle-build`;
|
const url = `${scheme}://${host}/circle-build`;
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
h.runCmd(`curl -iLX GET ${url}`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX GET ${url}`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX PUT ${url}`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX PUT ${url}`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX PATCH ${url}`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX PATCH ${url}`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX DELETE ${url}`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX DELETE ${url}`).then(h.verifyResponse(405)),
|
||||||
]).then(done);
|
]).then(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -334,10 +334,10 @@ describe(`nginx`, () => {
|
|||||||
|
|
||||||
it('should disallow non-POST requests', done => {
|
it('should disallow non-POST requests', done => {
|
||||||
Promise.all([
|
Promise.all([
|
||||||
h.runCmd(`curl -iLX GET ${url}`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX GET ${url}`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX PUT ${url}`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX PUT ${url}`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX PATCH ${url}`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX PATCH ${url}`).then(h.verifyResponse(405)),
|
||||||
h.runCmd(`curl -iLX DELETE ${url}`).then(h.verifyResponse([405, 'Not Allowed'])),
|
h.runCmd(`curl -iLX DELETE ${url}`).then(h.verifyResponse(405)),
|
||||||
]).then(done);
|
]).then(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json",
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"cli": {
|
"cli": {
|
||||||
"packageManager": "yarn",
|
"packageManager": "yarn",
|
||||||
@ -21,6 +21,7 @@
|
|||||||
"index": "src/index.html",
|
"index": "src/index.html",
|
||||||
"main": "src/main.ts",
|
"main": "src/main.ts",
|
||||||
"tsConfig": "src/tsconfig.app.json",
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
|
"webWorkerTsConfig": "src/tsconfig.worker.json",
|
||||||
"aot": true,
|
"aot": true,
|
||||||
"optimization": true,
|
"optimization": true,
|
||||||
"buildOptimizer": true,
|
"buildOptimizer": true,
|
||||||
@ -35,7 +36,6 @@
|
|||||||
"assets": [
|
"assets": [
|
||||||
"src/assets",
|
"src/assets",
|
||||||
"src/generated",
|
"src/generated",
|
||||||
"src/app/search/search-worker.js",
|
|
||||||
"src/pwa-manifest.json",
|
"src/pwa-manifest.json",
|
||||||
"src/google385281288605d160.html",
|
"src/google385281288605d160.html",
|
||||||
{
|
{
|
||||||
@ -104,6 +104,9 @@
|
|||||||
},
|
},
|
||||||
"archive": {
|
"archive": {
|
||||||
"browserTarget": "site:build:archive"
|
"browserTarget": "site:build:archive"
|
||||||
|
},
|
||||||
|
"ci": {
|
||||||
|
"progress": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -120,6 +123,7 @@
|
|||||||
"karmaConfig": "src/karma.conf.js",
|
"karmaConfig": "src/karma.conf.js",
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "src/tsconfig.spec.json",
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
|
"webWorkerTsConfig": "src/tsconfig.worker.json",
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
@ -127,7 +131,6 @@
|
|||||||
"assets": [
|
"assets": [
|
||||||
"src/assets",
|
"src/assets",
|
||||||
"src/generated",
|
"src/generated",
|
||||||
"src/app/search/search-worker.js",
|
|
||||||
"src/pwa-manifest.json",
|
"src/pwa-manifest.json",
|
||||||
"src/google385281288605d160.html",
|
"src/google385281288605d160.html",
|
||||||
{
|
{
|
||||||
@ -166,6 +169,11 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"protractorConfig": "tests/e2e/protractor.conf.js",
|
"protractorConfig": "tests/e2e/protractor.conf.js",
|
||||||
"devServerTarget": "site:serve"
|
"devServerTarget": "site:serve"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"ci": {
|
||||||
|
"devServerTarget": "site:serve:ci"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lint": {
|
"lint": {
|
||||||
|
9
aio/content/examples/.gitignore
vendored
9
aio/content/examples/.gitignore
vendored
@ -57,7 +57,9 @@ dist/
|
|||||||
|
|
||||||
# aot
|
# aot
|
||||||
**/*.ngsummary.json
|
**/*.ngsummary.json
|
||||||
|
upgrade-module/tsconfig-aot.json
|
||||||
!rollup-config.js
|
!rollup-config.js
|
||||||
|
upgrade-module/rollup-config.js
|
||||||
aot-compiler/**/*.d.ts
|
aot-compiler/**/*.d.ts
|
||||||
aot-compiler/**/*.factory.d.ts
|
aot-compiler/**/*.factory.d.ts
|
||||||
upgrade-phonecat-2-hybrid/aot/**/*
|
upgrade-phonecat-2-hybrid/aot/**/*
|
||||||
@ -84,5 +86,12 @@ upgrade-phonecat-2-hybrid/aot/**/*
|
|||||||
*stackblitz.no-link.html
|
*stackblitz.no-link.html
|
||||||
|
|
||||||
# ngUpgrade testing
|
# ngUpgrade testing
|
||||||
|
upgrade-phonecat-1-typescript/tsconfig-aot.json
|
||||||
|
upgrade-phonecat-1-typescript/rollup-config.js
|
||||||
|
upgrade-phonecat-3-final/tsconfig-aot.json
|
||||||
|
upgrade-phonecat-3-final/rollup-config.js
|
||||||
!upgrade-phonecat-*/**/karma.conf.js
|
!upgrade-phonecat-*/**/karma.conf.js
|
||||||
!upgrade-phonecat-*/**/karma-test-shim.js
|
!upgrade-phonecat-*/**/karma-test-shim.js
|
||||||
|
|
||||||
|
# schematics
|
||||||
|
!schematics-for-libraries/projects/my-lib/package.json
|
@ -20,7 +20,7 @@ export class AppComponent {
|
|||||||
movies: IMovie[] = [];
|
movies: IMovie[] = [];
|
||||||
showImage = true;
|
showImage = true;
|
||||||
title = 'AngularJS to Angular Quick Ref Cookbook';
|
title = 'AngularJS to Angular Quick Ref Cookbook';
|
||||||
toggleImage(event: UIEvent) {
|
toggleImage(event?: UIEvent) {
|
||||||
this.showImage = !this.showImage;
|
this.showImage = !this.showImage;
|
||||||
this.eventType = (event && event.type) || 'not provided';
|
this.eventType = (event && event.type) || 'not provided';
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import { Injectable, Pipe, PipeTransform } from '@angular/core';
|
|
||||||
import { DatePipe } from '@angular/common';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
// #docregion date-pipe
|
|
||||||
@Pipe({name: 'date', pure: true})
|
|
||||||
export class StringSafeDatePipe extends DatePipe implements PipeTransform {
|
|
||||||
transform(value: any, format: string): string {
|
|
||||||
value = typeof value === 'string' ?
|
|
||||||
Date.parse(value) : value;
|
|
||||||
return super.transform(value, format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// #enddocregion date-pipe
|
|
@ -19,6 +19,7 @@ import { HeroListAutoCalcPageComponent } from './hero-list-auto-page.component';
|
|||||||
import { HeroListAutoComponent } from './hero-list-auto.component';
|
import { HeroListAutoComponent } from './hero-list-auto.component';
|
||||||
import { HomeComponent } from './home.component';
|
import { HomeComponent } from './home.component';
|
||||||
import { AboutComponent } from './about.component';
|
import { AboutComponent } from './about.component';
|
||||||
|
import { InsertRemoveComponent } from './insert-remove.component';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -56,6 +57,7 @@ import { AboutComponent } from './about.component';
|
|||||||
HeroListAutoCalcPageComponent,
|
HeroListAutoCalcPageComponent,
|
||||||
HeroListAutoComponent,
|
HeroListAutoComponent,
|
||||||
HomeComponent,
|
HomeComponent,
|
||||||
|
InsertRemoveComponent,
|
||||||
AboutComponent
|
AboutComponent
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<h1>My First Attribute Directive</h1>
|
<h1>My First Attribute Directive</h1>
|
||||||
<!-- #docregion applied -->
|
<!-- #docregion applied -->
|
||||||
<p appHighlight>Highlight me!</p>
|
<p appHighlight>Highlight me!</p>
|
||||||
<!-- #enddocregion applied, -->
|
<!-- #enddocregion applied -->
|
||||||
|
|
||||||
<!-- #docregion color-1 -->
|
<!-- #docregion color-1 -->
|
||||||
<p appHighlight highlightColor="yellow">Highlighted in yellow</p>
|
<p appHighlight highlightColor="yellow">Highlighted in yellow</p>
|
||||||
@ -11,4 +11,4 @@
|
|||||||
|
|
||||||
<!-- #docregion color-2 -->
|
<!-- #docregion color-2 -->
|
||||||
<p appHighlight [highlightColor]="color">Highlighted with parent component's color</p>
|
<p appHighlight [highlightColor]="color">Highlighted with parent component's color</p>
|
||||||
<!-- #enddocregion color-2 -->
|
<!-- #enddocregion color-2 -->
|
@ -0,0 +1,3 @@
|
|||||||
|
<!-- #docregion unsupported -->
|
||||||
|
<p app:Highlight>This is invalid</p>
|
||||||
|
<!-- #enddocregion unsupported -->
|
@ -0,0 +1,20 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
|
import { browser, element, by } from 'protractor';
|
||||||
|
|
||||||
|
describe('Built Template Functions Example', function () {
|
||||||
|
beforeAll(function () {
|
||||||
|
browser.get('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have title Built-in Template Functions', function () {
|
||||||
|
let title = element.all(by.css('h1')).get(0);
|
||||||
|
expect(title.getText()).toEqual('Built-in Template Functions');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display $any( ) in h2', function () {
|
||||||
|
let header = element(by.css('h2'));
|
||||||
|
expect(header.getText()).toContain('$any( )');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,15 @@
|
|||||||
|
<h1>{{title}}</h1>
|
||||||
|
|
||||||
|
<h2><code>$any( )</code> type cast function and an undeclared member</h2>
|
||||||
|
|
||||||
|
<p>There is no such member as <code>bestByDate</code> in the following two examples, so nothing renders:</p>
|
||||||
|
<!-- #docregion any-type-cast-function-1 -->
|
||||||
|
<p>The item's undeclared best by date is: {{$any(item).bestByDate}}</p>
|
||||||
|
<!-- #enddocregion any-type-cast-function-1 -->
|
||||||
|
|
||||||
|
<h2>using <code>this</code></h2>
|
||||||
|
<!-- #docregion any-type-cast-function-2 -->
|
||||||
|
<p>The item's undeclared best by date is: {{$any(this).bestByDate}}</p>
|
||||||
|
<!-- #enddocregion any-type-cast-function-2 -->
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
it('should create the app', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
@ -0,0 +1,16 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.css']
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
title = 'Built-in Template Functions';
|
||||||
|
|
||||||
|
item = {
|
||||||
|
name : 'Telephone',
|
||||||
|
origin : 'Sweden',
|
||||||
|
price: 98
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule
|
||||||
|
],
|
||||||
|
providers: [],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
@ -0,0 +1,14 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Built-in Template Functions Example</title>
|
||||||
|
<base href="/">
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<app-root>Loading...</app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,4 +1,3 @@
|
|||||||
// #docregion
|
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"description": "Built-in Template Functions",
|
||||||
|
"files": [
|
||||||
|
"!**/*.d.ts",
|
||||||
|
"!**/*.js",
|
||||||
|
"!**/*.[1,2].*"
|
||||||
|
],
|
||||||
|
"file": "src/app/app.component.ts",
|
||||||
|
"tags": ["Built-in Template Functions"]
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"e2e": [
|
||||||
|
{
|
||||||
|
"cmd": "yarn",
|
||||||
|
"args": [
|
||||||
|
"e2e",
|
||||||
|
"--no-webdriver-update",
|
||||||
|
"--port={PORT}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -19,20 +19,20 @@ const DifferentParent = Parent;
|
|||||||
// #enddocregion provide-the-parent
|
// #enddocregion provide-the-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
|
||||||
const provideParent =
|
export function provideParent
|
||||||
// #enddocregion provide-parent, provide-the-parent
|
// #enddocregion provide-parent, provide-the-parent
|
||||||
// #docregion provide-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) };
|
||||||
};
|
}
|
||||||
// #enddocregion provide-parent
|
// #enddocregion provide-parent
|
||||||
|
|
||||||
// Simpler syntax version that always provides the component in the name of `Parent`.
|
// Simpler syntax version that always provides the component in the name of `Parent`.
|
||||||
const provideTheParent =
|
export function provideTheParent
|
||||||
// #docregion provide-the-parent
|
// #docregion provide-the-parent
|
||||||
(component: any) => {
|
(component: any) {
|
||||||
return { provide: Parent, useExisting: forwardRef(() => component) };
|
return { provide: Parent, useExisting: forwardRef(() => component) };
|
||||||
};
|
}
|
||||||
// #enddocregion provide-the-parent
|
// #enddocregion provide-the-parent
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"e2e": [
|
||||||
|
{
|
||||||
|
"cmd": "yarn",
|
||||||
|
"args": [
|
||||||
|
"e2e",
|
||||||
|
"--no-webdriver-update",
|
||||||
|
"--port={PORT}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
71
aio/content/examples/event-binding/e2e/src/app.e2e-spec.ts
Normal file
71
aio/content/examples/event-binding/e2e/src/app.e2e-spec.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
'use strict'; // necessary for es6 output in node
|
||||||
|
|
||||||
|
import { browser, element, by, protractor } from 'protractor';
|
||||||
|
|
||||||
|
describe('Event binding example', function () {
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
browser.get('');
|
||||||
|
});
|
||||||
|
|
||||||
|
let saveButton = element.all(by.css('button')).get(0);
|
||||||
|
let onSaveButton = element.all(by.css('button')).get(1);
|
||||||
|
let myClick = element.all(by.css('button')).get(2);
|
||||||
|
let deleteButton = element.all(by.css('button')).get(3);
|
||||||
|
let saveNoProp = element.all(by.css('button')).get(4);
|
||||||
|
let saveProp = element.all(by.css('button')).get(5);
|
||||||
|
|
||||||
|
|
||||||
|
it('should display Event Binding with Angular', function () {
|
||||||
|
expect(element(by.css('h1')).getText()).toEqual('Event Binding');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display 6 buttons', function() {
|
||||||
|
expect(saveButton.getText()).toBe('Save');
|
||||||
|
expect(onSaveButton.getText()).toBe('on-click Save');
|
||||||
|
expect(myClick.getText()).toBe('click with myClick');
|
||||||
|
expect(deleteButton.getText()).toBe('Delete');
|
||||||
|
expect(saveNoProp.getText()).toBe('Save, no propagation');
|
||||||
|
expect(saveProp.getText()).toBe('Save with propagation');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support user input', function () {
|
||||||
|
let input = element(by.css('input'));
|
||||||
|
let bindingResult = element.all(by.css('h4')).get(1);
|
||||||
|
expect(bindingResult.getText()).toEqual('Result: teapot');
|
||||||
|
input.sendKeys('abc');
|
||||||
|
expect(bindingResult.getText()).toEqual('Result: teapotabc');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should hide the item img', async () => {
|
||||||
|
let deleteButton = element.all(by.css('button')).get(3);
|
||||||
|
await deleteButton.click();
|
||||||
|
browser.switchTo().alert().accept();
|
||||||
|
expect(element.all(by.css('img')).get(0).getCssValue('display')).toEqual('none');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show two alerts', async () => {
|
||||||
|
let parentDiv = element.all(by.css('.parent-div'));
|
||||||
|
let childDiv = element.all(by.css('div > div')).get(1);
|
||||||
|
await parentDiv.click();
|
||||||
|
browser.switchTo().alert().accept();
|
||||||
|
expect(childDiv.getText()).toEqual('Click me too! (child)');
|
||||||
|
await childDiv.click();
|
||||||
|
expect(browser.switchTo().alert().getText()).toEqual('Click me. Event target class is child-div');
|
||||||
|
browser.switchTo().alert().accept();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show 1 alert from Save, no prop, button', async () => {
|
||||||
|
await saveNoProp.click();
|
||||||
|
expect(browser.switchTo().alert().getText()).toEqual('Saved. Event target is Save, no propagation');
|
||||||
|
browser.switchTo().alert().accept();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show 2 alerts from Save w/prop button', async () => {
|
||||||
|
await saveProp.click();
|
||||||
|
expect(browser.switchTo().alert().getText()).toEqual('Saved.');
|
||||||
|
browser.switchTo().alert().accept();
|
||||||
|
expect(browser.switchTo().alert().getText()).toEqual('Saved.');
|
||||||
|
browser.switchTo().alert().accept();
|
||||||
|
});
|
||||||
|
});
|
25
aio/content/examples/event-binding/src/app/app.component.css
Normal file
25
aio/content/examples/event-binding/src/app/app.component.css
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.group {
|
||||||
|
background-color: #dae8f9;
|
||||||
|
padding: 1rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.parent-div {
|
||||||
|
background-color: #bdd1f7;
|
||||||
|
border: solid 1px rgb(25, 118, 210);
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.parent-div:hover {
|
||||||
|
background-color: #8fb4f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.child-div {
|
||||||
|
margin-top: 1rem;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.child-div:hover {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
<h1 id="event-binding">Event Binding</h1>
|
||||||
|
|
||||||
|
<div class="group">
|
||||||
|
<h3>Target event</h3>
|
||||||
|
<!-- #docregion event-binding-1 -->
|
||||||
|
<button (click)="onSave($event)">Save</button>
|
||||||
|
<!-- #enddocregion event-binding-1 -->
|
||||||
|
|
||||||
|
<!-- #docregion event-binding-2 -->
|
||||||
|
<button on-click="onSave($event)">on-click Save</button>
|
||||||
|
<!-- #enddocregion event-binding-2 -->
|
||||||
|
|
||||||
|
<!-- #docregion custom-directive -->
|
||||||
|
<h4>myClick is an event on the custom ClickDirective:</h4>
|
||||||
|
<button (myClick)="clickMessage=$event" clickable>click with myClick</button>
|
||||||
|
{{clickMessage}}
|
||||||
|
<!-- #enddocregion custom-directive -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="group">
|
||||||
|
<h3>$event and event handling statements</h3>
|
||||||
|
<h4>Result: {{currentItem.name}}</h4>
|
||||||
|
|
||||||
|
<!-- #docregion event-binding-3-->
|
||||||
|
<input [value]="currentItem.name"
|
||||||
|
(input)="currentItem.name=$event.target.value" >
|
||||||
|
without NgModel
|
||||||
|
<!-- #enddocregion event-binding-3-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="group">
|
||||||
|
<h3>Binding to a nested component</h3>
|
||||||
|
<h4>Custom events with EventEmitter</h4>
|
||||||
|
<!-- #docregion event-binding-to-component -->
|
||||||
|
<app-item-detail (deleteRequest)="deleteItem($event)" [item]="currentItem"></app-item-detail>
|
||||||
|
<!-- #enddocregion event-binding-to-component -->
|
||||||
|
|
||||||
|
|
||||||
|
<h4>Click to see event target class:</h4>
|
||||||
|
<div class="parent-div" (click)="onClickMe($event)" clickable>Click me (parent)
|
||||||
|
<div class="child-div">Click me too! (child) </div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Saves only once:</h3>
|
||||||
|
<div (click)="onSave()" clickable>
|
||||||
|
<button (click)="onSave($event)">Save, no propagation</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Saves twice:</h3>
|
||||||
|
<div (click)="onSave()" clickable>
|
||||||
|
<button (click)="onSave()">Save with propagation</button>
|
||||||
|
</div>
|
@ -0,0 +1,27 @@
|
|||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
it('should create the app', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
}));
|
||||||
|
it(`should have as title 'Featured product:'`, async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app.title).toEqual('Featured product:');
|
||||||
|
}));
|
||||||
|
it('should render title in a p tag', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
|
expect(compiled.querySelector('p').textContent).toContain('Featured product:');
|
||||||
|
}));
|
||||||
|
});
|
29
aio/content/examples/event-binding/src/app/app.component.ts
Normal file
29
aio/content/examples/event-binding/src/app/app.component.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { Item } from './item';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.css']
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
|
||||||
|
currentItem = { name: 'teapot'} ;
|
||||||
|
clickMessage = '';
|
||||||
|
|
||||||
|
onSave(event?: KeyboardEvent) {
|
||||||
|
const evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).textContent : '';
|
||||||
|
alert('Saved.' + evtMsg);
|
||||||
|
if (event) { event.stopPropagation(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteItem(item?: Item) {
|
||||||
|
alert(`Delete the ${item}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickMe(event?: KeyboardEvent) {
|
||||||
|
const evtMsg = event ? ' Event target class is ' + (<HTMLElement>event.target).className : '';
|
||||||
|
alert('Click me.' + evtMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
aio/content/examples/event-binding/src/app/app.module.ts
Normal file
22
aio/content/examples/event-binding/src/app/app.module.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
import { ItemDetailComponent } from './item-detail/item-detail.component';
|
||||||
|
import { ClickDirective } from './click.directive';
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
ItemDetailComponent,
|
||||||
|
ClickDirective
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule
|
||||||
|
],
|
||||||
|
providers: [],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
@ -0,0 +1,18 @@
|
|||||||
|
/* tslint:disable use-output-property-decorator directive-class-suffix */
|
||||||
|
import { Directive, ElementRef, EventEmitter, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Directive({selector: '[myClick]'})
|
||||||
|
export class ClickDirective {
|
||||||
|
@Output('myClick') clicks = new EventEmitter<string>(); // @Output(alias) propertyName = ...
|
||||||
|
|
||||||
|
toggle = false;
|
||||||
|
|
||||||
|
constructor(el: ElementRef) {
|
||||||
|
el.nativeElement
|
||||||
|
.addEventListener('click', (event: Event) => {
|
||||||
|
this.toggle = !this.toggle;
|
||||||
|
this.clicks.emit(this.toggle ? 'Click!' : '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
|||||||
|
.detail {
|
||||||
|
border: 1px solid rgb(25, 118, 210);
|
||||||
|
padding: 1rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100px;
|
||||||
|
display: block;
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<div class="detail">
|
||||||
|
<p>This is the ItemDetailComponent</p>
|
||||||
|
<!-- #docregion line-through -->
|
||||||
|
<img src="{{itemImageUrl}}" [style.display]="displayNone">
|
||||||
|
<span [style.text-decoration]="lineThrough">{{ item.name }}
|
||||||
|
</span>
|
||||||
|
<button (click)="delete()">Delete</button>
|
||||||
|
<!-- #enddocregion line-through -->
|
||||||
|
</div>
|
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ItemDetailComponent } from './item-detail.component';
|
||||||
|
|
||||||
|
describe('ItemDetailComponent', () => {
|
||||||
|
let component: ItemDetailComponent;
|
||||||
|
let fixture: ComponentFixture<ItemDetailComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ItemDetailComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ItemDetailComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,30 @@
|
|||||||
|
/* tslint:disable use-input-property-decorator use-output-property-decorator */
|
||||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
|
||||||
|
import { Item } from '../item';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-item-detail',
|
||||||
|
styleUrls: ['./item-detail.component.css'],
|
||||||
|
templateUrl: './item-detail.component.html'
|
||||||
|
})
|
||||||
|
export class ItemDetailComponent {
|
||||||
|
|
||||||
|
@Input() item;
|
||||||
|
itemImageUrl = 'assets/teapot.svg';
|
||||||
|
lineThrough = '';
|
||||||
|
displayNone = '';
|
||||||
|
@Input() prefix = '';
|
||||||
|
|
||||||
|
// #docregion deleteRequest
|
||||||
|
// This component makes a request but it can't actually delete a hero.
|
||||||
|
@Output() deleteRequest = new EventEmitter<Item>();
|
||||||
|
|
||||||
|
delete() {
|
||||||
|
this.deleteRequest.emit(this.item.name);
|
||||||
|
this.displayNone = this.displayNone ? '' : 'none';
|
||||||
|
this.lineThrough = this.lineThrough ? '' : 'line-through';
|
||||||
|
}
|
||||||
|
// #enddocregion deleteRequest
|
||||||
|
|
||||||
|
}
|
4
aio/content/examples/event-binding/src/app/item.ts
Normal file
4
aio/content/examples/event-binding/src/app/item.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export class Item {
|
||||||
|
name: '';
|
||||||
|
}
|
||||||
|
|
1
aio/content/examples/event-binding/src/assets/teapot.svg
Normal file
1
aio/content/examples/event-binding/src/assets/teapot.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 23 KiB |
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Demo</title>
|
<title>EventBinding</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
@ -1,11 +1,12 @@
|
|||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
import { AppModule } from './app/app.module.1b';
|
import { AppModule } from './app/app.module';
|
||||||
import { environment } from './environments/environment';
|
import { environment } from './environments/environment';
|
||||||
|
|
||||||
if (environment.production) {
|
if (environment.production) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||||
|
.catch(err => console.log(err));
|
10
aio/content/examples/event-binding/stackblitz.json
Normal file
10
aio/content/examples/event-binding/stackblitz.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"description": "Event Binding",
|
||||||
|
"files": [
|
||||||
|
"!**/*.d.ts",
|
||||||
|
"!**/*.js",
|
||||||
|
"!**/*.[1,2].*"
|
||||||
|
],
|
||||||
|
"file": "src/app/app.component.ts",
|
||||||
|
"tags": ["Event Binding"]
|
||||||
|
}
|
@ -28,10 +28,7 @@ let checkLogForMessage = (message: string) => {
|
|||||||
expect(page.logList.getText()).toContain(message);
|
expect(page.logList.getText()).toContain(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(i): temorarily disable these tests because angular-in-memory-web-api is not compatible with rxjs v6 yet
|
describe('Http Tests', function() {
|
||||||
// and we don't have the backwards compatibility package yet.
|
|
||||||
// Reenable after rxjs v6 compatibility package is out or angular-in-memory-web-api is compatible with rxjs v6
|
|
||||||
xdescribe('Http Tests', function() {
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('');
|
browser.get('');
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
{
|
{
|
||||||
"projectType": "i18n"
|
"projectType": "i18n",
|
||||||
}
|
"e2e": [
|
||||||
|
{
|
||||||
|
"cmd": "yarn",
|
||||||
|
"args": [
|
||||||
|
"e2e",
|
||||||
|
"--no-webdriver-update",
|
||||||
|
"--port={PORT}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -50,9 +50,10 @@
|
|||||||
|
|
||||||
<div (keyup)="0">
|
<div (keyup)="0">
|
||||||
<h4>Template context: template reference variables (#customerInput):</h4>
|
<h4>Template context: template reference variables (#customerInput):</h4>
|
||||||
<label>Type something:
|
|
||||||
<!-- #docregion template-reference-variable -->
|
<!-- #docregion template-reference-variable -->
|
||||||
<input #customerInput>{{customerInput.value}}</label>
|
<label>Type something:
|
||||||
|
<input #customerInput>{{customerInput.value}}
|
||||||
|
</label>
|
||||||
<!-- #enddocregion template-reference-variable -->
|
<!-- #enddocregion template-reference-variable -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -13,15 +13,4 @@ describe('AppComponent', () => {
|
|||||||
const app = fixture.debugElement.componentInstance;
|
const app = fixture.debugElement.componentInstance;
|
||||||
expect(app).toBeTruthy();
|
expect(app).toBeTruthy();
|
||||||
}));
|
}));
|
||||||
it(`should have as title 'Featured product:'`, async(() => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.debugElement.componentInstance;
|
|
||||||
expect(app.title).toEqual('Featured product:');
|
|
||||||
}));
|
|
||||||
it('should render title in a p tag', async(() => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
fixture.detectChanges();
|
|
||||||
const compiled = fixture.debugElement.nativeElement;
|
|
||||||
expect(compiled.querySelector('p').textContent).toContain('Featured product:');
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 27 KiB |
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 14 KiB |
@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"description": "Contact NgModule v.1",
|
|
||||||
"files": [
|
|
||||||
"src/app/app.component.1b.ts",
|
|
||||||
"src/app/app.module.1b.ts",
|
|
||||||
"src/app/highlight.directive.ts",
|
|
||||||
"src/app/title.component.html",
|
|
||||||
"src/app/title.component.ts",
|
|
||||||
"src/app/user.service.ts",
|
|
||||||
|
|
||||||
"src/app/contact/awesome.pipe.ts",
|
|
||||||
"src/app/contact/contact.component.css",
|
|
||||||
"src/app/contact/contact.component.html",
|
|
||||||
"src/app/contact/contact.component.3.ts",
|
|
||||||
"src/app/contact/contact.service.ts",
|
|
||||||
"src/app/contact/contact-highlight.directive.ts",
|
|
||||||
|
|
||||||
"src/main.1b.ts",
|
|
||||||
"src/styles.css",
|
|
||||||
"src/index.1b.html"
|
|
||||||
],
|
|
||||||
"main": "src/index.1b.html",
|
|
||||||
"tags": ["NgModule"]
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"description": "Contact NgModule v.2",
|
|
||||||
"files": [
|
|
||||||
"src/app/app.component.2.ts",
|
|
||||||
"src/app/app.module.2.ts",
|
|
||||||
"src/app/highlight.directive.ts",
|
|
||||||
"src/app/title.component.html",
|
|
||||||
"src/app/title.component.ts",
|
|
||||||
"src/app/user.service.ts",
|
|
||||||
|
|
||||||
"src/app/contact/contact.component.css",
|
|
||||||
"src/app/contact/contact.component.html",
|
|
||||||
"src/app/contact/contact.service.ts",
|
|
||||||
|
|
||||||
"src/app/contact/awesome.pipe.ts",
|
|
||||||
"src/app/contact/contact.component.3.ts",
|
|
||||||
"src/app/contact/contact.module.2.ts",
|
|
||||||
"src/app/contact/contact-highlight.directive.ts",
|
|
||||||
|
|
||||||
"src/main.2.ts",
|
|
||||||
"src/styles.css",
|
|
||||||
"src/index.2.html"
|
|
||||||
],
|
|
||||||
"main": "src/index.2.html",
|
|
||||||
"tags": ["NgModule"]
|
|
||||||
}
|
|
@ -1,223 +0,0 @@
|
|||||||
'use strict'; // necessary for es6 output in node
|
|
||||||
|
|
||||||
import { browser, element, by } from 'protractor';
|
|
||||||
|
|
||||||
describe('NgModule', function () {
|
|
||||||
|
|
||||||
// helpers
|
|
||||||
const gold = 'rgba(255, 215, 0, 1)';
|
|
||||||
const powderblue = 'rgba(176, 224, 230, 1)';
|
|
||||||
const lightgray = 'rgba(211, 211, 211, 1)';
|
|
||||||
const white = 'rgba(0, 0, 0, 0)';
|
|
||||||
|
|
||||||
function getCommonsSectionStruct() {
|
|
||||||
const buttons = element.all(by.css('nav a'));
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: element.all(by.tagName('h1')).get(0),
|
|
||||||
welcome: element.all(by.css('app-title p i')).get(0),
|
|
||||||
contactButton: buttons.get(0),
|
|
||||||
crisisButton: buttons.get(1),
|
|
||||||
heroesButton: buttons.get(2)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getContactSectionStruct() {
|
|
||||||
const buttons = element.all(by.css('app-contact form button'));
|
|
||||||
|
|
||||||
return {
|
|
||||||
header: element.all(by.css('app-contact h2')).get(0),
|
|
||||||
popupMessage: element.all(by.css('app-contact div')).get(0),
|
|
||||||
contactNameHeader: element.all(by.css('app-contact form h3')).get(0),
|
|
||||||
input: element.all(by.css('app-contact form input')).get(0),
|
|
||||||
validationError: element.all(by.css('app-contact form .alert')).get(0),
|
|
||||||
saveButton: buttons.get(0), // can't be tested
|
|
||||||
nextContactButton: buttons.get(1),
|
|
||||||
newContactButton: buttons.get(2)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCrisisSectionStruct() {
|
|
||||||
return {
|
|
||||||
title: element.all(by.css('ng-component h3')).get(0),
|
|
||||||
items: element.all(by.css('ng-component a')),
|
|
||||||
itemId: element.all(by.css('ng-component div')).get(0),
|
|
||||||
listLink: element.all(by.css('ng-component a')).get(0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHeroesSectionStruct() {
|
|
||||||
return {
|
|
||||||
header: element.all(by.css('ng-component h2')).get(0),
|
|
||||||
title: element.all(by.css('ng-component h3')).get(0),
|
|
||||||
items: element.all(by.css('ng-component a')),
|
|
||||||
itemId: element.all(by.css('ng-component ng-component div div')).get(0),
|
|
||||||
itemInput: element.all(by.css('ng-component ng-component input')).get(0),
|
|
||||||
listLink: element.all(by.css('ng-component ng-component a')).get(0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// tests
|
|
||||||
function appTitleTests(color: string, name?: string) {
|
|
||||||
return function() {
|
|
||||||
it('should have a gray header', function() {
|
|
||||||
const commons = getCommonsSectionStruct();
|
|
||||||
expect(commons.title.getCssValue('backgroundColor')).toBe(color);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should welcome us', function () {
|
|
||||||
const commons = getCommonsSectionStruct();
|
|
||||||
expect(commons.welcome.getText()).toBe('Welcome, ' + (name || 'Sherlock Holmes'));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function contactTests(color: string, name?: string) {
|
|
||||||
return function() {
|
|
||||||
it('shows the contact\'s owner', function() {
|
|
||||||
const contacts = getContactSectionStruct();
|
|
||||||
expect(contacts.header.getText()).toBe('Contact of ' + (name || 'Sherlock Holmes'));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can cycle between contacts', function () {
|
|
||||||
const contacts = getContactSectionStruct();
|
|
||||||
const nextButton = contacts.nextContactButton;
|
|
||||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome Sam Spade');
|
|
||||||
expect(contacts.contactNameHeader.getCssValue('backgroundColor')).toBe(color);
|
|
||||||
nextButton.click().then(function () {
|
|
||||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome Nick Danger');
|
|
||||||
return nextButton.click();
|
|
||||||
}).then(function () {
|
|
||||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome Nancy Drew');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can change an existing contact', function () {
|
|
||||||
const contacts = getContactSectionStruct();
|
|
||||||
contacts.input.sendKeys('a');
|
|
||||||
expect(contacts.input.getCssValue('backgroundColor')).toBe(color);
|
|
||||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome Sam Spadea');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can create a new contact', function () {
|
|
||||||
const contacts = getContactSectionStruct();
|
|
||||||
const newContactButton = contacts.newContactButton;
|
|
||||||
newContactButton.click().then(function () {
|
|
||||||
expect(contacts.validationError.getText()).toBe('Name is required');
|
|
||||||
contacts.input.sendKeys('John Doe');
|
|
||||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome John Doe');
|
|
||||||
expect(contacts.validationError.getText()).toBe('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('index.html', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
browser.get('');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('app-title', appTitleTests(white, 'Miss Marple'));
|
|
||||||
|
|
||||||
describe('contact', contactTests(lightgray, 'Miss Marple'));
|
|
||||||
|
|
||||||
describe('crisis center', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
getCommonsSectionStruct().crisisButton.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows a list of crisis', function () {
|
|
||||||
const crisis = getCrisisSectionStruct();
|
|
||||||
expect(crisis.title.getText()).toBe('Crisis List');
|
|
||||||
expect(crisis.items.count()).toBe(4);
|
|
||||||
expect(crisis.items.get(0).getText()).toBe('1 - Dragon Burning Cities');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can navigate to one crisis details', function () {
|
|
||||||
const crisis = getCrisisSectionStruct();
|
|
||||||
crisis.items.get(0).click().then(function() {
|
|
||||||
expect(crisis.itemId.getText()).toBe('Crisis id: 1');
|
|
||||||
return crisis.listLink.click();
|
|
||||||
}).then(function () {
|
|
||||||
// We are back to the list
|
|
||||||
expect(crisis.items.count()).toBe(4);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('heroes', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
getCommonsSectionStruct().heroesButton.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows a list of heroes', function() {
|
|
||||||
const heroes = getHeroesSectionStruct();
|
|
||||||
expect(heroes.header.getText()).toBe('Heroes of Miss Marple');
|
|
||||||
expect(heroes.title.getText()).toBe('Hero List');
|
|
||||||
expect(heroes.items.count()).toBe(6);
|
|
||||||
expect(heroes.items.get(0).getText()).toBe('11 - Mr. Nice');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can navigate and edit one hero details', function () {
|
|
||||||
const heroes = getHeroesSectionStruct();
|
|
||||||
heroes.items.get(0).click().then(function () {
|
|
||||||
expect(heroes.itemId.getText()).toBe('Id: 11');
|
|
||||||
heroes.itemInput.sendKeys(' try');
|
|
||||||
return heroes.listLink.click();
|
|
||||||
}).then(function () {
|
|
||||||
// We are back to the list
|
|
||||||
expect(heroes.items.count()).toBe(6);
|
|
||||||
expect(heroes.items.get(0).getText()).toBe('11 - Mr. Nice try');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// describe('index.0.html', function() {
|
|
||||||
// beforeEach(function () {
|
|
||||||
// browser.get('index.0.html');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('has a title', function () {
|
|
||||||
// const title = element.all(by.tagName('h1')).get(0);
|
|
||||||
// expect(title.getText()).toBe('Minimal NgModule');
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('index.1.html', function () {
|
|
||||||
// beforeEach(function () {
|
|
||||||
// browser.get('index.1.html');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('app-title', appTitleTests(powderblue));
|
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('index.1b.html', function () {
|
|
||||||
// beforeEach(function () {
|
|
||||||
// browser.get('index.1b.html');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('app-title', appTitleTests(powderblue));
|
|
||||||
|
|
||||||
// describe('contact', contactTests(powderblue));
|
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('index.2.html', function () {
|
|
||||||
// beforeEach(function () {
|
|
||||||
// browser.get('index.2.html');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('app-title', appTitleTests(gold));
|
|
||||||
|
|
||||||
// describe('contact', contactTests(powderblue));
|
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('index.3.html', function () {
|
|
||||||
// beforeEach(function () {
|
|
||||||
// browser.get('index.3.html');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('app-title', appTitleTests(gold));
|
|
||||||
// });
|
|
||||||
|
|
||||||
});
|
|
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"description": "Minimal NgModule",
|
|
||||||
"files": [
|
|
||||||
"src/app/app.component.0.ts",
|
|
||||||
"src/app/app.module.0.ts",
|
|
||||||
"src/main.0.ts",
|
|
||||||
"src/styles.css",
|
|
||||||
"src/index.0.html"
|
|
||||||
],
|
|
||||||
"main": "src/index.0.html",
|
|
||||||
"tags": ["NgModule"]
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"description": "NgModule v.3",
|
|
||||||
"files": [
|
|
||||||
"src/app/app.component.3.ts",
|
|
||||||
"src/app/app.module.3.ts",
|
|
||||||
"src/app/app-routing.module.3.ts",
|
|
||||||
|
|
||||||
"src/app/highlight.directive.ts",
|
|
||||||
"src/app/title.component.html",
|
|
||||||
"src/app/title.component.ts",
|
|
||||||
"src/app/user.service.ts",
|
|
||||||
|
|
||||||
"src/app/contact/contact.component.css",
|
|
||||||
"src/app/contact/contact.component.html",
|
|
||||||
"src/app/contact/contact.service.ts",
|
|
||||||
|
|
||||||
"src/app/contact/awesome.pipe.ts",
|
|
||||||
"src/app/contact/contact.component.3.ts",
|
|
||||||
"src/app/contact/contact.module.3.ts",
|
|
||||||
"src/app/contact/contact-routing.module.3.ts",
|
|
||||||
"src/app/contact/contact-highlight.directive.ts",
|
|
||||||
|
|
||||||
"src/app/crisis/*.ts",
|
|
||||||
|
|
||||||
"src/app/hero/hero-detail.component.ts",
|
|
||||||
"src/app/hero/hero-list.component.ts",
|
|
||||||
"src/app/hero/hero.service.ts",
|
|
||||||
|
|
||||||
"src/app/hero/hero.component.3.ts",
|
|
||||||
"src/app/hero/hero.module.3.ts",
|
|
||||||
"src/app/hero/hero-routing.module.3.ts",
|
|
||||||
"src/app/hero/highlight.directive.ts",
|
|
||||||
|
|
||||||
"src/main.3.ts",
|
|
||||||
"src/styles.css",
|
|
||||||
"src/index.3.html"
|
|
||||||
],
|
|
||||||
"main": "src/index.3.html",
|
|
||||||
"tags": ["NgModule"]
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
import { ContactModule } from './contact/contact.module.3';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
|
|
||||||
{ path: 'crisis', loadChildren: './crisis/crisis.module#CrisisModule' },
|
|
||||||
{ path: 'heroes', loadChildren: './hero/hero.module.3#HeroModule' }
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
ContactModule,
|
|
||||||
RouterModule.forRoot(routes)
|
|
||||||
],
|
|
||||||
exports: [RouterModule]
|
|
||||||
})
|
|
||||||
export class AppRoutingModule {}
|
|
@ -1,30 +0,0 @@
|
|||||||
// #docregion
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
import { ContactModule } from './contact/contact.module';
|
|
||||||
|
|
||||||
// #docregion routes
|
|
||||||
const routes: Routes = [
|
|
||||||
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
|
|
||||||
// #docregion lazy-routes
|
|
||||||
{ path: 'crisis', loadChildren: './crisis/crisis.module#CrisisModule' },
|
|
||||||
{ path: 'heroes', loadChildren: './hero/hero.module#HeroModule' }
|
|
||||||
// #enddocregion lazy-routes
|
|
||||||
];
|
|
||||||
// #enddocregion routes
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
// #docregion imports
|
|
||||||
imports: [
|
|
||||||
ContactModule,
|
|
||||||
// #docregion forRoot
|
|
||||||
RouterModule.forRoot(routes),
|
|
||||||
// #enddocregion forRoot
|
|
||||||
],
|
|
||||||
// #enddocregion imports
|
|
||||||
// #docregion exports
|
|
||||||
exports: [RouterModule]
|
|
||||||
// #enddocregion exports
|
|
||||||
})
|
|
||||||
export class AppRoutingModule {}
|
|
@ -1,17 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
// #enddocregion
|
|
||||||
/*
|
|
||||||
// #docregion template
|
|
||||||
template: '<h1 highlight>{{title}}</h1>'
|
|
||||||
// #enddocregion template
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
template: '<app-title></app-title>'
|
|
||||||
})
|
|
||||||
export class AppComponent {}
|
|
||||||
// #enddocregion
|
|
@ -1,13 +0,0 @@
|
|||||||
// #docregion
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
// #docregion template
|
|
||||||
template: `
|
|
||||||
<app-title></app-title>
|
|
||||||
<app-contact></app-contact>
|
|
||||||
`
|
|
||||||
// #enddocregion template
|
|
||||||
})
|
|
||||||
export class AppComponent {}
|
|
@ -1,10 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
template: `
|
|
||||||
<app-title></app-title>
|
|
||||||
<app-contact></app-contact>
|
|
||||||
`
|
|
||||||
})
|
|
||||||
export class AppComponent {}
|
|
@ -1,17 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
// #docregion template
|
|
||||||
template: `
|
|
||||||
<app-title></app-title>
|
|
||||||
<nav>
|
|
||||||
<a routerLink="contact" routerLinkActive="active">Contact</a>
|
|
||||||
<a routerLink="crisis" routerLinkActive="active">Crisis Center</a>
|
|
||||||
<a routerLink="heroes" routerLinkActive="active">Heroes</a>
|
|
||||||
</nav>
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
`
|
|
||||||
// #enddocregion template
|
|
||||||
})
|
|
||||||
export class AppComponent {}
|
|
@ -1,17 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
template: `
|
|
||||||
<app-title></app-title>
|
|
||||||
<nav>
|
|
||||||
<a routerLink="contact" routerLinkActive="active">Contact</a>
|
|
||||||
<a routerLink="crisis" routerLinkActive="active">Crisis Center</a>
|
|
||||||
<a routerLink="heroes" routerLinkActive="active">Heroes</a>
|
|
||||||
</nav>
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
`
|
|
||||||
})
|
|
||||||
export class AppComponent {}
|
|
@ -1,13 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component.0';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
// #docregion imports
|
|
||||||
imports: [ BrowserModule ],
|
|
||||||
// #enddocregion imports
|
|
||||||
declarations: [ AppComponent ],
|
|
||||||
bootstrap: [ AppComponent ]
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
@ -1,52 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
/* Angular Imports */
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
/* App Imports */
|
|
||||||
// #enddocregion
|
|
||||||
import { AppComponent } from './app.component.1';
|
|
||||||
/*
|
|
||||||
// #docregion
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
// #enddocregion
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
import { HighlightDirective } from './highlight.directive';
|
|
||||||
import { TitleComponent } from './title.component';
|
|
||||||
import { UserService } from './user.service';
|
|
||||||
|
|
||||||
/* Contact Related Imports */
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
|
|
||||||
import { AwesomePipe } from './contact/awesome.pipe';
|
|
||||||
import { ContactComponent } from './contact/contact.component.3';
|
|
||||||
import {
|
|
||||||
ContactHighlightDirective as ContactHighlightDirective
|
|
||||||
} from './contact/contact-highlight.directive';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
// #docregion imports
|
|
||||||
imports: [ BrowserModule, FormsModule ],
|
|
||||||
// #enddocregion imports
|
|
||||||
// #docregion declarations, directive, component
|
|
||||||
declarations: [
|
|
||||||
AppComponent,
|
|
||||||
HighlightDirective,
|
|
||||||
// #enddocregion directive
|
|
||||||
TitleComponent,
|
|
||||||
// #enddocregion component
|
|
||||||
|
|
||||||
AwesomePipe,
|
|
||||||
ContactComponent,
|
|
||||||
ContactHighlightDirective
|
|
||||||
// #docregion directive, component
|
|
||||||
],
|
|
||||||
// #enddocregion declarations, directive, component
|
|
||||||
// #docregion providers
|
|
||||||
providers: [ UserService ],
|
|
||||||
// #enddocregion providers
|
|
||||||
bootstrap: [ AppComponent ]
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
@ -1,46 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
/* Angular Imports */
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
|
|
||||||
/* App Imports */
|
|
||||||
// #enddocregion
|
|
||||||
import { AppComponent } from './app.component.1b';
|
|
||||||
/*
|
|
||||||
// #docregion
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
// #enddocregion
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
import { HighlightDirective } from './highlight.directive';
|
|
||||||
import { TitleComponent } from './title.component';
|
|
||||||
import { UserService } from './user.service';
|
|
||||||
|
|
||||||
/* Contact Imports */
|
|
||||||
// #enddocregion
|
|
||||||
import { ContactComponent } from './contact/contact.component.3';
|
|
||||||
/*
|
|
||||||
// #docregion
|
|
||||||
import { ContactComponent } from './contact/contact.component';
|
|
||||||
// #enddocregion
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
import { AwesomePipe } from './contact/awesome.pipe';
|
|
||||||
import { ContactService } from './contact/contact.service';
|
|
||||||
import { ContactHighlightDirective } from './contact/contact-highlight.directive';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [ BrowserModule, FormsModule ],
|
|
||||||
// #docregion declarations
|
|
||||||
declarations: [
|
|
||||||
AppComponent, HighlightDirective, TitleComponent,
|
|
||||||
AwesomePipe, ContactComponent, ContactHighlightDirective
|
|
||||||
],
|
|
||||||
// #docregion providers
|
|
||||||
providers: [ ContactService, UserService ],
|
|
||||||
// #enddocregion providers
|
|
||||||
bootstrap: [ AppComponent ]
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
@ -1,36 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
/* Angular Imports */
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
/* App Imports */
|
|
||||||
// #enddocregion
|
|
||||||
import { AppComponent } from './app.component.2';
|
|
||||||
/*
|
|
||||||
// #docregion
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
// #enddocregion
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
import { HighlightDirective } from './highlight.directive';
|
|
||||||
import { TitleComponent } from './title.component';
|
|
||||||
import { UserService } from './user.service';
|
|
||||||
|
|
||||||
/* Contact Imports */
|
|
||||||
// #enddocregion
|
|
||||||
import { ContactModule } from './contact/contact.module.2';
|
|
||||||
/*
|
|
||||||
// #docregion
|
|
||||||
import { ContactModule } from './contact/contact.module';
|
|
||||||
// #enddocregion
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [ BrowserModule, ContactModule ],
|
|
||||||
declarations: [ AppComponent, HighlightDirective, TitleComponent ],
|
|
||||||
providers: [ UserService ],
|
|
||||||
bootstrap: [ AppComponent ],
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
@ -13,8 +13,8 @@ import { AppComponent } from './app.component';
|
|||||||
// #enddocregion
|
// #enddocregion
|
||||||
*/
|
*/
|
||||||
// #docregion
|
// #docregion
|
||||||
import { HighlightDirective } from './highlight.directive';
|
import { HighlightDirective } from './highlight.directive.1';
|
||||||
import { TitleComponent } from './title.component';
|
import { TitleComponent } from './title.component.1';
|
||||||
import { UserService } from './user.service';
|
import { UserService } from './user.service';
|
||||||
|
|
||||||
/* Routing Module */
|
/* Routing Module */
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
// #docregion v4
|
|
||||||
/* Angular Imports */
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
/* App Imports */
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
|
|
||||||
/* Core Modules */
|
|
||||||
import { CoreModule } from './core/core.module';
|
|
||||||
|
|
||||||
/* Routing Module */
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
// #docregion import-for-root
|
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
// #enddocregion v4
|
|
||||||
// #enddocregion import-for-root
|
|
||||||
/*
|
|
||||||
// #docregion v4
|
|
||||||
CoreModule,
|
|
||||||
// #enddocregion v4
|
|
||||||
*/
|
|
||||||
// #docregion import-for-root
|
|
||||||
CoreModule.forRoot({userName: 'Miss Marple'}),
|
|
||||||
// #docregion v4
|
|
||||||
AppRoutingModule
|
|
||||||
],
|
|
||||||
// #enddocregion import-for-root
|
|
||||||
declarations: [ AppComponent ],
|
|
||||||
bootstrap: [ AppComponent ]
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
||||||
// #enddocregion v4
|
|
||||||
// #enddocregion
|
|
@ -1,10 +0,0 @@
|
|||||||
// #docregion
|
|
||||||
import { Pipe, PipeTransform } from '@angular/core';
|
|
||||||
|
|
||||||
@Pipe({ name: 'awesome' })
|
|
||||||
/** Precede the input string with the word "Awesome " */
|
|
||||||
export class AwesomePipe implements PipeTransform {
|
|
||||||
transform(phrase: string) {
|
|
||||||
return phrase ? 'Awesome ' + phrase : '';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// Same directive name and selector as
|
|
||||||
// HighlightDirective in parent AppModule
|
|
||||||
// It selects for both input boxes and 'highlight' attr
|
|
||||||
// and it highlights in blue instead of gold
|
|
||||||
|
|
||||||
// #docregion
|
|
||||||
import { Directive, ElementRef } from '@angular/core';
|
|
||||||
|
|
||||||
// Highlight the host element or any InputElement in blue
|
|
||||||
@Directive({ selector: '[highlight], input' })
|
|
||||||
export class ContactHighlightDirective {
|
|
||||||
constructor(el: ElementRef) {
|
|
||||||
el.nativeElement.style.backgroundColor = 'powderblue';
|
|
||||||
// #enddocregion
|
|
||||||
console.log(`* Contact highlight called for ${el.nativeElement.tagName}`);
|
|
||||||
// #docregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// #enddocregion
|
|
@ -1,14 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
import { ContactComponent } from './contact.component.3';
|
|
||||||
|
|
||||||
const routes = [
|
|
||||||
{ path: 'contact', component: ContactComponent}
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [ RouterModule.forChild(routes) ],
|
|
||||||
exports: [ RouterModule ]
|
|
||||||
})
|
|
||||||
export class ContactRoutingModule {}
|
|
@ -1,16 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
import { ContactComponent } from './contact.component';
|
|
||||||
|
|
||||||
// #docregion routing
|
|
||||||
const routes = [
|
|
||||||
{ path: 'contact', component: ContactComponent}
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [ RouterModule.forChild(routes) ],
|
|
||||||
exports: [ RouterModule ]
|
|
||||||
})
|
|
||||||
export class ContactRoutingModule {}
|
|
||||||
// #enddocregion
|
|
@ -1,53 +0,0 @@
|
|||||||
// #docregion
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
import { Contact, ContactService } from './contact.service';
|
|
||||||
import { UserService } from '../user.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-contact',
|
|
||||||
templateUrl: './contact.component.html',
|
|
||||||
styleUrls: [ './contact.component.css' ]
|
|
||||||
})
|
|
||||||
export class ContactComponent implements OnInit {
|
|
||||||
contact: Contact;
|
|
||||||
contacts: Contact[];
|
|
||||||
|
|
||||||
msg = 'Loading contacts ...';
|
|
||||||
userName = '';
|
|
||||||
|
|
||||||
constructor(private contactService: ContactService, userService: UserService) {
|
|
||||||
this.userName = userService.userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.contactService.getContacts().subscribe(contacts => {
|
|
||||||
this.msg = '';
|
|
||||||
this.contacts = contacts;
|
|
||||||
this.contact = contacts[0];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
next() {
|
|
||||||
let ix = 1 + this.contacts.indexOf(this.contact);
|
|
||||||
if (ix >= this.contacts.length) { ix = 0; }
|
|
||||||
this.contact = this.contacts[ix];
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
// POST-DEMO TODO: do something like save it
|
|
||||||
this.displayMessage('Saved ' + this.contact.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
newContact() {
|
|
||||||
this.displayMessage('New contact');
|
|
||||||
this.contact = {id: 42, name: ''};
|
|
||||||
this.contacts.push(this.contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Display a message briefly, then remove it. */
|
|
||||||
displayMessage(msg: string) {
|
|
||||||
this.msg = msg;
|
|
||||||
setTimeout(() => this.msg = '', 1500);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/* #docregion */
|
|
||||||
.ng-valid[required] {
|
|
||||||
border-left: 5px solid #42A948; /* green */
|
|
||||||
}
|
|
||||||
|
|
||||||
.ng-invalid {
|
|
||||||
border-left: 5px solid #a94442; /* red */
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert {
|
|
||||||
padding: 15px;
|
|
||||||
margin: 8px 0;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.alert-danger {
|
|
||||||
color: #a94442;
|
|
||||||
background-color: #f2dede;
|
|
||||||
border-color: #ebccd1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg {
|
|
||||||
color: blue;
|
|
||||||
background-color: whitesmoke;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group {
|
|
||||||
padding-top: 12px;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
<!-- #docregion -->
|
|
||||||
<h2>Contact of {{userName}}</h2>
|
|
||||||
<div *ngIf="msg" class="msg">{{msg}}</div>
|
|
||||||
|
|
||||||
<form *ngIf="contacts" (ngSubmit)="onSubmit()" #contactForm="ngForm">
|
|
||||||
<!-- #docregion awesome -->
|
|
||||||
<h3 highlight>{{ contact.name | awesome }}</h3>
|
|
||||||
<!-- #enddocregion awesome -->
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="name">Name</label>
|
|
||||||
|
|
||||||
<!-- #docregion ngModel -->
|
|
||||||
<input type="text" class="form-control" required
|
|
||||||
[(ngModel)]="contact.name"
|
|
||||||
name="name" #name="ngModel" >
|
|
||||||
<!-- #enddocregion ngModel -->
|
|
||||||
|
|
||||||
<div [hidden]="name.valid" class="alert alert-danger">
|
|
||||||
Name is required
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="button-group">
|
|
||||||
<button type="submit" class="btn btn-default"
|
|
||||||
[disabled]="!contactForm.form.valid">
|
|
||||||
Save</button>
|
|
||||||
|
|
||||||
<button type="button" class="btn" (click)="next()"
|
|
||||||
[disabled]="!contactForm.form.valid">
|
|
||||||
Next Contact</button>
|
|
||||||
|
|
||||||
<button type="button" class="btn" (click)="newContact()">
|
|
||||||
New Contact</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<!-- #enddocregion -->
|
|
@ -1,54 +0,0 @@
|
|||||||
// Exact copy except import UserService from core
|
|
||||||
// #docregion
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
import { Contact, ContactService } from './contact.service';
|
|
||||||
import { UserService } from '../core/user.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-contact',
|
|
||||||
templateUrl: './contact.component.html',
|
|
||||||
styleUrls: [ './contact.component.css' ]
|
|
||||||
})
|
|
||||||
export class ContactComponent implements OnInit {
|
|
||||||
contact: Contact;
|
|
||||||
contacts: Contact[];
|
|
||||||
|
|
||||||
msg = 'Loading contacts ...';
|
|
||||||
userName = '';
|
|
||||||
|
|
||||||
constructor(private contactService: ContactService, userService: UserService) {
|
|
||||||
this.userName = userService.userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.contactService.getContacts().subscribe(contacts => {
|
|
||||||
this.msg = '';
|
|
||||||
this.contacts = contacts;
|
|
||||||
this.contact = contacts[0];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
next() {
|
|
||||||
let ix = 1 + this.contacts.indexOf(this.contact);
|
|
||||||
if (ix >= this.contacts.length) { ix = 0; }
|
|
||||||
this.contact = this.contacts[ix];
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
// POST-DEMO TODO: do something like save it
|
|
||||||
this.displayMessage('Saved ' + this.contact.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
newContact() {
|
|
||||||
this.displayMessage('New contact');
|
|
||||||
this.contact = {id: 42, name: ''};
|
|
||||||
this.contacts.push(this.contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Display a message briefly, then remove it. */
|
|
||||||
displayMessage(msg: string) {
|
|
||||||
this.msg = msg;
|
|
||||||
setTimeout(() => this.msg = '', 1500);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
// #docregion
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule
|
|
||||||
],
|
|
||||||
declarations: []
|
|
||||||
})
|
|
||||||
export class ContactModule { }
|
|
@ -1,37 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
|
|
||||||
import { AwesomePipe } from './awesome.pipe';
|
|
||||||
// #enddocregion
|
|
||||||
import { ContactComponent } from './contact.component.3';
|
|
||||||
/*
|
|
||||||
// #docregion
|
|
||||||
import { ContactComponent } from './contact.component';
|
|
||||||
// #enddocregion
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
import { ContactHighlightDirective } from './contact-highlight.directive';
|
|
||||||
import { ContactService } from './contact.service';
|
|
||||||
|
|
||||||
// #docregion class
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
AwesomePipe,
|
|
||||||
ContactComponent,
|
|
||||||
ContactHighlightDirective
|
|
||||||
],
|
|
||||||
// #docregion exports
|
|
||||||
exports: [ ContactComponent ],
|
|
||||||
// #enddocregion exports
|
|
||||||
providers: [ ContactService ]
|
|
||||||
})
|
|
||||||
export class ContactModule { }
|
|
||||||
// #enddocregion class
|
|
||||||
// #enddocregion
|
|
@ -1,44 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
|
|
||||||
import { AwesomePipe } from './awesome.pipe';
|
|
||||||
// #enddocregion
|
|
||||||
import { ContactComponent } from './contact.component.3';
|
|
||||||
/*
|
|
||||||
// #docregion
|
|
||||||
import { ContactComponent } from './contact.component';
|
|
||||||
// #enddocregion
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
import { ContactHighlightDirective } from './contact-highlight.directive';
|
|
||||||
import { ContactService } from './contact.service';
|
|
||||||
|
|
||||||
// #enddocregion
|
|
||||||
import { ContactRoutingModule } from './contact-routing.module.3';
|
|
||||||
/*
|
|
||||||
// #docregion
|
|
||||||
import { ContactRoutingModule } from './contact-routing.module';
|
|
||||||
// #enddocregion
|
|
||||||
*/
|
|
||||||
// #docregion
|
|
||||||
|
|
||||||
// #docregion class
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
ContactRoutingModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
AwesomePipe,
|
|
||||||
ContactComponent,
|
|
||||||
ContactHighlightDirective
|
|
||||||
],
|
|
||||||
providers: [ ContactService ]
|
|
||||||
})
|
|
||||||
export class ContactModule { }
|
|
||||||
// #enddocregion class
|
|
||||||
// #enddocregion
|
|
@ -1,19 +0,0 @@
|
|||||||
// #docregion
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { SharedModule } from '../shared/shared.module';
|
|
||||||
|
|
||||||
import { ContactComponent } from './contact.component';
|
|
||||||
import { ContactService } from './contact.service';
|
|
||||||
import { ContactRoutingModule } from './contact-routing.module';
|
|
||||||
|
|
||||||
// #docregion class
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
SharedModule,
|
|
||||||
ContactRoutingModule
|
|
||||||
],
|
|
||||||
declarations: [ ContactComponent ],
|
|
||||||
providers: [ ContactService ]
|
|
||||||
})
|
|
||||||
export class ContactModule { }
|
|
||||||
// #enddocregion class
|
|
@ -1,37 +0,0 @@
|
|||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
import { Injectable, OnDestroy } from '@angular/core';
|
|
||||||
|
|
||||||
import { Observable, of } from 'rxjs';
|
|
||||||
import { delay } from 'rxjs/operators';
|
|
||||||
|
|
||||||
export class Contact {
|
|
||||||
constructor(public id: number, public name: string) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
const CONTACTS: Contact[] = [
|
|
||||||
new Contact(21, 'Sam Spade'),
|
|
||||||
new Contact(22, 'Nick Danger'),
|
|
||||||
new Contact(23, 'Nancy Drew')
|
|
||||||
];
|
|
||||||
|
|
||||||
const FETCH_LATENCY = 500;
|
|
||||||
|
|
||||||
/** Simulate a data service that retrieves contacts from a server */
|
|
||||||
@Injectable()
|
|
||||||
export class ContactService implements OnDestroy {
|
|
||||||
// #enddocregion
|
|
||||||
constructor() { console.log('ContactService instance created.'); }
|
|
||||||
ngOnDestroy() { console.log('ContactService instance destroyed.'); }
|
|
||||||
|
|
||||||
// #docregion
|
|
||||||
getContacts(): Observable<Contact[]> {
|
|
||||||
return of(CONTACTS).pipe(delay(FETCH_LATENCY));
|
|
||||||
}
|
|
||||||
|
|
||||||
getContact(id: number | string): Observable<Contact> {
|
|
||||||
return of(CONTACTS.find(contact => contact.id === +id))
|
|
||||||
.pipe(delay(FETCH_LATENCY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// #enddocregion
|
|
@ -1,48 +0,0 @@
|
|||||||
/* tslint:disable:member-ordering no-unused-variable */
|
|
||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
// #docregion v4
|
|
||||||
import {
|
|
||||||
ModuleWithProviders, NgModule,
|
|
||||||
Optional, SkipSelf } from '@angular/core';
|
|
||||||
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
|
|
||||||
import { TitleComponent } from './title.component';
|
|
||||||
import { UserService } from './user.service';
|
|
||||||
// #enddocregion
|
|
||||||
import { UserServiceConfig } from './user.service';
|
|
||||||
|
|
||||||
// #docregion v4
|
|
||||||
@NgModule({
|
|
||||||
imports: [ CommonModule ],
|
|
||||||
declarations: [ TitleComponent ],
|
|
||||||
exports: [ TitleComponent ],
|
|
||||||
providers: [ UserService ]
|
|
||||||
})
|
|
||||||
export class CoreModule {
|
|
||||||
// #enddocregion v4
|
|
||||||
|
|
||||||
// #docregion ctor
|
|
||||||
constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
|
|
||||||
if (parentModule) {
|
|
||||||
throw new Error(
|
|
||||||
'CoreModule is already loaded. Import it in the AppModule only');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// #enddocregion ctor
|
|
||||||
|
|
||||||
// #docregion for-root
|
|
||||||
static forRoot(config: UserServiceConfig): ModuleWithProviders {
|
|
||||||
return {
|
|
||||||
ngModule: CoreModule,
|
|
||||||
providers: [
|
|
||||||
{provide: UserServiceConfig, useValue: config }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// #enddocregion for-root
|
|
||||||
// #docregion v4
|
|
||||||
}
|
|
||||||
// #enddocregion v4
|
|
||||||
// #enddocregion
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user