Compare commits
44 Commits
11.0.0-nex
...
creating-l
Author | SHA1 | Date | |
---|---|---|---|
63149810c1 | |||
e3bc073f7b | |||
4b9b094c47 | |||
75e59cc837 | |||
6ad701074a | |||
fb4df0a54c | |||
7b0fba0983 | |||
7bd65e5f1b | |||
c90d9fd468 | |||
4bd3debef2 | |||
43b1210f86 | |||
189686bea1 | |||
66592ac5a3 | |||
066da01295 | |||
03ca38a478 | |||
6452285a71 | |||
a81e82028a | |||
958d06fa69 | |||
15b311ac9f | |||
5717054caa | |||
44cf633cb1 | |||
957e152656 | |||
9ccf7631c6 | |||
225fdf9ac8 | |||
b206732b25 | |||
efef4b7dc1 | |||
92c7145139 | |||
d133525502 | |||
cd1817bf6d | |||
0d1491b1a6 | |||
f67774d84b | |||
37668d159e | |||
38554288f5 | |||
04dcc3bceb | |||
0910a2fc0d | |||
3325cb2f86 | |||
a1e8443bfb | |||
599d34b41e | |||
7fd1733882 | |||
2e42123870 | |||
4cbb90daf7 | |||
cf2663b034 | |||
95681b16bd | |||
e620827fa8 |
9
.bazelrc
9
.bazelrc
@ -136,6 +136,15 @@ build:remote --remote_executor=remotebuildexecution.googleapis.com
|
||||
# retry mechanism and we do not want to retry unnecessarily if Karma already tried multiple times.
|
||||
test:saucelabs --flaky_test_attempts=1
|
||||
|
||||
###############################
|
||||
# NodeJS rules settings
|
||||
# These settings are required for rules_nodejs
|
||||
###############################
|
||||
|
||||
# Turn on managed directories feature in Bazel
|
||||
# This allows us to avoid installing a second copy of node_modules
|
||||
common --experimental_allow_incremental_repository_updates
|
||||
|
||||
####################################################
|
||||
# User bazel configuration
|
||||
# NOTE: This needs to be the *last* entry in the config.
|
||||
|
@ -32,8 +32,8 @@ var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelver
|
||||
|
||||
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
||||
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
||||
var_5: &components_repo_unit_tests_cache_key v9-angular-components-09e68db8ed5b1253f2fe38ff954ef0df019fc25a
|
||||
var_6: &components_repo_unit_tests_cache_key_fallback v9-angular-components-
|
||||
var_5: &components_repo_unit_tests_cache_key v7-angular-components-f428c00465dfcf8a020237f22532480eedbd2cb6
|
||||
var_6: &components_repo_unit_tests_cache_key_fallback v7-angular-components-
|
||||
|
||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
||||
# `build-ivy-npm-packages`.
|
||||
@ -653,23 +653,9 @@ jobs:
|
||||
name: Starting Saucelabs tunnel service
|
||||
command: ./tools/saucelabs/sauce-service.sh run
|
||||
background: true
|
||||
# add module umd tsc compile option so the test can work
|
||||
# properly in the legacy browsers
|
||||
- run: yarn tsc -p packages --module UMD
|
||||
- run: yarn tsc -p modules --module UMD
|
||||
- run: yarn tsc -p packages
|
||||
- run: yarn tsc -p modules
|
||||
- run: yarn bazel build //packages/zone.js:npm_package
|
||||
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
|
||||
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
|
||||
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
|
||||
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
|
||||
# test in all supported browsers on Saucelabs anyway until this job can be removed.
|
||||
- run:
|
||||
name: Preparing Bazel-generated fixtures required in legacy tests
|
||||
command: |
|
||||
yarn bazel build //packages/core/test:downleveled_es5_fixture
|
||||
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
|
||||
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
|
||||
dist/all/@angular/core/test/reflection/es5_downleveled_inheritance_fixture.js
|
||||
- run:
|
||||
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
|
||||
name: Waiting for Saucelabs tunnel to connect
|
||||
@ -749,8 +735,6 @@ jobs:
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ &&
|
||||
yarn --cwd packages/zone.js electrontest
|
||||
- run: yarn --cwd packages/zone.js jesttest
|
||||
- run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive
|
||||
- run: yarn --cwd packages/zone.js/test/typings test
|
||||
|
||||
# Windows jobs
|
||||
# Docs: https://circleci.com/docs/2.0/hello-world-windows/
|
||||
|
@ -74,7 +74,7 @@ setPublicVar COMPONENTS_REPO_TMP_DIR "/tmp/angular-components-repo"
|
||||
setPublicVar COMPONENTS_REPO_URL "https://github.com/angular/components.git"
|
||||
setPublicVar COMPONENTS_REPO_BRANCH "master"
|
||||
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI `config.yml`.
|
||||
setPublicVar COMPONENTS_REPO_COMMIT "09e68db8ed5b1253f2fe38ff954ef0df019fc25a"
|
||||
setPublicVar COMPONENTS_REPO_COMMIT "f428c00465dfcf8a020237f22532480eedbd2cb6"
|
||||
|
||||
|
||||
####################################################################################################
|
||||
|
69
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
69
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
@ -1,69 +0,0 @@
|
||||
---
|
||||
name: "\U0001F41E Bug report"
|
||||
about: Report a bug in the Angular Framework
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
|
||||
# 🐞 bug report
|
||||
|
||||
### Affected Package
|
||||
<!-- Can you pin-point one or more @angular/* packages as the source of the bug? -->
|
||||
<!-- ✍️edit: --> The issue is caused by package @angular/....
|
||||
|
||||
|
||||
### Is this a regression?
|
||||
|
||||
<!-- Did this behavior use to work in the previous version? -->
|
||||
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
<!-- ✍️--> A clear and concise description of the problem...
|
||||
|
||||
|
||||
## 🔬 Minimal Reproduction
|
||||
<!--
|
||||
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-ivy
|
||||
-->
|
||||
<!-- ✍️--> https://stackblitz.com/...
|
||||
|
||||
<!--
|
||||
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue.
|
||||
A good way to make a minimal reproduction is to create a new app via `ng new repro-app` and add the minimum possible code to show the problem.
|
||||
Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
|
||||
|
||||
Issues that don't have enough info and can't be reproduced will be closed.
|
||||
|
||||
You can read more about issue submission guidelines here: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-submitting-an-issue
|
||||
-->
|
||||
|
||||
## 🔥 Exception or Error
|
||||
<pre><code>
|
||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
|
||||
## 🌍 Your Environment
|
||||
|
||||
**Angular Version:**
|
||||
<pre><code>
|
||||
<!-- run `ng version` and paste output below -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
**Anything else relevant?**
|
||||
<!-- ✍️Is this a browser specific issue? If so, please specify the browser and version. -->
|
||||
|
||||
<!-- ✍️Do any of these matter: operating system, IDE, package manager, HTTP server, ...? If so, please mention it below. -->
|
32
.github/ISSUE_TEMPLATE/2-feature-request.md
vendored
32
.github/ISSUE_TEMPLATE/2-feature-request.md
vendored
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: "\U0001F680 Feature request"
|
||||
about: Suggest a feature for Angular Framework
|
||||
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
|
||||
# 🚀 feature request
|
||||
|
||||
### Relevant Package
|
||||
<!-- Can you pin-point one or more @angular/* packages the are relevant for this feature request? -->
|
||||
<!-- ✍️edit: --> This feature request is for @angular/....
|
||||
|
||||
|
||||
### Description
|
||||
<!-- ✍️--> A clear and concise description of the problem or missing capability...
|
||||
|
||||
|
||||
### Describe the solution you'd like
|
||||
<!-- ✍️--> If you have a solution in mind, please describe it.
|
||||
|
||||
|
||||
### Describe alternatives you've considered
|
||||
<!-- ✍️--> Have you considered any alternative solutions or workarounds?
|
55
.github/ISSUE_TEMPLATE/3-docs-bug.md
vendored
55
.github/ISSUE_TEMPLATE/3-docs-bug.md
vendored
@ -1,55 +0,0 @@
|
||||
---
|
||||
name: "📚 Docs or angular.io issue report"
|
||||
about: Report an issue in Angular's documentation or angular.io application
|
||||
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
# 📚 Docs or angular.io bug report
|
||||
|
||||
### Description
|
||||
|
||||
<!-- ✍️edit:--> A clear and concise description of the problem...
|
||||
|
||||
|
||||
## 🔬 Minimal Reproduction
|
||||
|
||||
### What's the affected URL?**
|
||||
<!-- ✍️edit:--> https://angular.io/...
|
||||
|
||||
### Reproduction Steps**
|
||||
<!-- If applicable please list the steps to take to reproduce the issue -->
|
||||
<!-- ✍️edit:-->
|
||||
|
||||
### Expected vs Actual Behavior**
|
||||
<!-- If applicable please describe the difference between the expected and actual behavior after following the repro steps. -->
|
||||
<!-- ✍️edit:-->
|
||||
|
||||
|
||||
## 📷Screenshot
|
||||
<!-- Often a screenshot can help to capture the issue better than a long description. -->
|
||||
<!-- ✍️upload a screenshot:-->
|
||||
|
||||
|
||||
## 🔥 Exception or Error
|
||||
<pre><code>
|
||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
|
||||
## 🌍 Your Environment
|
||||
|
||||
### Browser info
|
||||
<!-- ✍️Is this a browser specific issue? If so, please specify the device, browser, and version. -->
|
||||
|
||||
### Anything else relevant?
|
||||
<!-- ✍️Please provide additional info if necessary. -->
|
@ -1,11 +0,0 @@
|
||||
---
|
||||
name: ⚠️ Security issue disclosure
|
||||
about: Report a security issue in Angular Framework, Material, or CLI
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please read https://angular.io/guide/security#report-issues on how to disclose security related issues.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
16
.github/ISSUE_TEMPLATE/5-support-request.md
vendored
16
.github/ISSUE_TEMPLATE/5-support-request.md
vendored
@ -1,16 +0,0 @@
|
||||
---
|
||||
name: "❓ Support request"
|
||||
about: Questions and requests for support
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please do not file questions or support requests on the GitHub issues tracker.
|
||||
|
||||
You can get your questions answered using other communication channels. Please see:
|
||||
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
|
||||
|
||||
Thank you!
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
13
.github/ISSUE_TEMPLATE/6-angular-cli.md
vendored
13
.github/ISSUE_TEMPLATE/6-angular-cli.md
vendored
@ -1,13 +0,0 @@
|
||||
---
|
||||
name: "\U0001F6E0️ Angular CLI"
|
||||
about: Issues and feature requests for Angular CLI
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please file any Angular CLI issues at: https://github.com/angular/angular-cli/issues/new
|
||||
|
||||
For the time being, we keep Angular CLI issues in a separate repository.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
13
.github/ISSUE_TEMPLATE/7-angular-components.md
vendored
13
.github/ISSUE_TEMPLATE/7-angular-components.md
vendored
@ -1,13 +0,0 @@
|
||||
---
|
||||
name: "\U0001F48E Angular Components"
|
||||
about: Issues and feature requests for Angular Components
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please file any Angular Components issues at: https://github.com/angular/components/issues/new
|
||||
|
||||
For the time being, we keep Angular Components issues in a separate repository.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
22
.github/ISSUE_TEMPLATE/8-translate-docs.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/8-translate-docs.md
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
name: "📚Traducir doc al español"
|
||||
about: Solicitud para traducir ciertos docs al español
|
||||
|
||||
---
|
||||
|
||||
📚Traducir: <!-- ✍️ editar: --> creating-libraries.md
|
||||
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Traducción de la documentación oficial de Angular a español
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
|
||||
## Nombre del archivo:
|
||||
<!-- ✍️ editar: --> creating-libraries.md
|
||||
|
||||
|
||||
## Ruta donde se encuentra el archivo dentro del proyecto de Angular
|
||||
|
||||
<!-- ✍️ editar: --> https://github.com/angular-hispano/angular/blob/master/aio/content/guide/creating-libraries.md
|
62
.github/PULL_REQUEST_TEMPLATE.md
vendored
62
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,43 +1,35 @@
|
||||
## PR Checklist
|
||||
Please check if your PR fulfills the following requirements:
|
||||
## Lista de Verificación del PR
|
||||
Comprueba si tu PR cumple los siguientes requisitos:
|
||||
|
||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
|
||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||
- [ ] Docs have been added / updated (for bug fixes / features)
|
||||
- [ ] El mensaje de commit conforme con [nuestras reglas](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit)
|
||||
- [ ] Prueba los cambios que agregaste (arreglo de bugs / funcionalidades)
|
||||
- [ ] Revisa tus traducciones o cambios de contenido
|
||||
- [ ] Consulté el [diccionario de términos](https://github.com/angular-hispano/angular/issues/9) en español
|
||||
- [ ] Se han creado dos archivos con la extensión correspondiente(.en.md para el archivo en inglés y .md para el Archivo en español)
|
||||
- [ ] PR enlazada con el issue correspondiente
|
||||
|
||||
|
||||
## PR Type
|
||||
What kind of change does this PR introduce?
|
||||
## Tipo de PR
|
||||
¿Qué tipo de cambio introduce este PR?
|
||||
|
||||
<!-- Please check the one that applies to this PR using "x". -->
|
||||
<!-- Marca con una "x" las opciones que aplican. -->
|
||||
|
||||
- [ ] Bugfix
|
||||
- [ ] Feature
|
||||
- [ ] Code style update (formatting, local variables)
|
||||
- [ ] Refactoring (no functional changes, no api changes)
|
||||
- [ ] Build related changes
|
||||
- [ ] CI related changes
|
||||
- [ ] Documentation content changes
|
||||
- [ ] angular.io application / infrastructure changes
|
||||
- [ ] Other... Please describe:
|
||||
- [ ] Funcionalidad
|
||||
- [ ] Actualizar el estilo del código (formato, variables locales)
|
||||
- [ ] Refactorización (no cambios en la funcionalidad, no cambios en el api)
|
||||
- [ ] Cambios relacionados al build
|
||||
- [ ] Cambios relacionados al CI (Integración continua)
|
||||
- [ ] Cambios en el contenido de la documentación
|
||||
- [ ] Cambios en la aplicación / infrastructura de angular.io
|
||||
- [ ] Otro... Por favor describela:
|
||||
|
||||
## ¿Cuál es el comportamiento actual?
|
||||
<!-- Describe el comportamiento actual que está modificando o vincule a un problema relevante.
|
||||
-->
|
||||
|
||||
|
||||
## What is the current behavior?
|
||||
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
|
||||
|
||||
Issue Number: N/A
|
||||
|
||||
|
||||
## What is the new behavior?
|
||||
|
||||
|
||||
## Does this PR introduce a breaking change?
|
||||
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
|
||||
|
||||
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
|
||||
|
||||
|
||||
## Other information
|
||||
## ¿Cuál es el nuevo comportamiento?
|
||||
<!--
|
||||
Ejemplo: Archivo en inglés traducido al español
|
||||
-->
|
||||
|
30
.github/angular-robot.yml
vendored
30
.github/angular-robot.yml
vendored
@ -48,7 +48,6 @@ merge:
|
||||
- "packages/bazel/src/protractor/**"
|
||||
- "packages/bazel/src/schematics/**"
|
||||
- "packages/compiler-cli/ngcc/**"
|
||||
- "packages/compiler-cli/src/ngtsc/sourcemaps/**",
|
||||
- "packages/docs/**"
|
||||
- "packages/elements/schematics/**"
|
||||
- "packages/examples/**"
|
||||
@ -69,20 +68,20 @@ merge:
|
||||
- "packages/**/integrationtest/**"
|
||||
- "packages/**/test/**"
|
||||
- "packages/zone.js/*"
|
||||
- "packages/zone.js/dist/**"
|
||||
- "packages/zone.js/doc/**"
|
||||
- "packages/zone.js/example/**"
|
||||
- "packages/zone.js/scripts/**"
|
||||
|
||||
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
|
||||
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.\nPlease help to unblock it by resolving these conflicts. Thanks!"
|
||||
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.
|
||||
\nPlease help to unblock it by resolving these conflicts. Thanks!"
|
||||
|
||||
# label to monitor
|
||||
mergeLabel: "action: merge"
|
||||
mergeLabel: "PR action: merge"
|
||||
|
||||
# adding any of these labels will also add the merge label
|
||||
mergeLinkedLabels:
|
||||
- "action: merge-assistance"
|
||||
- "PR action: merge-assistance"
|
||||
|
||||
# list of checks that will determine if the merge label can be added
|
||||
checks:
|
||||
@ -95,17 +94,17 @@ merge:
|
||||
|
||||
# whether the PR shouldn't have a conflict with the base branch
|
||||
noConflict: true
|
||||
# list of labels that a PR needs to have, checked with a regexp (e.g. "target:" will work for the label "target: master")
|
||||
# list of labels that a PR needs to have, checked with a regexp (e.g. "PR target:" will work for the label "PR target: master")
|
||||
requiredLabels:
|
||||
- "target: *"
|
||||
- "PR target: *"
|
||||
- "cla: yes"
|
||||
|
||||
# list of labels that a PR shouldn't have, checked after the required labels with a regexp
|
||||
forbiddenLabels:
|
||||
- "target: TBD"
|
||||
- "action: cleanup"
|
||||
- "action: review"
|
||||
- "state: blocked"
|
||||
- "PR target: TBD"
|
||||
- "PR action: cleanup"
|
||||
- "PR action: review"
|
||||
- "PR state: blocked"
|
||||
- "cla: no"
|
||||
|
||||
# list of PR statuses that need to be successful
|
||||
@ -122,7 +121,12 @@ merge:
|
||||
# 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
|
||||
# {{PLACEHOLDER}} will be replaced by the list of failing checks
|
||||
mergeRemovedComment: "I see that you just added the `{{MERGE_LABEL}}` label, but the following checks are still failing:\n{{PLACEHOLDER}}\n\n**If you want your PR to be merged, it has to pass all the CI checks.**\n\nIf you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help."
|
||||
mergeRemovedComment: "I see that you just added the `{{MERGE_LABEL}}` label, but the following checks are still failing:
|
||||
\n{{PLACEHOLDER}}
|
||||
\n
|
||||
\n**If you want your PR to be merged, it has to pass all the CI checks.**
|
||||
\n
|
||||
\nIf you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help."
|
||||
|
||||
# options for the triage plugin
|
||||
triage:
|
||||
@ -182,4 +186,4 @@ rerunCircleCI:
|
||||
# set to true to disable
|
||||
disabled: false
|
||||
# the label which when added triggers a rerun of the default CircleCI workflow
|
||||
triggerRerunLabel: "action: rerun CI at HEAD"
|
||||
triggerRerunLabel: "PR action: rerun CI at HEAD"
|
||||
|
2
.github/workflows/lock-closed.yml
vendored
2
.github/workflows/lock-closed.yml
vendored
@ -10,6 +10,6 @@ jobs:
|
||||
if: github.repository == 'angular/angular'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/lock-closed@414834b2b24dd2df37c6ed00808387ee6fd91b66
|
||||
- uses: angular/dev-infra/github-actions/lock-closed@66462f6
|
||||
with:
|
||||
lock-bot-key: ${{ secrets.LOCK_BOT_PRIVATE_KEY }}
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -40,9 +40,6 @@ yarn-error.log
|
||||
# User specific bazel settings
|
||||
.bazelrc.user
|
||||
|
||||
# User specific ng-dev settings
|
||||
.ng-dev.user*
|
||||
|
||||
.notes.md
|
||||
baseline.json
|
||||
|
||||
|
@ -105,9 +105,9 @@ Fixes #<issue number>
|
||||
# │ │
|
||||
# │ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
# │ elements|forms|http|language-service|localize|platform-browser|
|
||||
# │ platform-browser-dynamic|platform-server|router|service-worker|
|
||||
# │ upgrade|zone.js|packaging|changelog|dev-infra|docs-infra|migrations|
|
||||
# │ ngcc|ve
|
||||
# │ platform-browser-dynamic|platform-server|platform-webworker|
|
||||
# │ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
|
||||
# │ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
|
||||
# │ https://github.com/angular/angular/blob/master/CONTRIBUTING.md#scope
|
||||
# │
|
||||
# └─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
|
||||
|
@ -1,19 +0,0 @@
|
||||
import {CaretakerConfig} from '../dev-infra/caretaker/config';
|
||||
|
||||
/** The configuration for `ng-dev caretaker` commands. */
|
||||
export const caretaker: CaretakerConfig = {
|
||||
githubQueries: [
|
||||
{
|
||||
name: 'Merge Queue',
|
||||
query: `is:pr is:open status:success label:"action: merge"`,
|
||||
},
|
||||
{
|
||||
name: 'Merge Assistance Queue',
|
||||
query: `is:pr is:open status:success label:"action: merge-assistance"`,
|
||||
},
|
||||
{
|
||||
name: 'Primary Triage Queue',
|
||||
query: `is:open is:issue no:milestone`,
|
||||
}
|
||||
]
|
||||
};
|
@ -7,6 +7,18 @@ export const commitMessage: CommitMessageConfig = {
|
||||
maxLineLength: 120,
|
||||
minBodyLength: 20,
|
||||
minBodyLengthTypeExcludes: ['docs'],
|
||||
types: [
|
||||
'build',
|
||||
'ci',
|
||||
'docs',
|
||||
'feat',
|
||||
'fix',
|
||||
'perf',
|
||||
'refactor',
|
||||
'release',
|
||||
'style',
|
||||
'test',
|
||||
],
|
||||
scopes: [
|
||||
'animations',
|
||||
'bazel',
|
||||
|
@ -1,15 +1,11 @@
|
||||
import {caretaker} from './caretaker';
|
||||
import {commitMessage} from './commit-message';
|
||||
import {format} from './format';
|
||||
import {github} from './github';
|
||||
import {merge} from './merge';
|
||||
import {release} from './release';
|
||||
|
||||
module.exports = {
|
||||
commitMessage,
|
||||
format,
|
||||
github,
|
||||
merge,
|
||||
caretaker,
|
||||
release,
|
||||
};
|
||||
|
@ -1,28 +1,38 @@
|
||||
import {DevInfraMergeConfig} from '../dev-infra/pr/merge/config';
|
||||
import {getDefaultTargetLabelConfiguration} from '../dev-infra/pr/merge/defaults';
|
||||
import {github} from './github';
|
||||
import {release} from './release';
|
||||
import {MergeConfig} from '../dev-infra/pr/merge/config';
|
||||
|
||||
/**
|
||||
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
|
||||
* are respected by the merge script (e.g. the target labels).
|
||||
*/
|
||||
export const merge: DevInfraMergeConfig['merge'] = async api => {
|
||||
export const merge = (): MergeConfig => {
|
||||
// TODO: resume dynamically determining patch branch
|
||||
const patch = '10.0.x';
|
||||
return {
|
||||
githubApiMerge: false,
|
||||
claSignedLabel: 'cla: yes',
|
||||
mergeReadyLabel: /^action: merge(-assistance)?/,
|
||||
caretakerNoteLabel: 'action: merge-assistance',
|
||||
mergeReadyLabel: /^PR action: merge(-assistance)?/,
|
||||
caretakerNoteLabel: 'PR action: merge-assistance',
|
||||
commitMessageFixupLabel: 'commit message fixup',
|
||||
// We can pick any of the NPM packages as we are in a monorepo where all packages are
|
||||
// published together with the same version and branching.
|
||||
labels: await getDefaultTargetLabelConfiguration(api, github, release),
|
||||
labels: [
|
||||
{
|
||||
pattern: 'PR target: master-only',
|
||||
branches: ['master'],
|
||||
},
|
||||
{
|
||||
pattern: 'PR target: patch-only',
|
||||
branches: [patch],
|
||||
},
|
||||
{
|
||||
pattern: 'PR target: master & patch',
|
||||
branches: ['master', patch],
|
||||
},
|
||||
],
|
||||
requiredBaseCommits: {
|
||||
// PRs that target either `master` or the patch branch, need to be rebased
|
||||
// on top of the latest commit message validation fix.
|
||||
// These SHAs are the commits that update the required license text in the header.
|
||||
'master': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
|
||||
'10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24',
|
||||
[patch]: '27b95ba64a5d99757f4042073fd1860e20e3ed24'
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -1,33 +0,0 @@
|
||||
import {join} from 'path';
|
||||
import {exec} from 'shelljs';
|
||||
import {ReleaseConfig} from '../dev-infra/release/config';
|
||||
|
||||
/** Configuration for the `ng-dev release` command. */
|
||||
export const release: ReleaseConfig = {
|
||||
npmPackages: [
|
||||
'@angular/animations',
|
||||
'@angular/bazel',
|
||||
'@angular/common',
|
||||
'@angular/compiler',
|
||||
'@angular/compiler-cli',
|
||||
'@angular/core',
|
||||
'@angular/elements',
|
||||
'@angular/forms',
|
||||
'@angular/language-service',
|
||||
'@angular/localize',
|
||||
'@angular/platform-browser',
|
||||
'@angular/platform-browser-dynamic',
|
||||
'@angular/platform-server',
|
||||
'@angular/platform-webworker',
|
||||
'@angular/platform-webworker-dynamic',
|
||||
'@angular/router',
|
||||
'@angular/service-worker',
|
||||
'@angular/upgrade',
|
||||
],
|
||||
// TODO: Implement release package building here.
|
||||
buildPackages: async () => [],
|
||||
// TODO: This can be removed once there is a org-wide tool for changelog generation.
|
||||
generateReleaseNotesForHead: async () => {
|
||||
exec('yarn -s gulp changelog', {cwd: join(__dirname, '../')});
|
||||
},
|
||||
};
|
@ -67,25 +67,6 @@ version: 3
|
||||
# Meta field that goes unused by PullApprove to allow for defining aliases to be
|
||||
# used throughout the config.
|
||||
meta:
|
||||
# The following groups have no file based conditions and will be initially `active` on all PRs
|
||||
# - `global-approvers`
|
||||
# - `global-docs-approvers`
|
||||
# - `required-minimum-review`
|
||||
#
|
||||
# By checking the number of active/pending/rejected groups when these are excluded, we can determine
|
||||
# if any other groups are matched.
|
||||
#
|
||||
# Note: Because all inactive groups start as pending, we are only checking pending and rejected active groups.
|
||||
#
|
||||
# Also note that the ordering of groups matters in this file. The only groups visible to the current
|
||||
# one are those that appear above it.
|
||||
no-groups-above-this-pending: &no-groups-above-this-pending
|
||||
len(groups.active.pending.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
|
||||
no-groups-above-this-rejected: &no-groups-above-this-rejected
|
||||
len(groups.active.rejected.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
|
||||
no-groups-above-this-active: &no-groups-above-this-active
|
||||
len(groups.active.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
|
||||
|
||||
can-be-global-approved: &can-be-global-approved "\"global-approvers\" not in groups.approved"
|
||||
can-be-global-docs-approved: &can-be-global-docs-approved "\"global-docs-approvers\" not in groups.approved"
|
||||
defaults: &defaults
|
||||
@ -284,7 +265,7 @@ groups:
|
||||
users:
|
||||
- alxhub
|
||||
- crisbeto
|
||||
# OOO as of 2020-09-28 - devversion
|
||||
- devversion
|
||||
|
||||
|
||||
# =========================================================
|
||||
@ -303,6 +284,8 @@ groups:
|
||||
'packages/platform-browser/**',
|
||||
'packages/examples/platform-browser/**',
|
||||
'packages/platform-browser-dynamic/**',
|
||||
'packages/platform-webworker/**',
|
||||
'packages/platform-webworker-dynamic/**',
|
||||
'packages/examples/common/**',
|
||||
'packages/docs/**',
|
||||
'aio/content/guide/accessibility.md',
|
||||
@ -417,7 +400,7 @@ groups:
|
||||
- atscott
|
||||
- ~kara # do not request reviews from Kara, but allow her to approve PRs
|
||||
- mhevery
|
||||
# OOO as of 2020-09-28 - pkozlowski-opensource
|
||||
- pkozlowski-opensource
|
||||
|
||||
|
||||
# =========================================================
|
||||
@ -507,8 +490,8 @@ groups:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'packages/core/src/i18n/**',
|
||||
'packages/core/src/render3/i18n/**',
|
||||
'packages/core/src/render3/instructions/i18n.ts',
|
||||
'packages/core/src/render3/i18n.ts',
|
||||
'packages/core/src/render3/i18n.md',
|
||||
'packages/core/src/render3/interfaces/i18n.ts',
|
||||
'packages/common/locales/**',
|
||||
'packages/common/src/i18n/**',
|
||||
@ -660,7 +643,7 @@ groups:
|
||||
users:
|
||||
- AndrewKushnir
|
||||
- IgorMinar
|
||||
# OOO as of 2020-09-28 - pkozlowski-opensource
|
||||
- pkozlowski-opensource
|
||||
|
||||
|
||||
# =========================================================
|
||||
@ -677,7 +660,7 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- IgorMinar
|
||||
# OOO as of 2020-09-28 - pkozlowski-opensource
|
||||
- pkozlowski-opensource
|
||||
|
||||
|
||||
# =========================================================
|
||||
@ -695,7 +678,7 @@ groups:
|
||||
users:
|
||||
- IgorMinar
|
||||
- jelbourn
|
||||
# OOO as of 2020-09-28 - pkozlowski-opensource
|
||||
- pkozlowski-opensource
|
||||
|
||||
|
||||
# =========================================================
|
||||
@ -721,7 +704,7 @@ groups:
|
||||
- IgorMinar
|
||||
- mhevery
|
||||
- jelbourn
|
||||
# OOO as of 2020-09-28 - pkozlowski-opensource
|
||||
- pkozlowski-opensource
|
||||
reviews:
|
||||
request: -1 # request reviews from everyone
|
||||
required: 2 # require at least 2 approvals
|
||||
@ -880,7 +863,6 @@ groups:
|
||||
- *can-be-global-docs-approved
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'aio/content/guide/roadmap.md',
|
||||
'aio/content/marketing/**',
|
||||
'aio/content/images/bios/**',
|
||||
'aio/content/images/marketing/**',
|
||||
@ -1108,7 +1090,6 @@ groups:
|
||||
'dev-infra/**',
|
||||
'docs/BAZEL.md',
|
||||
'docs/CARETAKER.md',
|
||||
'docs/CODING_STANDARDS.md',
|
||||
'docs/COMMITTER.md',
|
||||
'docs/DEBUG.md',
|
||||
'docs/DEBUG_COMPONENTS_REPO_IVY.md',
|
||||
@ -1148,7 +1129,7 @@ groups:
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
# OOO as of 2020-09-28 - devversion
|
||||
- devversion
|
||||
- filipesilva
|
||||
- gkalpak
|
||||
- IgorMinar
|
||||
@ -1161,8 +1142,6 @@ groups:
|
||||
public-api:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- *no-groups-above-this-pending
|
||||
- *no-groups-above-this-rejected
|
||||
- *can-be-global-approved
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
@ -1176,16 +1155,14 @@ groups:
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- AndrewKushnir
|
||||
- IgorMinar
|
||||
- alxhub
|
||||
- atscott
|
||||
- jelbourn
|
||||
- petebacondarwin
|
||||
# OOO as of 2020-09-28 - pkozlowski-opensource
|
||||
- pkozlowski-opensource
|
||||
reviews:
|
||||
request: 4 # Request reviews from four people
|
||||
required: 3 # Require that three people approve
|
||||
request: -1 # request reviews from everyone
|
||||
required: 3 # require at least 3 approvals
|
||||
reviewed_for: required
|
||||
|
||||
|
||||
@ -1195,8 +1172,6 @@ groups:
|
||||
size-tracking:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- *no-groups-above-this-pending
|
||||
- *no-groups-above-this-rejected
|
||||
- *can-be-global-approved
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
@ -1204,16 +1179,14 @@ groups:
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- AndrewKushnir
|
||||
- IgorMinar
|
||||
- alxhub
|
||||
- atscott
|
||||
- jelbourn
|
||||
- petebacondarwin
|
||||
# OOO as of 2020-09-28 - pkozlowski-opensource
|
||||
- pkozlowski-opensource
|
||||
reviews:
|
||||
request: 4 # Request reviews from four people
|
||||
required: 2 # Require that two people approve
|
||||
request: -1 # request reviews from everyone
|
||||
required: 2 # require at least 2 approvals
|
||||
reviewed_for: required
|
||||
|
||||
|
||||
@ -1223,8 +1196,6 @@ groups:
|
||||
circular-dependencies:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- *no-groups-above-this-pending
|
||||
- *no-groups-above-this-rejected
|
||||
- *can-be-global-approved
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
@ -1232,13 +1203,11 @@ groups:
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- AndrewKushnir
|
||||
- IgorMinar
|
||||
- alxhub
|
||||
- atscott
|
||||
- jelbourn
|
||||
- josephperrott
|
||||
- petebacondarwin
|
||||
# OOO as of 2020-09-28 - pkozlowski-opensource
|
||||
- pkozlowski-opensource
|
||||
|
||||
|
||||
####################################################################################
|
||||
@ -1258,10 +1227,7 @@ groups:
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- AndrewKushnir
|
||||
- IgorMinar
|
||||
- alxhub
|
||||
- atscott
|
||||
- jelbourn
|
||||
- josephperrott
|
||||
- mhevery
|
||||
@ -1291,7 +1257,14 @@ groups:
|
||||
# `global-approvers` can still approve PRs that match this `fallback` rule,
|
||||
# but that should be an exception and not an expectation.
|
||||
conditions:
|
||||
- *no-groups-above-this-active
|
||||
# The following groups have no file based conditions and will be initially `active` on all PRs
|
||||
# - `global-approvers`
|
||||
# - `global-docs-approvers`
|
||||
# - `required-minimum-review`
|
||||
#
|
||||
# By checking the number of active groups when these are excluded, we can determine
|
||||
# if any other groups are matched.
|
||||
- len(groups.active.exclude("required-minimum-review").exclude("global-approvers").exclude("global-docs-approvers")) == 0
|
||||
# When any of the `global-*` groups is approved, they cause other groups to deactivate.
|
||||
# In those cases, the condition above would evaluate to `true` while in reality, only a global
|
||||
# approval has been provided. To ensure we don't activate the fallback group in such cases,
|
||||
|
@ -44654,7 +44654,7 @@ const FOLDERS_IGNORE = [
|
||||
const DEFAULT_IGNORE = (0, (_filter || _load_filter()).ignoreLinesToRegex)([...FOLDERS_IGNORE,
|
||||
|
||||
// ignore cruft
|
||||
'yarn.lock', '.lock-wscript', '.wafpickle-{0..9}', '*.swp', '._*', 'npm-debug.log', 'yarn-error.log', '.npmrc', '.yarnrc', '.yarnrc.yml', '.npmignore', '.gitignore', '.DS_Store']);
|
||||
'yarn.lock', '.lock-wscript', '.wafpickle-{0..9}', '*.swp', '._*', 'npm-debug.log', 'yarn-error.log', '.npmrc', '.yarnrc', '.npmignore', '.gitignore', '.DS_Store']);
|
||||
|
||||
const NEVER_IGNORE = (0, (_filter || _load_filter()).ignoreLinesToRegex)([
|
||||
// never ignore these files
|
||||
@ -44663,7 +44663,6 @@ const NEVER_IGNORE = (0, (_filter || _load_filter()).ignoreLinesToRegex)([
|
||||
function packWithIgnoreAndHeaders(cwd, ignoreFunction, { mapHeader } = {}) {
|
||||
return tar.pack(cwd, {
|
||||
ignore: ignoreFunction,
|
||||
sort: true,
|
||||
map: header => {
|
||||
const suffix = header.name === '.' ? '' : `/${header.name}`;
|
||||
header.name = `package${suffix}`;
|
||||
@ -46679,7 +46678,7 @@ function mkdirfix (name, opts, cb) {
|
||||
/* 194 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.22.5","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^3.1.0","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","cli-table3":"^0.4.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^6.2.0","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","js-yaml":"^3.13.1","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.4","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-inline-import":"^3.0.0","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.28","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.11.0","fancy-log":"^1.3.2","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^4.0.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","string-replace-loader":"^2.1.1","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}}
|
||||
module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.22.4","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^3.1.0","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","cli-table3":"^0.4.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^6.2.0","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","js-yaml":"^3.13.1","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.4","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-inline-import":"^3.0.0","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.28","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.11.0","fancy-log":"^1.3.2","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^4.0.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","string-replace-loader":"^2.1.1","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}}
|
||||
|
||||
/***/ }),
|
||||
/* 195 */
|
||||
@ -98339,7 +98338,7 @@ var _buildSubCommands = (0, (_buildSubCommands2 || _load_buildSubCommands()).def
|
||||
|
||||
const bundle = yield fetchBundle(config, bundleUrl);
|
||||
|
||||
const yarnPath = path.resolve(config.lockfileFolder, `.yarn/releases/yarn-${bundleVersion}.cjs`);
|
||||
const yarnPath = path.resolve(config.lockfileFolder, `.yarn/releases/yarn-${bundleVersion}.js`);
|
||||
reporter.log(`Saving it into ${chalk.magenta(yarnPath)}...`);
|
||||
yield (_fs || _load_fs()).mkdirp(path.dirname(yarnPath));
|
||||
yield (_fs || _load_fs()).writeFile(yarnPath, bundle);
|
||||
@ -100191,7 +100190,7 @@ let main = exports.main = (() => {
|
||||
|
||||
const config = new (_config || _load_config()).default(reporter);
|
||||
const outputWrapperEnabled = (0, (_conversion || _load_conversion()).boolifyWithDefault)(process.env.YARN_WRAP_OUTPUT, true);
|
||||
const shouldWrapOutput = outputWrapperEnabled && !(_commander || _load_commander()).default.json && command.hasWrapper((_commander || _load_commander()).default, (_commander || _load_commander()).default.args) && !(commandName === 'init' && (_commander || _load_commander()).default[`2`]);
|
||||
const shouldWrapOutput = outputWrapperEnabled && !(_commander || _load_commander()).default.json && command.hasWrapper((_commander || _load_commander()).default, (_commander || _load_commander()).default.args);
|
||||
|
||||
if (shouldWrapOutput) {
|
||||
reporter.header(commandName, { name: 'yarn', version: (_yarnVersion || _load_yarnVersion()).version });
|
||||
@ -100605,7 +100604,7 @@ let start = (() => {
|
||||
});
|
||||
|
||||
try {
|
||||
if (/\.[cm]?js$/.test(yarnPath)) {
|
||||
if (yarnPath.endsWith(`.js`)) {
|
||||
exitCode = yield (0, (_child || _load_child()).spawnp)(process.execPath, [yarnPath, ...argv], opts);
|
||||
} else {
|
||||
exitCode = yield (0, (_child || _load_child()).spawnp)(yarnPath, argv, opts);
|
2
.yarnrc
2
.yarnrc
@ -2,4 +2,4 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
yarn-path ".yarn/releases/yarn-1.22.5.js"
|
||||
yarn-path ".yarn/releases/yarn-1.22.4.js"
|
||||
|
@ -34,7 +34,7 @@ filegroup(
|
||||
filegroup(
|
||||
name = "angularjs_scripts",
|
||||
srcs = [
|
||||
# We also declare the unminified 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)
|
||||
"@npm//:node_modules/angular/angular.js",
|
||||
"@npm//:node_modules/angular/angular.min.js",
|
||||
|
541
CHANGELOG.md
541
CHANGELOG.md
@ -1,476 +1,3 @@
|
||||
<a name="11.0.0-next.4"></a>
|
||||
# 11.0.0-next.4 (2020-09-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** correct and simplify typing of `KeyValuePipe` ([#37447](https://github.com/angular/angular/issues/37447)) ([4dfe0fa](https://github.com/angular/angular/commit/4dfe0fa))
|
||||
* **common:** correct and simplify typing of AsyncPipe ([#37447](https://github.com/angular/angular/issues/37447)) ([5f815c0](https://github.com/angular/angular/commit/5f815c0))
|
||||
* **common:** correct and simplify typing of I18nPluralPipe ([#37447](https://github.com/angular/angular/issues/37447)) ([3b919ef](https://github.com/angular/angular/commit/3b919ef))
|
||||
* **common:** correct typing and implementation of `SlicePipe` ([#37447](https://github.com/angular/angular/issues/37447)) ([4744c22](https://github.com/angular/angular/commit/4744c22))
|
||||
* **common:** let case conversion pipes accept type unions with `null` ([#36259](https://github.com/angular/angular/issues/36259)) ([#37447](https://github.com/angular/angular/issues/37447)) ([c7d5555](https://github.com/angular/angular/commit/c7d5555))
|
||||
* **compiler-cli:** perform DOM schema checks even in basic mode in g3 ([#38943](https://github.com/angular/angular/issues/38943)) ([40975e0](https://github.com/angular/angular/commit/40975e0))
|
||||
* **language-service:** hybrid visitor returns parent node of BoundAttribute ([#38995](https://github.com/angular/angular/issues/38995)) ([323be39](https://github.com/angular/angular/commit/323be39))
|
||||
* **packaging:** remove polyfills needed to run tests on IE9 and IE 10 ([#38931](https://github.com/angular/angular/issues/38931)) ([4ca1c73](https://github.com/angular/angular/commit/4ca1c73))
|
||||
* **platform-webworker:** remove platform-webworker and platform-webworker-dynamic ([#38846](https://github.com/angular/angular/issues/38846)) ([93c3d8f](https://github.com/angular/angular/commit/93c3d8f))
|
||||
* **router:** make relativeLinkResolution corrected by default ([#25609](https://github.com/angular/angular/issues/25609)) ([837889f](https://github.com/angular/angular/commit/837889f)), closes [#22394](https://github.com/angular/angular/issues/22394)
|
||||
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* **router:** Adjust type of parameter in navigateByUrl and createUrlTree to be more accurate ([#38227](https://github.com/angular/angular/issues/38227)) ([e4f4d18](https://github.com/angular/angular/commit/e4f4d18)), closes [#18798](https://github.com/angular/angular/issues/18798)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **common:** stricter types for DatePipe ([#37447](https://github.com/angular/angular/issues/37447)) ([daf8b7f](https://github.com/angular/angular/commit/daf8b7f))
|
||||
* **common:** stricter types for number pipes ([#37447](https://github.com/angular/angular/issues/37447)) ([7b2aac9](https://github.com/angular/angular/commit/7b2aac9))
|
||||
* **compiler:** Add keySpan to Variable Node ([#38965](https://github.com/angular/angular/issues/38965)) ([239968d](https://github.com/angular/angular/commit/239968d))
|
||||
* **router:** Add `relativeLinkResolution` migration to update default value ([#38698](https://github.com/angular/angular/issues/38698)) ([15ea811](https://github.com/angular/angular/commit/15ea811))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **packaging:** In v10, IE 9, 10, and IE mobile support was deprecated. In v11, Angular framework removes IE 9,
|
||||
10, and IE mobile support completely.
|
||||
Supporting outdated browsers like these increases bundle size, code complexity, and test load,
|
||||
and also requires time and effort that could be spent on improvements to the framework.
|
||||
For example, fixing issues can be more difficult, as a straightforward fix for modern browsers
|
||||
could break old ones that have quirks due to not receiving updates from vendors.
|
||||
* **platform-webworker:** @angular/platform-webworker and @angular/platform-webworker-dynamic
|
||||
have been removed as they were deprecated in v8
|
||||
* **common:** The `slice` pipe now returns `null` for the `undefined` input value,
|
||||
which is consistent with the behavior of most pipes. If you rely on
|
||||
`undefined` being the result in that case, you now need to check for it
|
||||
explicitly.
|
||||
* **common:** The typing of the `keyvalue` pipe has been fixed to report that for
|
||||
input objects that have `number` keys, the result will contain the
|
||||
string representation of the keys. This was already the case and the
|
||||
code has simply been updated to reflect this. Please update the
|
||||
consumers of the pipe output if they were relying on the incorrect
|
||||
types. Note that this does not affect use cases where the input values
|
||||
are `Map`s, so if you need to preserve `number`s, this is an effective
|
||||
way.
|
||||
* **common:** The signatures of the number pipes now explicitly state which types are
|
||||
accepted. This should only cause issues in corner cases, as any other
|
||||
values would result in runtime exceptions.
|
||||
* **common:** The signature of the `date` pipe now explicitly states which types are
|
||||
accepted. This should only cause issues in corner cases, as any other
|
||||
values would result in runtime exceptions.
|
||||
* **common:** The async pipe no longer claims to return `undefined` for an input that
|
||||
was typed as `undefined`. Note that the code actually returned `null` on
|
||||
`undefined` inputs. In the unlikely case you were relying on this,
|
||||
please fix the typing of the consumers of the pipe output.
|
||||
* **common:** The case conversion pipes no longer let falsy values through. They now
|
||||
map both `null` and `undefined` to `null` and raise an exception on
|
||||
invalid input (`0`, `false`, `NaN`) just like most "common pipes". If
|
||||
your code required falsy values to pass through, you need to handle them
|
||||
explicitly.
|
||||
* **router:** While the new parameter types allow a variable of type
|
||||
`NavigationExtras` to be passed in, they will not allow object literals,
|
||||
as they may only specify known properties. They will also not accept
|
||||
types that do not have properties in common with the ones in the `Pick`.
|
||||
To fix this error, only specify properties from the `NavigationExtras` which are
|
||||
actually used in the respective function calls or use a type assertion
|
||||
on the object or variable: `as NavigationExtras`.
|
||||
* **router:** This commit changes the default value of
|
||||
`relativeLinkResolution` from `'legacy'` to `'default'`. If your
|
||||
application previously used the default by not specifying a value in the
|
||||
`ExtraOptions` and uses relative links when navigating from children of
|
||||
empty path routes, you will need to update your `RouterModule` to
|
||||
specifically specify `'legacy'` for `relativeLinkResolution`.
|
||||
See https://angular.io/api/router/ExtraOptions#relativeLinkResolution
|
||||
for more details.
|
||||
|
||||
|
||||
|
||||
<a name="10.1.4"></a>
|
||||
## 10.1.4 (2020-09-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler-cli:** enable [@types](https://github.com/types) discovery in incremental rebuilds ([#39011](https://github.com/angular/angular/issues/39011)) ([6e99427](https://github.com/angular/angular/commit/6e99427)), closes [#38979](https://github.com/angular/angular/issues/38979)
|
||||
|
||||
|
||||
|
||||
<a name="11.0.0-next.3"></a>
|
||||
# 11.0.0-next.3 (2020-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** add `params` and `reportProgress` options to `HttpClient.put()` overload ([#37873](https://github.com/angular/angular/issues/37873)) ([dd8d8c8](https://github.com/angular/angular/commit/dd8d8c8)), closes [#23600](https://github.com/angular/angular/issues/23600)
|
||||
* **compiler-cli:** generate `let` statements in ES2015+ mode ([#38775](https://github.com/angular/angular/issues/38775)) ([123bff7](https://github.com/angular/angular/commit/123bff7))
|
||||
* **core:** ensure TestBed is not instantiated before override provider ([#38717](https://github.com/angular/angular/issues/38717)) ([c8f056b](https://github.com/angular/angular/commit/c8f056b))
|
||||
* **forms:** type NG_VALUE_ACCESSOR injection token as array ([#29723](https://github.com/angular/angular/issues/29723)) ([2b1b718](https://github.com/angular/angular/commit/2b1b718)), closes [#29351](https://github.com/angular/angular/issues/29351)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **common:** Add ISO week-numbering year formats support to formatDate ([#38828](https://github.com/angular/angular/issues/38828)) ([984ed39](https://github.com/angular/angular/commit/984ed39))
|
||||
* **compiler:** Parse and recover on incomplete opening HTML tags ([#38681](https://github.com/angular/angular/issues/38681)) ([6ae3b68](https://github.com/angular/angular/commit/6ae3b68)), closes [#38596](https://github.com/angular/angular/issues/38596)
|
||||
* **router:** add migration to update calls to navigateByUrl and createUrlTree with invalid parameters ([#38825](https://github.com/angular/angular/issues/38825)) ([7849fdd](https://github.com/angular/angular/commit/7849fdd)), closes [#38227](https://github.com/angular/angular/issues/38227)
|
||||
* **service-worker:** add the option to prefer network for navigation requests ([#38565](https://github.com/angular/angular/issues/38565)) ([a206852](https://github.com/angular/angular/commit/a206852)), closes [#38194](https://github.com/angular/angular/issues/38194)
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **core:** If you call `TestBed.overrideProvider` after TestBed initialization, provider overrides are not applied. This
|
||||
behavior is consistent with other override methods (such as `TestBed.overrideDirective`, etc) but they
|
||||
throw an error to indicate that, when the check was missing in the `TestBed.overrideProvider` function.
|
||||
Now calling `TestBed.overrideProvider` after TestBed initialization also triggers an
|
||||
error, thus there is a chance that some tests (where `TestBed.overrideProvider` is
|
||||
called after TestBed initialization) will start to fail and require updates to move `TestBed.overrideProvider` calls
|
||||
before TestBed initialization is completed.
|
||||
|
||||
|
||||
|
||||
<a name="10.1.3"></a>
|
||||
## 10.1.3 (2020-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **http:** Fix error message when we call jsonp without importing HttpClientJsonpModule ([#38756](https://github.com/angular/angular/issues/38756)) ([3902ec0](https://github.com/angular/angular/commit/3902ec0))
|
||||
* **ngcc:** fix compilation of `ChangeDetectorRef` in pipe constructors ([#38892](https://github.com/angular/angular/issues/38892)) ([093c3a1](https://github.com/angular/angular/commit/093c3a1)), closes [#38666](https://github.com/angular/angular/issues/38666) [#38883](https://github.com/angular/angular/issues/38883)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* feat(router): better warning message when a router outlet has not been instantiated ([#38920](https://github.com/angular/angular/issues/38920)) ([04d0aa6](https://github.com/angular/angular/commit/04d0aa6))
|
||||
|
||||
|
||||
|
||||
<a name="11.0.0-next.2"></a>
|
||||
# 11.0.0-next.2 (2020-09-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** do not round up fractions of a millisecond in `DatePipe` ([#38009](https://github.com/angular/angular/issues/38009)) ([26f2820](https://github.com/angular/angular/commit/26f2820)), closes [/www.ecma-international.org/ecma-262/5.1/#sec-15](https://github.com//www.ecma-international.org/ecma-262/5.1//issues/sec-15) [#37989](https://github.com/angular/angular/issues/37989)
|
||||
* **common:** mark locale data arrays as readonly ([#30397](https://github.com/angular/angular/issues/30397)) ([6acea54](https://github.com/angular/angular/commit/6acea54)), closes [#27003](https://github.com/angular/angular/issues/27003)
|
||||
* **compiler:** source span for microsyntax text att should be key span ([#38766](https://github.com/angular/angular/issues/38766)) ([8f349b2](https://github.com/angular/angular/commit/8f349b2))
|
||||
* **router:** Fix arguments order for call to shouldReuseRoute ([#26949](https://github.com/angular/angular/issues/26949)) ([3817e5f](https://github.com/angular/angular/commit/3817e5f)), closes [#16192](https://github.com/angular/angular/issues/16192) [#16192](https://github.com/angular/angular/issues/16192)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler-cli:** `TemplateTypeChecker` operation to get `Symbol` from a template node ([#38618](https://github.com/angular/angular/issues/38618)) ([c4556db](https://github.com/angular/angular/commit/c4556db))
|
||||
* **compiler-cli:** Add ability to get `Symbol` of `Template`s and `Element`s in component template ([#38618](https://github.com/angular/angular/issues/38618)) ([cf2e8b9](https://github.com/angular/angular/commit/cf2e8b9))
|
||||
* **compiler-cli:** Add ability to get `Symbol` of AST expression in component template ([#38618](https://github.com/angular/angular/issues/38618)) ([f56ece4](https://github.com/angular/angular/commit/f56ece4))
|
||||
* **compiler-cli:** add ability to get symbol of reference or variable ([#38618](https://github.com/angular/angular/issues/38618)) ([19598b4](https://github.com/angular/angular/commit/19598b4))
|
||||
* **compiler-cli:** define interfaces to be used for TemplateTypeChecker ([#38618](https://github.com/angular/angular/issues/38618)) ([9e77bd3](https://github.com/angular/angular/commit/9e77bd3))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **compiler-cli:** only emit directive/pipe references that are used ([#38539](https://github.com/angular/angular/issues/38539)) ([077f516](https://github.com/angular/angular/commit/077f516))
|
||||
* **compiler-cli:** optimize computation of type-check scope information ([#38539](https://github.com/angular/angular/issues/38539)) ([297c060](https://github.com/angular/angular/commit/297c060))
|
||||
* **router:** use `ngDevMode` to tree-shake error messages in router ([#38674](https://github.com/angular/angular/issues/38674)) ([db21c4f](https://github.com/angular/angular/commit/db21c4f))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **router:** This change corrects the argument order when calling
|
||||
RouteReuseStrategy#shouldReuseRoute. Previously, when evaluating child
|
||||
routes, they would be called with the future and current arguments would
|
||||
be swapped. If your RouteReuseStrategy relies specifically on only the future
|
||||
or current snapshot state, you may need to update the shouldReuseRoute
|
||||
implementation's use of "future" and "current" ActivateRouteSnapshots.
|
||||
* **common:** The locale data API has been marked as returning readonly arrays, rather
|
||||
than mutable arrays, since these arrays are shared across calls to the
|
||||
API. If you were mutating them (e.g. calling `sort()`, `push()`, `splice()`, etc)
|
||||
then your code will not longer compile. If you need to mutate the array, you
|
||||
should now take a copy (e.g. by calling `slice()`) and mutate the copy.
|
||||
* **common:** When passing a date-time formatted string to the `DatePipe` in a format that contains
|
||||
fractions of a millisecond, the milliseconds will now always be rounded down rather than
|
||||
to the nearest millisecond.
|
||||
|
||||
Most applications will not be affected by this change. If this is not the desired behaviour
|
||||
then consider pre-processing the string to round the millisecond part before passing
|
||||
it to the `DatePipe`.
|
||||
|
||||
|
||||
|
||||
<a name="10.1.2"></a>
|
||||
## 10.1.2 (2020-09-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** detect pipes in ICUs in template binder ([#38810](https://github.com/angular/angular/issues/38810)) ([ec2dbe7](https://github.com/angular/angular/commit/ec2dbe7)), closes [#38539](https://github.com/angular/angular/issues/38539) [#38539](https://github.com/angular/angular/issues/38539) [#38539](https://github.com/angular/angular/issues/38539)
|
||||
* **core:** clear the `RefreshTransplantedView` when detached ([#38768](https://github.com/angular/angular/issues/38768)) ([edb7f90](https://github.com/angular/angular/commit/edb7f90)), closes [#38619](https://github.com/angular/angular/issues/38619)
|
||||
* **localize:** ensure that `formatOptions` is optional ([#38787](https://github.com/angular/angular/issues/38787)) ([a47383d](https://github.com/angular/angular/commit/a47383d))
|
||||
* **router:** Ensure routes are processed in priority order and only if needed ([#38780](https://github.com/angular/angular/issues/38780)) ([9c51ba3](https://github.com/angular/angular/commit/9c51ba3)), closes [#38691](https://github.com/angular/angular/issues/38691)
|
||||
* **upgrade:** add try/catch when downgrading injectables ([#38671](https://github.com/angular/angular/issues/38671)) ([5de2ac3](https://github.com/angular/angular/commit/5de2ac3)), closes [#37579](https://github.com/angular/angular/issues/37579)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **compiler-cli:** only emit directive/pipe references that are used ([#38843](https://github.com/angular/angular/issues/38843)) ([5658405](https://github.com/angular/angular/commit/5658405))
|
||||
* **compiler-cli:** optimize computation of type-check scope information ([#38843](https://github.com/angular/angular/issues/38843)) ([ebede67](https://github.com/angular/angular/commit/ebede67))
|
||||
* **ngcc:** introduce cache for sharing data across entry-points ([#38840](https://github.com/angular/angular/issues/38840)) ([58411e7](https://github.com/angular/angular/commit/58411e7))
|
||||
* **ngcc:** reduce maximum worker count ([#38840](https://github.com/angular/angular/issues/38840)) ([ea36466](https://github.com/angular/angular/commit/ea36466))
|
||||
|
||||
|
||||
|
||||
<a name="11.0.0-next.1"></a>
|
||||
# 11.0.0-next.1 (2020-09-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler-cli:** compute source-mappings for localized strings ([#38645](https://github.com/angular/angular/issues/38645)) ([7e0b3fd](https://github.com/angular/angular/commit/7e0b3fd)), closes [#38588](https://github.com/angular/angular/issues/38588)
|
||||
* **core:** remove CollectionChangeRecord symbol ([#38668](https://github.com/angular/angular/issues/38668)) ([fdea180](https://github.com/angular/angular/commit/fdea180))
|
||||
* **router:** support lazy loading for empty path named outlets ([#38379](https://github.com/angular/angular/issues/38379)) ([926ffcd](https://github.com/angular/angular/commit/926ffcd)), closes [#12842](https://github.com/angular/angular/issues/12842)
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **core:** CollectionChangeRecord has been removed, use IterableChangeRecord
|
||||
instead
|
||||
|
||||
|
||||
|
||||
<a name="10.1.1"></a>
|
||||
## 10.1.1 (2020-09-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** correct confusion between field and property names ([#38685](https://github.com/angular/angular/issues/38685)) ([a1c34c6](https://github.com/angular/angular/commit/a1c34c6))
|
||||
* **compiler-cli:** compute source-mappings for localized strings ([#38747](https://github.com/angular/angular/issues/38747)) ([b4eb016](https://github.com/angular/angular/commit/b4eb016)), closes [#38588](https://github.com/angular/angular/issues/38588)
|
||||
* **compiler-cli:** ensure that a declaration is available in type-to-value conversion ([#38684](https://github.com/angular/angular/issues/38684)) ([56d5ff2](https://github.com/angular/angular/commit/56d5ff2)), closes [#38670](https://github.com/angular/angular/issues/38670)
|
||||
* **core:** reset `tView` between tests in Ivy TestBed ([#38659](https://github.com/angular/angular/issues/38659)) ([efc7606](https://github.com/angular/angular/commit/efc7606)), closes [#38600](https://github.com/angular/angular/issues/38600)
|
||||
* **localize:** do not expose NodeJS typings in $localize runtime code ([#38700](https://github.com/angular/angular/issues/38700)) ([4de8dc3](https://github.com/angular/angular/commit/4de8dc3)), closes [#38692](https://github.com/angular/angular/issues/38692)
|
||||
* **localize:** enable whitespace preservation marker in XLIFF files ([#38737](https://github.com/angular/angular/issues/38737)) ([190dca0](https://github.com/angular/angular/commit/190dca0)), closes [#38679](https://github.com/angular/angular/issues/38679)
|
||||
* **localize:** install `[@angular](https://github.com/angular)/localize` in `devDependencies` by default ([#38680](https://github.com/angular/angular/issues/38680)) ([dbab744](https://github.com/angular/angular/commit/dbab744)), closes [#38329](https://github.com/angular/angular/issues/38329)
|
||||
* **localize:** render context of translation file parse errors ([#38673](https://github.com/angular/angular/issues/38673)) ([32f33f0](https://github.com/angular/angular/commit/32f33f0)), closes [#38377](https://github.com/angular/angular/issues/38377)
|
||||
* **localize:** render location in XLIFF 2 even if there is no metadata ([#38713](https://github.com/angular/angular/issues/38713)) ([ab4f953](https://github.com/angular/angular/commit/ab4f953)), closes [#38705](https://github.com/angular/angular/issues/38705)
|
||||
* **ngcc:** use aliased exported types correctly ([#38666](https://github.com/angular/angular/issues/38666)) ([6a28675](https://github.com/angular/angular/commit/6a28675)), closes [#38238](https://github.com/angular/angular/issues/38238)
|
||||
* **router:** If users are using the Alt key when clicking the router links, prioritize browser’s default behavior ([#38375](https://github.com/angular/angular/issues/38375)) ([309709d](https://github.com/angular/angular/commit/309709d))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **core:** use `ngDevMode` to tree-shake error messages ([#38612](https://github.com/angular/angular/issues/38612)) ([b084bff](https://github.com/angular/angular/commit/b084bff))
|
||||
|
||||
|
||||
|
||||
<a name="11.0.0-next.0"></a>
|
||||
# 11.0.0-next.0 (2020-09-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **forms:** ensure to emit `statusChanges` on subsequent value update/validations ([#38354](https://github.com/angular/angular/issues/38354)) ([d9fea85](https://github.com/angular/angular/commit/d9fea85)), closes [#20424](https://github.com/angular/angular/issues/20424) [#14542](https://github.com/angular/angular/issues/14542)
|
||||
* **service-worker:** fix condition to check for a cache-busted request ([#36847](https://github.com/angular/angular/issues/36847)) ([5be4edf](https://github.com/angular/angular/commit/5be4edf))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **service-worker:** add `UnrecoverableStateError` ([#36847](https://github.com/angular/angular/issues/36847)) ([036a2fa](https://github.com/angular/angular/commit/036a2fa)), closes [#36539](https://github.com/angular/angular/issues/36539)
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **forms:** Previously if FormControl, FormGroup and FormArray class instances had async validators
|
||||
defined at initialization time, the status change event was not emitted once async validator
|
||||
completed. After this change the status event is emitted into the `statusChanges` observable.
|
||||
If your code relies on the old behavior, you can filter/ignore this additional status change
|
||||
event.
|
||||
|
||||
|
||||
|
||||
<a name="10.1.0"></a>
|
||||
# 10.1.0 (2020-09-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bazel:** provide LinkablePackageInfo from ng_module ([#37623](https://github.com/angular/angular/issues/37623)) ([6898eab](https://github.com/angular/angular/commit/6898eab))
|
||||
* **common:** add ReadonlyMap in place of Map in keyValuePipe ([#37311](https://github.com/angular/angular/issues/37311)) ([3373453](https://github.com/angular/angular/commit/3373453)), closes [#37308](https://github.com/angular/angular/issues/37308)
|
||||
* **compiler-cli:** add `SourceFile.getOriginalLocation()` to sourcemaps package ([#32912](https://github.com/angular/angular/issues/32912)) ([6abb8d0](https://github.com/angular/angular/commit/6abb8d0))
|
||||
* **compiler-cli:** Add compiler option to report errors when assigning to restricted input fields ([#38249](https://github.com/angular/angular/issues/38249)) ([71138f6](https://github.com/angular/angular/commit/71138f6))
|
||||
* **compiler-cli:** add support for TypeScript 4.0 ([#38076](https://github.com/angular/angular/issues/38076)) ([0fc44e0](https://github.com/angular/angular/commit/0fc44e0))
|
||||
* **compiler-cli:** explain why an expression cannot be used in AOT compilations ([#37587](https://github.com/angular/angular/issues/37587)) ([712f1bd](https://github.com/angular/angular/commit/712f1bd))
|
||||
* **compiler:** support unary operators for more accurate type checking ([#37918](https://github.com/angular/angular/issues/37918)) ([874792d](https://github.com/angular/angular/commit/874792d)), closes [#20845](https://github.com/angular/angular/issues/20845) [#36178](https://github.com/angular/angular/issues/36178)
|
||||
* **core:** rename async to waitForAsync to avoid confusing ([#37583](https://github.com/angular/angular/issues/37583)) ([8f07429](https://github.com/angular/angular/commit/8f07429))
|
||||
* **core:** support injection token as predicate in queries ([#37506](https://github.com/angular/angular/issues/37506)) ([97dc85b](https://github.com/angular/angular/commit/97dc85b)), closes [#21152](https://github.com/angular/angular/issues/21152) [#36144](https://github.com/angular/angular/issues/36144)
|
||||
* **core:** update reference and doc to change `async` to `waitAsync`. ([#37583](https://github.com/angular/angular/issues/37583)) ([8fbf40b](https://github.com/angular/angular/commit/8fbf40b))
|
||||
* **forms:** AbstractControl to store raw validators in addition to combined validators function ([#37881](https://github.com/angular/angular/issues/37881)) ([ad7046b](https://github.com/angular/angular/commit/ad7046b))
|
||||
* **localize:** allow duplicate messages to be handled during extraction ([#38082](https://github.com/angular/angular/issues/38082)) ([cf9a47b](https://github.com/angular/angular/commit/cf9a47b)), closes [#38077](https://github.com/angular/angular/issues/38077)
|
||||
* **localize:** expose `canParse()` diagnostics ([#37909](https://github.com/angular/angular/issues/37909)) ([ec32eba](https://github.com/angular/angular/commit/ec32eba)), closes [#37901](https://github.com/angular/angular/issues/37901)
|
||||
* **localize:** implement message extraction tool ([#32912](https://github.com/angular/angular/issues/32912)) ([190561d](https://github.com/angular/angular/commit/190561d))
|
||||
* **platform-browser:** Allow `sms`-URLs ([#31463](https://github.com/angular/angular/issues/31463)) ([fc5c34d](https://github.com/angular/angular/commit/fc5c34d)), closes [#31462](https://github.com/angular/angular/issues/31462)
|
||||
* **platform-server:** add option for absolute URL HTTP support ([#37539](https://github.com/angular/angular/issues/37539)) ([d37049a](https://github.com/angular/angular/commit/d37049a)), closes [#37071](https://github.com/angular/angular/issues/37071)
|
||||
* **router:** better warning message when a router outlet has not been instantiated ([#30246](https://github.com/angular/angular/issues/30246)) ([1609815](https://github.com/angular/angular/commit/1609815))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** fix integration test for bazel building ([#38629](https://github.com/angular/angular/issues/38629)) ([dd82f2f](https://github.com/angular/angular/commit/dd82f2f))
|
||||
* **common:** date pipe gives wrong week number ([#37632](https://github.com/angular/angular/issues/37632)) ([ef1fb6d](https://github.com/angular/angular/commit/ef1fb6d)), closes [#33961](https://github.com/angular/angular/issues/33961)
|
||||
* **common:** narrow `NgIf` context variables in template type checker ([#36627](https://github.com/angular/angular/issues/36627)) ([9c8bc4a](https://github.com/angular/angular/commit/9c8bc4a))
|
||||
* **compiler-cli:** avoid creating value expressions for symbols from type-only imports ([#37912](https://github.com/angular/angular/issues/37912)) ([18098d3](https://github.com/angular/angular/commit/18098d3)), closes [#37900](https://github.com/angular/angular/issues/37900)
|
||||
* **compiler-cli:** ensure source-maps can handle webpack:// protocol ([#32912](https://github.com/angular/angular/issues/32912)) ([decd95e](https://github.com/angular/angular/commit/decd95e))
|
||||
* **compiler-cli:** only read source-map comment from last line ([#32912](https://github.com/angular/angular/issues/32912)) ([07a07e3](https://github.com/angular/angular/commit/07a07e3))
|
||||
* **compiler-cli:** type-check inputs that include undefined when there's coercion members ([#38273](https://github.com/angular/angular/issues/38273)) ([7525f3a](https://github.com/angular/angular/commit/7525f3a))
|
||||
* **compiler:** incorrectly inferring namespace for HTML nodes inside SVG ([#38477](https://github.com/angular/angular/issues/38477)) ([0dda97e](https://github.com/angular/angular/commit/0dda97e)), closes [#37218](https://github.com/angular/angular/issues/37218)
|
||||
* **compiler:** mark `NgModuleFactory` construction as not side effectful ([#38147](https://github.com/angular/angular/issues/38147)) ([7f8c222](https://github.com/angular/angular/commit/7f8c222))
|
||||
* **core:** Allow modification of lifecycle hooks any time before bootstrap ([#35464](https://github.com/angular/angular/issues/35464)) ([737506e](https://github.com/angular/angular/commit/737506e)), closes [#30497](https://github.com/angular/angular/issues/30497)
|
||||
* **core:** detect DI parameters in JIT mode for downleveled ES2015 classes ([#38463](https://github.com/angular/angular/issues/38463)) ([ca07da4](https://github.com/angular/angular/commit/ca07da4)), closes [#38453](https://github.com/angular/angular/issues/38453)
|
||||
* **core:** determine required DOMParser feature availability ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([c509243](https://github.com/angular/angular/commit/c509243))
|
||||
* **core:** do not trigger CSP alert/report in Firefox and Chrome ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([b950d46](https://github.com/angular/angular/commit/b950d46)), closes [#25214](https://github.com/angular/angular/issues/25214)
|
||||
* **core:** move generated i18n statements to the `consts` field of ComponentDef ([#38404](https://github.com/angular/angular/issues/38404)) ([cb05c01](https://github.com/angular/angular/commit/cb05c01))
|
||||
* **elements:** run strategy methods in correct zone ([#37814](https://github.com/angular/angular/issues/37814)) ([8df888d](https://github.com/angular/angular/commit/8df888d)), closes [#24181](https://github.com/angular/angular/issues/24181)
|
||||
* **forms:** handle form groups/arrays own pending async validation ([#22575](https://github.com/angular/angular/issues/22575)) ([77b62a5](https://github.com/angular/angular/commit/77b62a5)), closes [#10064](https://github.com/angular/angular/issues/10064)
|
||||
* **language-service:** non-existent module format in package output ([#37623](https://github.com/angular/angular/issues/37623)) ([413a0fb](https://github.com/angular/angular/commit/413a0fb))
|
||||
* **localize:** ensure required XLIFF parameters are serialized ([#38575](https://github.com/angular/angular/issues/38575)) ([f0af387](https://github.com/angular/angular/commit/f0af387)), closes [#38570](https://github.com/angular/angular/issues/38570)
|
||||
* **localize:** extract the correct message ids ([#38498](https://github.com/angular/angular/issues/38498)) ([ac461e1](https://github.com/angular/angular/commit/ac461e1))
|
||||
* **localize:** render ICU placeholders in extracted translation files ([#38484](https://github.com/angular/angular/issues/38484)) ([81c3e80](https://github.com/angular/angular/commit/81c3e80))
|
||||
* **localize:** render text of extracted placeholders ([#38536](https://github.com/angular/angular/issues/38536)) ([14e90be](https://github.com/angular/angular/commit/14e90be))
|
||||
* **ngcc:** detect synthesized delegate constructors for downleveled ES2015 classes ([#38463](https://github.com/angular/angular/issues/38463)) ([3b9c802](https://github.com/angular/angular/commit/3b9c802)), closes [#38453](https://github.com/angular/angular/issues/38453) [#38453](https://github.com/angular/angular/issues/38453)
|
||||
* **router:** defer loading of wildcard module until needed ([#38348](https://github.com/angular/angular/issues/38348)) ([8f708b5](https://github.com/angular/angular/commit/8f708b5)), closes [#25494](https://github.com/angular/angular/issues/25494)
|
||||
* **router:** fix navigation ignoring logic to compare to the browser url ([#37716](https://github.com/angular/angular/issues/37716)) ([a5ffca0](https://github.com/angular/angular/commit/a5ffca0)), closes [#16710](https://github.com/angular/angular/issues/16710) [#13586](https://github.com/angular/angular/issues/13586)
|
||||
* **router:** properly compare array queryParams for equality ([#37709](https://github.com/angular/angular/issues/37709)) ([#37860](https://github.com/angular/angular/issues/37860)) ([1801d0c](https://github.com/angular/angular/commit/1801d0c))
|
||||
* **router:** remove parenthesis for primary outlet segment after removing auxiliary outlet segment ([#24656](https://github.com/angular/angular/issues/24656)) ([#37163](https://github.com/angular/angular/issues/37163)) ([71f008f](https://github.com/angular/angular/commit/71f008f))
|
||||
* **router:** restore 'history.state' object for navigations coming from Angular router ([#28108](https://github.com/angular/angular/issues/28108)) ([#28176](https://github.com/angular/angular/issues/28176)) ([df76a20](https://github.com/angular/angular/commit/df76a20))
|
||||
|
||||
### Code Refactoring
|
||||
* **router:** export DefaultRouteReuseStrategy to Router public_api ([#31575](https://github.com/angular/angular/issues/31575)) ([ca79880](https://github.com/angular/angular/commit/ca79880))
|
||||
|
||||
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
* **compiler-cli:** don't emit template guards when child scope is empty ([#38418](https://github.com/angular/angular/issues/38418)) ([1388c17](https://github.com/angular/angular/commit/1388c17))
|
||||
* **compiler-cli:** fix regressions in incremental program reuse ([#37641](https://github.com/angular/angular/issues/37641)) ([5103d90](https://github.com/angular/angular/commit/5103d90))
|
||||
* **compiler-cli:** only generate directive declarations when used ([#38418](https://github.com/angular/angular/issues/38418)) ([fb8f4b4](https://github.com/angular/angular/commit/fb8f4b4))
|
||||
* **compiler-cli:** only generate type-check code for referenced DOM elements ([#38418](https://github.com/angular/angular/issues/38418)) ([f42e6ce](https://github.com/angular/angular/commit/f42e6ce))
|
||||
* **forms:** use internal `ngDevMode` flag to tree-shake error messages in prod builds ([#37821](https://github.com/angular/angular/issues/37821)) ([201a546](https://github.com/angular/angular/commit/201a546)), closes [#37697](https://github.com/angular/angular/issues/37697)
|
||||
* **ngcc:** shortcircuit tokenizing in ESM dependency host ([#37639](https://github.com/angular/angular/issues/37639)) ([bd7f440](https://github.com/angular/angular/commit/bd7f440))
|
||||
* **ngcc:** use `EntryPointManifest` to speed up noop `ProgramBaseEntryPointFinder` ([#37665](https://github.com/angular/angular/issues/37665)) ([9318e23](https://github.com/angular/angular/commit/9318e23))
|
||||
* **router:** apply prioritizedGuardValue operator to optimize CanLoad guards ([#37523](https://github.com/angular/angular/issues/37523)) ([d7dd295](https://github.com/angular/angular/commit/d7dd295))
|
||||
|
||||
|
||||
|
||||
<a name="10.0.14"></a>
|
||||
## 10.0.14 (2020-08-26)
|
||||
|
||||
|
||||
<a name="10.0.12"></a>
|
||||
## 10.0.12 (2020-08-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler-cli:** adding references to const enums in runtime code ([#38542](https://github.com/angular/angular/issues/38542)) ([814b436](https://github.com/angular/angular/commit/814b436)), closes [#38513](https://github.com/angular/angular/issues/38513)
|
||||
* **core:** remove closing body tag from inert DOM builder ([#38454](https://github.com/angular/angular/issues/38454)) ([5528536](https://github.com/angular/angular/commit/5528536))
|
||||
* **localize:** include the last placeholder in parsed translation text ([#38452](https://github.com/angular/angular/issues/38452)) ([57d1a48](https://github.com/angular/angular/commit/57d1a48))
|
||||
* **localize:** parse all parts of a translation with nested HTML ([#38452](https://github.com/angular/angular/issues/38452)) ([07b99f5](https://github.com/angular/angular/commit/07b99f5)), closes [#38422](https://github.com/angular/angular/issues/38422)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **language-service:** introduce hybrid visitor to locate AST node ([#38540](https://github.com/angular/angular/issues/38540)) ([66d8c22](https://github.com/angular/angular/commit/66d8c22))
|
||||
|
||||
|
||||
<a name="10.0.11"></a>
|
||||
## 10.0.11 (2020-08-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **router:** ensure routerLinkActive updates when associated routerLinks change (resubmit of [#38349](https://github.com/angular/angular/issues/38349)) ([#38511](https://github.com/angular/angular/issues/38511)) ([0af9533](https://github.com/angular/angular/commit/0af9533)), closes [#18469](https://github.com/angular/angular/issues/18469)
|
||||
|
||||
|
||||
|
||||
<a name="10.0.10"></a>
|
||||
## 10.0.10 (2020-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** Allow scrolling when browser supports scrollTo ([#38468](https://github.com/angular/angular/issues/38468)) ([b32126c](https://github.com/angular/angular/commit/b32126c)), closes [#30630](https://github.com/angular/angular/issues/30630)
|
||||
* **core:** detect DI parameters in JIT mode for downleveled ES2015 classes ([#38500](https://github.com/angular/angular/issues/38500)) ([863acb6](https://github.com/angular/angular/commit/863acb6)), closes [#38453](https://github.com/angular/angular/issues/38453)
|
||||
* **core:** error if CSS custom property in host binding has number in name ([#38432](https://github.com/angular/angular/issues/38432)) ([cb83b8a](https://github.com/angular/angular/commit/cb83b8a)), closes [#37292](https://github.com/angular/angular/issues/37292)
|
||||
* **core:** fix multiple nested views removal from ViewContainerRef ([#38317](https://github.com/angular/angular/issues/38317)) ([d5e09f4](https://github.com/angular/angular/commit/d5e09f4)), closes [#38201](https://github.com/angular/angular/issues/38201)
|
||||
* **ngcc:** detect synthesized delegate constructors for downleveled ES2015 classes ([#38500](https://github.com/angular/angular/issues/38500)) ([f3dd6c2](https://github.com/angular/angular/commit/f3dd6c2)), closes [#38453](https://github.com/angular/angular/issues/38453) [#38453](https://github.com/angular/angular/issues/38453)
|
||||
* **router:** ensure routerLinkActive updates when associated routerLinks change ([#38349](https://github.com/angular/angular/issues/38349)) ([989e8a1](https://github.com/angular/angular/commit/989e8a1)), closes [#18469](https://github.com/angular/angular/issues/18469)
|
||||
|
||||
|
||||
|
||||
<a name="10.0.9"></a>
|
||||
## 10.0.9 (2020-08-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** ensure scrollRestoration is writable ([#30630](https://github.com/angular/angular/issues/30630)) ([#38357](https://github.com/angular/angular/issues/38357)) ([58f4b3a](https://github.com/angular/angular/commit/58f4b3a)), closes [#30629](https://github.com/angular/angular/issues/30629)
|
||||
* **compiler:** evaluate safe navigation expressions in correct binding order ([#37911](https://github.com/angular/angular/issues/37911)) ([f5b9d87](https://github.com/angular/angular/commit/f5b9d87)), closes [#37194](https://github.com/angular/angular/issues/37194)
|
||||
* **compiler-cli:** avoid creating value expressions for symbols from type-only imports ([#38415](https://github.com/angular/angular/issues/38415)) ([ca2b4bc](https://github.com/angular/angular/commit/ca2b4bc)), closes [#37912](https://github.com/angular/angular/issues/37912)
|
||||
* **compiler-cli:** infer quote expressions as any type in type checker ([#37917](https://github.com/angular/angular/issues/37917)) ([5b87c67](https://github.com/angular/angular/commit/5b87c67)), closes [#36568](https://github.com/angular/angular/issues/36568)
|
||||
* **compiler-cli:** mark eager `NgModuleFactory` construction as not side effectful ([#38320](https://github.com/angular/angular/issues/38320)) ([016a41b](https://github.com/angular/angular/commit/016a41b)), closes [#38147](https://github.com/angular/angular/issues/38147)
|
||||
* **compiler-cli:** match wrapHost parameter types within plugin interface ([#38004](https://github.com/angular/angular/issues/38004)) ([df01a82](https://github.com/angular/angular/commit/df01a82))
|
||||
* **compiler-cli:** preserve quotes in class member names ([#38387](https://github.com/angular/angular/issues/38387)) ([c9acb7b](https://github.com/angular/angular/commit/c9acb7b)), closes [#38311](https://github.com/angular/angular/issues/38311)
|
||||
* **core:** prevent NgModule scope being overwritten in JIT compiler ([#37795](https://github.com/angular/angular/issues/37795)) ([3acebdc](https://github.com/angular/angular/commit/3acebdc)), closes [#37105](https://github.com/angular/angular/issues/37105)
|
||||
* **core:** queries not matching string injection tokens ([#38321](https://github.com/angular/angular/issues/38321)) ([32109dc](https://github.com/angular/angular/commit/32109dc)), closes [#38313](https://github.com/angular/angular/issues/38313) [#38315](https://github.com/angular/angular/issues/38315)
|
||||
* **core:** Store the currently selected ICU in `LView` ([#38345](https://github.com/angular/angular/issues/38345)) ([ee5123f](https://github.com/angular/angular/commit/ee5123f))
|
||||
* **platform-server:** remove styles added by ServerStylesHost on destruction ([#38367](https://github.com/angular/angular/issues/38367)) ([7f11149](https://github.com/angular/angular/commit/7f11149))
|
||||
* **router:** prevent calling unsubscribe on undefined subscription in RouterPreloader ([#38344](https://github.com/angular/angular/issues/38344)) ([4151314](https://github.com/angular/angular/commit/4151314))
|
||||
* **service-worker:** fix the chrome debugger syntax highlighter ([#38332](https://github.com/angular/angular/issues/38332)) ([f5d5bac](https://github.com/angular/angular/commit/f5d5bac))
|
||||
|
||||
|
||||
<a name="10.0.8"></a>
|
||||
## 10.0.8 (2020-08-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** add PURE annotation to getInheritedFactory calls ([#38291](https://github.com/angular/angular/issues/38291)) ([03d8e31](https://github.com/angular/angular/commit/03d8e31))
|
||||
* **compiler:** update unparsable character reference entity error messages ([#38319](https://github.com/angular/angular/issues/38319)) ([cea4678](https://github.com/angular/angular/commit/cea4678)), closes [#26067](https://github.com/angular/angular/issues/26067)
|
||||
|
||||
|
||||
|
||||
<a name="10.0.7"></a>
|
||||
## 10.0.7 (2020-07-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** Metadata should not include methods on Object.prototype ([#38292](https://github.com/angular/angular/issues/38292)) ([879ff08](https://github.com/angular/angular/commit/879ff08))
|
||||
|
||||
|
||||
|
||||
<a name="10.0.6"></a>
|
||||
## 10.0.6 (2020-07-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** share identical stylesheets between components in the same file ([#38213](https://github.com/angular/angular/issues/38213)) ([264950b](https://github.com/angular/angular/commit/264950b)), closes [#38204](https://github.com/angular/angular/issues/38204)
|
||||
* **compiler-cli:** Add support for string literal class members ([#38226](https://github.com/angular/angular/issues/38226)) ([b1e7775](https://github.com/angular/angular/commit/b1e7775))
|
||||
* **core:** `Attribute` decorator `attributeName` is mandatory ([#38131](https://github.com/angular/angular/issues/38131)) ([1c4fcce](https://github.com/angular/angular/commit/1c4fcce)), closes [#32658](https://github.com/angular/angular/issues/32658)
|
||||
* **core:** unify the signature between ngZone and noopZone ([#37581](https://github.com/angular/angular/issues/37581)) ([d5264f5](https://github.com/angular/angular/commit/d5264f5))
|
||||
|
||||
|
||||
|
||||
<a name="10.0.5"></a>
|
||||
## 10.0.5 (2020-07-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** properly associate source spans for implicitly closed elements ([#38126](https://github.com/angular/angular/issues/38126)) ([e80278c](https://github.com/angular/angular/commit/e80278c)), closes [#36118](https://github.com/angular/angular/issues/36118)
|
||||
* **compiler-cli:** ensure file_system handles mixed Windows drives ([#38030](https://github.com/angular/angular/issues/38030)) ([dba4023](https://github.com/angular/angular/commit/dba4023)), closes [#36777](https://github.com/angular/angular/issues/36777)
|
||||
* **core:** Allow modification of lifecycle hooks any time before bootstrap ([#38119](https://github.com/angular/angular/issues/38119)) ([14b4718](https://github.com/angular/angular/commit/14b4718)), closes [#30497](https://github.com/angular/angular/issues/30497)
|
||||
* **core:** error due to integer overflow when there are too many host bindings ([#38014](https://github.com/angular/angular/issues/38014)) ([7b6e73c](https://github.com/angular/angular/commit/7b6e73c)), closes [#37876](https://github.com/angular/angular/issues/37876) [#37876](https://github.com/angular/angular/issues/37876)
|
||||
* **core:** incorrectly validating properties on ng-content and ng-container ([#37773](https://github.com/angular/angular/issues/37773)) ([17ddab9](https://github.com/angular/angular/commit/17ddab9))
|
||||
|
||||
|
||||
|
||||
<a name="10.0.4"></a>
|
||||
## 10.0.4 (2020-07-15)
|
||||
|
||||
@ -491,6 +18,62 @@ event.
|
||||
* **bazel:** provide LinkablePackageInfo from ng_module ([#37778](https://github.com/angular/angular/issues/37778)) ([6cd10a1](https://github.com/angular/angular/commit/6cd10a1)), closes [/github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl#L144-L146](https://github.com//github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl/issues/L144-L146)
|
||||
|
||||
|
||||
<a name="10.1.0-next.1"></a>
|
||||
# 10.1.0-next.1 (2020-07-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** ng_module rule does not expose flat module information in Ivy ([#36971](https://github.com/angular/angular/issues/36971)) ([1550663](https://github.com/angular/angular/commit/1550663))
|
||||
* **compiler:** check more cases for pipe usage inside host bindings ([#37883](https://github.com/angular/angular/issues/37883)) ([9322b9a](https://github.com/angular/angular/commit/9322b9a)), closes [#34655](https://github.com/angular/angular/issues/34655) [#37610](https://github.com/angular/angular/issues/37610)
|
||||
* **compiler-cli:** ensure file_system handles mixed Windows drives ([#37959](https://github.com/angular/angular/issues/37959)) ([6b31155](https://github.com/angular/angular/commit/6b31155)), closes [#36777](https://github.com/angular/angular/issues/36777)
|
||||
* **language-service:** remove completion for string ([#37983](https://github.com/angular/angular/issues/37983)) ([10aba15](https://github.com/angular/angular/commit/10aba15))
|
||||
* **ngcc:** report a warning if ngcc tries to use a solution-style tsconfig ([#38003](https://github.com/angular/angular/issues/38003)) ([b358495](https://github.com/angular/angular/commit/b358495)), closes [#36386](https://github.com/angular/angular/issues/36386)
|
||||
* **router:** ensure duplicate popstate/hashchange events are handled correctly ([#37674](https://github.com/angular/angular/issues/37674)) ([9185c6e](https://github.com/angular/angular/commit/9185c6e)), closes [/github.com/angular/angular/issues/16710#issuecomment-646919529](https://github.com//github.com/angular/angular/issues/16710/issues/issuecomment-646919529) [#16710](https://github.com/angular/angular/issues/16710)
|
||||
* **service-worker:** correctly handle relative base href ([#37922](https://github.com/angular/angular/issues/37922)) ([d19ef65](https://github.com/angular/angular/commit/d19ef65)), closes [#25055](https://github.com/angular/angular/issues/25055) [#25055](https://github.com/angular/angular/issues/25055)
|
||||
* **service-worker:** correctly serve `ngsw/state` with a non-root SW scope ([#37922](https://github.com/angular/angular/issues/37922)) ([2156bee](https://github.com/angular/angular/commit/2156bee)), closes [#30505](https://github.com/angular/angular/issues/30505)
|
||||
|
||||
|
||||
|
||||
<a name="10.1.0-next.0"></a>
|
||||
# 10.1.0-next.0 (2020-07-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** date pipe gives wrong week number ([#37632](https://github.com/angular/angular/issues/37632)) ([ef1fb6d](https://github.com/angular/angular/commit/ef1fb6d)), closes [#33961](https://github.com/angular/angular/issues/33961)
|
||||
* **compiler-cli:** ensure source-maps can handle webpack:// protocol ([#32912](https://github.com/angular/angular/issues/32912)) ([decd95e](https://github.com/angular/angular/commit/decd95e))
|
||||
* **compiler-cli:** only read source-map comment from last line ([#32912](https://github.com/angular/angular/issues/32912)) ([07a07e3](https://github.com/angular/angular/commit/07a07e3))
|
||||
* **core:** determine required DOMParser feature availability ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([c509243](https://github.com/angular/angular/commit/c509243))
|
||||
* **core:** do not trigger CSP alert/report in Firefox and Chrome ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([b950d46](https://github.com/angular/angular/commit/b950d46)), closes [#25214](https://github.com/angular/angular/issues/25214)
|
||||
* **forms:** handle form groups/arrays own pending async validation ([#22575](https://github.com/angular/angular/issues/22575)) ([77b62a5](https://github.com/angular/angular/commit/77b62a5)), closes [#10064](https://github.com/angular/angular/issues/10064)
|
||||
* **language-service:** non-existent module format in package output ([#37623](https://github.com/angular/angular/issues/37623)) ([413a0fb](https://github.com/angular/angular/commit/413a0fb))
|
||||
* **router:** fix navigation ignoring logic to compare to the browser url ([#37716](https://github.com/angular/angular/issues/37716)) ([a5ffca0](https://github.com/angular/angular/commit/a5ffca0)), closes [#16710](https://github.com/angular/angular/issues/16710) [#13586](https://github.com/angular/angular/issues/13586)
|
||||
* **router:** properly compare array queryParams for equality ([#37709](https://github.com/angular/angular/issues/37709)) ([#37860](https://github.com/angular/angular/issues/37860)) ([1801d0c](https://github.com/angular/angular/commit/1801d0c))
|
||||
* **router:** remove parenthesis for primary outlet segment after removing auxiliary outlet segment ([#24656](https://github.com/angular/angular/issues/24656)) ([#37163](https://github.com/angular/angular/issues/37163)) ([71f008f](https://github.com/angular/angular/commit/71f008f))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bazel:** provide LinkablePackageInfo from ng_module ([#37623](https://github.com/angular/angular/issues/37623)) ([6898eab](https://github.com/angular/angular/commit/6898eab))
|
||||
* **compiler-cli:** add `SourceFile.getOriginalLocation()` to sourcemaps package ([#32912](https://github.com/angular/angular/issues/32912)) ([6abb8d0](https://github.com/angular/angular/commit/6abb8d0))
|
||||
* **compiler-cli:** explain why an expression cannot be used in AOT compilations ([#37587](https://github.com/angular/angular/issues/37587)) ([712f1bd](https://github.com/angular/angular/commit/712f1bd))
|
||||
* **core:** support injection token as predicate in queries ([#37506](https://github.com/angular/angular/issues/37506)) ([97dc85b](https://github.com/angular/angular/commit/97dc85b)), closes [#21152](https://github.com/angular/angular/issues/21152) [#36144](https://github.com/angular/angular/issues/36144)
|
||||
* **localize:** expose `canParse()` diagnostics ([#37909](https://github.com/angular/angular/issues/37909)) ([ec32eba](https://github.com/angular/angular/commit/ec32eba)), closes [#37901](https://github.com/angular/angular/issues/37901)
|
||||
* **localize:** implement message extraction tool ([#32912](https://github.com/angular/angular/issues/32912)) ([190561d](https://github.com/angular/angular/commit/190561d))
|
||||
* **platform-browser:** Allow `sms`-URLs ([#31463](https://github.com/angular/angular/issues/31463)) ([fc5c34d](https://github.com/angular/angular/commit/fc5c34d)), closes [#31462](https://github.com/angular/angular/issues/31462)
|
||||
* **platform-server:** add option for absolute URL HTTP support ([#37539](https://github.com/angular/angular/issues/37539)) ([d37049a](https://github.com/angular/angular/commit/d37049a)), closes [#37071](https://github.com/angular/angular/issues/37071)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **compiler-cli:** fix regressions in incremental program reuse ([#37641](https://github.com/angular/angular/issues/37641)) ([5103d90](https://github.com/angular/angular/commit/5103d90))
|
||||
* **ngcc:** shortcircuit tokenizing in ESM dependency host ([#37639](https://github.com/angular/angular/issues/37639)) ([bd7f440](https://github.com/angular/angular/commit/bd7f440))
|
||||
* **ngcc:** use `EntryPointManifest` to speed up noop `ProgramBaseEntryPointFinder` ([#37665](https://github.com/angular/angular/issues/37665)) ([9318e23](https://github.com/angular/angular/commit/9318e23))
|
||||
* **router:** apply prioritizedGuardValue operator to optimize CanLoad guards ([#37523](https://github.com/angular/angular/issues/37523)) ([d7dd295](https://github.com/angular/angular/commit/d7dd295))
|
||||
|
||||
|
||||
|
||||
<a name="10.0.3"></a>
|
||||
## 10.0.3 (2020-07-08)
|
||||
|
||||
@ -772,12 +355,12 @@ https://github.com/microsoft/TypeScript/issues/38374 for more
|
||||
information and updates.
|
||||
|
||||
If you used Closure Compiler with Angular in the past, you will likely
|
||||
be better off consuming Angular packages built from sources directly
|
||||
be better off consuming Angular packages built from sources directly
|
||||
rather than consuming the version we publish on npm,
|
||||
which is primarily optimized for Webpack/Rollup + Terser build pipeline.
|
||||
|
||||
As a temporary workaround, you might consider using your current build
|
||||
pipeline with Closure flag `--compilation_level=SIMPLE`. This flag
|
||||
pipeline with Closure flag `--compilation_level=SIMPLE`. This flag
|
||||
will ensure that your build pipeline produces buildable and
|
||||
runnable artifacts, at the cost of increased payload size due to
|
||||
advanced optimizations being disabled.
|
||||
@ -785,17 +368,17 @@ advanced optimizations being disabled.
|
||||
If you were affected by this change, please help us understand your
|
||||
needs by leaving a comment on https://github.com/angular/angular/issues/37234.
|
||||
|
||||
* **core:** make generic mandatory for ModuleWithProviders
|
||||
* **core:** make generic mandatory for ModuleWithProviders
|
||||
|
||||
A generic type parameter has always been required for the `ModuleWithProviders` pattern to work with Ivy, but prior to this commit, View Engine allowed the generic type to be omitted (though support was officially deprecated).
|
||||
If you're using `ModuleWithProviders` without a generic type in your application code, a v10 migration will update your code for you.
|
||||
If you're using `ModuleWithProviders` without a generic type in your application code, a v10 migration will update your code for you.
|
||||
|
||||
However, if you are using View Engine and also depending on a library that omits the generic type, you will now get a build time error similar to:
|
||||
|
||||
```
|
||||
error TS2314: Generic type 'ModuleWithProviders<T>' requires 1 type argument(s).
|
||||
```
|
||||
|
||||
|
||||
In this case, ngcc won't help you (because it's Ivy-only) and the migration only covers application code.
|
||||
You should contact the library author to fix their library to provide a type parameter when they use this class.
|
||||
|
||||
@ -2123,7 +1706,7 @@ API surface going forward.
|
||||
* **core:** Injector.get now accepts abstract classes to return
|
||||
type-safe values. Previous implementation returned `any` through the
|
||||
deprecated implementation.
|
||||
* Angular now compiles with Ivy by default ([#32219](https://github.com/angular/angular/issues/32219)) ([ec4381d](https://github.com/angular/angular/commit/ec4381d)).
|
||||
* Angular now compiles with Ivy by default ([#32219](https://github.com/angular/angular/issues/32219)) ([ec4381d](https://github.com/angular/angular/commit/ec4381d)).
|
||||
|
||||
If you aren't familiar with Ivy, read our [blog post about the Ivy preview](https://blog.angular.io/its-time-for-the-compatibility-opt-in-preview-of-ivy-38f3542a282f?gi=8bfeb44b05c) and see the list of changes [here](https://docs.google.com/document/d/1Dije0AsJ0PxL3NaeNPxpYDeapj30b_QC0xfeIvIIzgg/preview).
|
||||
|
||||
|
@ -209,9 +209,9 @@ Any line of the commit message cannot be longer than 100 characters.
|
||||
│ │
|
||||
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
│ elements|forms|http|language-service|localize|platform-browser|
|
||||
│ platform-browser-dynamic|platform-server|router|service-worker|
|
||||
│ upgrade|zone.js|packaging|changelog|dev-infra|docs-infra|migrations|
|
||||
│ ngcc|ve
|
||||
│ platform-browser-dynamic|platform-server|platform-webworker|
|
||||
│ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
|
||||
│ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
|
||||
│
|
||||
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
|
||||
```
|
||||
@ -230,6 +230,7 @@ Must be one of the following:
|
||||
* **fix**: A bug fix
|
||||
* **perf**: A code change that improves performance
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
||||
* **test**: Adding missing tests or correcting existing tests
|
||||
|
||||
|
||||
@ -253,6 +254,8 @@ The following is the list of supported scopes:
|
||||
* `platform-browser`
|
||||
* `platform-browser-dynamic`
|
||||
* `platform-server`
|
||||
* `platform-webworker`
|
||||
* `platform-webworker-dynamic`
|
||||
* `router`
|
||||
* `service-worker`
|
||||
* `upgrade`
|
||||
|
21
README.md
21
README.md
@ -5,22 +5,21 @@
|
||||
|
||||
# Angular
|
||||
|
||||
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.
|
||||
Angular es una plataforma de desarrollo para construir aplicaciones web y móviles que usa TypeScript/JavaScript y otros lenguajes de programación.
|
||||
|
||||
## Quickstart
|
||||
## Guía rápida
|
||||
|
||||
[Get started in 5 minutes][quickstart].
|
||||
[Comienza a usarlo en 5 minutos][quickstart].
|
||||
|
||||
## Changelog
|
||||
## Registro de cambios (Changelog)
|
||||
|
||||
[Learn about the latest improvements][changelog].
|
||||
[Últimas mejoras realizadas][changelog].
|
||||
|
||||
## Want to help?
|
||||
## ¿Quieres ayudar?
|
||||
|
||||
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
|
||||
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
|
||||
¿Quieres encontrar fallos, colaborar con código, o mejorar la documentación? ¡Excelente! Lee nuestras
|
||||
pautas para [colaborar][contributing] y luego revisa algunos de nuestras incidencias (issues) en [ayuda comunitaria](https://github.com/angular-hispano/angular/labels/ayuda%20comunitaria).
|
||||
|
||||
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md
|
||||
[quickstart]: https://angular.io/start
|
||||
[contributing]: https://github.com/angular-hispano/angular/blob/master/CONTRIBUTING.md
|
||||
[quickstart]: https://docs.angular.lat/start
|
||||
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
|
||||
[ng]: https://angular.io
|
||||
|
@ -6,7 +6,6 @@ Everything in this folder is part of the documentation project. This includes
|
||||
* the dgeni configuration for converting source files to rendered files that can be viewed in the web site.
|
||||
* the tooling for setting up examples for development; and generating live-example and zip files from the examples.
|
||||
|
||||
<a name="developer-tasks"></a>
|
||||
## Developer tasks
|
||||
|
||||
We use [Yarn](https://yarnpkg.com) to manage the dependencies and to run build tasks.
|
||||
|
@ -16,6 +16,13 @@ import {BuildNums, PrNums, SHA} from './constants';
|
||||
|
||||
const logger = new Logger('mock-external-apis');
|
||||
|
||||
const log = (...args: any[]) => {
|
||||
// Filter out non-matching URL checks
|
||||
if (!/^matching.+: false$/.test(args[0])) {
|
||||
logger.log(...args);
|
||||
}
|
||||
};
|
||||
|
||||
const AIO_CIRCLE_CI_TOKEN = getEnvVar('AIO_CIRCLE_CI_TOKEN');
|
||||
const AIO_GITHUB_TOKEN = getEnvVar('AIO_GITHUB_TOKEN');
|
||||
|
||||
@ -84,8 +91,8 @@ const createArchive = (buildNum: number, prNum: number, sha: string) => {
|
||||
};
|
||||
|
||||
// Create request scopes
|
||||
const circleCiApi = nock(CIRCLE_CI_API_HOST).persist();
|
||||
const githubApi = nock(GITHUB_API_HOST).persist().matchHeader('Authorization', `token ${AIO_GITHUB_TOKEN}`);
|
||||
const circleCiApi = nock(CIRCLE_CI_API_HOST).log(log).persist();
|
||||
const githubApi = nock(GITHUB_API_HOST).log(log).persist().matchHeader('Authorization', `token ${AIO_GITHUB_TOKEN}`);
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
|
@ -27,28 +27,28 @@
|
||||
"body-parser": "^1.19.0",
|
||||
"delete-empty": "^3.0.0",
|
||||
"express": "^4.17.1",
|
||||
"jasmine": "^3.6.1",
|
||||
"nock": "^13.0.4",
|
||||
"node-fetch": "^2.6.1",
|
||||
"jasmine": "^3.5.0",
|
||||
"nock": "^12.0.3",
|
||||
"node-fetch": "^2.6.0",
|
||||
"shelljs": "^0.8.4",
|
||||
"source-map-support": "^0.5.19",
|
||||
"tar-stream": "^2.1.3",
|
||||
"tslib": "^2.0.1"
|
||||
"tar-stream": "^2.1.2",
|
||||
"tslib": "^1.11.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/body-parser": "^1.19.0",
|
||||
"@types/express": "^4.17.8",
|
||||
"@types/jasmine": "^3.5.14",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/jasmine": "^3.5.10",
|
||||
"@types/nock": "^11.1.0",
|
||||
"@types/node": "^14.6.4",
|
||||
"@types/node": "^13.13.2",
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@types/shelljs": "^0.8.8",
|
||||
"@types/supertest": "^2.0.10",
|
||||
"nodemon": "^2.0.4",
|
||||
"@types/shelljs": "^0.8.7",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"nodemon": "^2.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"supertest": "^4.0.2",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint": "^6.1.1",
|
||||
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
||||
"typescript": "^4.0.2"
|
||||
"typescript": "^3.8.3"
|
||||
}
|
||||
}
|
||||
|
@ -214,24 +214,23 @@ describe('GithubApi', () => {
|
||||
});
|
||||
|
||||
|
||||
it('should call \'https.request()\' with the correct options', async () => {
|
||||
it('should call \'https.request()\' with the correct options', () => {
|
||||
const requestHandler = nock('https://api.github.com')
|
||||
.intercept('/path', 'method')
|
||||
.reply(200);
|
||||
|
||||
await (api as any).request('method', '/path');
|
||||
(api as any).request('method', '/path');
|
||||
requestHandler.done();
|
||||
});
|
||||
|
||||
|
||||
it('should add the \'Authorization\' header containing the \'githubToken\'', async () => {
|
||||
it('should add the \'Authorization\' header containing the \'githubToken\'', () => {
|
||||
const requestHandler = nock('https://api.github.com')
|
||||
.intercept('/path', 'method', undefined, {
|
||||
reqheaders: {Authorization: 'token 12345'},
|
||||
})
|
||||
.reply(200);
|
||||
|
||||
await (api as any).request('method', '/path');
|
||||
(api as any).request('method', '/path');
|
||||
requestHandler.done();
|
||||
});
|
||||
|
||||
@ -245,13 +244,12 @@ describe('GithubApi', () => {
|
||||
});
|
||||
|
||||
|
||||
it('should \'JSON.stringify\' and send the data along with the request', async () => {
|
||||
it('should \'JSON.stringify\' and send the data along with the request', () => {
|
||||
const data = {key: 'value'};
|
||||
const requestHandler = nock('https://api.github.com')
|
||||
.intercept('/path', 'method', JSON.stringify(data))
|
||||
.reply(200);
|
||||
|
||||
await (api as any).request('method', '/path', data);
|
||||
(api as any).request('method', '/path', data);
|
||||
requestHandler.done();
|
||||
});
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ you don't need to specify values for those.
|
||||
The domain name of the server.
|
||||
|
||||
- `AIO_GITHUB_ORGANIZATION`:
|
||||
The GitHub organization whose teams are trusted for accepting build artifacts.
|
||||
The GitHub organization whose teams are whitelisted for accepting build artifacts.
|
||||
See also `AIO_GITHUB_TEAM_SLUGS`.
|
||||
|
||||
- `AIO_GITHUB_REPO`:
|
||||
|
@ -98,7 +98,7 @@ This section describes how each of the aforementioned sub-tasks is accomplished:
|
||||
Such a label can only have been added by a maintainer (with the necessary rights) and
|
||||
designates that they have manually verified the PR contents.
|
||||
2. We can verify (again using the GitHub API) the author's membership in one of the
|
||||
trusted GitHub teams. For this operation, we need a Personal Access Token with the
|
||||
whitelisted/trusted GitHub teams. For this operation, we need a Personal Access Token with the
|
||||
`read:org` scope issued by a user that can "see" the specified GitHub organization.
|
||||
Here too, we use the token by @mary-poppins.
|
||||
|
||||
|
3
aio/content/examples/.gitignore
vendored
3
aio/content/examples/.gitignore
vendored
@ -17,9 +17,7 @@
|
||||
**/e2e/tsconfig.e2e.json
|
||||
**/src/karma.conf.js
|
||||
**/.angular-cli.json
|
||||
**/.browserslistrc
|
||||
**/.editorconfig
|
||||
**/.gitignore
|
||||
**/angular.json
|
||||
**/tsconfig.json
|
||||
**/bs-config.e2e.json
|
||||
@ -31,6 +29,7 @@
|
||||
**/tslint.json
|
||||
**/karma-test-shim.js
|
||||
**/browser-test-shim.js
|
||||
**/browserslist
|
||||
**/node_modules
|
||||
|
||||
# built files
|
||||
|
@ -1,3 +1,5 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Accessibility example e2e tests', () => {
|
||||
@ -6,11 +8,11 @@ describe('Accessibility example e2e tests', () => {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should display Accessibility Example', () => {
|
||||
it('should display Accessibility Example', function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual('Accessibility Example');
|
||||
});
|
||||
|
||||
it('should take a number and change progressbar width', () => {
|
||||
it('should take a number and change progressbar width', function () {
|
||||
element(by.css('input')).sendKeys('16');
|
||||
expect(element(by.css('input')).getAttribute('value')).toEqual('016');
|
||||
expect(element(by.css('app-example-progressbar div')).getCssValue('width')).toBe('48px');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// tslint:disable: no-host-metadata-property
|
||||
// #docregion progressbar-component
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
|
@ -1,18 +1,20 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('AngularJS to Angular Quick Reference Tests', () => {
|
||||
describe('AngularJS to Angular Quick Reference Tests', function () {
|
||||
|
||||
beforeAll(() => {
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should display no poster images after bootstrap', () => {
|
||||
it('should display no poster images after bootstrap', function () {
|
||||
testImagesAreDisplayed(false);
|
||||
});
|
||||
|
||||
it('should display proper movie data', () => {
|
||||
it('should display proper movie data', function () {
|
||||
// We check only a few samples
|
||||
const expectedSamples: any[] = [
|
||||
let expectedSamples: any[] = [
|
||||
{row: 0, column: 0, element: 'img', attr: 'src', value: 'images/hero.png', contains: true},
|
||||
{row: 0, column: 2, value: 'Celeritas'},
|
||||
{row: 1, column: 3, matches: /Dec 1[678], 2015/}, // absorb timezone dif; we care about date format
|
||||
@ -23,17 +25,18 @@ describe('AngularJS to Angular Quick Reference Tests', () => {
|
||||
];
|
||||
|
||||
// Go through the samples
|
||||
const movieRows = getMovieRows();
|
||||
for (const sample of expectedSamples) {
|
||||
const tableCell = movieRows.get(sample.row)
|
||||
let movieRows = getMovieRows();
|
||||
for (let i = 0; i < expectedSamples.length; i++) {
|
||||
let sample = expectedSamples[i];
|
||||
let tableCell = movieRows.get(sample.row)
|
||||
.all(by.tagName('td')).get(sample.column);
|
||||
// Check the cell or its nested element
|
||||
const elementToCheck = sample.element
|
||||
let elementToCheck = sample.element
|
||||
? tableCell.element(by.tagName(sample.element))
|
||||
: tableCell;
|
||||
|
||||
// Check element attribute or text
|
||||
const valueToCheck = sample.attr
|
||||
let valueToCheck = sample.attr
|
||||
? elementToCheck.getAttribute(sample.attr)
|
||||
: elementToCheck.getText();
|
||||
|
||||
@ -48,42 +51,42 @@ describe('AngularJS to Angular Quick Reference Tests', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should display images after Show Poster', () => {
|
||||
it('should display images after Show Poster', function () {
|
||||
testPosterButtonClick('Show Poster', true);
|
||||
});
|
||||
|
||||
it('should hide images after Hide Poster', () => {
|
||||
it('should hide images after Hide Poster', function () {
|
||||
testPosterButtonClick('Hide Poster', false);
|
||||
});
|
||||
|
||||
it('should display no movie when no favorite hero is specified', () => {
|
||||
it('should display no movie when no favorite hero is specified', function () {
|
||||
testFavoriteHero(null, 'Please enter your favorite hero.');
|
||||
});
|
||||
|
||||
it('should display no movie for Magneta', () => {
|
||||
it('should display no movie for Magneta', function () {
|
||||
testFavoriteHero('Magneta', 'No movie, sorry!');
|
||||
});
|
||||
|
||||
it('should display a movie for Dr Nice', () => {
|
||||
it('should display a movie for Dr Nice', function () {
|
||||
testFavoriteHero('Dr Nice', 'Excellent choice!');
|
||||
});
|
||||
|
||||
function testImagesAreDisplayed(isDisplayed: boolean) {
|
||||
const expectedMovieCount = 3;
|
||||
let expectedMovieCount = 3;
|
||||
|
||||
const movieRows = getMovieRows();
|
||||
let movieRows = getMovieRows();
|
||||
expect(movieRows.count()).toBe(expectedMovieCount);
|
||||
for (let i = 0; i < expectedMovieCount; i++) {
|
||||
const movieImage = movieRows.get(i).element(by.css('td > img'));
|
||||
let movieImage = movieRows.get(i).element(by.css('td > img'));
|
||||
expect(movieImage.isDisplayed()).toBe(isDisplayed);
|
||||
}
|
||||
}
|
||||
|
||||
function testPosterButtonClick(expectedButtonText: string, isDisplayed: boolean) {
|
||||
const posterButton = element(by.css('app-movie-list tr > th > button'));
|
||||
let posterButton = element(by.css('app-movie-list tr > th > button'));
|
||||
expect(posterButton.getText()).toBe(expectedButtonText);
|
||||
|
||||
posterButton.click().then(() => {
|
||||
posterButton.click().then(function () {
|
||||
testImagesAreDisplayed(isDisplayed);
|
||||
});
|
||||
}
|
||||
@ -93,12 +96,12 @@ describe('AngularJS to Angular Quick Reference Tests', () => {
|
||||
}
|
||||
|
||||
function testFavoriteHero(heroName: string, expectedLabel: string) {
|
||||
const movieListComp = element(by.tagName('app-movie-list'));
|
||||
const heroInput = movieListComp.element(by.tagName('input'));
|
||||
const favoriteHeroLabel = movieListComp.element(by.tagName('h3'));
|
||||
const resultLabel = movieListComp.element(by.css('span > p'));
|
||||
let movieListComp = element(by.tagName('app-movie-list'));
|
||||
let heroInput = movieListComp.element(by.tagName('input'));
|
||||
let favoriteHeroLabel = movieListComp.element(by.tagName('h3'));
|
||||
let resultLabel = movieListComp.element(by.css('span > p'));
|
||||
|
||||
heroInput.clear().then(() => {
|
||||
heroInput.clear().then(function () {
|
||||
heroInput.sendKeys(heroName || '');
|
||||
expect(resultLabel.getText()).toBe(expectedLabel);
|
||||
if (heroName) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { MovieListComponent } from './movie-list.component';
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
|
@ -1,9 +1,9 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppComponent } from './app.component';
|
||||
import { MovieListComponent } from './movie-list.component';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, ExpectedConditions as EC } from 'protractor';
|
||||
import { logging } from 'selenium-webdriver';
|
||||
import * as openClose from './open-close.po';
|
||||
|
@ -34,7 +34,7 @@ export class AppComponent {
|
||||
|
||||
// #docregion prepare-router-outlet
|
||||
prepareRoute(outlet: RouterOutlet) {
|
||||
return outlet && outlet.activatedRouteData && outlet.activatedRouteData.animation;
|
||||
return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation'];
|
||||
}
|
||||
|
||||
// #enddocregion prepare-router-outlet
|
||||
|
@ -1,6 +1,4 @@
|
||||
// tslint:disable: variable-name
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Component, HostBinding, OnInit } from '@angular/core';
|
||||
import { trigger, transition, animate, style, query, stagger } from '@angular/animations';
|
||||
import { HEROES } from './mock-heroes';
|
||||
@ -54,11 +52,13 @@ export class HeroListPageComponent implements OnInit {
|
||||
@HostBinding('@pageAnimations')
|
||||
public animatePage = true;
|
||||
|
||||
_heroes = [];
|
||||
// #docregion filter-animations
|
||||
heroTotal = -1;
|
||||
// #enddocregion filter-animations
|
||||
get heroes() { return this._heroes; }
|
||||
private _heroes = [];
|
||||
get heroes() {
|
||||
return this._heroes;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this._heroes = HEROES;
|
||||
|
@ -8,7 +8,8 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
||||
// #docregion trigger, trigger-wildcard1, trigger-transition
|
||||
animations: [
|
||||
trigger('openClose', [
|
||||
// #docregion state1
|
||||
// #enddocregion events1
|
||||
// #docregion state1, events1
|
||||
// ...
|
||||
// #enddocregion events1
|
||||
state('open', style({
|
||||
@ -33,7 +34,8 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
||||
transition('closed => open', [
|
||||
animate('0.5s')
|
||||
]),
|
||||
// #enddocregion transition2, trigger, component
|
||||
// #enddocregion trigger, component
|
||||
// #enddocregion transition2
|
||||
// #docregion trigger-wildcard1
|
||||
transition('* => closed', [
|
||||
animate('1s')
|
||||
@ -68,9 +70,7 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
||||
})
|
||||
// #docregion events
|
||||
export class OpenCloseComponent {
|
||||
// #enddocregion events1, events, component
|
||||
@Input() logging = false;
|
||||
// #docregion component
|
||||
// #enddocregion events1, events
|
||||
isOpen = true;
|
||||
|
||||
toggle() {
|
||||
@ -78,8 +78,9 @@ export class OpenCloseComponent {
|
||||
}
|
||||
|
||||
// #enddocregion component
|
||||
@Input() logging = false;
|
||||
// #docregion events1, events
|
||||
onAnimationEvent( event: AnimationEvent ) {
|
||||
onAnimationEvent ( event: AnimationEvent ) {
|
||||
// #enddocregion events1, events
|
||||
if (!this.logging) {
|
||||
return;
|
||||
|
@ -1,3 +1,5 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { protractor, browser, element, by, ElementFinder } from 'protractor';
|
||||
|
||||
const nameSuffix = 'X';
|
||||
@ -19,7 +21,7 @@ describe('Architecture', () => {
|
||||
});
|
||||
|
||||
it(`has h2 '${expectedH2}'`, () => {
|
||||
const h2 = element.all(by.css('h2')).map((elt: any) => elt.getText());
|
||||
let h2 = element.all(by.css('h2')).map((elt: any) => elt.getText());
|
||||
expect(h2).toEqual(expectedH2);
|
||||
});
|
||||
|
||||
@ -32,42 +34,42 @@ function heroTests() {
|
||||
const targetHero: Hero = { id: 2, name: 'Dr Nice' };
|
||||
|
||||
it('has the right number of heroes', () => {
|
||||
const page = getPageElts();
|
||||
let page = getPageElts();
|
||||
expect(page.heroes.count()).toEqual(3);
|
||||
});
|
||||
|
||||
it('has no hero details initially', () => {
|
||||
const page = getPageElts();
|
||||
it('has no hero details initially', function () {
|
||||
let page = getPageElts();
|
||||
expect(page.heroDetail.isPresent()).toBeFalsy('no hero detail');
|
||||
});
|
||||
|
||||
it('shows selected hero details', async () => {
|
||||
await element(by.cssContainingText('li', targetHero.name)).click();
|
||||
const page = getPageElts();
|
||||
const hero = await heroFromDetail(page.heroDetail);
|
||||
let page = getPageElts();
|
||||
let hero = await heroFromDetail(page.heroDetail);
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(targetHero.name);
|
||||
});
|
||||
|
||||
it(`shows updated hero name in details`, async () => {
|
||||
const input = element.all(by.css('input')).first();
|
||||
let input = element.all(by.css('input')).first();
|
||||
input.sendKeys(nameSuffix);
|
||||
const page = getPageElts();
|
||||
const hero = await heroFromDetail(page.heroDetail);
|
||||
const newName = targetHero.name + nameSuffix;
|
||||
let page = getPageElts();
|
||||
let hero = await heroFromDetail(page.heroDetail);
|
||||
let newName = targetHero.name + nameSuffix;
|
||||
expect(hero.id).toEqual(targetHero.id);
|
||||
expect(hero.name).toEqual(newName);
|
||||
});
|
||||
}
|
||||
|
||||
function salesTaxTests() {
|
||||
it('has no sales tax initially', () => {
|
||||
const page = getPageElts();
|
||||
it('has no sales tax initially', function () {
|
||||
let page = getPageElts();
|
||||
expect(page.salesTaxDetail.isPresent()).toBeFalsy('no sales tax info');
|
||||
});
|
||||
|
||||
it('shows sales tax', async () => {
|
||||
const page = getPageElts();
|
||||
it('shows sales tax', async function () {
|
||||
let page = getPageElts();
|
||||
page.salesTaxAmountInput.sendKeys('10', protractor.Key.ENTER);
|
||||
expect(page.salesTaxDetail.getText()).toEqual('The sales tax is $1.00');
|
||||
});
|
||||
@ -86,11 +88,13 @@ function getPageElts() {
|
||||
|
||||
async function heroFromDetail(detail: ElementFinder): Promise<Hero> {
|
||||
// Get hero id from the first <div>
|
||||
const id = await detail.all(by.css('div')).first().getText();
|
||||
// let _id = await detail.all(by.css('div')).first().getText();
|
||||
let _id = await detail.all(by.css('div')).first().getText();
|
||||
// Get name from the h2
|
||||
const name = await detail.element(by.css('h4')).getText();
|
||||
// let _name = await detail.element(by.css('h4')).getText();
|
||||
let _name = await detail.element(by.css('h4')).getText();
|
||||
return {
|
||||
id: +id.substr(id.indexOf(' ') + 1),
|
||||
name: name.substr(0, name.lastIndexOf(' ')),
|
||||
id: +_id.substr(_id.indexOf(' ') + 1),
|
||||
name: _name.substr(0, _name.lastIndexOf(' '))
|
||||
};
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
// #docregion imports
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AppComponent } from './app.component';
|
||||
// #enddocregion imports
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
import { SalesTaxComponent } from './sales-tax.component';
|
||||
import { HeroService } from './hero.service';
|
||||
import { BackendService } from './backend.service';
|
||||
import { Logger } from './logger.service';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
import { SalesTaxComponent } from './sales-tax.component';
|
||||
import { HeroService } from './hero.service';
|
||||
import { BackendService } from './backend.service';
|
||||
import { Logger } from './logger.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -18,7 +18,7 @@ export class BackendService {
|
||||
// TODO: get from the database
|
||||
return Promise.resolve<Hero[]>(HEROES);
|
||||
}
|
||||
const err = new Error('Cannot get object of this type');
|
||||
let err = new Error('Cannot get object of this type');
|
||||
this.logger.error(err);
|
||||
throw err;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
// #docregion metadata, providers
|
||||
@Component({
|
||||
|
@ -22,7 +22,7 @@ export class AppComponent {
|
||||
}
|
||||
|
||||
// #docregion module
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
// #docregion import-browser-module
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
// #enddocregion import-browser-module
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { SalesTaxService } from './sales-tax.service';
|
||||
import { TaxRateService } from './tax-rate.service';
|
||||
import { TaxRateService } from './tax-rate.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sales-tax',
|
||||
|
@ -7,7 +7,7 @@ export class SalesTaxService {
|
||||
constructor(private rateService: TaxRateService) { }
|
||||
|
||||
getVAT(value: string | number) {
|
||||
const amount = (typeof value === 'string') ?
|
||||
let amount = (typeof value === 'string') ?
|
||||
parseFloat(value) : value;
|
||||
return (amount || 0) * this.rateService.getRate('VAT');
|
||||
}
|
||||
|
@ -1,32 +1,34 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Attribute binding example', () => {
|
||||
describe('Attribute binding example', function () {
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should display Property Binding with Angular', () => {
|
||||
it('should display Property Binding with Angular', function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual('Attribute, class, and style bindings');
|
||||
});
|
||||
|
||||
it('should display a table', () => {
|
||||
it('should display a table', function() {
|
||||
expect(element.all(by.css('table')).isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
it('should display an Aria button', () => {
|
||||
it('should display an Aria button', function () {
|
||||
expect(element.all(by.css('button')).get(0).getText()).toBe('Go for it with Aria');
|
||||
});
|
||||
|
||||
it('should display a blue background on div', () => {
|
||||
it('should display a blue background on div', function () {
|
||||
expect(element.all(by.css('div')).get(1).getCssValue('background-color')).toEqual('rgba(25, 118, 210, 1)');
|
||||
});
|
||||
|
||||
it('should display a blue div with a red border', () => {
|
||||
it('should display a blue div with a red border', function () {
|
||||
expect(element.all(by.css('div')).get(1).getCssValue('border')).toEqual('2px solid rgb(212, 30, 46)');
|
||||
});
|
||||
|
||||
it('should display a div with many classes', () => {
|
||||
it('should display a div with many classes', function () {
|
||||
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('special');
|
||||
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('clearance');
|
||||
});
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Component, HostBinding } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'comp-with-host-binding',
|
||||
template: 'I am a component!',
|
||||
host: {
|
||||
'[class.special]': 'isSpecial',
|
||||
'[style.color]': 'color',
|
||||
'[style.width]': 'width'
|
||||
}
|
||||
})
|
||||
export class CompWithHostBindingComponent {
|
||||
@HostBinding('class.special')
|
||||
isSpecial = false;
|
||||
|
||||
@HostBinding('style.color')
|
||||
color = 'green';
|
||||
|
||||
@HostBinding('style.width')
|
||||
width = '200px';
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Attribute directives', () => {
|
||||
|
||||
const title = 'My First Attribute Directive';
|
||||
let _title = 'My First Attribute Directive';
|
||||
|
||||
beforeAll(() => {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it(`should display correct title: ${title}`, () => {
|
||||
expect(element(by.css('h1')).getText()).toEqual(title);
|
||||
it(`should display correct title: ${_title}`, () => {
|
||||
expect(element(by.css('h1')).getText()).toEqual(_title);
|
||||
});
|
||||
|
||||
it('should be able to select green highlight', () => {
|
||||
|
@ -3,7 +3,7 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component.1';
|
||||
import { AppComponent } from './app.component.1';
|
||||
import { HighlightDirective as HLD1 } from './highlight.directive.1';
|
||||
import { HighlightDirective as HLD2 } from './highlight.directive.2';
|
||||
import { HighlightDirective as HLD3 } from './highlight.directive.3';
|
||||
|
@ -3,55 +3,57 @@ import { logging } from 'selenium-webdriver';
|
||||
|
||||
describe('Binding syntax e2e tests', () => {
|
||||
|
||||
beforeEach(() => browser.get(''));
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
|
||||
// helper function used to test what's logged to the console
|
||||
async function logChecker(button, contents) {
|
||||
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
||||
const messages = logs.filter(({ message }) => message.indexOf(contents) !== -1 ? true : false);
|
||||
expect(messages.length).toBeGreaterThan(0);
|
||||
}
|
||||
// helper function used to test what's logged to the console
|
||||
async function logChecker(button, contents) {
|
||||
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
||||
const message = logs.filter(({ message }) => message.indexOf(contents) !== -1 ? true : false);
|
||||
expect(message.length).toBeGreaterThan(0);
|
||||
}
|
||||
|
||||
|
||||
it('should display Binding syntax', () => {
|
||||
it('should display Binding syntax', function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual('Binding syntax');
|
||||
});
|
||||
|
||||
it('should display Save button', () => {
|
||||
it('should display Save button', function () {
|
||||
expect(element.all(by.css('button')).get(0).getText()).toBe('Save');
|
||||
});
|
||||
|
||||
it('should display HTML attributes and DOM properties', () => {
|
||||
it('should display HTML attributes and DOM properties', function () {
|
||||
expect(element.all(by.css('h2')).get(1).getText()).toBe('HTML attributes and DOM properties');
|
||||
});
|
||||
|
||||
it('should display 1. Use the inspector...', () => {
|
||||
it('should display 1. Use the inspector...', function () {
|
||||
expect(element.all(by.css('p')).get(0).getText()).toContain('1. Use the inspector');
|
||||
});
|
||||
|
||||
it('should display Disabled property vs. attribute', () => {
|
||||
it('should display Disabled property vs. attribute', function () {
|
||||
expect(element.all(by.css('h3')).get(0).getText()).toBe('Disabled property vs. attribute');
|
||||
});
|
||||
|
||||
|
||||
it('should log a message including Sarah', async () => {
|
||||
const attributeButton = element.all(by.css('button')).get(1);
|
||||
let attributeButton = element.all(by.css('button')).get(1);
|
||||
await attributeButton.click();
|
||||
const contents = 'Sarah';
|
||||
logChecker(attributeButton, contents);
|
||||
});
|
||||
|
||||
it('should log a message including Sarah for DOM property', async () => {
|
||||
const DOMPropertyButton = element.all(by.css('button')).get(2);
|
||||
let DOMPropertyButton = element.all(by.css('button')).get(2);
|
||||
await DOMPropertyButton.click();
|
||||
const contents = 'Sarah';
|
||||
logChecker(DOMPropertyButton, contents);
|
||||
});
|
||||
|
||||
it('should log a message including Sally for DOM property', async () => {
|
||||
const DOMPropertyButton = element.all(by.css('button')).get(2);
|
||||
const input = element(by.css('input'));
|
||||
let DOMPropertyButton = element.all(by.css('button')).get(2);
|
||||
let input = element(by.css('input'));
|
||||
input.sendKeys('Sally');
|
||||
await DOMPropertyButton.click();
|
||||
const contents = 'Sally';
|
||||
@ -59,14 +61,14 @@ describe('Binding syntax e2e tests', () => {
|
||||
});
|
||||
|
||||
it('should log a message that Test Button works', async () => {
|
||||
const testButton = element.all(by.css('button')).get(3);
|
||||
let testButton = element.all(by.css('button')).get(3);
|
||||
await testButton.click();
|
||||
const contents = 'Test';
|
||||
logChecker(testButton, contents);
|
||||
});
|
||||
|
||||
it('should toggle Test Button disabled', async () => {
|
||||
const toggleButton = element.all(by.css('button')).get(4);
|
||||
let toggleButton = element.all(by.css('button')).get(4);
|
||||
await toggleButton.click();
|
||||
const contents = 'true';
|
||||
logChecker(toggleButton, contents);
|
||||
|
@ -26,7 +26,7 @@ export class AppComponent {
|
||||
|
||||
toggleDisabled(): any {
|
||||
|
||||
const testButton = document.getElementById('testButton') as HTMLInputElement;
|
||||
let testButton = <HTMLInputElement> document.getElementById('testButton');
|
||||
testButton.disabled = !testButton.disabled;
|
||||
console.warn(testButton.disabled);
|
||||
}
|
||||
|
@ -21,13 +21,11 @@ import { ItemDirective } from './item.directive';
|
||||
ItemDirective
|
||||
],
|
||||
// #enddocregion declarations
|
||||
// #docregion imports
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpClientModule
|
||||
],
|
||||
// #enddocregion imports
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
@ -1,19 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Built-in Directives', () => {
|
||||
describe('Built-in Directives', function () {
|
||||
|
||||
beforeAll(() => {
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should have title Built-in Directives', () => {
|
||||
const title = element.all(by.css('h1')).get(0);
|
||||
it('should have title Built-in Directives', function () {
|
||||
let title = element.all(by.css('h1')).get(0);
|
||||
expect(title.getText()).toEqual('Built-in Directives');
|
||||
});
|
||||
|
||||
it('should change first Teapot header', async () => {
|
||||
const firstLabel = element.all(by.css('p')).get(0);
|
||||
const firstInput = element.all(by.css('input')).get(0);
|
||||
let firstLabel = element.all(by.css('p')).get(0);
|
||||
let firstInput = element.all(by.css('input')).get(0);
|
||||
|
||||
expect(firstLabel.getText()).toEqual('Current item name: Teapot');
|
||||
firstInput.sendKeys('abc');
|
||||
@ -21,49 +23,49 @@ describe('Built-in Directives', () => {
|
||||
});
|
||||
|
||||
|
||||
it('should modify sentence when modified checkbox checked', () => {
|
||||
const modifiedChkbxLabel = element.all(by.css('input[type="checkbox"]')).get(1);
|
||||
const modifiedSentence = element.all(by.css('div')).get(1);
|
||||
it('should modify sentence when modified checkbox checked', function () {
|
||||
let modifiedChkbxLabel = element.all(by.css('input[type="checkbox"]')).get(1);
|
||||
let modifiedSentence = element.all(by.css('div')).get(1);
|
||||
|
||||
modifiedChkbxLabel.click();
|
||||
expect(modifiedSentence.getText()).toContain('modified');
|
||||
});
|
||||
|
||||
it('should modify sentence when normal checkbox checked', () => {
|
||||
const normalChkbxLabel = element.all(by.css('input[type="checkbox"]')).get(4);
|
||||
const normalSentence = element.all(by.css('div')).get(7);
|
||||
it('should modify sentence when normal checkbox checked', function () {
|
||||
let normalChkbxLabel = element.all(by.css('input[type="checkbox"]')).get(4);
|
||||
let normalSentence = element.all(by.css('div')).get(7);
|
||||
|
||||
normalChkbxLabel.click();
|
||||
expect(normalSentence.getText()).toContain('normal weight and, extra large');
|
||||
});
|
||||
|
||||
it('should toggle app-item-detail', () => {
|
||||
const toggleButton = element.all(by.css('button')).get(3);
|
||||
const toggledDiv = element.all(by.css('app-item-detail')).get(0);
|
||||
it('should toggle app-item-detail', function () {
|
||||
let toggleButton = element.all(by.css('button')).get(3);
|
||||
let toggledDiv = element.all(by.css('app-item-detail')).get(0);
|
||||
|
||||
toggleButton.click();
|
||||
expect(toggledDiv.isDisplayed()).toBe(true);
|
||||
});
|
||||
|
||||
it('should hide app-item-detail', () => {
|
||||
const hiddenMessage = element.all(by.css('p')).get(11);
|
||||
const hiddenDiv = element.all(by.css('app-item-detail')).get(2);
|
||||
it('should hide app-item-detail', function () {
|
||||
let hiddenMessage = element.all(by.css('p')).get(11);
|
||||
let hiddenDiv = element.all(by.css('app-item-detail')).get(2);
|
||||
|
||||
expect(hiddenMessage.getText()).toContain('in the DOM');
|
||||
expect(hiddenDiv.isDisplayed()).toBe(true);
|
||||
});
|
||||
|
||||
it('should have 10 lists each containing the string Teapot', () => {
|
||||
const listDiv = element.all(by.cssContainingText('.box', 'Teapot'));
|
||||
it('should have 10 lists each containing the string Teapot', function () {
|
||||
let listDiv = element.all(by.cssContainingText('.box', 'Teapot'));
|
||||
expect(listDiv.count()).toBe(10);
|
||||
});
|
||||
|
||||
it('should switch case', () => {
|
||||
const tvRadioButton = element.all(by.css('input[type="radio"]')).get(3);
|
||||
const tvDiv = element(by.css('app-lost-item'));
|
||||
it('should switch case', function () {
|
||||
let tvRadioButton = element.all(by.css('input[type="radio"]')).get(3);
|
||||
let tvDiv = element(by.css('app-lost-item'));
|
||||
|
||||
const fishbowlRadioButton = element.all(by.css('input[type="radio"]')).get(4);
|
||||
const fishbowlDiv = element(by.css('app-unknown-item'));
|
||||
let fishbowlRadioButton = element.all(by.css('input[type="radio"]')).get(4);
|
||||
let fishbowlDiv = element(by.css('app-unknown-item'));
|
||||
|
||||
tvRadioButton.click();
|
||||
expect(tvDiv.getText()).toContain('Television');
|
||||
|
@ -30,14 +30,6 @@ export class AppComponent implements OnInit {
|
||||
itemsWithTrackByCountReset = 0;
|
||||
itemIdIncrement = 1;
|
||||
|
||||
// #docregion setClasses
|
||||
currentClasses: {};
|
||||
// #enddocregion setClasses
|
||||
|
||||
// #docregion setStyles
|
||||
currentStyles: {};
|
||||
// #enddocregion setStyles
|
||||
|
||||
ngOnInit() {
|
||||
this.resetItems();
|
||||
this.setCurrentClasses();
|
||||
@ -49,18 +41,20 @@ export class AppComponent implements OnInit {
|
||||
this.currentItem.name = name.toUpperCase();
|
||||
}
|
||||
|
||||
// #docregion setClasses
|
||||
// #docregion setClasses
|
||||
currentClasses: {};
|
||||
setCurrentClasses() {
|
||||
// CSS classes: added/removed per current state of component properties
|
||||
this.currentClasses = {
|
||||
saveable: this.canSave,
|
||||
modified: !this.isUnchanged,
|
||||
special: this.isSpecial
|
||||
'saveable': this.canSave,
|
||||
'modified': !this.isUnchanged,
|
||||
'special': this.isSpecial
|
||||
};
|
||||
}
|
||||
// #enddocregion setClasses
|
||||
|
||||
// #docregion setStyles
|
||||
currentStyles: {};
|
||||
setCurrentStyles() {
|
||||
// CSS styles: set per current state of component properties
|
||||
this.currentStyles = {
|
||||
@ -76,7 +70,11 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
giveNullCustomerValue() {
|
||||
this.nullCustomer = 'Kelly';
|
||||
!(this.nullCustomer = null) ? (this.nullCustomer = 'Kelly') : (this.nullCustomer = null);
|
||||
}
|
||||
|
||||
resetNullItem() {
|
||||
this.nullCustomer = null;
|
||||
}
|
||||
|
||||
resetItems() {
|
||||
@ -86,7 +84,7 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
resetList() {
|
||||
this.resetItems();
|
||||
this.resetItems()
|
||||
this.itemsWithTrackByCountReset = 0;
|
||||
this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;
|
||||
}
|
||||
@ -109,7 +107,7 @@ export class AppComponent implements OnInit {
|
||||
trackByItems(index: number, item: Item): number { return item.id; }
|
||||
// #enddocregion trackByItems
|
||||
|
||||
trackById(index: number, item: any): number { return item.id; }
|
||||
trackById(index: number, item: any): number { return item['id']; }
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,19 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Built Template Functions Example', () => {
|
||||
beforeAll(() => {
|
||||
describe('Built Template Functions Example', function () {
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should have title Built-in Template Functions', () => {
|
||||
const title = element.all(by.css('h1')).get(0);
|
||||
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', () => {
|
||||
const header = element(by.css('h2'));
|
||||
it('should display $any( ) in h2', function () {
|
||||
let header = element(by.css('h2'));
|
||||
expect(header.getText()).toContain('$any( )');
|
||||
});
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
/*
|
||||
* This example project is special in that it is not a cli app. To run tests appropriate for this
|
||||
* project, the test command is overwritten in `aio/content/examples/observables/example-config.json`.
|
||||
*
|
||||
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.js` runs
|
||||
* tests for this project.
|
||||
*
|
||||
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
|
||||
*/
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"tests": [
|
||||
{
|
||||
"cmd": "yarn",
|
||||
"args": ["tsc", "--project", "tsconfig.spec.json", "--module", "commonjs"]
|
||||
},
|
||||
{
|
||||
"cmd": "yarn",
|
||||
"args": ["jasmine", "out-tsc/**/*.spec.js"]
|
||||
}
|
||||
]
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
import { docRegionChain, docRegionObservable, docRegionUnsubscribe } from './observables';
|
||||
|
||||
describe('observables', () => {
|
||||
it('should print 2', (doneFn: DoneFn) => {
|
||||
const consoleLogSpy = spyOn(console, 'log');
|
||||
const observable = docRegionObservable(console);
|
||||
observable.subscribe(() => {
|
||||
expect(consoleLogSpy).toHaveBeenCalledTimes(1);
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith(2);
|
||||
doneFn();
|
||||
});
|
||||
});
|
||||
|
||||
it('should close the subscription', () => {
|
||||
const subscription = docRegionUnsubscribe();
|
||||
expect(subscription.closed).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should chain an observable', (doneFn: DoneFn) => {
|
||||
const observable = docRegionChain();
|
||||
observable.subscribe(value => {
|
||||
expect(value).toBe(4);
|
||||
doneFn();
|
||||
});
|
||||
});
|
||||
});
|
@ -1,72 +1,40 @@
|
||||
// #docplaster
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export function docRegionObservable(console: Console) {
|
||||
// #docregion observable
|
||||
// #docregion observable
|
||||
|
||||
// declare a publishing operation
|
||||
const observable = new Observable<number>(observer => {
|
||||
// Subscriber fn...
|
||||
// #enddocregion observable
|
||||
// The below code is used for unit testing only
|
||||
observer.next(2);
|
||||
// #docregion observable
|
||||
});
|
||||
// declare a publishing operation
|
||||
const observable = new Observable<number>(observer => {
|
||||
// Subscriber fn...
|
||||
});
|
||||
|
||||
// initiate execution
|
||||
observable.subscribe(value => {
|
||||
// observer handles notifications
|
||||
// #enddocregion observable
|
||||
// The below code is used for unit testing only
|
||||
console.log(value);
|
||||
// #docregion observable
|
||||
});
|
||||
// initiate execution
|
||||
observable.subscribe(() => {
|
||||
// observer handles notifications
|
||||
});
|
||||
|
||||
// #enddocregion observable
|
||||
return observable;
|
||||
}
|
||||
// #enddocregion observable
|
||||
|
||||
export function docRegionUnsubscribe() {
|
||||
const observable = new Observable<number>(() => {
|
||||
// Subscriber fn...
|
||||
});
|
||||
// #docregion unsubscribe
|
||||
// #docregion unsubscribe
|
||||
|
||||
const subscription = observable.subscribe(() => {
|
||||
// observer handles notifications
|
||||
});
|
||||
const subscription = observable.subscribe(() => {
|
||||
// observer handles notifications
|
||||
});
|
||||
|
||||
subscription.unsubscribe();
|
||||
subscription.unsubscribe();
|
||||
|
||||
// #enddocregion unsubscribe
|
||||
return subscription;
|
||||
}
|
||||
// #enddocregion unsubscribe
|
||||
|
||||
export function docRegionError() {
|
||||
const observable = new Observable<number>(() => {
|
||||
// Subscriber fn...
|
||||
});
|
||||
// #docregion error
|
||||
|
||||
// #docregion error
|
||||
observable.subscribe(() => {
|
||||
throw new Error('my error');
|
||||
});
|
||||
// #enddocregion error
|
||||
}
|
||||
observable.subscribe(() => {
|
||||
throw Error('my error');
|
||||
});
|
||||
|
||||
export function docRegionChain() {
|
||||
let observable = new Observable<number>(observer => {
|
||||
// Subscriber fn...
|
||||
observer.next(2);
|
||||
});
|
||||
// #enddocregion error
|
||||
|
||||
observable =
|
||||
// #docregion chain
|
||||
// #docregion chain
|
||||
|
||||
observable.pipe(map(v => 2 * v));
|
||||
observable.pipe(map(v => 2 * v));
|
||||
|
||||
// #enddocregion chain
|
||||
return observable;
|
||||
}
|
||||
// #enddocregion chain
|
||||
|
@ -1,23 +0,0 @@
|
||||
import { docRegionError, docRegionPromise } from './promises';
|
||||
|
||||
describe('promises', () => {
|
||||
it('should print 2', (doneFn: DoneFn) => {
|
||||
const consoleLogSpy = spyOn(console, 'log');
|
||||
const pr = docRegionPromise(console, 2);
|
||||
pr.then((value) => {
|
||||
expect(consoleLogSpy).toHaveBeenCalledTimes(1);
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith(2);
|
||||
expect(value).toBe(4);
|
||||
doneFn();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an error', (doneFn: DoneFn) => {
|
||||
const promise = docRegionError();
|
||||
promise
|
||||
.then(() => {
|
||||
throw new Error('Promise should be rejected.');
|
||||
},
|
||||
() => doneFn());
|
||||
});
|
||||
});
|
@ -1,44 +1,25 @@
|
||||
// #docplaster
|
||||
// #docregion promise
|
||||
// initiate execution
|
||||
const promise = new Promise<number>((resolve, reject) => {
|
||||
// Executer fn...
|
||||
});
|
||||
|
||||
export function docRegionPromise(console: Console, inputValue: number) {
|
||||
// #docregion promise
|
||||
// initiate execution
|
||||
let promise = new Promise<number>((resolve, reject) => {
|
||||
// Executer fn...
|
||||
// #enddocregion promise
|
||||
// The below is used in the unit tests.
|
||||
resolve(inputValue);
|
||||
// #docregion promise
|
||||
});
|
||||
// #enddocregion promise
|
||||
promise =
|
||||
// #docregion promise
|
||||
promise.then(value => {
|
||||
// handle result here
|
||||
// #enddocregion promise
|
||||
// The below is used in the unit tests.
|
||||
console.log(value);
|
||||
return value;
|
||||
// #docregion promise
|
||||
});
|
||||
// #enddocregion promise
|
||||
promise =
|
||||
// #docregion chain
|
||||
promise.then(v => 2 * v);
|
||||
// #enddocregion chain
|
||||
promise.then(value => {
|
||||
// handle result here
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
// #enddocregion promise
|
||||
|
||||
export function docRegionError() {
|
||||
let promise = Promise.resolve();
|
||||
promise =
|
||||
// #docregion error
|
||||
// #docregion chain
|
||||
|
||||
promise.then(() => {
|
||||
throw new Error('my error');
|
||||
});
|
||||
promise.then(v => 2 * v);
|
||||
|
||||
// #enddocregion error
|
||||
return promise;
|
||||
}
|
||||
// #enddocregion chain
|
||||
|
||||
// #docregion error
|
||||
|
||||
promise.then(() => {
|
||||
throw Error('my error');
|
||||
});
|
||||
|
||||
// #enddocregion error
|
||||
|
@ -1,236 +1,229 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
describe('Component Communication Cookbook Tests', () => {
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
beforeEach(() => browser.get(browser.baseUrl));
|
||||
describe('Component Communication Cookbook Tests', function () {
|
||||
|
||||
describe('Parent-to-child communication', () => {
|
||||
// Note: '?e2e' which app can read to know it is running in protractor
|
||||
// e.g. `if (!/e2e/.test(location.search)) { ...`
|
||||
beforeAll(function () {
|
||||
browser.get('?e2e');
|
||||
});
|
||||
|
||||
describe('Parent-to-child communication', function() {
|
||||
// #docregion parent-to-child
|
||||
// ...
|
||||
const heroNames = ['Dr IQ', 'Magneta', 'Bombasto'];
|
||||
const masterName = 'Master';
|
||||
let _heroNames = ['Dr IQ', 'Magneta', 'Bombasto'];
|
||||
let _masterName = 'Master';
|
||||
|
||||
it('should pass properties to children properly', () => {
|
||||
const parent = element(by.tagName('app-hero-parent'));
|
||||
const heroes = parent.all(by.tagName('app-hero-child'));
|
||||
it('should pass properties to children properly', function () {
|
||||
let parent = element.all(by.tagName('app-hero-parent')).get(0);
|
||||
let heroes = parent.all(by.tagName('app-hero-child'));
|
||||
|
||||
for (let i = 0; i < heroNames.length; i++) {
|
||||
const childTitle = heroes.get(i).element(by.tagName('h3')).getText();
|
||||
const childDetail = heroes.get(i).element(by.tagName('p')).getText();
|
||||
expect(childTitle).toEqual(heroNames[i] + ' says:');
|
||||
expect(childDetail).toContain(masterName);
|
||||
for (let i = 0; i < _heroNames.length; i++) {
|
||||
let childTitle = heroes.get(i).element(by.tagName('h3')).getText();
|
||||
let childDetail = heroes.get(i).element(by.tagName('p')).getText();
|
||||
expect(childTitle).toEqual(_heroNames[i] + ' says:');
|
||||
expect(childDetail).toContain(_masterName);
|
||||
}
|
||||
});
|
||||
// ...
|
||||
// #enddocregion parent-to-child
|
||||
});
|
||||
|
||||
describe('Parent-to-child communication with setter', () => {
|
||||
describe('Parent-to-child communication with setter', function() {
|
||||
// #docregion parent-to-child-setter
|
||||
// ...
|
||||
it('should display trimmed, non-empty names', () => {
|
||||
const nonEmptyNameIndex = 0;
|
||||
const nonEmptyName = '"Dr IQ"';
|
||||
const parent = element(by.tagName('app-name-parent'));
|
||||
const hero = parent.all(by.tagName('app-name-child')).get(nonEmptyNameIndex);
|
||||
it('should display trimmed, non-empty names', function () {
|
||||
let _nonEmptyNameIndex = 0;
|
||||
let _nonEmptyName = '"Dr IQ"';
|
||||
let parent = element.all(by.tagName('app-name-parent')).get(0);
|
||||
let hero = parent.all(by.tagName('app-name-child')).get(_nonEmptyNameIndex);
|
||||
|
||||
const displayName = hero.element(by.tagName('h3')).getText();
|
||||
expect(displayName).toEqual(nonEmptyName);
|
||||
let displayName = hero.element(by.tagName('h3')).getText();
|
||||
expect(displayName).toEqual(_nonEmptyName);
|
||||
});
|
||||
|
||||
it('should replace empty name with default name', () => {
|
||||
const emptyNameIndex = 1;
|
||||
const defaultName = '"<no name set>"';
|
||||
const parent = element(by.tagName('app-name-parent'));
|
||||
const hero = parent.all(by.tagName('app-name-child')).get(emptyNameIndex);
|
||||
it('should replace empty name with default name', function () {
|
||||
let _emptyNameIndex = 1;
|
||||
let _defaultName = '"<no name set>"';
|
||||
let parent = element.all(by.tagName('app-name-parent')).get(0);
|
||||
let hero = parent.all(by.tagName('app-name-child')).get(_emptyNameIndex);
|
||||
|
||||
const displayName = hero.element(by.tagName('h3')).getText();
|
||||
expect(displayName).toEqual(defaultName);
|
||||
let displayName = hero.element(by.tagName('h3')).getText();
|
||||
expect(displayName).toEqual(_defaultName);
|
||||
});
|
||||
// ...
|
||||
// #enddocregion parent-to-child-setter
|
||||
});
|
||||
|
||||
describe('Parent-to-child communication with ngOnChanges', () => {
|
||||
describe('Parent-to-child communication with ngOnChanges', function() {
|
||||
// #docregion parent-to-child-onchanges
|
||||
// ...
|
||||
// Test must all execute in this exact order
|
||||
it('should set expected initial values', () => {
|
||||
const actual = getActual();
|
||||
it('should set expected initial values', function () {
|
||||
let actual = getActual();
|
||||
|
||||
const initialLabel = 'Version 1.23';
|
||||
const initialLog = 'Initial value of major set to 1, Initial value of minor set to 23';
|
||||
let initialLabel = 'Version 1.23';
|
||||
let initialLog = 'Initial value of major set to 1, Initial value of minor set to 23';
|
||||
|
||||
expect(actual.label).toBe(initialLabel);
|
||||
expect(actual.count).toBe(1);
|
||||
expect(actual.logs.get(0).getText()).toBe(initialLog);
|
||||
});
|
||||
|
||||
it('should set expected values after clicking \'Minor\' twice', async () => {
|
||||
const repoTag = element(by.tagName('app-version-parent'));
|
||||
const newMinorButton = repoTag.all(by.tagName('button')).get(0);
|
||||
it('should set expected values after clicking \'Minor\' twice', function () {
|
||||
let repoTag = element(by.tagName('app-version-parent'));
|
||||
let newMinorButton = repoTag.all(by.tagName('button')).get(0);
|
||||
|
||||
await newMinorButton.click();
|
||||
await newMinorButton.click();
|
||||
newMinorButton.click().then(function() {
|
||||
newMinorButton.click().then(function() {
|
||||
let actual = getActual();
|
||||
|
||||
const actual = getActual();
|
||||
let labelAfter2Minor = 'Version 1.25';
|
||||
let logAfter2Minor = 'minor changed from 24 to 25';
|
||||
|
||||
const labelAfter2Minor = 'Version 1.25';
|
||||
const logAfter2Minor = 'minor changed from 24 to 25';
|
||||
|
||||
expect(actual.label).toBe(labelAfter2Minor);
|
||||
expect(actual.count).toBe(3);
|
||||
expect(actual.logs.get(2).getText()).toBe(logAfter2Minor);
|
||||
expect(actual.label).toBe(labelAfter2Minor);
|
||||
expect(actual.count).toBe(3);
|
||||
expect(actual.logs.get(2).getText()).toBe(logAfter2Minor);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set expected values after clicking \'Major\' once', async () => {
|
||||
const repoTag = element(by.tagName('app-version-parent'));
|
||||
const newMajorButton = repoTag.all(by.tagName('button')).get(1);
|
||||
it('should set expected values after clicking \'Major\' once', function () {
|
||||
let repoTag = element(by.tagName('app-version-parent'));
|
||||
let newMajorButton = repoTag.all(by.tagName('button')).get(1);
|
||||
|
||||
await newMajorButton.click();
|
||||
const actual = getActual();
|
||||
newMajorButton.click().then(function() {
|
||||
let actual = getActual();
|
||||
|
||||
const labelAfterMajor = 'Version 2.0';
|
||||
const logAfterMajor = 'major changed from 1 to 2, minor changed from 23 to 0';
|
||||
let labelAfterMajor = 'Version 2.0';
|
||||
let logAfterMajor = 'major changed from 1 to 2, minor changed from 25 to 0';
|
||||
|
||||
expect(actual.label).toBe(labelAfterMajor);
|
||||
expect(actual.count).toBe(2);
|
||||
expect(actual.logs.get(1).getText()).toBe(logAfterMajor);
|
||||
expect(actual.label).toBe(labelAfterMajor);
|
||||
expect(actual.count).toBe(4);
|
||||
expect(actual.logs.get(3).getText()).toBe(logAfterMajor);
|
||||
});
|
||||
});
|
||||
|
||||
function getActual() {
|
||||
const versionTag = element(by.tagName('app-version-child'));
|
||||
const label = versionTag.element(by.tagName('h3')).getText();
|
||||
const ul = versionTag.element((by.tagName('ul')));
|
||||
const logs = ul.all(by.tagName('li'));
|
||||
let versionTag = element(by.tagName('app-version-child'));
|
||||
let label = versionTag.element(by.tagName('h3')).getText();
|
||||
let ul = versionTag.element((by.tagName('ul')));
|
||||
let logs = ul.all(by.tagName('li'));
|
||||
|
||||
return {
|
||||
label,
|
||||
logs,
|
||||
label: label,
|
||||
logs: logs,
|
||||
count: logs.count()
|
||||
};
|
||||
}
|
||||
// ...
|
||||
// #enddocregion parent-to-child-onchanges
|
||||
|
||||
});
|
||||
|
||||
describe('Child-to-parent communication', () => {
|
||||
describe('Child-to-parent communication', function() {
|
||||
// #docregion child-to-parent
|
||||
// ...
|
||||
it('should not emit the event initially', () => {
|
||||
const voteLabel = element(by.tagName('app-vote-taker')).element(by.tagName('h3'));
|
||||
expect(voteLabel.getText()).toBe('Agree: 0, Disagree: 0');
|
||||
it('should not emit the event initially', function () {
|
||||
let voteLabel = element(by.tagName('app-vote-taker'))
|
||||
.element(by.tagName('h3')).getText();
|
||||
expect(voteLabel).toBe('Agree: 0, Disagree: 0');
|
||||
});
|
||||
|
||||
it('should process Agree vote', async () => {
|
||||
const voteLabel = element(by.tagName('app-vote-taker')).element(by.tagName('h3'));
|
||||
const agreeButton1 = element.all(by.tagName('app-voter')).get(0)
|
||||
it('should process Agree vote', function () {
|
||||
let agreeButton1 = element.all(by.tagName('app-voter')).get(0)
|
||||
.all(by.tagName('button')).get(0);
|
||||
|
||||
await agreeButton1.click();
|
||||
|
||||
expect(voteLabel.getText()).toBe('Agree: 1, Disagree: 0');
|
||||
agreeButton1.click().then(function() {
|
||||
let voteLabel = element(by.tagName('app-vote-taker'))
|
||||
.element(by.tagName('h3')).getText();
|
||||
expect(voteLabel).toBe('Agree: 1, Disagree: 0');
|
||||
});
|
||||
});
|
||||
|
||||
it('should process Disagree vote', async () => {
|
||||
const voteLabel = element(by.tagName('app-vote-taker')).element(by.tagName('h3'));
|
||||
const agreeButton1 = element.all(by.tagName('app-voter')).get(1)
|
||||
it('should process Disagree vote', function () {
|
||||
let agreeButton1 = element.all(by.tagName('app-voter')).get(1)
|
||||
.all(by.tagName('button')).get(1);
|
||||
|
||||
await agreeButton1.click();
|
||||
|
||||
expect(voteLabel.getText()).toBe('Agree: 0, Disagree: 1');
|
||||
agreeButton1.click().then(function() {
|
||||
let voteLabel = element(by.tagName('app-vote-taker'))
|
||||
.element(by.tagName('h3')).getText();
|
||||
expect(voteLabel).toBe('Agree: 1, Disagree: 1');
|
||||
});
|
||||
});
|
||||
// ...
|
||||
// #enddocregion child-to-parent
|
||||
});
|
||||
|
||||
describe('Parent calls child via local var', () => {
|
||||
countDownTimerTests('app-countdown-parent-lv');
|
||||
// Can't run timer tests in protractor because
|
||||
// interaction w/ zones causes all tests to freeze & timeout.
|
||||
xdescribe('Parent calls child via local var', function() {
|
||||
countDownTimerTests('countdown-parent-lv');
|
||||
});
|
||||
|
||||
describe('Parent calls ViewChild', () => {
|
||||
countDownTimerTests('app-countdown-parent-vc');
|
||||
xdescribe('Parent calls ViewChild', function() {
|
||||
countDownTimerTests('countdown-parent-vc');
|
||||
});
|
||||
|
||||
function countDownTimerTests(parentTag: string) {
|
||||
// #docregion countdown-timer-tests
|
||||
// ...
|
||||
// The tests trigger periodic asynchronous operations (via `setInterval()`), which will prevent
|
||||
// the app from stabilizing. See https://angular.io/api/core/ApplicationRef#is-stable-examples
|
||||
// for more details.
|
||||
// To allow the tests to complete, we will disable automatically waiting for the Angular app to
|
||||
// stabilize.
|
||||
beforeEach(() => browser.waitForAngularEnabled(false));
|
||||
afterEach(() => browser.waitForAngularEnabled(true));
|
||||
|
||||
it('timer and parent seconds should match', async () => {
|
||||
const parent = element(by.tagName(parentTag));
|
||||
const startButton = parent.element(by.buttonText('Start'));
|
||||
const seconds = parent.element(by.className('seconds'));
|
||||
const timer = parent.element(by.tagName('app-countdown-timer'));
|
||||
|
||||
await startButton.click();
|
||||
|
||||
// Wait for `<app-countdown-timer>` to be populated with any text.
|
||||
await browser.wait(() => timer.getText(), 2000);
|
||||
|
||||
expect(await timer.getText()).toContain(await seconds.getText());
|
||||
it('timer and parent seconds should match', function () {
|
||||
let parent = element(by.tagName(parentTag));
|
||||
let message = parent.element(by.tagName('app-countdown-timer')).getText();
|
||||
browser.sleep(10); // give `seconds` a chance to catchup with `message`
|
||||
let seconds = parent.element(by.className('seconds')).getText();
|
||||
expect(message).toContain(seconds);
|
||||
});
|
||||
|
||||
it('should stop the countdown', async () => {
|
||||
const parent = element(by.tagName(parentTag));
|
||||
const startButton = parent.element(by.buttonText('Start'));
|
||||
const stopButton = parent.element(by.buttonText('Stop'));
|
||||
const timer = parent.element(by.tagName('app-countdown-timer'));
|
||||
it('should stop the countdown', function () {
|
||||
let parent = element(by.tagName(parentTag));
|
||||
let stopButton = parent.all(by.tagName('button')).get(1);
|
||||
|
||||
await startButton.click();
|
||||
expect(await timer.getText()).not.toContain('Holding');
|
||||
|
||||
await stopButton.click();
|
||||
expect(await timer.getText()).toContain('Holding');
|
||||
stopButton.click().then(function() {
|
||||
let message = parent.element(by.tagName('app-countdown-timer')).getText();
|
||||
expect(message).toContain('Holding');
|
||||
});
|
||||
});
|
||||
// ...
|
||||
// #enddocregion countdown-timer-tests
|
||||
}
|
||||
|
||||
describe('Parent and children communicate via a service', () => {
|
||||
|
||||
describe('Parent and children communicate via a service', function() {
|
||||
// #docregion bidirectional-service
|
||||
// ...
|
||||
it('should announce a mission', async () => {
|
||||
const missionControl = element(by.tagName('app-mission-control'));
|
||||
const announceButton = missionControl.all(by.tagName('button')).get(0);
|
||||
const history = missionControl.all(by.tagName('li'));
|
||||
|
||||
await announceButton.click();
|
||||
|
||||
expect(history.count()).toBe(1);
|
||||
expect(history.get(0).getText()).toMatch(/Mission.* announced/);
|
||||
it('should announce a mission', function () {
|
||||
let missionControl = element(by.tagName('app-mission-control'));
|
||||
let announceButton = missionControl.all(by.tagName('button')).get(0);
|
||||
announceButton.click().then(function () {
|
||||
let history = missionControl.all(by.tagName('li'));
|
||||
expect(history.count()).toBe(1);
|
||||
expect(history.get(0).getText()).toMatch(/Mission.* announced/);
|
||||
});
|
||||
});
|
||||
|
||||
it('should confirm the mission by Lovell', async () => {
|
||||
await testConfirmMission(1, 'Lovell');
|
||||
it('should confirm the mission by Lovell', function () {
|
||||
testConfirmMission(1, 2, 'Lovell');
|
||||
});
|
||||
|
||||
it('should confirm the mission by Haise', async () => {
|
||||
await testConfirmMission(3, 'Haise');
|
||||
it('should confirm the mission by Haise', function () {
|
||||
testConfirmMission(3, 3, 'Haise');
|
||||
});
|
||||
|
||||
it('should confirm the mission by Swigert', async () => {
|
||||
await testConfirmMission(2, 'Swigert');
|
||||
it('should confirm the mission by Swigert', function () {
|
||||
testConfirmMission(2, 4, 'Swigert');
|
||||
});
|
||||
|
||||
async function testConfirmMission(buttonIndex: number, astronaut: string) {
|
||||
const missionControl = element(by.tagName('app-mission-control'));
|
||||
const announceButton = missionControl.all(by.tagName('button')).get(0);
|
||||
const confirmButton = missionControl.all(by.tagName('button')).get(buttonIndex);
|
||||
const history = missionControl.all(by.tagName('li'));
|
||||
|
||||
await announceButton.click();
|
||||
await confirmButton.click();
|
||||
|
||||
expect(history.count()).toBe(2);
|
||||
expect(history.get(1).getText()).toBe(`${astronaut} confirmed the mission`);
|
||||
function testConfirmMission(buttonIndex: number, expectedLogCount: number, astronaut: string) {
|
||||
let _confirmedLog = ' confirmed the mission';
|
||||
let missionControl = element(by.tagName('app-mission-control'));
|
||||
let confirmButton = missionControl.all(by.tagName('button')).get(buttonIndex);
|
||||
confirmButton.click().then(function () {
|
||||
let history = missionControl.all(by.tagName('li'));
|
||||
expect(history.count()).toBe(expectedLogCount);
|
||||
expect(history.get(expectedLogCount - 1).getText()).toBe(astronaut + _confirmedLog);
|
||||
});
|
||||
}
|
||||
// ...
|
||||
// #enddocregion bidirectional-service
|
||||
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"tests": [
|
||||
{
|
||||
"cmd": "yarn",
|
||||
"args": [
|
||||
"e2e",
|
||||
"--protractor-config=e2e/protractor-puppeteer.conf.js",
|
||||
"--no-webdriver-update",
|
||||
"--port={PORT}"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -30,21 +30,22 @@
|
||||
<app-vote-taker></app-vote-taker>
|
||||
</div>
|
||||
<a href="#top" class="to-top">Back to Top</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="parent-to-child-local-var">
|
||||
<app-countdown-parent-lv></app-countdown-parent-lv>
|
||||
</div>
|
||||
<a href="#top" class="to-top">Back to Top</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="parent-to-view-child">
|
||||
<app-countdown-parent-vc></app-countdown-parent-vc>
|
||||
</div>
|
||||
<a href="#top" class="to-top">Back to Top</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="bidirectional-service">
|
||||
<app-mission-control></app-mission-control>
|
||||
</div>
|
||||
<a href="#top" class="to-top">Back to Top</a>
|
||||
<hr>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AstronautComponent } from './astronaut.component';
|
||||
@ -15,17 +15,10 @@ import { VersionParentComponent } from './version-parent.component';
|
||||
import { VoterComponent } from './voter.component';
|
||||
import { VoteTakerComponent } from './votetaker.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
],
|
||||
declarations: [
|
||||
let directives: any[] = [
|
||||
AppComponent,
|
||||
AstronautComponent,
|
||||
CountdownLocalVarParentComponent,
|
||||
CountdownTimerComponent,
|
||||
CountdownViewChildParentComponent,
|
||||
HeroChildComponent,
|
||||
HeroParentComponent,
|
||||
MissionControlComponent,
|
||||
@ -34,8 +27,28 @@ import { VoteTakerComponent } from './votetaker.component';
|
||||
VersionChildComponent,
|
||||
VersionParentComponent,
|
||||
VoterComponent,
|
||||
VoteTakerComponent,
|
||||
VoteTakerComponent
|
||||
];
|
||||
|
||||
let schemas: any[] = [];
|
||||
|
||||
// Include Countdown examples
|
||||
// unless in e2e tests which they break.
|
||||
if (!/e2e/.test(location.search)) {
|
||||
console.log('adding countdown timer examples');
|
||||
directives.push(CountdownLocalVarParentComponent);
|
||||
directives.push(CountdownViewChildParentComponent);
|
||||
} else {
|
||||
// In e2e test use CUSTOM_ELEMENTS_SCHEMA to suppress unknown element errors
|
||||
schemas.push(CUSTOM_ELEMENTS_SCHEMA);
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
declarations: directives,
|
||||
bootstrap: [ AppComponent ],
|
||||
schemas: schemas
|
||||
})
|
||||
export class AppModule { }
|
||||
|
@ -2,7 +2,7 @@
|
||||
import { Component, Input, OnDestroy } from '@angular/core';
|
||||
|
||||
import { MissionService } from './mission.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-astronaut',
|
||||
|
@ -2,8 +2,8 @@
|
||||
// #docregion vc
|
||||
import { AfterViewInit, ViewChild } from '@angular/core';
|
||||
// #docregion lv
|
||||
import { Component } from '@angular/core';
|
||||
import { CountdownTimerComponent } from './countdown-timer.component';
|
||||
import { Component } from '@angular/core';
|
||||
import { CountdownTimerComponent } from './countdown-timer.component';
|
||||
|
||||
// #enddocregion lv
|
||||
// #enddocregion vc
|
||||
|
@ -1,16 +1,19 @@
|
||||
// #docregion
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-countdown-timer',
|
||||
template: '<p>{{message}}</p>'
|
||||
})
|
||||
export class CountdownTimerComponent implements OnDestroy {
|
||||
export class CountdownTimerComponent implements OnInit, OnDestroy {
|
||||
|
||||
intervalId = 0;
|
||||
message = '';
|
||||
seconds = 11;
|
||||
|
||||
clearTimer() { clearInterval(this.intervalId); }
|
||||
|
||||
ngOnInit() { this.start(); }
|
||||
ngOnDestroy() { this.clearTimer(); }
|
||||
|
||||
start() { this.countDown(); }
|
||||
@ -19,8 +22,6 @@ export class CountdownTimerComponent implements OnDestroy {
|
||||
this.message = `Holding at T-${this.seconds} seconds`;
|
||||
}
|
||||
|
||||
private clearTimer() { clearInterval(this.intervalId); }
|
||||
|
||||
private countDown() {
|
||||
this.clearTimer();
|
||||
this.intervalId = window.setInterval(() => {
|
||||
|
@ -12,6 +12,6 @@ import { Hero } from './hero';
|
||||
})
|
||||
export class HeroChildComponent {
|
||||
@Input() hero: Hero;
|
||||
@Input('master') masterName: string; // tslint:disable-line: no-input-rename
|
||||
@Input('master') masterName: string;
|
||||
}
|
||||
// #enddocregion
|
||||
|
@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class MissionService {
|
||||
|
@ -1,7 +1,7 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { MissionService } from './mission.service';
|
||||
import { MissionService } from './mission.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mission-control',
|
||||
@ -34,7 +34,7 @@ export class MissionControlComponent {
|
||||
}
|
||||
|
||||
announce() {
|
||||
const mission = this.missions[this.nextMission++];
|
||||
let mission = this.missions[this.nextMission++];
|
||||
this.missionService.announceMission(mission);
|
||||
this.history.push(`Mission "${mission}" announced`);
|
||||
if (this.nextMission >= this.missions.length) { this.nextMission = 0; }
|
||||
|
@ -1,4 +1,3 @@
|
||||
// tslint:disable: variable-name
|
||||
// #docregion
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
@ -7,11 +6,13 @@ import { Component, Input } from '@angular/core';
|
||||
template: '<h3>"{{name}}"</h3>'
|
||||
})
|
||||
export class NameChildComponent {
|
||||
private _name = '';
|
||||
|
||||
@Input()
|
||||
get name(): string { return this._name; }
|
||||
set name(name: string) {
|
||||
this._name = (name && name.trim()) || '<no name set>';
|
||||
}
|
||||
private _name = '';
|
||||
|
||||
get name(): string { return this._name; }
|
||||
}
|
||||
// #enddocregion
|
||||
|
@ -18,14 +18,14 @@ export class VersionChildComponent implements OnChanges {
|
||||
changeLog: string[] = [];
|
||||
|
||||
ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
|
||||
const log: string[] = [];
|
||||
for (const propName in changes) {
|
||||
const changedProp = changes[propName];
|
||||
const to = JSON.stringify(changedProp.currentValue);
|
||||
let log: string[] = [];
|
||||
for (let propName in changes) {
|
||||
let changedProp = changes[propName];
|
||||
let to = JSON.stringify(changedProp.currentValue);
|
||||
if (changedProp.isFirstChange()) {
|
||||
log.push(`Initial value of ${propName} set to ${to}`);
|
||||
} else {
|
||||
const from = JSON.stringify(changedProp.previousValue);
|
||||
let from = JSON.stringify(changedProp.previousValue);
|
||||
log.push(`${propName} changed from ${from} to ${to}`);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-vote-taker',
|
||||
|
@ -1,14 +1,16 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Component Style Tests', () => {
|
||||
describe('Component Style Tests', function () {
|
||||
|
||||
beforeAll(() => {
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('scopes component styles to component view', () => {
|
||||
const componentH1 = element(by.css('app-root > h1'));
|
||||
const externalH1 = element(by.css('body > h1'));
|
||||
it('scopes component styles to component view', function() {
|
||||
let componentH1 = element(by.css('app-root > h1'));
|
||||
let externalH1 = element(by.css('body > h1'));
|
||||
|
||||
// Note: sometimes webdriver returns the fontWeight as "normal",
|
||||
// other times as "400", both of which are equal in CSS terms.
|
||||
@ -17,49 +19,49 @@ describe('Component Style Tests', () => {
|
||||
});
|
||||
|
||||
|
||||
it('allows styling :host element', () => {
|
||||
const host = element(by.css('app-hero-details'));
|
||||
it('allows styling :host element', function() {
|
||||
let host = element(by.css('app-hero-details'));
|
||||
|
||||
expect(host.getCssValue('borderWidth')).toEqual('1px');
|
||||
});
|
||||
|
||||
it('supports :host() in function form', () => {
|
||||
const host = element(by.css('app-hero-details'));
|
||||
it('supports :host() in function form', function() {
|
||||
let host = element(by.css('app-hero-details'));
|
||||
|
||||
host.element(by.buttonText('Activate')).click();
|
||||
expect(host.getCssValue('borderWidth')).toEqual('3px');
|
||||
});
|
||||
|
||||
it('allows conditional :host-context() styling', () => {
|
||||
const h2 = element(by.css('app-hero-details h2'));
|
||||
it('allows conditional :host-context() styling', function() {
|
||||
let h2 = element(by.css('app-hero-details h2'));
|
||||
|
||||
expect(h2.getCssValue('backgroundColor')).toEqual('rgba(238, 238, 255, 1)'); // #eeeeff
|
||||
});
|
||||
|
||||
it('styles both view and content children with /deep/', () => {
|
||||
const viewH3 = element(by.css('app-hero-team h3'));
|
||||
const contentH3 = element(by.css('app-hero-controls h3'));
|
||||
it('styles both view and content children with /deep/', function() {
|
||||
let viewH3 = element(by.css('app-hero-team h3'));
|
||||
let contentH3 = element(by.css('app-hero-controls h3'));
|
||||
|
||||
expect(viewH3.getCssValue('fontStyle')).toEqual('italic');
|
||||
expect(contentH3.getCssValue('fontStyle')).toEqual('italic');
|
||||
});
|
||||
|
||||
it('includes styles loaded with CSS @import', () => {
|
||||
const host = element(by.css('app-hero-details'));
|
||||
it('includes styles loaded with CSS @import', function() {
|
||||
let host = element(by.css('app-hero-details'));
|
||||
|
||||
expect(host.getCssValue('padding')).toEqual('10px');
|
||||
});
|
||||
|
||||
it('processes template inline styles', () => {
|
||||
const button = element(by.css('app-hero-controls button'));
|
||||
const externalButton = element(by.css('body > button'));
|
||||
it('processes template inline styles', function() {
|
||||
let button = element(by.css('app-hero-controls button'));
|
||||
let externalButton = element(by.css('body > button'));
|
||||
expect(button.getCssValue('backgroundColor')).toEqual('rgba(255, 255, 255, 1)'); // #ffffff
|
||||
expect(externalButton.getCssValue('backgroundColor')).not.toEqual('rgba(255, 255, 255, 1)');
|
||||
});
|
||||
|
||||
it('processes template <link>s', () => {
|
||||
const li = element(by.css('app-hero-team li:first-child'));
|
||||
const externalLi = element(by.css('body > ul li'));
|
||||
it('processes template <link>s', function() {
|
||||
let li = element(by.css('app-hero-team li:first-child'));
|
||||
let externalLi = element(by.css('body > ul li'));
|
||||
|
||||
expect(li.getCssValue('listStyleType')).toEqual('square');
|
||||
expect(externalLi.getCssValue('listStyleType')).not.toEqual('square');
|
||||
|
@ -1,74 +1,76 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Dependency Injection Cookbook', () => {
|
||||
describe('Dependency Injection Cookbook', function () {
|
||||
|
||||
beforeAll(() => {
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should render Logged in User example', () => {
|
||||
const loggedInUser = element.all(by.xpath('//h3[text()="Logged in user"]')).get(0);
|
||||
it('should render Logged in User example', function () {
|
||||
let loggedInUser = element.all(by.xpath('//h3[text()="Logged in user"]')).get(0);
|
||||
expect(loggedInUser).toBeDefined();
|
||||
});
|
||||
|
||||
it('"Bombasto" should be the logged in user', () => {
|
||||
const loggedInUser = element.all(by.xpath('//div[text()="Name: Bombasto"]')).get(0);
|
||||
it('"Bombasto" should be the logged in user', function () {
|
||||
let loggedInUser = element.all(by.xpath('//div[text()="Name: Bombasto"]')).get(0);
|
||||
expect(loggedInUser).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render sorted heroes', () => {
|
||||
const sortedHeroes = element.all(by.xpath('//h3[text()="Sorted Heroes" and position()=1]')).get(0);
|
||||
it('should render sorted heroes', function () {
|
||||
let sortedHeroes = element.all(by.xpath('//h3[text()="Sorted Heroes" and position()=1]')).get(0);
|
||||
expect(sortedHeroes).toBeDefined();
|
||||
});
|
||||
|
||||
it('Dr Nice should be in sorted heroes', () => {
|
||||
const sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Dr Nice" and position()=2]')).get(0);
|
||||
it('Dr Nice should be in sorted heroes', function () {
|
||||
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Dr Nice" and position()=2]')).get(0);
|
||||
expect(sortedHero).toBeDefined();
|
||||
});
|
||||
|
||||
it('RubberMan should be in sorted heroes', () => {
|
||||
const sortedHero = element.all(by.xpath('//sorted-heroes/[text()="RubberMan" and position()=3]')).get(0);
|
||||
it('RubberMan should be in sorted heroes', function () {
|
||||
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="RubberMan" and position()=3]')).get(0);
|
||||
expect(sortedHero).toBeDefined();
|
||||
});
|
||||
|
||||
it('Magma should be in sorted heroes', () => {
|
||||
const sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Magma"]')).get(0);
|
||||
it('Magma should be in sorted heroes', function () {
|
||||
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Magma"]')).get(0);
|
||||
expect(sortedHero).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render Hero of the Month', () => {
|
||||
const heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0);
|
||||
it('should render Hero of the Month', function () {
|
||||
let heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0);
|
||||
expect(heroOfTheMonth).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render Hero Bios', () => {
|
||||
const heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0);
|
||||
it('should render Hero Bios', function () {
|
||||
let heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0);
|
||||
expect(heroBios).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render Magma\'s description in Hero Bios', () => {
|
||||
const magmaText = element.all(by.xpath('//textarea[text()="Hero of all trades"]')).get(0);
|
||||
it('should render Magma\'s description in Hero Bios', function () {
|
||||
let magmaText = element.all(by.xpath('//textarea[text()="Hero of all trades"]')).get(0);
|
||||
expect(magmaText).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render Magma\'s phone in Hero Bios and Contacts', () => {
|
||||
const magmaPhone = element.all(by.xpath('//div[text()="Phone #: 555-555-5555"]')).get(0);
|
||||
it('should render Magma\'s phone in Hero Bios and Contacts', function () {
|
||||
let magmaPhone = element.all(by.xpath('//div[text()="Phone #: 555-555-5555"]')).get(0);
|
||||
expect(magmaPhone).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render Hero-of-the-Month runner-ups', () => {
|
||||
const runnersUp = element(by.id('rups1')).getText();
|
||||
it('should render Hero-of-the-Month runner-ups', function () {
|
||||
let runnersUp = element(by.id('rups1')).getText();
|
||||
expect(runnersUp).toContain('RubberMan, Dr Nice');
|
||||
});
|
||||
|
||||
it('should render DateLogger log entry in Hero-of-the-Month', () => {
|
||||
const logs = element.all(by.id('logs')).get(0).getText();
|
||||
it('should render DateLogger log entry in Hero-of-the-Month', function () {
|
||||
let logs = element.all(by.id('logs')).get(0).getText();
|
||||
expect(logs).toContain('INFO: starting up at');
|
||||
});
|
||||
|
||||
it('should highlight Hero Bios and Contacts container when mouseover', () => {
|
||||
const target = element(by.css('div[appHighlight="yellow"]'));
|
||||
const yellow = 'rgba(255, 255, 0, 1)';
|
||||
it('should highlight Hero Bios and Contacts container when mouseover', function () {
|
||||
let target = element(by.css('div[appHighlight="yellow"]'));
|
||||
let yellow = 'rgba(255, 255, 0, 1)';
|
||||
|
||||
expect(target.getCssValue('background-color')).not.toEqual(yellow);
|
||||
|
||||
@ -79,25 +81,25 @@ describe('Dependency Injection Cookbook', () => {
|
||||
browser.wait(() => target.getCssValue('background-color').then(c => c === yellow), 2000);
|
||||
});
|
||||
|
||||
describe('in Parent Finder', () => {
|
||||
const cathy1 = element(by.css('alex cathy'));
|
||||
const craig1 = element(by.css('alex craig'));
|
||||
const carol1 = element(by.css('alex carol p'));
|
||||
const carol2 = element(by.css('barry carol p'));
|
||||
describe('in Parent Finder', function () {
|
||||
let cathy1 = element(by.css('alex cathy'));
|
||||
let craig1 = element(by.css('alex craig'));
|
||||
let carol1 = element(by.css('alex carol p'));
|
||||
let carol2 = element(by.css('barry carol p'));
|
||||
|
||||
it('"Cathy" should find "Alex" via the component class', () => {
|
||||
it('"Cathy" should find "Alex" via the component class', function () {
|
||||
expect(cathy1.getText()).toContain('Found Alex via the component');
|
||||
});
|
||||
|
||||
it('"Craig" should not find "Alex" via the base class', () => {
|
||||
it('"Craig" should not find "Alex" via the base class', function () {
|
||||
expect(craig1.getText()).toContain('Did not find Alex via the base');
|
||||
});
|
||||
|
||||
it('"Carol" within "Alex" should have "Alex" parent', () => {
|
||||
it('"Carol" within "Alex" should have "Alex" parent', function () {
|
||||
expect(carol1.getText()).toContain('Alex');
|
||||
});
|
||||
|
||||
it('"Carol" within "Barry" should have "Barry" parent', () => {
|
||||
it('"Carol" within "Barry" should have "Barry" parent', function () {
|
||||
expect(carol2.getText()).toContain('Barry');
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
const routes: Routes = [];
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion import-services
|
||||
import { LoggerService } from './logger.service';
|
||||
import { LoggerService } from './logger.service';
|
||||
import { UserContextService } from './user-context.service';
|
||||
import { UserService } from './user.service';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
|
@ -1,26 +1,26 @@
|
||||
// #docregion
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
|
||||
// import { AppRoutingModule } from './app-routing.module';
|
||||
// import { AppRoutingModule } from './app-routing.module';
|
||||
import { LocationStrategy,
|
||||
HashLocationStrategy } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
HashLocationStrategy } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { HeroData } from './hero-data';
|
||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||
import { HeroData } from './hero-data';
|
||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { HeroBioComponent } from './hero-bio.component';
|
||||
import { AppComponent } from './app.component';
|
||||
import { HeroBioComponent } from './hero-bio.component';
|
||||
import { HeroBiosComponent,
|
||||
HeroBiosAndContactsComponent } from './hero-bios.component';
|
||||
import { HeroOfTheMonthComponent } from './hero-of-the-month.component';
|
||||
import { HeroContactComponent } from './hero-contact.component';
|
||||
import { HeroOfTheMonthComponent } from './hero-of-the-month.component';
|
||||
import { HeroContactComponent } from './hero-contact.component';
|
||||
import { HeroesBaseComponent,
|
||||
SortedHeroesComponent } from './sorted-heroes.component';
|
||||
import { HighlightDirective } from './highlight.directive';
|
||||
SortedHeroesComponent } from './sorted-heroes.component';
|
||||
import { HighlightDirective } from './highlight.directive';
|
||||
import { ParentFinderComponent,
|
||||
AlexComponent,
|
||||
AliceComponent,
|
||||
@ -30,8 +30,8 @@ import { ParentFinderComponent,
|
||||
CathyComponent,
|
||||
BarryComponent,
|
||||
BethComponent,
|
||||
BobComponent } from './parent-finder.component';
|
||||
import { StorageComponent } from './storage.component';
|
||||
BobComponent } from './parent-finder.component';
|
||||
import { StorageComponent } from './storage.component';
|
||||
|
||||
const declarations = [
|
||||
AppComponent,
|
||||
@ -42,11 +42,11 @@ const declarations = [
|
||||
ParentFinderComponent,
|
||||
];
|
||||
|
||||
const componentListA = [ AliceComponent, AlexComponent ];
|
||||
const a_components = [AliceComponent, AlexComponent ];
|
||||
|
||||
const componentListB = [ BarryComponent, BethComponent, BobComponent ];
|
||||
const b_components = [ BarryComponent, BethComponent, BobComponent ];
|
||||
|
||||
const componentListC = [
|
||||
const c_components = [
|
||||
CarolComponent, ChrisComponent, CraigComponent,
|
||||
CathyComponent
|
||||
];
|
||||
@ -61,9 +61,9 @@ const componentListC = [
|
||||
],
|
||||
declarations: [
|
||||
declarations,
|
||||
componentListA,
|
||||
componentListB,
|
||||
componentListC,
|
||||
a_components,
|
||||
b_components,
|
||||
c_components,
|
||||
StorageComponent,
|
||||
],
|
||||
bootstrap: [ AppComponent ],
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* tslint:disable:one-line*/
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { LoggerService } from './logger.service';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// #docregion
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import { HeroCacheService } from './hero-cache.service';
|
||||
import { HeroCacheService } from './hero-cache.service';
|
||||
|
||||
// #docregion component
|
||||
@Component({
|
||||
|
@ -1,9 +1,9 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { HeroService } from './hero.service';
|
||||
import { LoggerService } from './logger.service';
|
||||
import { HeroService } from './hero.service';
|
||||
import { LoggerService } from './logger.service';
|
||||
|
||||
//////// HeroBiosComponent ////
|
||||
// #docregion simple
|
||||
|
@ -1,7 +1,7 @@
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Hero } from './hero';
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
// #docregion service
|
||||
|
@ -3,7 +3,7 @@
|
||||
import { Component, Host, Optional } from '@angular/core';
|
||||
|
||||
import { HeroCacheService } from './hero-cache.service';
|
||||
import { LoggerService } from './logger.service';
|
||||
import { LoggerService } from './logger.service';
|
||||
|
||||
// #docregion component
|
||||
@Component({
|
||||
|
@ -3,7 +3,7 @@ import { Hero } from './hero';
|
||||
|
||||
export class HeroData {
|
||||
createDb() {
|
||||
const heroes = [
|
||||
let heroes = [
|
||||
new Hero(1, 'Windstorm'),
|
||||
new Hero(2, 'Bombasto'),
|
||||
new Hero(3, 'Magneta'),
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Illustrative (not used), mini-version of the actual HeroOfTheMonthComponent
|
||||
// Injecting with the MinimalLogger "interface-class"
|
||||
import { Component, NgModule } from '@angular/core';
|
||||
import { LoggerService } from './logger.service';
|
||||
import { MinimalLogger } from './minimal-logger.service';
|
||||
import { LoggerService } from './logger.service';
|
||||
import { MinimalLogger } from './minimal-logger.service';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
|
@ -10,12 +10,12 @@ export const TITLE = new InjectionToken<string>('title');
|
||||
import { Component, Inject } from '@angular/core';
|
||||
|
||||
import { DateLoggerService } from './date-logger.service';
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
import { LoggerService } from './logger.service';
|
||||
import { MinimalLogger } from './minimal-logger.service';
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
import { LoggerService } from './logger.service';
|
||||
import { MinimalLogger } from './minimal-logger.service';
|
||||
import { RUNNERS_UP,
|
||||
runnersUpFactory } from './runners-up';
|
||||
runnersUpFactory } from './runners-up';
|
||||
|
||||
// #enddocregion hero-of-the-month
|
||||
// #docregion some-hero
|
||||
|
@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Hero } from './hero';
|
||||
import { Hero } from './hero';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -1,4 +1,5 @@
|
||||
// tslint:disable: component-selector space-before-function-paren
|
||||
/* tslint:disable:no-unused-variable component-selector-name one-line check-open-brace */
|
||||
/* tslint:disable:*/
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Component, forwardRef, Optional, SkipSelf } from '@angular/core';
|
||||
@ -19,7 +20,8 @@ const DifferentParent = Parent;
|
||||
// The `parentType` defaults to `Parent` when omitting the second parameter.
|
||||
// #docregion provide-the-parent
|
||||
export function provideParent
|
||||
// #enddocregion provide-the-parent
|
||||
// #enddocregion provide-parent, provide-the-parent
|
||||
// #docregion provide-parent
|
||||
(component: any, parentType?: any) {
|
||||
return { provide: parentType || Parent, useExisting: forwardRef(() => component) };
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// #docregion
|
||||
import { InjectionToken } from '@angular/core';
|
||||
|
||||
import { Hero } from './hero';
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
// #docregion runners-up
|
||||
@ -22,5 +22,5 @@ export function runnersUpFactory(take: number) {
|
||||
.join(', ');
|
||||
// #docregion factory-synopsis
|
||||
};
|
||||
}
|
||||
};
|
||||
// #enddocregion factory-synopsis
|
||||
|
@ -2,8 +2,8 @@
|
||||
// #docregion
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
/////// HeroesBaseComponent /////
|
||||
// #docregion heroes-base, injection
|
||||
|
@ -1,9 +1,9 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { LoggerService } from './logger.service';
|
||||
import { UserService } from './user.service';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
// #docregion injectables, injectable
|
||||
@Injectable({
|
||||
@ -24,7 +24,7 @@ export class UserContextService {
|
||||
// #enddocregion ctor, injectables
|
||||
|
||||
loadUser(userId: number) {
|
||||
const user = this.userService.getUserById(userId);
|
||||
let user = this.userService.getUserById(userId);
|
||||
this.name = user.name;
|
||||
this.role = user.role;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user