Compare commits

...

28 Commits

Author SHA1 Message Date
362b3e4d03 release: cut the v8.2.10 release 2019-10-09 13:55:51 -07:00
2952ea57a5 docs: correct sentence in AoT compiler guide (#33020)
PR Close #33020
2019-10-07 13:13:58 -07:00
3541e590f4 docs: fix accessibility lint rules (#32661)
Add and fix accessibility rules, bump codelyzer to support pseudo events
for template-click-events-have-key-events rule.

PR Close #32661
2019-10-07 11:22:50 -07:00
8ef0ae3561 docs: add dotnettricks to training (#32771)
PR Close #32771
2019-10-07 11:03:04 -07:00
c3ff66c1ba docs: add missing parenthesis (#31041)
PR Close #31041
2019-10-07 11:02:34 -07:00
a1d9848456 build(docs-infra): update in-memory-we-api and karma-jasmine-html-reporter version (#32892)
The `karma-jasmine-html-reporter` update also includes a fix for
taras42/karma-jasmine-html-reporter#31.

Fixes #29802

PR Close #32892
2019-10-07 10:51:20 -07:00
a3482f7076 refactor(forms): refactor Validators.email() regexp for easier comparison with WHATWG version (#32961)
As mentioned in the previous commit, the regexp used by
`Validators.email()` is a slightly enhanced version of the
[WHATWG one](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address).

This commit refactors the regexp (without changing its behavior) to make
it more closely match the format of WHATWG version, so that it is easier
for people to compare it against the WHATWG one and understand the
differences.

The main changes were:
- Changing the order of characters/character classes inside `[...]`;
  e.g. `[A-Za-z]` --> `[a-zA-Z]`
- Mark all groups as non-capturing (since we do not use the captured
  values); e.g. `(foo)` --> `(?:foo)`
  (This could theoretically also have a positive performance impact, but
  I suspect JavaScript engines are already optimizing away capturing
  groups when they are not used.)

PR Close #32961
2019-10-07 10:51:01 -07:00
006af0b985 docs(forms): expand e-mail validation description (#32961)
Previously, there was no documentation of what `Validators.email()`
expects as a valid e-mail address, making it difficult for people to
determine whether it covers their requirements or not. Even more so that
the used pattern slightly deviates from the
[WHATWG version](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address).
One's only option was to look at the source code and try to decipher the
regexp pattern.

This commit adds a high-level description of the validator and mentions
its similarity to and differences from the WHATWG version. It also adds
a brief explanation of the regexp's behavior and references for more
information in the source code to provide more context to
maintainers/users trying to understand the implementation in the future.

Fixes #18985
Fixes #25186
Closes #32747

PR Close #32961
2019-10-07 10:51:01 -07:00
9dc4815e39 ci: shorten the display name of init_environment steps that are shown in all jobs (#32998)
The `init_environment` custom command is used in almost all other jobs.
The this is implemented in CircleCI is that the steps of the command are
inlined into the other jobs.

Some of the `init_environment` commands are quite long and (since the
default display name for a step is its command) they clutter the
CircleCI UI. Additionally, multiple related commands are shown as
separate steps, which makes it more difficult to get to the actual steps
of a job.

This commit improves this by:
1. Defining explicit, short names for steps with long commands.
2. Grouping multiple related steps into one.

PR Close #32998
2019-10-04 08:39:21 -07:00
4263d9ea0d ci: refactor notification commands into a single parametrized one (#32745) (#32982)
notify_caretaker_on_fail and notify_dev_infra_on_fail are the same, except for the url they notify.

PR Close #32745

PR Close #32982
2019-10-03 14:14:56 -07:00
30253a7df3 ci: use CircleCI parameterized jobs (#32745) (#32982)
Parameterized jobs lets us reduce duplication of very similar jobs.

See https://circleci.com/docs/2.0/reusing-config/#authoring-parameterized-jobs for more info.

PR Close #32745

PR Close #32982
2019-10-03 14:14:56 -07:00
16b83e8e2f ci: use CircleCI commands (#32745) (#32982)
When we needed to run multiple commands in a reusable fashion, we needed to make a giant run block with multiple things inside. Using custom commands gives us a better way to do this.

See https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-commands for more info.

PR Close #32745

PR Close #32982
2019-10-03 14:14:55 -07:00
e0c10632ea ci: keep cache key fallback in a var (#32745) (#32982)
This way it's right next to the original key and it's easier to keep them in sync.

PR Close #32745

PR Close #32982
2019-10-03 14:14:55 -07:00
686b62129c ci: use CircleCI executors (#32745) (#32982)
Executors let you define custom execution contexts for jobs.

See https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-executors for more information.

PR Close #32745

PR Close #32982
2019-10-03 14:14:55 -07:00
dd2587d9e5 build: create script for setting up RBE in local dev environment (#31200)
PR Close #31200
2019-10-03 12:17:57 -07:00
2742649a52 docs(core): mark EventEmitter#__isAsync as internal to hide from API docs (#31378)
The `__isAsync` property is not part of the public API and should not
appear in the API docs.

PR Close #31378
2019-10-03 10:24:35 -07:00
eb0461d2d4 fix(docs-infra): ignore ng*Def members in API docs (#31378)
`ng*Def` properties (such as `ngInjectorDef`) are not considered part of
the public API and should not appear in the API docs. This commit adds a
filter to remove these properties from the docs metadata.

PR Close #31378
2019-10-03 10:24:35 -07:00
e24393c35b test(upgrade): add unit tests for AngularJSUrlCodec's parse method (#32976)
Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.

test(upgrade): add unit tests for AngularJSUrlCodec's parse method

Add additional coverage and fix spacing

test(upgrade): add unit tests for AngularJSUrlCodec's parse method

Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.

test(upgrade): add unit tests for AngularJSUrlCodec's parse method

Add additional coverage and fix spacing

test(upgrade): add unit tests for AngularJSUrlCodec's parse method

Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.

test(upgrade): add unit tests for AngularJSUrlCodec's parse method

Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.

test(upgrade): add unit tests for AngularJSUrlCodec's parse method

Add additional coverage and fix spacing

test(upgrade): add unit tests for AngularJSUrlCodec's parse method

Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.

PR Close #32976
2019-10-03 09:55:27 -07:00
8237e958a6 docs: fix typo in attribute-directives.md (#32943)
Fixes #32924

PR Close #32943
2019-10-02 14:30:51 -07:00
9ba898d588 docs: remove Renderer2 section (#32972)
PR Close #32972
2019-10-02 13:47:50 -07:00
cd1b0c1b1f Revert "docs: move renderer2 deprecation guide into own file (#32626)" (#32972)
This reverts commit 222af38462.

PR Close #32972
2019-10-02 13:47:50 -07:00
06072e0062 Revert "docs: add undecorated classes migration faq (#32478)" (#32972)
This reverts commit bd679581e2.

PR Close #32972
2019-10-02 13:47:49 -07:00
288e0ef7b6 Revert "docs: add dynamic queries flag migration documentation (#32582)" (#32972)
This reverts commit 206fb82330.

PR Close #32972
2019-10-02 13:47:49 -07:00
88ad5052bf docs: add comment about newEvent utility function (#32001)
PR Close #32001
2019-10-02 13:28:39 -07:00
7e6644a25a docs(docs-infra): use recommended type assertion (#31042)
Angular uses tslint:recommended by default. The default for no-angle-bracket-type-assertion is true
See https://github.com/palantir/tslint/blob/master/src/configs/recommended.ts#L69

PR Close #31042
2019-10-02 13:25:40 -07:00
d533d15001 docs: add ngOnInit description (#32789)
PR Close #32789
2019-10-02 13:24:31 -07:00
d0abf1bc54 refactor(bazel): ng_module action description should include compile mode (#32955)
Similarly to `ts_library` compilation actions, the `ng_module` compile action should include
the current compile mode in the action description. This makes it consistent with `ts_library`
targets and also avoids confusion when both output flavors are requested.

Currently when both output flavors are requested (e.g. in the `ng_package` rule), both
devmode and prodmode compilations have the same action name. This is confusing and
looks like the given target is built *twice* due to a bug (which is obviously not the case though)

PR Close #32955
2019-10-02 13:21:40 -07:00
56ac18ea8c docs: fix stackblitz example polyfills (#32969)
PR Close #32969
2019-10-02 13:20:38 -07:00
35 changed files with 715 additions and 752 deletions

View File

@ -7,158 +7,162 @@
# To validate changes, use an online parser, eg.
# http://yaml-online-parser.appspot.com/
# Note that the browser docker image comes with Chrome and Firefox preinstalled. This is just
# 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
# docker image with browsers pre-installed.
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
# **NOTE 3**: If you change the version of the `*-browsers` docker image, make sure the
# `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.
var_1: &default_docker_image circleci/node:10.16@sha256:75c05084fff4afa3683a03c5a04a4a3ad95c536ff2439d8fe14e7e1f5c58b09a
var_2: &browsers_docker_image circleci/node:10.16-browsers@sha256:d2a96fe1cbef51257ee626b5f645e64dade3e886f00ba9cb7e8ea65b4efe8db1
# CircleCI configuration version
# Version 2.1 allows for extra config reuse features
# https://circleci.com/docs/2.0/reusing-config/#getting-started-with-config-reuse
version: 2.1
# 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 1 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
# **NOTE 2 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
var_3: &cache_key v3-angular-node-10.16-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
# Initializes the CI environment by setting up common environment variables.
var_4: &init_environment
run:
name: Initializing environment (setting up variables, overwriting Yarn)
# 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.17.3/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
run:
name: "Setup bazel RBE remote execution"
command: |
# We need ensure that the same default digest is used for encoding and decoding
# with openssl. Openssl versions might have different default digests which can
# cause decryption failures based on the openssl version. https://stackoverflow.com/a/39641378/4317734
openssl aes-256-cbc -d -in .circleci/gcp_token -md md5 -k "$CI_REPO_NAME" -out /home/circleci/.gcp_credentials
echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV
./.circleci/setup-rbe.sh .bazelrc.user
# Settings common to each job
var_6: &job_defaults
working_directory: ~/ng
docker:
- image: *default_docker_image
# After checkout, rebase on top of target branch.
var_7: &post_checkout
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
run:
name: Running Yarn install
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
run:
name: Setting up CircleCI bazel configuration
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.16-
# Branch filter that can be specified for jobs that should only run on publish branches
# (e.g. master or the patch branch)
var_11: &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_12: &attach_workspace
attach_workspace:
at: ~/
var_13: &notify_caretaker_on_fail
run:
when: on_fail
name: Notify caretaker about failure
# `$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: |
notificationJson="{\"text\":\":x: \`$CIRCLE_JOB\` job for $CIRCLE_BRANCH branch failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}"
curl --request POST --header "Content-Type: application/json" --data "$notificationJson" $SLACK_CARETAKER_WEBHOOK_URL
var_14: &notify_dev_infra_on_fail
run:
when: on_fail
name: Notify dev-infra about failure
# `$SLACK_DEV_INFRA_CI_FAILURES_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: |
notificationJson="{\"text\":\":x: \`$CIRCLE_JOB\` job for $CIRCLE_BRANCH branch failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}"
curl --request POST --header "Content-Type: application/json" --data "$notificationJson" $SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
var_4: &cache_key_fallback v3-angular-node-10.16-
# Cache key for the Material unit tests job. **Note** when updating the SHA in the cache keys,
# also update the SHA for the "MATERIAL_REPO_COMMIT" environment variable.
var_15: &material_unit_tests_cache_key v4-angular-material-18b9ef3f5529f0fa8f034944681486447af7b879
var_16: &material_unit_tests_cache_key_short v4-angular-material
var_5: &material_unit_tests_cache_key v4-angular-material-18b9ef3f5529f0fa8f034944681486447af7b879
var_6: &material_unit_tests_cache_key_fallback v4-angular-material-
version: 2
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
# `build-ivy-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_7: &workspace_location ~/
# Executor Definitions
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-executors
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
# **NOTE 2**: If you change the version of the docker images, also change the `cache_key` suffix.
# **NOTE 3**: If you change the version of the `*-browsers` docker image, make sure the
# `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.
executors:
default-executor:
parameters:
resource_class:
type: string
default: medium
docker:
- image: circleci/node:10.16@sha256:75c05084fff4afa3683a03c5a04a4a3ad95c536ff2439d8fe14e7e1f5c58b09a
resource_class: << parameters.resource_class >>
working_directory: ~/ng
browsers-executor:
parameters:
resource_class:
type: string
default: medium
docker:
# The browser docker image comes with Chrome and Firefox preinstalled. This is just
# 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
# docker image with browsers pre-installed.
- image: circleci/node:10.16-browsers@sha256:d2a96fe1cbef51257ee626b5f645e64dade3e886f00ba9cb7e8ea65b4efe8db1
resource_class: << parameters.resource_class >>
working_directory: ~/ng
# Command Definitions
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-commands
commands:
custom_attach_workspace:
description: Attach workspace at a predefined location
steps:
- attach_workspace:
at: *workspace_location
# Initializes the CI environment by setting up common environment variables.
init_environment:
description: Initializing environment (setting up variables, overwriting Yarn)
steps:
- run: ./.circleci/env.sh
- run:
# Overwrite the yarn installed in the docker container with our own version.
name: Overwrite yarn with our own version
command: |
ourYarn=$(realpath ./third_party/github.com/yarnpkg/yarn/releases/download/v1.17.3/bin/yarn.js)
sudo chmod a+x $ourYarn
sudo ln -fs $ourYarn /usr/local/bin/yarn
- run: echo "Yarn version $(yarn --version)"
- run:
# Configure git as the CircleCI `checkout` command does.
# This is needed because we only checkout on the setup job.
# Add GitHub to known hosts
name: Configure git
command: |
mkdir -p ~/.ssh
echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
git config --global gc.auto 0 || true
setup_circleci_bazel_config:
description: Set up CircleCI bazel configuration
steps:
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
setup_bazel_rbe:
description: Setup bazel RBE remote execution
steps:
# We need ensure that the same default digest is used for encoding and decoding
# with openssl. Openssl versions might have different default digests which can
# cause decryption failures based on the openssl version. https://stackoverflow.com/a/39641378/4317734
- run: openssl aes-256-cbc -d -in .circleci/gcp_token -md md5 -k "$CI_REPO_NAME" -out /home/circleci/.gcp_credentials
- run: echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV
- run: ./.circleci/setup-rbe.sh .bazelrc.user
notify_webhook_on_fail:
description: Notify a webhook about failure
parameters:
# `webhook_url_env_var` are secret env vars defined in CircleCI project settings.
# The URLs come from https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
webhook_url_env_var:
type: env_var_name
steps:
- run:
when: on_fail
command: |
notificationJson="{\"text\":\":x: \`$CIRCLE_JOB\` job for $CIRCLE_BRANCH branch failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}"
curl --request POST --header "Content-Type: application/json" --data "$notificationJson" ${<< parameters.webhook_url_env_var >>}
# Job definitions
# Jobs can include parameters that are passed in the workflow job invocation.
# https://circleci.com/docs/2.0/reusing-config/#authoring-parameterized-jobs
jobs:
setup:
<<: *job_defaults
executor: default-executor
steps:
- checkout
- *post_checkout
- run:
name: Rebase PR on target branch
# After checkout, rebase on top of 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
# This cache is saved in the build-npm-packages so that Bazel cache is also included.
- *restore_cache
- *init_environment
- *yarn_install
- restore_cache:
keys:
- *cache_key
- *cache_key_fallback
- init_environment
- run:
name: Running Yarn install
command: yarn install --frozen-lockfile --non-interactive
# Yarn's requests sometimes take more than 10mins to complete.
no_output_timeout: 45m
- 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.
@ -168,19 +172,18 @@ jobs:
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.
# **NOTE**: To add new content to the workspace, always persist on the same root.
- persist_to_workspace:
root: ~/
root: *workspace_location
paths:
- ./ng
- ./bazel_repository_cache
lint:
<<: *job_defaults
executor: default-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
- run: 'yarn bazel:format -mode=check ||
(echo "BUILD files not formatted. Please run ''yarn bazel:format''" ; exit 1)'
@ -192,25 +195,29 @@ jobs:
- run: node tools/verify-codeownership
test:
<<: *job_defaults
resource_class: xlarge
executor:
name: default-executor
resource_class: xlarge
steps:
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- custom_attach_workspace
- init_environment
- setup_circleci_bazel_config
# Setup remote execution and run RBE-compatible tests.
- *setup_bazel_remote_execution
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
- setup_bazel_rbe
- run:
command: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
no_output_timeout: 20m
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_aot:
<<: *job_defaults
resource_class: xlarge
executor:
name: default-executor
resource_class: xlarge
steps:
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *setup_bazel_remote_execution
- custom_attach_workspace
- init_environment
- setup_circleci_bazel_config
- setup_bazel_rbe
# We need to explicitly specify the --symlink_prefix option because otherwise we would
# not be able to easily find the output bin directory when uploading artifacts for size
@ -242,16 +249,17 @@ jobs:
#
# NOTE: This is currently limited to master builds only. See the `default_workflow` configuration.
test_saucelabs_bazel:
<<: *job_defaults
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
executor:
name: default-executor
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
steps:
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *setup_bazel_remote_execution
- custom_attach_workspace
- init_environment
- setup_circleci_bazel_config
- setup_bazel_rbe
- run:
name: Run Bazel tests in saucelabs
# All web tests are contained within a single //:test_web_all target for Saucelabs
@ -266,16 +274,16 @@ jobs:
--username $SAUCE_USERNAME \
--key $(echo $SAUCE_ACCESS_KEY | rev) \
yarn bazel test //:test_web_all
- *notify_dev_infra_on_fail
no_output_timeout: 20m
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
test_aio:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
executor: browsers-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
# Build aio
- run: yarn --cwd aio build --progress=false
# Lint the code
@ -294,27 +302,27 @@ jobs:
- run: yarn --cwd aio redirects-test
deploy_aio:
<<: *job_defaults
docker:
# Needed because before deploying the deploy-production script runs the PWA score tests.
- image: *browsers_docker_image
executor: browsers-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
# Deploy angular.io to production (if necessary)
- run: setPublicVar_CI_STABLE_BRANCH
- run: yarn --cwd aio deploy-production
test_aio_local:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
parameters:
ivy:
type: boolean
default: false
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
executor: browsers-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
# Build aio (with local Angular packages)
- run: yarn --cwd aio build-local-ci
- run: yarn --cwd aio build-local<<# parameters.ivy >>-with-ivy<</ parameters.ivy >>-ci
# Run unit tests
- run: yarn --cwd aio test --progress=false --watch=false
# Run e2e tests
@ -322,32 +330,13 @@ jobs:
# Run PWA-score tests
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Check the bundle sizes.
- run: yarn --cwd aio payload-size aio-local
test_aio_local_ivy:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
steps:
- *attach_workspace
- *init_environment
# Build aio with Ivy (using local Angular packages)
- run: yarn --cwd aio build-with-ivy-ci
# Run unit tests
- run: yarn --cwd aio test --progress=false --watch=false
# Run e2e tests
- run: yarn --cwd aio e2e --configuration=ci
# Run PWA-score tests
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Check the bundle sizes.
- run: yarn --cwd aio payload-size aio-local-ivy
- run: yarn --cwd aio payload-size aio-local<<# parameters.ivy >>-ivy<</ parameters.ivy >>
test_aio_tools:
<<: *job_defaults
executor: default-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
# Install
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
- run: yarn --cwd aio extract-cli-command-docs
@ -356,56 +345,42 @@ jobs:
- run: ./aio/aio-builds-setup/scripts/test.sh
test_docs_examples:
<<: *job_defaults
docker:
parameters:
ivy:
type: boolean
default: false
executor:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
parallelism: 4
resource_class: xlarge
steps:
- *attach_workspace
- *init_environment
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# 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
# 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 --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL} --retry 2
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.
name: browsers-executor
resource_class: xlarge
parallelism: 5
steps:
- *attach_workspace
- *init_environment
- custom_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} --retry 2
- when:
condition: << parameters.ivy >>
steps:
# 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. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
# Since the parallelism is set to "5", there will be five parallel CircleCI containers.
# with either "0", "1", etc as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local <<# parameters.ivy >>--ivy<</ parameters.ivy >> --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL} --retry 2
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview:
<<: *job_defaults
executor: default-executor
environment:
AIO_SNAPSHOT_ARTIFACT_PATH: &aio_preview_artifact_path 'aio/tmp/snapshot.tgz'
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CI_PULL_REQUEST $CI_COMMIT
- store_artifacts:
path: *aio_preview_artifact_path
@ -416,13 +391,11 @@ jobs:
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
test_aio_preview:
<<: *job_defaults
docker:
# Needed because the test-preview script runs e2e tests and the PWA score test with Chrome.
- image: *browsers_docker_image
# Needed because the test-preview script runs e2e tests and the PWA score test with Chrome.
executor: browsers-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
- run:
name: Wait for preview and run tests
@ -438,19 +411,20 @@ jobs:
# Build the view engine npm packages. No new jobs should depend on this.
build-npm-packages:
<<: *job_defaults
resource_class: xlarge
executor:
name: default-executor
resource_class: xlarge
steps:
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *setup_bazel_remote_execution
- custom_attach_workspace
- init_environment
- setup_circleci_bazel_config
- setup_bazel_rbe
- run: scripts/build-packages-dist.sh
# Save the npm packages from //packages/... for other workflow jobs to read
- persist_to_workspace:
root: ~/
root: *workspace_location
paths:
- ng/dist/packages-dist
@ -464,19 +438,20 @@ jobs:
# Build the ivy npm packages.
build-ivy-npm-packages:
<<: *job_defaults
resource_class: xlarge
executor:
name: default-executor
resource_class: xlarge
steps:
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *setup_bazel_remote_execution
- custom_attach_workspace
- init_environment
- setup_circleci_bazel_config
- setup_bazel_rbe
- run: scripts/build-ivy-npm-packages.sh
# Save the npm packages from //packages/... for other workflow jobs to read
- persist_to_workspace:
root: ~/
root: *workspace_location
paths:
- ng/dist/packages-dist-ivy-aot
@ -487,18 +462,17 @@ jobs:
# need to re-run manually should be alleviated.
# See comments inside the integration/run_tests.sh script.
integration_test:
<<: *job_defaults
parallelism: 4
docker:
executor:
# Needed because the integration tests expect Chrome to be installed (e.g cli-hello-world)
- image: *browsers_docker_image
# Note: we run Bazel in one of the integration tests, and it can consume >2G
# of memory. Together with the system under test, this can exhaust the RAM
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
name: browsers-executor
# Note: we run Bazel in one of the integration tests, and it can consume >2G
# of memory. Together with the system under test, this can exhaust the RAM
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
parallelism: 4
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
# 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.
- run: ./integration/run_tests.sh ${CIRCLE_NODE_INDEX} ${CIRCLE_NODE_TOTAL}
@ -506,7 +480,7 @@ jobs:
# This job updates the content of repos like github.com/angular/core-builds
# for every green build on angular/angular.
publish_snapshot:
<<: *job_defaults
executor: default-executor
steps:
# See below - ideally this job should not trigger for non-upstream builds.
# But since it does, we have to check this condition.
@ -520,8 +494,8 @@ jobs:
[[ "$CIRCLE_PROJECT_REPONAME" != "angular" ]]; then
circleci step halt
fi
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
# CircleCI has a config setting to force SSH for all github connections
# This is not compatible with our mechanism of using a Personal Access Token
# Clear the global setting
@ -535,14 +509,12 @@ jobs:
- run: ./scripts/ci/publish-build-artifacts.sh
aio_monitoring_stable:
<<: *job_defaults
docker:
# This job needs Chrome to be globally installed because the tests run with Protractor
# which does not load the browser through the Bazel webtesting rules.
- image: *browsers_docker_image
# This job needs Chrome to be globally installed because the tests run with Protractor
# which does not load the browser through the Bazel webtesting rules.
executor: browsers-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
- run: setPublicVar_CI_STABLE_BRANCH
- run:
name: Check out `aio/` from the stable branch
@ -552,33 +524,36 @@ jobs:
- run:
name: Run tests against https://angular.io/
command: ./aio/scripts/test-production.sh https://angular.io/ $CI_AIO_MIN_PWA_SCORE
- *notify_caretaker_on_fail
- *notify_dev_infra_on_fail
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_CARETAKER_WEBHOOK_URL
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
aio_monitoring_next:
<<: *job_defaults
docker:
# This job needs Chrome to be globally installed because the tests run with Protractor
# which does not load the browser through the Bazel webtesting rules.
- image: *browsers_docker_image
# This job needs Chrome to be globally installed because the tests run with Protractor
# which does not load the browser through the Bazel webtesting rules.
executor: browsers-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
- run:
name: Run tests against https://next.angular.io/
command: ./aio/scripts/test-production.sh https://next.angular.io/ $CI_AIO_MIN_PWA_SCORE
- *notify_caretaker_on_fail
- *notify_dev_infra_on_fail
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_CARETAKER_WEBHOOK_URL
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
legacy-unit-tests-saucelabs:
<<: *job_defaults
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
executor:
name: default-executor
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
- run:
name: Preparing environment for running tests on Saucelabs.
command: |
@ -597,10 +572,10 @@ jobs:
- run: ./scripts/saucelabs/stop-tunnel.sh
legacy-misc-tests:
<<: *job_defaults
executor: default-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
- run: yarn gulp check-cycle
# 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
@ -609,23 +584,22 @@ jobs:
# Job to run unit tests from angular/material2. Needs a browser since all
# component unit tests assume they're running in the browser environment.
material-unit-tests:
<<: *job_defaults
resource_class: xlarge
docker:
- image: *browsers_docker_image
executor:
name: browsers-executor
resource_class: xlarge
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
# Although RBE is configured below for the Material repo, also setup RBE in the Angular repo
# to provision Angular's GCP token into the environment variables.
- *setup_bazel_remote_execution
- setup_bazel_rbe
# Restore the cache before cloning the repository because the clone script re-uses
# the restored repository if present. This reduces the amount of times the components
# repository needs to be cloned (this is slow and increases based on commits in the repo).
- restore_cache:
keys:
- *material_unit_tests_cache_key
- *material_unit_tests_cache_key_short
- *material_unit_tests_cache_key_fallback
- run:
name: "Fetching Material repository"
command: ./scripts/ci/clone_angular_material_repo.sh
@ -648,10 +622,10 @@ jobs:
command: ./scripts/ci/run_angular_material_unit_tests.sh
test_zonejs:
<<: *job_defaults
executor: default-executor
steps:
- *attach_workspace
- *init_environment
- custom_attach_workspace
- init_environment
# Install
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
# Run zone.js tools tests
@ -710,7 +684,9 @@ workflows:
- test_aio_local:
requires:
- build-npm-packages
- test_aio_local_ivy:
- test_aio_local:
name: test_aio_local_ivy
ivy: true
requires:
- build-npm-packages
- test_aio_tools:
@ -719,7 +695,9 @@ workflows:
- test_docs_examples:
requires:
- build-npm-packages
- test_docs_examples_ivy:
- test_docs_examples:
name: test_docs_examples_ivy
ivy: true
requires:
- build-ivy-npm-packages
- aio_preview:

4
.github/CODEOWNERS vendored
View File

@ -841,9 +841,7 @@ testing/** @angular/fw-test
/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
/aio/content/guide/deprecations.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/migration-renderer.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/migration-undecorated-classes.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/migration-dynamic-flag.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
# ================================================

View File

@ -1,3 +1,10 @@
<a name="8.2.10"></a>
## [8.2.10](https://github.com/angular/angular/compare/8.2.9...8.2.10) (2019-10-09)
This release contains various API docs improvements.
<a name="8.2.9"></a>
## [8.2.9](https://github.com/angular/angular/compare/8.2.8...8.2.9) (2019-10-02)

View File

@ -201,7 +201,7 @@ Must be one of the following:
* **test**: Adding missing tests or correcting existing tests
### Scope
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages.
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
The following is the list of supported scopes:

View File

@ -18,7 +18,7 @@ Here are the most important tasks you might need to use:
* `yarn build` - create a production build of the application (after installing dependencies, boilerplate, etc).
* `yarn build-local` - same as `build`, but use `setup-local` instead of `setup`.
* `yarn build-with-ivy` - same as `build-local`, but in addition also turns on `ivy` mode in aio.
* `yarn build-local-with-ivy` - same as `build-local`, but in addition also turns on `ivy` mode in aio.
(Note: To turn on `ivy` mode in examples, see `yarn boilerplate:add` below.)
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.

View File

@ -206,6 +206,7 @@ function heroModuleSetup() {
nameInput.value = 'quick BROWN fOx';
// dispatch a DOM event so that Angular learns of input value change.
// use newEvent utility function (not provided by Angular) for better browser compatibility
nameInput.dispatchEvent(newEvent('input'));
// Tell Angular to update the display binding through the title pipe

View File

@ -28,7 +28,7 @@ export class KeyUpComponent_v1 {
// #docregion key-up-component-1-class
onKey(event: KeyboardEvent) { // with type info
this.values += (<HTMLInputElement>event.target).value + ' | ';
this.values += (event.target as HTMLInputElement).value + ' | ';
}
// #docregion key-up-component-1-class-no-type
}

View File

@ -467,7 +467,7 @@ export class AppComponent {
The collector can represent a function call or object creation with `new` as long as the syntax is valid.
The compiler, however, can later refuse to generate a call to a _particular_ function or creation of a _particular_ object.
The compiler can only create instances certain classes, supports only core decorators, and only supports calls to macros (functions or static methods) that return expressions.
The compiler can only create instances of certain classes, supports only core decorators, and only supports calls to macros (functions or static methods) that return expressions.
* New instances
The compiler only allows metadata that create instances of the class `InjectionToken` from `@angular/core`.

View File

@ -142,7 +142,7 @@ Begin by adding `HostListener` to the list of imported symbols.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (imports)" region="imports"></code-example>
Then add two eventhandlers that respond when the mouse enters or leaves,
Then add two event handlers that respond when the mouse enters or leaves,
each adorned by the `HostListener` decorator.
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (mouse-methods)" region="mouse-methods"></code-example>

View File

@ -321,7 +321,7 @@ In a typical Angular project, the polyfill is not used in production builds, so
{@a static-query-resolution}
### `@ViewChild()` / `@ContentChild()` static resolution as the default
See the [dedicated migration guide for static queries](guide/static-query-migration).
See our [dedicated migration guide for static queries](guide/static-query-migration).
{@a contentchild-input-together}
### `@ContentChild()` / `@Input()` used together
@ -389,23 +389,6 @@ As of Angular version 8, all `platform-webworker` APIs are deprecated.
This includes both packages: `@angular/platform-webworker` and
`@angular/platform-webworker-dynamic`.
## Angular version 9 schematics
{@a renderer-to-renderer2}
### Migrating from `Renderer` to `Renderer2`
See the [dedicated migration guide for Renderer](guide/migration-renderer).
{@a undecorated-classes}
### Migrating undecorated classes
See the [dedicated migration guide for undecorated classes](guide/migration-undecorated-classes).
{@a flag-migration}
### Dynamic queries flag migration
See the [dedicated migration guide for dynamic queries](guide/migration-dynamic-flag).
{@a removed}
## Removed APIs

View File

@ -1,107 +0,0 @@
# Dynamic queries flag migration
## What does this migration do?
In Angular version 8, a schematic added `static` flags to all `@ViewChild()`
and `@ContentChild()` queries.
This was the first step towards changing the default behavior.
With version 9, the default value
changes to `static: false` and the flag becomes optional.
This schematic scans classes in the compilation and for each
class, checks if the members have a `@ViewChild()` or
`@ContentChild()` query with the `static` flag set to
`false`. If so, the schematic removes the flag, as it
now matches the default.
**Before:**
```ts
@ViewChild('foo', {static: false}) foo: ElementRef;
@ViewChild('bar', {static: true}) bar: ElementRef;
```
**After:**
```ts
@ViewChild('foo') foo: ElementRef;
// this query doesn't change because the static value is true
@ViewChild('bar', {static: true}) bar: ElementRef;
```
Note that the flag is not supported in `@ViewChildren()`
or `@ContentChildren()` queries, so the schematic
will not check these properties.
## Why is this migration necessary?
This schematic performs a code cleanup to remove `static`
flags that match the default, as they are no longer
necessary. Functionally, the code change should be a noop.
Before version 9, Angular figured out the static or
dynamic nature of a query automatically, based
on how the template was written. Looking at templates
in this way, however, caused buggy and surprising behavior
(see more about that in the [Static Query Migration Guide](guide/static-query-migration#what-does-this-flag-mean)).
As of version 9, Angular uses dynamic queries
(`static: false`) by default, which simplifies
queries. Developers can still explicitly set a
query to `static: true` if necessary.
<div class=" alert is-helpful">
### What is the difference between static and dynamic queries?
The `static` option for `@ViewChild()` and `@ContentChild()`
queries determines when
the query results become available.
With static queries (`static: true`), the query resolves
once the view has been created, but before change detection runs.
The result, though, will never be updated to reflect
changes to your view, such as
changes to `ngIf` and `ngFor` blocks.
With dynamic queries (`static: false`), the query resolves
after either `ngAfterViewInit()` or
`ngAfterContentInit()` for `@ViewChild()` and `@ContentChild()`
respectively. The result will
be updated for changes to your view, such as changes to
`ngIf` and `ngFor` blocks.
For more information, see the following entries in the
[Static Query Migration Guide](https://angular.io/guide/static-query-migration):
* [How do I choose which `static` flag value to use: `true` or `false`?](https://angular.io/guide/static-query-migration#how-do-i-choose-which-static-flag-value-to-use-true-or-false)
* [Is there a case where I should use `{static: true}`?](https://angular.io/guide/static-query-migration#is-there-a-case-where-i-should-use-static-true)
</div>
## What does this mean for libraries?
In order to support applications that are still running
with version 8, the safest option for libraries is to
retain the `static` flag to keep the resolution
timing consistent.
- *Libraries on version 9 with applications running version 8: *
The schematic won't run on libraries. As long as libraries retain their `static` flags from version 8, they should work with apps on 8.
- *Libraries on version 8 with applications running version 9: *
Libraries will have explicit flags defined. The behavior
with explicit flags has not changed.
### What about applications using non-migrated libraries?
Because this is a code cleanup that is a noop,
non-migrated libraries will work the same either way.

View File

@ -1,96 +0,0 @@
# `Renderer` to `Renderer2` migration
## Migration Overview
The `Renderer` class has been marked as deprecated since Angular version 4. This section provides guidance on migrating from this deprecated API to the newer `Renderer2` API and what it means for your app.
## Why should I migrate to Renderer2?
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API. Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`. The API surface is quite large (with 19 methods), but the schematic should simplify this process for your applications.
## Is there action required on my end?
No. The schematic should handle most cases with the exception of `Renderer.animate()` and `Renderer.setDebugInfo()`, which already arent supported.
## What are the `__ngRendererX` methods? Why are they necessary?
Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression. For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
```ts
const [namespace, name] = splitNamespace(namespaceAndName);
const el = renderer.createElement(name, namespace);
if (parentNode) {
renderer.appendChild(parentNode, el);
}
return el;
```
Migration has to guarantee that the return values of functions and types of variables stay the same. To handle the majority of cases safely, the schematic declares helper functions at the bottom of the user's file. These helpers encapsulate your own logic and keep the replacements inside your code down to a single function call. Here's an example of how the `createElement()` migration looks:
**Before:**
```ts
public createAndAppendElement() {
const el = this.renderer.createElement('span');
el.textContent = 'hello world';
return el;
}
```
**After:**
<code-example>
public createAndAppendElement() {
const el = __ngRendererCreateElement(this.renderer, this.element, 'span');
el.textContent = 'hello world';
return el;
}
// Generated code at the bottom of the file
__ngRendererCreateElement(renderer: any, parentNode: any, nameAndNamespace: any) {
const [namespace, name] = __ngRendererSplitNamespace(namespaceAndName);
const el = renderer.createElement(name, namespace);
if (parentNode) {
renderer.appendChild(parentNode, el);
}
return el;
}
__ngRendererSplitNamespace(nameAndNamespace: any) {
// returns the split name and namespace
}
</code-example>
When implementing these helper functions, the schematic ensures that they're only declared once per file and that their names are unique enough that there's a small chance of colliding with pre-existing functions in your code. The schematic also keeps their parameter types as `any` so that it doesn't have to insert extra logic that ensures that their values have the correct type.
### Im a library author. Should I run this migration?
**Library authors should definitely use this migration to move away from the `Renderer`. Otherwise, the libraries won't work with applications built with version 9.**
### Full list of method migrations
The following table shows all methods that the migration maps from `Renderer` to `Renderer2`.
|Renderer|Renderer2|
|---|---|
|`listen(renderElement, name, callback)`|`listen(renderElement, name, callback)`|
|`setElementProperty(renderElement, propertyName, propertyValue)`|`setProperty(renderElement, propertyName, propertyValue)`|
|`setText(renderNode, text)`|`setValue(renderNode, text)`|
|`listenGlobal(target, name, callback)`|`listen(target, name, callback)`|
|`selectRootElement(selectorOrNode, debugInfo?)`|`selectRootElement(selectorOrNode)`|
|`createElement(parentElement, name, debugInfo?)`|`appendChild(parentElement, createElement(name))`|
|`setElementStyle(el, style, value?)`|`value == null ? removeStyle(el, style) : setStyle(el, style, value)`
|`setElementAttribute(el, name, value?)`|`attributeValue == null ? removeAttribute(el, name) : setAttribute(el, name, value)`
|`createText(parentElement, value, debugInfo?)`|`appendChild(parentElement, createText(value))`|
|`createTemplateAnchor(parentElement)`|`appendChild(parentElement, createComment(''))`|
|`setElementClass(renderElement, className, isAdd)`|`isAdd ? addClass(renderElement, className) : removeClass(renderElement, className)`|
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i < nodes.length; i<ins></ins>) { appendChild(parentElement, nodes<i>); }`|
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i < viewRootNodes.length; i<ins></ins>) { insertBefore(parentElement, viewRootNodes<i>, nextSibling);}`|
|`detachView(viewRootNodes)`|`for (let i = 0; i < viewRootNodes.length; i<ins></ins>) {const node = viewRootNodes<i>; const parentElement = parentNode(node); removeChild(parentElement, node);}`|
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i < viewAllNodes.length; i<ins></ins>) { destroyNode(viewAllNodes<i>); }`|
|`setBindingDebugInfo()`|This function is a noop in `Renderer2`.|
|`createViewRoot(hostElement)`|Should be replaced with a reference to `hostElement`|
|`invokeElementMethod(renderElement, methodName, args?)`|`(renderElement as any)<methodName>.apply(renderElement, args);`|
|`animate(element, startingStyles, keyframes, duration, delay, easing, previousPlayers?)`|Throws an error (same behavior as `Renderer.animate()`)|

View File

@ -1,138 +0,0 @@
# Undecorated classes migration (DI)
This section discusses an Angular version 9 schematic that migrates
two inheritance patterns that need to be updated to work with Ivy.
## What does this migration do?
This migration adds an empty `@Directive()` decorator to undecorated
base classes that are extended by either directives or components.
Before:
```ts
export class BaseMenu {
constructor(private vcr: ViewContainerRef) {}
}
@Directive({selector: '[settingsMenu]'})
export class SettingsMenu extends BaseMenu {}
```
After:
```ts
@Directive()
export class BaseMenu {
constructor(private vcr: ViewContainerRef) {}
}
@Directive({selector: '[settingsMenu]'})
export class SettingsMenu extends BaseMenu {}
```
The schematic also copies any inherited directive or component metadata to the derived class.
Before:
```ts
@Component({
selector: 'base-menu',
template: '<div></div>'
})
class BaseMenu {}
export class SettingsMenu extends BaseMenu {}
```
After:
```ts
@Component({
selector: 'base-menu',
template: '<div></div>'
})
class BaseMenu {}
@Component({
selector: 'settings-menu',
template: '<div></div>'
})
export class SettingsMenu extends BaseMenu {}
```
## Why is this migration necessary?
When a class has a `@Directive()` or `@Component()` decorator,
the Angular compiler generates extra code to inject dependencies into
the constructor. When using inheritance, Ivy needs both the parent class
and the child class to apply a decorator to generate the correct code.
You can think of this change as two cases: a parent class is missing a
decorator or a child class is missing a decorator. In both scenarios,
Angular's run-time needs additional information from the compiler.
This additional information comes from adding decorators.
### Decorator missing from parent class
When the decorator is missing from the parent class,
the subclass will inherit a constructor from a class for
which the compiler did not generate special constructor
info (because it was not decorated as a directive).
When Angular then tries to create the subclass,
it doesn't have the correct info
to create it.
In View Engine, the compiler has global knowledge, so it
can look up the missing data. However, the Ivy compiler
only processes each directive in isolation. This means that
compilation can be faster, but the compiler can't
automatically infer the same
information as before. Adding the `@Directive()` explicitly
provides this information.
In the future, add `@Directive()` to base classes that
do not already have decorators and are extended by directives.
### Decorator missing from child class
When the child class is missing the decorator, the
child class inherits from the
parent class yet has no decorators of its own.
Without a decorator, the compiler has no way of knowing
that the class is a `@Directive` or `@Component`, so
it doesn't generate the proper instructions for the directive.
## What does it mean to have a `@Directive()` decorator with no metadata inside of it?
The presence of the `@Directive` decorator causes Angular to generate
extra code for the affected class. If that decorator includes no
properties (metadata),
the directive won't be matched to elements or instantiated
directly, but other classes that _extend_ the
directive class will inherit this generated code. You can think of
this as an "abstract" directive.
Adding an abstract directive to an `NgModule` will cause an error.
A directive must have a `selector` property defined in order to match some element in a template.
## When do I need a `@Directive()` decorator without a selector?
If you're using dependency injection, or any Angular-specific
feature, such as `@HostBinding()`, `@ViewChild()`, or `@Input()`, you need a
`@Directive()` or `@Component()` decorator.
The decorator lets the compiler know to generate the correct
instructions to create that class and any classes that extend it.
If you don't want to use that base class as a directive directly, leave
the selector blank. If you do want it to be usable independently,
fill in the metadata as usual.
Classes that don't use Angular features don't need an Angular decorator.
## I'm a library author. Should I add the `@Directive()` decorator to base classes?
As support for selectorless decorators is introduced in
Angular version 9, if you want to support Angular version 8 and earlier, you
shouldn't add a selectorless `@Directive()` decorator.
You can either add `@Directive()` with a selector or
add an explicit constructor to affected subclasses.

View File

@ -674,6 +674,13 @@
"rev": true,
"title": "MDB Angular Boilerplate",
"url": "https://github.com/mdbootstrap/Angular-Bootstrap-Boilerplate"
},
"dotnettricks": {
"desc": "Online videos and training for Angular.",
"logo": "",
"rev": true,
"title": "DotNetTricks",
"url": "https://www.dotnettricks.com/courses/angular"
}
}
},

View File

@ -90,8 +90,16 @@ The product details component handles the display of each product. The Angular R
<code-example path="getting-started/src/app/product-details/product-details.component.1.ts" region="get-product">
</code-example>
Angular calls `ngOnInit()` shortly after creating a component.
The route parameters correspond to the path variables defined in the route. The `productId` is provided from
the URL that was matched to the route. You use the `productId` to display the details for each unique product.
the URL that was matched to the route. You use the `productId` to display the details for each unique product.
<div class="alert is-helpful">
For more information on `ngOnInit()`, see [Lifecycle hooks](guide/lifecycle-hooks).
</div>
1. Update the template to display product details information inside an `*ngIf`.

View File

@ -19,10 +19,10 @@
"build-local": "yarn ~~build",
"prebuild-local-ci": "yarn setup-local --no-build-packages",
"build-local-ci": "yarn ~~build --progress=false",
"prebuild-with-ivy": "yarn setup-local && node scripts/switch-to-ivy",
"build-with-ivy": "yarn ~~build",
"prebuild-with-ivy-ci": "yarn setup-local --no-build-packages && node scripts/switch-to-ivy",
"build-with-ivy-ci": "yarn ~~build --progress=false",
"prebuild-local-with-ivy": "yarn setup-local && node scripts/switch-to-ivy",
"build-local-with-ivy": "yarn ~~build",
"prebuild-local-with-ivy-ci": "yarn setup-local --no-build-packages && node scripts/switch-to-ivy",
"build-local-with-ivy-ci": "yarn ~~build --progress=false",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js e21aeeecd",
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
"test": "yarn check-env && ng test",
@ -115,7 +115,7 @@
"chalk": "^2.1.0",
"chrome-launcher": "^0.10.7",
"cjson": "^0.5.0",
"codelyzer": "^5.0.0",
"codelyzer": "^5.1.1",
"cross-spawn": "^5.1.0",
"css-selector-parser": "^1.3.0",
"dgeni": "^0.4.11",

View File

@ -7,10 +7,11 @@ import { LocationService } from 'app/shared/location.service';
selector: `aio-contributor-list`,
template: `
<div class="flex-center group-buttons">
<a *ngFor="let name of groupNames"
[class.selected]="name == selectedGroup.name"
class="button mat-button filter-button"
(click)="selectGroup(name)">{{name}}</a>
<a *ngFor="let name of groupNames"
[class.selected]="name == selectedGroup.name"
class="button mat-button filter-button"
(click)="selectGroup(name)"
(keyup.enter)="selectGroup(name)">{{name}}</a>
</div>
<section *ngIf="selectedGroup" class="grid-fluid">
<div class="contributor-group">

View File

@ -8,7 +8,7 @@ import { CONTENT_URL_PREFIX } from 'app/documents/document.service';
template: `
<div [ngClass]="{ 'flipped': person.isFlipped }" class="contributor-card">
<div class="card-front" (click)="flipCard(person)">
<div class="card-front" (click)="flipCard(person)" (keyup.enter)="flipCard(person)">
<h3>{{person.name}}</h3>
<div class="contributor-image" [style.background-image]="'url('+pictureBase+(person.picture || noPicture)+')'">
@ -28,7 +28,7 @@ import { CONTENT_URL_PREFIX } from 'app/documents/document.service';
</div>
</div>
<div class="card-back" *ngIf="person.isFlipped" (click)="flipCard(person)">
<div class="card-back" *ngIf="person.isFlipped" (click)="flipCard(person)" (keyup.enter)="flipCard(person)">
<h3>{{person.name}}</h3>
<p class="contributor-bio">{{person.bio}}</p>
</div>

View File

@ -4,6 +4,7 @@ import { PlatformLocation } from '@angular/common';
import { Category } from './resource.model';
import { ResourceService } from './resource.service';
/* tslint:disable:template-accessibility-elements-content */
@Component({
selector: 'aio-resource-list',
templateUrl: 'resource-list.component.html'

View File

@ -1,4 +1,4 @@
<span class="content" (click)="contentClick()">
<span class="content" (click)="contentClick()" (keyup.enter)="contentClick()">
<ng-content></ng-content>
</span>

View File

@ -21,16 +21,6 @@
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/** IE10 and IE11 requires the following for the Reflect API. */
/**
* DO NOT REMOVE
* By default, Reflect polyfills are auto-included by the CLI and
* are required for JIT compilation. StackBlitz examples are
* compiled using JIT.
*/
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
@ -65,8 +55,7 @@ import 'core-js/es7/reflect';
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
import 'zone.js/dist/zone-patch-canvas';
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS

View File

@ -33,7 +33,7 @@
"@nguniversal/express-engine": "^8.0.0-rc.1",
"@nguniversal/module-map-ngfactory-loader": "^8.0.0-rc.1",
"angular": "1.7.8",
"angular-in-memory-web-api": "github:brandonroberts/in-memory-web-api-bazel#50a34d8",
"angular-in-memory-web-api": "^0.9.0",
"angular-route": "1.7.8",
"core-js": "^2.5.4",
"express": "^4.14.1",
@ -69,7 +69,7 @@
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-jasmine-html-reporter": "^1.4.2",
"lite-server": "^2.2.2",
"lodash": "^4.16.2",
"protractor": "~5.4.0",

View File

@ -795,11 +795,10 @@ amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
"angular-in-memory-web-api@github:brandonroberts/in-memory-web-api-bazel#50a34d8":
version "0.8.0"
resolved "https://codeload.github.com/brandonroberts/in-memory-web-api-bazel/tar.gz/50a34d84b627ec88816242dec77603d6dcb9c880"
dependencies:
tslib "^1.9.0"
angular-in-memory-web-api@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/angular-in-memory-web-api/-/angular-in-memory-web-api-0.9.0.tgz#6c98d9494fadc6b98f54e68376a1998ccfff04bc"
integrity sha512-//PiJ5qb1+Yf/N7270ioQqR2laf4/Irjavg+M+WEn8y4At9LUoYgbQ5HVwvM5xUTlVlL0XkbJRLxREcGGNdIEw==
angular-route@1.7.8:
version "1.7.8"
@ -4430,15 +4429,10 @@ karma-coverage-istanbul-reporter@~2.0.1:
istanbul-api "^2.0.5"
minimatch "^3.0.4"
karma-jasmine-html-reporter@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz#48a8e5ef18807617ee2b5e33c1194c35b439524c"
dependencies:
karma-jasmine "^1.0.2"
karma-jasmine@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-1.1.0.tgz#22e4c06bf9a182e5294d1f705e3733811b810acf"
karma-jasmine-html-reporter@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.4.2.tgz#16d100fd701271192d27fd28ddc90b710ad36fff"
integrity sha512-7g0gPj8+9JepCNJR9WjDyQ2RkZ375jpdurYQyAYv8PorUCadepl8vrD6LmMqOGcM17cnrynBawQYZHaumgDjBw==
karma-jasmine@~2.0.1:
version "2.0.1"

View File

@ -29,6 +29,7 @@ module.exports =
.processor(require('./processors/processClassLikeMembers'))
.processor(require('./processors/markBarredODocsAsPrivate'))
.processor(require('./processors/filterPrivateDocs'))
.processor(require('./processors/filterMembers'))
.processor(require('./processors/computeSearchTitle'))
.processor(require('./processors/simplifyMemberAnchors'))
.processor(require('./processors/computeStability'))
@ -176,6 +177,12 @@ module.exports =
filterContainedDocs.docTypes = API_CONTAINED_DOC_TYPES;
})
.config(function(filterMembers) {
filterMembers.notAllowedPatterns.push(
/^ng[A-Z].*Def$/
);
})
.config(function(computePathsProcessor, EXPORT_DOC_TYPES, generateApiListDoc) {

View File

@ -0,0 +1,21 @@
/**
* Filter out members (i.e. static and instance properties and methods) that match specific
* patterns. Patterns can be added (as `RegExp`s) to the `notAllowedPatterns` array.
*
* (By default, no members are excluded.)
*/
module.exports = function filterMembers() {
return {
$runAfter: ['processing-docs'],
$runBefore: ['docs-processed'],
notAllowedPatterns: [],
$process(docs) {
const isAllowed = ({name}) => !this.notAllowedPatterns.some(re => re.test(name));
docs.forEach(doc => {
if (doc.statics) doc.statics = doc.statics.filter(isAllowed);
if (doc.members) doc.members = doc.members.filter(isAllowed);
});
},
};
};

View File

@ -0,0 +1,102 @@
const processorFactory = require('./filterMembers');
const testPackage = require('../../helpers/test-package');
const Dgeni = require('dgeni');
describe('filterMembers processor', () => {
it('should be available on the injector', () => {
const dgeni = new Dgeni([testPackage('angular-api-package')]);
const injector = dgeni.configureInjector();
const processor = injector.get('filterMembers');
expect(processor.$process).toBeDefined();
expect(processor.$runAfter).toEqual(['processing-docs']);
expect(processor.$runBefore).toEqual(['docs-processed']);
});
it('should remove members that match one of the not allowed patterns', () => {
const processor = processorFactory();
processor.notAllowedPatterns = [/^foo/, /bar$/];
const docs = [
// Doc without members.
{ },
// Doc with static members only.
{
statics: [
{ name: 'fooStatic' }, // Will be removed.
{ name: 'FOOStatic' },
{ name: 'barStatic' },
{ name: 'statiCbar' }, // Will be removed.
],
},
// Doc with instance members only.
{
members: [
{ name: 'fooInstance' }, // Will be removed.
{ name: 'FOOInstance' },
{ name: 'barInstance' },
{ name: 'instancEbar' }, // Will be removed.
],
},
// Doc with both static and instance members.
{
statics: [
{ name: 'fooStatic' }, // Will be removed.
{ name: 'FOOStatic' },
{ name: 'barStatic' },
{ name: 'statiCbar' }, // Will be removed.
],
members: [
{ name: 'fooInstance' }, // Will be removed.
{ name: 'FOOInstance' },
{ name: 'barInstance' },
{ name: 'instancEbar' }, // Will be removed.
],
},
];
processor.$process(docs);
expect(docs).toEqual([
{ },
{
statics: [ { name: 'FOOStatic' }, { name: 'barStatic' } ],
},
{
members: [ { name: 'FOOInstance' }, { name: 'barInstance' } ],
},
{
statics: [ { name: 'FOOStatic' }, { name: 'barStatic' } ],
members: [ { name: 'FOOInstance' }, { name: 'barInstance' } ],
},
]);
});
it('should remove no members by default', () => {
const processor = processorFactory();
const expectedDocs = [
{
statics: [
{ name: '' },
{ name: 'foo' },
{ name: '__bar' },
{ name: 'ngBazDef' },
],
members: [
{ name: '' },
{ name: 'foo' },
{ name: '__bar' },
{ name: 'ngBazDef' },
],
},
];
const actualDocs = JSON.parse(JSON.stringify(expectedDocs));
processor.$process(actualDocs);
expect(processor.notAllowedPatterns).toEqual([]);
expect(actualDocs).toEqual(expectedDocs);
});
});

View File

@ -96,6 +96,16 @@
"ban-keywords",
"check-format",
"require-const-for-all-caps"
]
],
"template-accessibility-alt-text": true,
"template-accessibility-elements-content": true,
"template-accessibility-label-for": true,
"template-accessibility-tabindex-no-positive": true,
"template-accessibility-table-scope": true,
"template-accessibility-valid-aria": true,
"template-click-events-have-key-events": true,
"template-mouse-events-have-key-events": true,
"template-no-autofocus": true,
"template-no-distracting-elements": true
}
}

View File

@ -938,10 +938,10 @@ anymatch@^3.0.1:
normalize-path "^3.0.0"
picomatch "^2.0.4"
app-root-path@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a"
integrity sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo=
app-root-path@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a"
integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==
append-transform@^1.0.0:
version "1.0.0"
@ -2179,12 +2179,12 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codelyzer@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-5.0.0.tgz#e4032efb23a7c5d4bcfe7321fc1789490c679837"
integrity sha512-Bif70XYt8NFf/Q9GPTxmC86OsBRfQZq1dBjdruJ5kZhJ8/jKhJL6MvCLKnYtSOG6Rhiv/44DU0cHk6GYthjy8Q==
codelyzer@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-5.1.1.tgz#a599fa8c2a5847f553a792b934e493d1506a4a62"
integrity sha512-t8ZLSZBUjVFOJVk4jASLgmTdKWK/0ZsQCnPXy6PXw1LWOOormQOVnyy4OYoiZ6rAWTrz60Obx+zA2t8xY53QzQ==
dependencies:
app-root-path "^2.1.0"
app-root-path "^2.2.1"
aria-query "^3.0.0"
axobject-query "^2.0.2"
css-selector-tokenizer "^0.7.1"

View File

@ -1,6 +1,6 @@
{
"name": "angular-srcs",
"version": "8.2.9",
"version": "8.2.10",
"private": true,
"description": "Angular - a web framework for modern web apps",
"homepage": "https://github.com/angular/angular",

View File

@ -372,7 +372,8 @@ def ngc_compile_action(
node_opts,
locale = None,
i18n_args = [],
dts_bundles_out = None):
dts_bundles_out = None,
compile_mode = "prodmode"):
"""Helper function to create the ngc action.
This is exposed for google3 to wire up i18n replay rules, and is not intended
@ -397,13 +398,13 @@ def ngc_compile_action(
is_legacy_ngc = _is_legacy_ngc(ctx)
mnemonic = "AngularTemplateCompile"
progress_message = "Compiling Angular templates (%s) %s" % (_compiler_name(ctx), label)
progress_message = "Compiling Angular templates (%s - %s) %s" % (_compiler_name(ctx), compile_mode, label)
if locale:
mnemonic = "AngularI18NMerging"
supports_workers = "0"
progress_message = ("Recompiling Angular templates (ngc) %s for locale %s" %
(label, locale))
progress_message = ("Recompiling Angular templates (ngc - %s) %s for locale %s" %
(compile_mode, label, locale))
else:
supports_workers = str(int(ctx.attr._supports_workers))
@ -463,7 +464,7 @@ def ngc_compile_action(
dts_entry_points.append(_R3_SYMBOLS_DTS_FILE)
ctx.actions.run(
progress_message = "Bundling DTS %s" % str(ctx.label),
progress_message = "Bundling DTS (%s) %s" % (compile_mode, str(ctx.label)),
mnemonic = "APIExtractor",
executable = ctx.executable.api_extractor,
inputs = filter_inputs,
@ -495,7 +496,15 @@ def _filter_ts_inputs(all_inputs):
if f.path.endswith(".js") or f.path.endswith(".ts") or f.path.endswith(".json")
]
def _compile_action(ctx, inputs, outputs, dts_bundles_out, messages_out, tsconfig_file, node_opts):
def _compile_action(
ctx,
inputs,
outputs,
dts_bundles_out,
messages_out,
tsconfig_file,
node_opts,
compile_mode):
# Give the Angular compiler all the user-listed assets
file_inputs = list(ctx.files.assets)
@ -533,16 +542,16 @@ def _compile_action(ctx, inputs, outputs, dts_bundles_out, messages_out, tsconfi
],
)
return ngc_compile_action(ctx, ctx.label, action_inputs, outputs, messages_out, tsconfig_file, node_opts, None, [], dts_bundles_out)
return ngc_compile_action(ctx, ctx.label, action_inputs, outputs, messages_out, tsconfig_file, node_opts, None, [], dts_bundles_out, compile_mode)
def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
outs = _expected_outs(ctx)
return _compile_action(ctx, inputs, outputs + outs.closure_js, None, outs.i18n_messages, tsconfig_file, node_opts)
return _compile_action(ctx, inputs, outputs + outs.closure_js, None, outs.i18n_messages, tsconfig_file, node_opts, "prodmode")
def _devmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
outs = _expected_outs(ctx)
compile_action_outputs = outputs + outs.devmode_js + outs.declarations + outs.summaries + outs.metadata
_compile_action(ctx, inputs, compile_action_outputs, outs.dts_bundles, None, tsconfig_file, node_opts)
_compile_action(ctx, inputs, compile_action_outputs, outs.dts_bundles, None, tsconfig_file, node_opts, "devmode")
def _ts_expected_outs(ctx, label, srcs_files = []):
# rules_typescript expects a function with two or more arguments, but our

View File

@ -0,0 +1,79 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AngularJSUrlCodec} from '../src/params';
describe('AngularJSUrlCodec', () => {
const codec = new AngularJSUrlCodec();
describe('parse', () => {
it('should parse a complex URL', () => {
const result = codec.parse('http://server.com:1234/foo?bar=true#heading');
expect(result.href).toBe('http://server.com:1234/foo?bar=true#heading');
expect(result.protocol).toBe('http');
expect(result.host).toBe('server.com:1234');
expect(result.search).toBe('bar=true');
expect(result.hash).toBe('heading');
expect(result.hostname).toBe('server.com');
expect(result.port).toBe('1234');
expect(result.pathname).toBe('/foo');
});
it('should parse a URL without search', () => {
const result = codec.parse('http://server.com:1234/foo#heading');
expect(result.href).toBe('http://server.com:1234/foo#heading');
expect(result.search).toBe('');
expect(result.hash).toBe('heading');
expect(result.pathname).toBe('/foo');
});
it('should parse a URL without hash', () => {
const result = codec.parse('http://server.com:1234/foo?bar=true');
expect(result.href).toBe('http://server.com:1234/foo?bar=true');
expect(result.search).toBe('bar=true');
expect(result.hash).toBe('');
expect(result.pathname).toBe('/foo');
});
it('should parse a basic URL', () => {
const result = codec.parse('http://server.com');
expect(result.href).toBe('http://server.com/');
expect(result.protocol).toBe('http');
expect(result.host).toBe('server.com');
expect(result.search).toBe('');
expect(result.hash).toBe('');
expect(result.hostname).toBe('server.com');
expect(result.port).toBe('');
expect(result.pathname).toBe('/');
});
it('should apply a base', () => {
const withoutSlash = codec.parse('foo/bar', 'http://abc.xyz');
expect(withoutSlash.href).toBe('http://abc.xyz/foo/bar');
const withSlash = codec.parse('/foo/bar', 'http://abc.xyz/');
expect(withSlash.href).toBe('http://abc.xyz/foo/bar');
});
it('should ignore an empty base', () => {
const result = codec.parse('http://abc.xyz', '');
expect(result.href).toBe('http://abc.xyz/');
});
it('should throw an error for an invalid URL', () => {
expect(() => {
codec.parse('/foo/bar');
}).toThrowError('Invalid URL (/foo/bar) with base (undefined)');
});
it('should throw an error for an invalid base', () => {
expect(() => {
codec.parse('http://foo.bar', 'abc');
}).toThrowError('Invalid URL (http://foo.bar) with base (abc)');
});
});
});

View File

@ -62,12 +62,8 @@ import {Subject, Subscription} from 'rxjs';
* @publicApi
*/
export class EventEmitter<T extends any> extends Subject<T> {
// TODO: mark this as internal once all the facades are gone
// we can't mark it as internal now because EventEmitter exported via @angular/core would not
// contain this property making it incompatible with all the code that uses EventEmitter via
// facades, which are local to the code and do not have this property stripped.
/**
* Internal
* @internal
*/
__isAsync: boolean; // tslint:disable-line

View File

@ -57,8 +57,38 @@ export const NG_VALIDATORS = new InjectionToken<Array<Validator|Function>>('NgVa
export const NG_ASYNC_VALIDATORS =
new InjectionToken<Array<Validator|Function>>('NgAsyncValidators');
/**
* A regular expression that matches valid e-mail addresses.
*
* At a high level, this regexp matches e-mail addresses of the format `local-part@tld`, where:
* - `local-part` consists of one or more of the allowed characters (alphanumeric and some
* punctuation symbols).
* - `local-part` cannot begin or end with a period (`.`).
* - `local-part` cannot be longer than 64 characters.
* - `tld` consists of one or more `labels` separated by periods (`.`). For example `localhost` or
* `foo.com`.
* - A `label` consists of one or more of the allowed characters (alphanumeric, dashes (`-`) and
* periods (`.`)).
* - A `label` cannot begin or end with a dash (`-`) or a period (`.`).
* - A `label` cannot be longer than 63 characters.
* - The whole address cannot be longer than 254 characters.
*
* ## Implementation background
*
* This regexp was ported over from AngularJS (see there for git history):
* https://github.com/angular/angular.js/blob/c133ef836/src/ng/directive/input.js#L27
* It is based on the
* [WHATWG version](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address) with
* some enhancements to incorporate more RFC rules (such as rules related to domain names and the
* lengths of different parts of the address). The main differences from the WHATWG version are:
* - Disallow `local-part` to begin or end with a period (`.`).
* - Disallow `local-part` length to exceed 64 characters.
* - Disallow total address length to exceed 254 characters.
*
* See [this commit](https://github.com/angular/angular.js/commit/f3f5cf72e) for more details.
*/
const EMAIL_REGEXP =
/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
/^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
/**
* @description
@ -191,6 +221,20 @@ export class Validators {
* @description
* Validator that requires the control's value pass an email validation test.
*
* Tests the value using a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)
* pattern suitable for common usecases. The pattern is based on the definition of a valid email
* address in the [WHATWG HTML specification](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address)
* with some enhancements to incorporate more RFC rules (such as rules related to domain names and
* the lengths of different parts of the address).
*
* The differences from the WHATWG version include:
* - Disallow `local-part` (the part before the `@` symbol) to begin or end with a period (`.`).
* - Disallow `local-part` to be longer than 64 characters.
* - Disallow the whole address to be longer than 254 characters.
*
* If this pattern does not satisfy your business needs, you can use `Validators.pattern()` to
* validate the value against a different pattern.
*
* @usageNotes
*
* ### Validate that the field matches a valid email pattern

70
scripts/local-dev/setup-rbe.sh Executable file
View File

@ -0,0 +1,70 @@
#!/bin/bash
# A script for automatically configuring a user's local dev
# environment to use Remote Build Execution.
# Determine the root directory of the Angular github repo.
project_directory=$(git rev-parse --show-toplevel 2> /dev/null);
if [[ $? -ne 0 ]]; then
echo "This command must be run from within the cloned \"angular/angular\" repository.";
exit 1;
fi
# Confirm gcloud installed and available as a command.
if [ ! -x "$(command -v gcloud)" ]; then
echo "gcloud command is not available. Please install gcloud before continuing.";
exit 1;
fi
# Confirm the parameter provided to the script is a directory
if [[ ! -d $1 ]]; then
echo -e "Invalid command syntax.
\e[1mUsage:\e[0m $0 <ServiceAccountKeyLocation>
\e[1mExample:\e[0m ./setup-rbe ~/my_key_storage_directory/
The directory provided will be used to store the GCP service account key
for the angular-local-dev service account. This key will then be used to
authenticate for usage of the Remote Build Execution system and Remote Caching.
";
exit 1;
fi
credentials_directory=$(readlink -f $1)
if [[ ! -d $credentials_directory ]]; then
echo "The specified directory does not exist. Please create the directory and rerun.";
exit 1;
fi
# Create the service account key in the provided directory.
echo "Checking provided directory for a service account key.";
json_key_filepath="$credentials_directory/angular-local-dev-key.json";
if [[ -f $json_key_filepath ]]; then
echo "Angular Local Dev key already exists, reusing this key.";
else
# Confirm the user is already logged into gcloud, if they aren't
# attempt to login
echo "Checking gcloud login state.";
gcloud auth print-identity-token &> /dev/null;
if [[ $? -ne 0 ]]; then
echo "Not currently logged into gcloud. Starting gcloud login now.";
gcloud auth login;
if [[ $? -ne 0 ]]; then
echo "gcloud login failed. Aborting.";
exit 2;
fi
fi
gcloud iam service-accounts keys create $json_key_filepath \
--iam-account angular-local-dev@internal-200822.iam.gserviceaccount.com \
--quiet --project internal-200822;
if [[ $? -ne 0 ]]; then
echo "Downloading service account key failed. Aborting.";
exit 2;
fi
fi
# The full path to the .bazelrc.user file
bazelrc_user_filepath="$project_directory/.bazelrc.user";
# Create the bazelrc.user file, echo the config flags into the file.
touch $bazelrc_user_filepath;
echo "build --config=remote-http-caching" >> $bazelrc_user_filepath;
echo "build --google_credentials=$json_key_filepath" >> $bazelrc_user_filepath;

View File

@ -326,7 +326,6 @@ export declare class ErrorHandler {
}
export declare class EventEmitter<T extends any> extends Subject<T> {
__isAsync: boolean;
constructor(isAsync?: boolean);
emit(value?: T): void;
subscribe(generatorOrNext?: any, error?: any, complete?: any): Subscription;