Compare commits

...

186 Commits

Author SHA1 Message Date
Joey Perrott 6ef06bbb38 release: cut the v12.1.4 release (#42981)
PR Close #42981
2021-07-28 11:34:19 -07:00
codebriefcase c7e4f14bc8 docs: include interpolations in the "What is Angular" example (#42702)
Affected URL - https://angular.io/guide/what-is-angular#template

Fixes #42665

PR Close #42702
2021-07-28 10:53:33 -07:00
Paul Gschwendtner 9d6fdd0af0 feat(dev-infra): introduce release action for directly branching-off into RC (#42973)
Introduces a new release action for cutting a release-action by directly
moving the next release-train into the `release-candidate` phase.

This allows the Angular team to release minor versions without
needing to branch-off first into the feature-freeze phase. For
minors this phase can be skipped. Switching into the feature-freeze
phase beforehand as a workaround would have allowed for branching-off
but has the downside that `target: minor` would no longer point to the
branched-off release train (only `target: rc` would work then).

PR Close #42973
2021-07-28 10:50:24 -07:00
Dylan Hunn 5474f80f6a Revert "refactor(compiler-cli): add makeTemplateDiagnostic wrapper (#42937)" (#42971)
This reverts commit bb5facbcd2.

PR Close #42971
2021-07-27 14:14:32 -07:00
George Kalpakas 3e1657d560 fix(docs-infra): notify ErrorHandler of UnrecoverableState errors (#42941)
With this commit, the `ErrorHandler` is notified of ServiceWorker
`UnrecoverableState` errors. The main purpose of this change is
gathering info about the occurrence (and frequency) of such errors in
Google analytics.

PR Close #42941
2021-07-27 09:23:15 -07:00
Andrew Scott 6e55752ad4 ci: add atscott to fw-compiler reviewers (#42963)
add atscott to fw-compiler reviewers

PR Close #42963
2021-07-27 09:22:50 -07:00
Vladyslav 0bf6ab4066 docs: updated input-output page documentation content (#42964)
PR Close #42964
2021-07-27 09:22:20 -07:00
Daniel Trevino bb5facbcd2 refactor(compiler-cli): add makeTemplateDiagnostic wrapper (#42937)
Add a `makeTemplateDiagnostic` wrapper in the `TemplateTypeChecker`. This requiers less parameters to create template diagnostics, since the `TemplateTypeChecker` can get the templateId and mapping from it's scope with the `ts.ClassDeclartion`. The `TemplateTypeChecker` is often used to determine if a diagnostic should be produced, so it makes sense to have a function in it that helps create them.

Refs #42966

PR Close #42937
2021-07-26 18:00:46 -07:00
JoostK 77ae4459d3 fix(compiler-cli): use correct module resolution context for absolute imports in .d.ts files (#42879)
The compiler keeps track of how a declaration has been referenced
using absolute module imports and from which path the absolute module
should be resolved from. There was a bug in how the .d.ts metadata
extraction would incorrectly use the .d.ts file itself as resolution
context for symbols that had been imported using a relative module
specifier. This could result in module resolution failures.

For example, when extracting NgModule metadata from
`/node_modules/lib/index.d.ts` that looks like

```
import {LibDirective} from './dir';

@NgModule({
  declarations: [LibDirective],
  exports: [LibDirective],
})
export class LibModule {}
```

and `/app.module.ts` that contains

```
import {LibModule} from 'lib';

@NgModule({
  imports: [LibModule],
})
export class AppModule {}
```

then `AppModule` would have recorded a reference to `LibModule` using
the `'lib'` module specifier. When extracting the NgModule metadata from
the `/node_modules/lib/index.d.ts` file the relative import into `./dir`
should also be assumed to be importable from `'lib'` (according to APF
where symbols need to be exported from a single entry-point)
so the reference to `LibDirective` should have `'lib'` as absolute
module specifier, but it would incorrectly have
`/node_modules/lib/index.d.ts` as resolution context path. The latter is
incorrect as `'lib'` needs to be resolved from `/app.module.ts` and not
from within the library itself.

Fixes #42810

PR Close #42879
2021-07-26 13:17:45 -07:00
Paul Gschwendtner 0736882836 build: remove ts-api-guardian from repository (#42735)
This commit removes `ts-api-guardian` from the repository. We introduced
a new tool for testing API signature that is part of the shared
dev-infra package. The TS API guardian package will be deprecated for
the public in favor of Microsoft's API extractor that has support for
more parts of the syntax, such as alias exports.

PR Close #42735
2021-07-26 12:02:15 -07:00
Yuvaraj 5cffdd0e54 docs: fix the selector in component interaction guide (#42891)
The selector for the `CountdownTimerComponent` is `app-countdown-timer`
not `countdown-timer`.

PR Close #42891
2021-07-26 11:47:56 -07:00
Teri Glover e8eb87ff58 docs: Edits to remove jargon (#42861)
PR Close #42861
2021-07-23 17:12:51 -07:00
Andrew Scott ee1f824c40 test(router): move computed state restoration tests to own file (#42933)
To reduce the enormouse size of the integration.spec.ts file, move tests related to the computed
state restoration to their own file.

PR Close #42933
2021-07-23 14:25:07 -07:00
Andrew Scott 1e7644d560 refactor(router): Ensure computed state restoration works for thrown errors (#42933)
When `canceledNavigationResolution='computed'`, the `Router` needs to
handle the cases where errors are thrown. Previously, the logic was not
updated and would simply do a `replaceState` rather than determining
where in the history we should move to restore the page/url from before
the failed navigation.

PR Close #42933
2021-07-23 14:25:07 -07:00
Joey Perrott 0b8f3a14b3 ci: update pullapprove config to properly handle global approvals (#42929)
Update the config to properly identify a global approval as approved rather than
as no file matching based groups being matched.

PR Close #42929
2021-07-23 12:09:27 -07:00
Andrew Scott e242d1da14 docs: Add import line to router event example for clarification (#42935)
Without the `import {Event} from '@angular/router';`, the filter will
not work because the type is understood as the native `Event`.

Fixes #42920

PR Close #42935
2021-07-23 12:06:35 -07:00
Joey Perrott 772dbe8a8e feat(dev-infra): include experimental version stamp in env stamps (#42934)
Include the determined experimental version for stamping in the env stamps
created for release and snapshot builds.

PR Close #42934
2021-07-23 10:37:09 -07:00
George Kalpakas 065d263547 build(docs-infra): upgrade cli command docs sources to 0ab046223 (#42944)
Updating [angular#12.1.x](https://github.com/angular/angular/tree/12.1.x) from
[cli-builds#12.1.x](https://github.com/angular/cli-builds/tree/12.1.x).

##
Relevant changes in
[commit range](https://github.com/angular/cli-builds/compare/18bbd044d...0ab046223):

**Modified**
- help/generate.json

PR Close #42944
2021-07-23 10:36:22 -07:00
Renovate Bot a69edc487f build: update dependency globby to v12 (#42945)
Update dependency `globby` to v12.

PR Close #42945
2021-07-23 10:35:30 -07:00
George Kalpakas 246cdadcdc build(docs-infra): switch the example-e2e script to ESM (#42945)
Switch the JS script used for running the docs examples tests from
CommonJS to ESM format. This is necessary for upgrading the `globby`
dependency to [version 12.0.0][1] in a subsequent commit.

[1]: https://github.com/sindresorhus/globby/releases/v12.0.0

PR Close #42945
2021-07-23 10:35:30 -07:00
George Kalpakas da0dabc6b4 build(docs-infra): switch the generate-stackblitz/zips scripts to ESM (#42945)
Switch the JS scripts used for generating StackBlitz projects and zips
from CommonJS to ESM format. This is necessary for upgrading the
`globby` dependency to [version 12.0.0][1] in a subsequent commit.

[1]: https://github.com/sindresorhus/globby/releases/v12.0.0

PR Close #42945
2021-07-23 10:35:30 -07:00
Joey Perrott c20103c7ca refactor(dev-infra): move semver utils into the utils directory (#42917)
Move semver into the utils directory rather than as a set of utils specifically
for release tooling.  While the utils are only currently used in the release
tooling, they are not providing a release specific utility and can be used by
any subtool of ng-dev.

PR Close #42917
2021-07-22 18:01:19 +00:00
Joey Perrott 11bc6fffa2 fix(dev-infra): fix creating experimental semver versions to include prerelease chunk (#42917)
SemVers created for experimental versions should also include the prerelease chunk (i.e. -next.3).

PR Close #42917
2021-07-22 18:01:18 +00:00
Joey Perrott c06516c9db Revert "fix(dev-infra): perform actual npm login verification for wombot proxy (#42871)" (#42917)
This reverts commit fd92a3e87f.

It turns out that wombot proxy will return who is logged in, but does so regardless of
if the users token is currently active.  Since we cannot rely on `npm whoami` to
determine the login state, we revert to our previous state of assuming new login is
needed.

PR Close #42917
2021-07-22 18:01:18 +00:00
Pete Bacon Darwin 268ba5c4ca ci: fix typo in docs-bug issue template (#42908)
"browser specific" should be replaced with "browser-specific" because it's a compound modifier (cf. https://en.wikipedia.org/wiki/Compound_modifier).

See #42906

PR Close #42908
2021-07-22 16:25:40 +00:00
Pete Bacon Darwin dda23b9cb0 docs: fix spacing in code style guide (#42908)
Fixes #42906

PR Close #42908
2021-07-22 16:25:40 +00:00
Teri Glover c2d3f60da0 docs: Edits to remove jargon (#42907)
PR Close #42907
2021-07-22 16:24:16 +00:00
JoostK f589b01672 perf(compiler-cli): skip analysis in incremental builds for files without Angular behavior (#42562)
In an incremental rebuild, the compiler attempts to reuse as much
analysis data from a prior compilation as possible to avoid doing the
analysis work again. For source files without Angular behavior however,
no analysis data would be recorded such that the source file had to be
reanalyzed each rebuild, even if it has not changed.

This commit avoids the analysis of such source files by registering
these files as not containing any Angular behavior; allowing subsequent
rebuilds to avoid the analysis work.

PR Close #42562
2021-07-21 22:40:39 +00:00
George Kalpakas a779a1029b fix(core): correctly handle null or undefined in ErrorHandler#handleError() (#42881)
Since `ErrorHandler#handleError()` expects an argument of type `any` it
should be able to handle values such as `null` and `undefined`.
Previously, it failed to handle these values, because it was trying to
access properties on them.

This commit fixes it by ensuring no properties are accessed on `null` or
`undefined` values.

NOTE: This is part of fully addressing #28106.

Fixes #21252

PR Close #42881
2021-07-21 22:35:35 +00:00
Paul Gschwendtner 4307d6e5bd ci: no longer use deprecated pullapprove_conditions option (#42895)
PullApprove deprecated the `pullapprove_conditions` config
option and introduced the `overrides` option. This commit
migrates to the new option, while also eliminating the
`fallback` group with a simple override (as per recommendation
from the pull approve docs).

PR Close #42895
2021-07-21 22:34:25 +00:00
Joey Perrott 879bf22823 refactor(dev-infra): remove usages and dependency on shelljs (#42911)
Remove usages of shelljs and instead use spawn/spawnSync.

PR Close #42911
2021-07-21 22:33:38 +00:00
Joey Perrott b3328a9722 refactor(dev-infra): add spawnSync to child process utils, normalize naming of child-process utils (#42911)
Create a `spawnSync` command for common usage, additionally update naming to use `spawn` instead of
`spawnWithDebugOutput`

PR Close #42911
2021-07-21 22:33:38 +00:00
Alex Rickabaugh b0854e2ec6 release: cut the v12.1.3 release (#42914)
PR Close #42914
2021-07-21 14:32:51 -07:00
George Kalpakas 29f50976db fix(docs-infra): fix keyword color in CLI pages code blocks (#42889)
Previously, names of CLI commands that also happened to be keywords were
shown in black color in the code block demonstrating the command's
usage. This worked fine when in light mode (where the code block
background is white) but not in the recently introduced dark mode (where
the code block background is dark gray).

This commit fixes this by ensuring the `.kwd` token color is inherited
from its parent (which has an appropriate color for the current theme).
Previously, the `.kwd` token was reset to its initial value (which is
`black` regardless of the theme).

**Before:** ![CLI pages keyword before][1]
**After:** ![cli-pages-keyword after][2]

[1]: https://user-images.githubusercontent.com/8604205/126073803-af317f0c-d04f-4c3a-9a83-e92541d7dd5a.png
[2]: https://user-images.githubusercontent.com/8604205/126073806-1d57e3ed-90b1-4735-ae2a-d0a39862bb95.png

PR Close #42889
2021-07-20 11:56:34 -07:00
JoostK d207ea06d1 fix(compiler-cli): use correct module import for types behind a forwardRef (#42887)
The static interpreter assumed that a foreign function expression would
have to be imported from the absolute module specifier that was used for
the foreign function itself. This assumption does not hold for the
`forwardRef` foreign function resolver, as that extracts the resolved
expression from the function's argument, which is not behind the
absolute module import of the `forwardRef` function.

The prior behavior has worked for the typical usage of `forwardRef`,
when it is contained within the same source file as where the static
evaluation started. In that case, the resulting reference would
incorrectly have an absolute module guess of `@angular/core`, but the
local identifier emit strategy was capable of emitting the reference
without generating an import using the absolute module guess.

In the scenario where the static interpreter would first have to follow
a reference to a different source that contained the `forwardRef` would
the compilation fail. In that case, there is no local identifier
available such that the absolute module emitter would try to locate the
imported symbol from `@angular/core`. which fails as the symbol is not
exported from there.

This commit fixes the issue by checking whether a foreign expression
occurs in the same source file as the call expression. If it does, then
the absolute module specifier that was used to resolve the call
expression is ignored.

Fixes #42865

PR Close #42887
2021-07-20 11:56:07 -07:00
Joey Perrott 18e2dba7ae fix(dev-infra): use the version from package.json rather than tags (#42872)
Use the version value from the primary package.json file rather than
checking the branch for the latest semver tag.  This allows for us
to explictly create changelogs from the previous version to the new
version.

PR Close #42872
2021-07-20 11:30:34 -07:00
Joey Perrott e31eaf8595 feat(dev-infra): update package version verification to allow for experimental version (#42898)
The angular-cli repo publishes experimental versioned packages in addition to standard
versioned packages.  Both experimental and standard verions, based on the expected new
version provided are treated as valid and correct.

PR Close #42898
2021-07-20 11:30:01 -07:00
dario-piotrowicz e6b7472d11 build(docs-infra): improve @usageNotes message (#42888)
improve the @usageNotes message by adding the word "is"
(outcome: "Further information is available in...", compared to
"Further information available in...")

PR Close #42888
2021-07-19 17:37:57 -07:00
JoostK a6db152c78 fix(core): use correct injector when resolving DI tokens from within a directive provider factory (#42886)
When a directive provides a DI token using a factory function and
interacting with a standalone injector from within that factory, the
standalone injector should not have access to either the directive
injector nor the NgModule injector; only the standalone injector should
be used.

This commit ensures that a standalone injector never reaches into the
directive-level injection context while resolving DI tokens.

Fixes #42651

PR Close #42886
2021-07-19 17:36:30 -07:00
George Kalpakas 778edfc63c fix(docs-infra): prevent main content from overlapping with ToC (#42884)
Previously, if there was more content than what would horizontally fit
in the main content area, it would overflow to the right and overlap
with the Table of Contents (ToC).
This was accidentally introduced in #42787.

This commit fixes it by ensuring that the main content area will not
overlap with ToC and the necessary space for the ToC will be reserved
using `margin` (instead of `padding`, which contributes to the element's
size).

Fixes #42867

PR Close #42884
2021-07-19 17:35:36 -07:00
George Kalpakas 89893972c8 fix(docs-infra): correctly handle reported errors (#42883)
Error-handling in AIO happens mainly in two places:
1. For errors happening inside the app we have a custom `ErrorHandler`
   implementation, `ReportingErrorHandler`. `ReportingErrorHandler`
   passes errors to the default `ErrorHandler` (for them to be logged to
   the console) and also forwards them to `window.onerror()`.
2. Errors happening outside the app and errors forwarded by
   `ReportingErrorHandler` are handled by `window.onerror()`, which in
   turn reports them to Google analytics.

Previously, we were making some assumptions (which turned out to be
incorrect based on the info captured in Google analytics - see #28106):
- `ReportingErrorHandler` assumed that the errors passed to its
  `handleError()` method would be either strings or `Error` instances.
  _Apparently, other values (such as `null` or `undefined`) may also be
  passed._
- `window.onerror()` assumed that if an `Error` instance was passed in,
  it would always have a stacktrace (i.e. its `stack` property would be
  defined).
  _This is not necessarily true, although it is not clear (based on the
  logs) whether reported errors of this type are caused by `Error`
  instance with no stacktrace or by non-string error objects which are
  incorrectly treated as `Error` instances.

This commit ensures that all types of error arguments can be handled
correctly, including `Error` instances with no stacktrace and other
types of objects or primitives.

NOTE:
PR #42881 is related as it fixes handling `null` and `undefined`
arguments in the default `ErrorHandler`.

Fixes #28106

PR Close #42883
2021-07-19 17:35:03 -07:00
Paul Gschwendtner aeff926381 feat(dev-infra): add option to setup global types in API golden test (#42876)
Previously we disabled automatic type-resolution for the API
extractor because in non-sandbox environments this resulted in
different API reports. There are cases where global types are
still needed for analysis of an entry-point. To support this,
we add a new property called `types` which allows for explicit
type targets being specified.

Note that we do not want to determine types from the `data`
runfiles because API extractor itself also brings in types
which should not always be part of the API report analysis.

PR Close #42876
2021-07-19 17:33:20 -07:00
Paul Gschwendtner 24cc1441f5 ci: remove RBE workaround from components-repo-unit-tests job (#42875)
In the past when we had issues with our RBE instance, we wanted
to get CI green as soon as possible, and couldn't wait on the
components repo to land their RBE instance fix. We manually
fixed the RBE instance name using a CI step using `sed`.

This is no longer needed if we update to the most recent
state of the components repository.

PR Close #42875
2021-07-19 17:32:44 -07:00
Paul Gschwendtner 6eea132952 build: remove unnecessary husky gitignore file (#42870)
We recently updated to Husky v7 through Renovate, but
as of Husky v7, a `.gitignore` file is no longer needed.

This commit removes the file.

PR Close #42870
2021-07-19 17:31:55 -07:00
Paul Gschwendtner a47ea85c5e ci: exempt bazel scope from merge tool target label checks (#42869)
Currently, changes with the `bazel` scope are guarded by the
merge tool target label checks. i.e. feature commits with
the `bazel` scope cannot land in the patch branch. This is
expected for all public packages, but given the `bazel`
package being used internal-only, it should be possible
to land these in a patch branch. Especially since we want
tooling to be in sync between version branches as much
as possible.

PR Close #42869
2021-07-19 17:29:02 -07:00
Joey Perrott 9ee4441c55 fix(dev-infra): prevent verbose messaging of git checkout and commit for release (#42871)
Prevent logging verbose messages to the output for commit and checkout during
the release process.

PR Close #42871
2021-07-19 17:15:55 -07:00
Joey Perrott e7b3b34e62 fix(dev-infra): perform actual npm login verification for wombot proxy (#42871)
Previously the wombot proxy was not able to be queried for login state, now
that it is able to be checked via `npm whoami` a specific alternate flow
is no longer needed.

PR Close #42871
2021-07-19 17:15:54 -07:00
Joey Perrott ca2165e8df refactor(dev-infra): provide entire pull request object to waitForPullRequestToBeMerged (#42871)
`waitForPullRequestToBeMerged` should get the entire `PullRequest` object rather than
just the id to allow it to have more information/context for logging and messaging.

PR Close #42871
2021-07-19 17:15:54 -07:00
Joey Perrott d845643ba1 fix(dev-infra): don't pollute standard out during commit message hooks (#42871)
When a commit message is not restored, there is not need to log this to
stdout.  It is a better experience to silently succeed.

PR Close #42871
2021-07-19 17:15:54 -07:00
dario-piotrowicz 8f109da1c8 refactor(animations): remove unused animation trigger imports (#42763)
in the animation_trigger.ts file there are unused imports
remove them to clean up the file

PR Close #42763
2021-07-19 17:13:46 -07:00
dario-piotrowicz 6de37b8f0a refactor(animations): remove publicApi annotations from triggers (#42763)
the buildTrigger function and AnimationTrigger class are annotated
as publicApi which seems wrong and makes changes to the two
problematic, so they are being removed here

see: https://github.com/angular/angular/pull/42763/files#r671481902

PR Close #42763
2021-07-19 17:13:46 -07:00
dario-piotrowicz 3cddc3d6bc fix(animations): normalize final styles in buildStyles (#42763)
the final styles created in buildStyles lack normalization, meaning that pixel values remain as numbers (without "px") and so such properties fail to be correctly set/applied

Example: "width: 300" is applies as "width": "300" (and thus ignored) instead of the correct "width": "300px"

PR Close #42763
2021-07-19 17:13:46 -07:00
dario-piotrowicz 0dfb4e8c8b refactor(animations): fix typo in transition animations spec file (#42763)
fix the typo "mean't" in the transition_animation_engine spec file
to "meant" (the typo is simply in a code comment so the change
does not have any impact)

PR Close #42763
2021-07-19 17:13:46 -07:00
Joey Perrott 97fa1cf544 build: add configuration for caretaker handoff (#42859)
Add configuration information about groups for caretaker handoff assistant.

PR Close #42859
2021-07-15 13:34:59 -07:00
Joey Perrott 9d4b580c12 feat(dev-infra): create caretaker handoff assistant to update github team membership (#42859)
Create a handoff assistant, currently only assists in updating github team membership
for caretaking team.

PR Close #42859
2021-07-15 13:34:59 -07:00
Minko Gechev 0ef8b01804 docs: remove reference to an obsolete design doc (#42842)
The type checking design document is no longer relevant. This PR
removes the reference to it. Close #42424.

PR Close #42842
2021-07-15 13:24:58 -07:00
David Shevitz c06cbb2ec4 docs: remove references to future in topic (#42841)
Fixes #25704

PR Close #42841
2021-07-15 13:23:28 -07:00
dario-piotrowicz 688b1c5b53 docs(docs-infra): remove unnecessary "Podcast" from happy-angular podcast's title (#42756)
PR Close #42756
2021-07-15 13:22:04 -07:00
dario-piotrowicz 12ad314d5a docs(docs-infra): add the angular show to the podcast resources (#42756)
PR Close #42756
2021-07-15 13:22:04 -07:00
dario-piotrowicz 8b9aea9503 docs(docs-infra): podcast keys cleanup in resources.json (#42756)
PR Close #42756
2021-07-15 13:22:04 -07:00
dario-piotrowicz 1d9d74a2d1 docs(docs-infra): remove deep dive from podcast resources (#42756)
PR Close #42756
2021-07-15 13:22:03 -07:00
JoostK d4567b28f7 refactor(core): expand error logging when the JIT compiler is not available (#42693)
If a decorator or partial declaration has not been AOT compiled, then
the compiler is needed at runtime to be able to JIT compile the code.
However, it may occur that the compiler is not available, if it has not
been loaded into the application. The error that was reported in this
case did not provide insight into which class requested compilation, nor
did it differentiate between decorators vs. partial declarations.

This commit expands the error logging to provide better insight into the
class that initiated JIT compilation and offers a specialized error
message for partial declarations. This should help a developer better
understand why the error occurs and what can be done to resolve it.

Closes #40609

PR Close #42693
2021-07-15 13:19:05 -07:00
JoostK e6d520f3d9 perf(compiler-cli): optimize cycle detection using a persistent cache (#41271)
For the compilation of a component, the compiler verifies that the
imports it needs to generate to reference the used directives and pipes
would not create an import cycle in the program. This requires visiting
the transitive import graphs of all directive/pipe usage in search of
the component file. The observation can be made that all directive/pipe
usages can leverage the exploration work in search of the component
file, thereby allowing sub-graphs of the import graph to be only visited
once instead of repeatedly per usage. Additionally, the transitive
imports of a file are no longer collected into a set to reduce memory
pressure.

PR Close #41271
2021-07-15 13:13:49 -07:00
Krzysztof Kotowicz e6f01d777d revert: docs: remove references to Trusted Types due to incompatibility with Webpack 5 (#42796)
Re-add reference to Trusted Types since the issue #41754 is resolved in 12.1.1.

This reverts commit 7254fbc2baa1455e3b24400597342843df3017f2.

PR Close #42796
2021-07-14 11:14:08 -07:00
Alan Agius fa3e7f87e7 docs: remove End-to-end test files structure (#42844)
Since version 12, the Angular CLI no longer generates end-to-end tests.

PR Close #42844
2021-07-14 11:12:42 -07:00
David Shevitz 8d184f9a31 docs: update incorrect bullet text (#42839)
Fixes #42286

PR Close #42839
2021-07-14 11:11:56 -07:00
Andrew Kushnir 2a61728137 release: cut the v12.1.2 release (#42856) 2021-07-14 10:47:57 -07:00
JoostK 63013546e1 fix(core): associate the NgModule scope for an overridden component (#42817)
When using `TestBed.overrideComponent`, the overridden component would
incorrectly lose access to its NgModule's declaration scope if the
NgModule had been imported into the testing NgModule as a
`ModuleWithProviders`, e.g. using a `forRoot` call.

The issue occurred as the `TestBed` compiler did not consider NgModules
that had been imported as a `ModuleWithProviders` when associating
NgModules with component overrides. This caused the overridden component
to be compiled standalone, meaning that it does not have access to
its NgModule's declarations. This commit extends the logic for
traversing the NgModule graph to also consider `ModuleWithProviders`
imports.

Fixes #42734

PR Close #42817
2021-07-13 15:59:28 -07:00
JoostK 9ebd41e39c fix(core): allow proper type inference when ngFor is used with a trackBy function (#42692)
In #41995 the type of `TrackByFunction` was changed such that the
declaration of a `trackBy` function did not cause the item type to be
widened to the `trackBy`'s item type, which may be a supertype of the
iterated type. This has introduced situations where the template type
checker is now reporting errors for cases where a `trackBy` function is
no longer assignable to `TrackByFunction`.

This commit fixes the error by also including the item type `T` in
addition to the constrained type parameter `U`, allowing TypeScript to
infer an appropriate `T`.

Fixes #42609

PR Close #42692
2021-07-13 14:08:06 -07:00
David Shevitz 34b2669d3a docs: update routing-overview topic with link to custom route matches tutorial (#42837)
PR Close #42837
2021-07-13 14:07:16 -07:00
Meir Blumenfeld d654c7933a fix(common): re-sort output of KeyValuePipe when compareFn changes (#42821)
Previously, if only the `compareFn` changed but the data itself did not, then
the `KeyValuePipe` did not re-sort the output.

Fixes #42819

PR Close #42821
2021-07-13 11:33:21 -07:00
Mark Goho b101ad0d98 docs: clarify voting phase for feature requests (#42663)
PR Close #42663
2021-07-12 15:25:46 -07:00
Andrew Kushnir 75a11d9ac8 Revert "refactor(dev-infra): add spawnSync to child process utils, normalize naming of child-process utils (#42394)" (#42829)
This reverts commit 08444c6679.

PR Close #42829
2021-07-12 15:24:55 -07:00
Andrew Kushnir 2cdf074034 Revert "refactor(dev-infra): remove usages and dependency on shelljs (#42394)" (#42829)
This reverts commit f0d857eff8.

PR Close #42829
2021-07-12 15:24:55 -07:00
Kristiyan Kostadinov 2566cbb48c fix(compiler): add mappings for all HTML entities (#42818)
Angular inserts text either through text nodes (`document.createTextNode`) or using `textContent`, but the drawback of doing so is that HTML entities won't be decoded. In order to work around it, the compiler has some logic that maps the entities to their unicode representation which can safely be inserted. The problem is that our current mapping is arbitrarily limited which means that some entities will be mapped while others will throw an error, even though they're valid.

These changes expand the list to cover all entities that are supported by the HTML spec.

Fixes #41186.

PR Close #42818
2021-07-12 14:41:21 -07:00
Joey Perrott afeab76497 refactor(dev-infra): remove usages and dependency on shelljs (#42394)
Remove usages of shelljs and instead use spawn/spawnSync.

PR Close #42394
2021-07-12 14:39:08 -07:00
Joey Perrott bfb738c3c3 refactor(dev-infra): add spawnSync to child process utils, normalize naming of child-process utils (#42394)
Create a `spawnSync` command for common usage, additionally update naming to use `spawn` instead of
`spawnWithDebugOutput`

PR Close #42394
2021-07-12 14:39:08 -07:00
Paul Gschwendtner eeef3e7479 fix(dev-infra): transitive targets cannot be resolved by API extractor (#42828)
For API golden tests not running against a NPM package, we extract
all transitive declarations of the specified `data` targets. This is
necessary because API extractor needs to resolve other targets that have
been linked by the Bazel NodeJS rules. The linker by default only
provides access to JavaScript sources, but the API extractor is
specifically concerned with type definitions that we need to manually
extract.

PR Close #42828
2021-07-12 14:38:05 -07:00
Paul Gschwendtner c2e5d76674 fix(dev-infra): do not include all types in api golden test (#42828)
The API golden test tool should not include all types
from the `node_modules/`. This results in unnecessary
type resolution when the API golden tool is run outside
of sandbox (i.e. on windows or with `bazel run` for accept).

PR Close #42828
2021-07-12 14:38:05 -07:00
Paul Gschwendtner d249665bd2 feat(dev-infra): better caching for browser archive contents (#42814)
Adds better caching for browser archives and their extraction.
This is done because the archives are currently extracted as a build
action and these are actions are invalidated frequently, causing
flakiness on the CI and slow-down in local development.

Here is an example flaky error on the CI (that surfaces often
with RBE execution):

```
ERROR:
/home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/external/npm/@angular/dev-infra-private/bazel/browsers/chromium/BUILD.bazel:22:17:
Extracting ../org_chromium_chromium_amd64/file/chrome-linux.zip failed:
(Exit 34): extract.sh failed: error executing command
external/io_bazel_rules_webtesting/web/internal/extract.sh
external/org_chromium_chromium_amd64/file/chrome-linux.zip ...
(remaining 2 argument(s) skipped). Note: Remote connection/protocol
failed with: execution failed
```

We fix this by introducing a new rule that downloads a browser
archive and unpacks it directly into a Bazel repository. Before
this change, the archive would just be downloaded but extracted
later as part of a build action. This is unnecessary and results
in less efficient caching as build actions are invalidated more
often, especially if developers run `bazel clean` in between.

The root cause on why the extraction often fails in RBE containers
is unclear. It's unclear why the extacted archive is not cached
properly as part of a build action (most likely some hermeticity
issue within `rules_webtesting`, but it seems more Bazel-idiomatic
to unpack the archives as part of the repository anyway, and this solves
the flakiness issue.

PR Close #42814
2021-07-12 14:37:10 -07:00
Pete Bacon Darwin 4f8a7280c1 docs: move start tutorial alert for clarity (#42764)
The alert was placed in the middle of a set of steps, which
was causing some confusion. This has been moved to the
above the steps in the section and slightly reworded to
make it clearer.

Fixes #42752

PR Close #42764
2021-07-12 13:20:13 -07:00
Paul Gschwendtner 04472d23c2 refactor: add override keyword to members implementing abstract declarations (#42512)
In combination with the TS `noImplicitOverride` compatibility changes,
we also want to follow the best-practice of adding `override` to
members which are implemented as part of abstract classes. This
commit fixes all instances which will be flagged as part of the
custom `no-implicit-override-abstract` TSLint rule.

PR Close #42512
2021-07-12 13:11:20 -07:00
Paul Gschwendtner 8dbae89ed4 feat(dev-infra): add lint rule to enforce no-implicit-override abstract members (#42512)
TypeScript introduced a new flag called `noImplicitOverride` as part
of TypeScript v4.3. This flag introduces a new keyword called `override`
that can be applied to members which override declarations from a base
class. This helps with code health as TS will report an error if e.g.
the base class changes the method name but the override would still
have the old method name. Similarly, if the base class removes the method
completely, TS would complain that the memeber with `override` no longer
overrides any method.

A similar concept applies to abstract methods, with the exception that
TypeScript's builtin `noImplicitOverride` option does not flag members
which are implemented as part of an abstract class. We want to enforce
this as a best-practice in the repository as adding `override` to such
implemented members will cause TS to complain if an abstract member is
removed, but still implemented by derived classes.

More details: https://github.com/microsoft/TypeScript/issues/44457.

PR Close #42512
2021-07-12 13:11:20 -07:00
Paul Gschwendtner 6e13179fe1 refactor: ensure compatibility with noImplicitOverride for examples (#42512)
Adds the `override` keyword to the `examples` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:20 -07:00
Paul Gschwendtner 1a66199a7f refactor(zone.js): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `zone.js` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:20 -07:00
Paul Gschwendtner 9e8a919385 refactor(localize): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `localize` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:20 -07:00
Paul Gschwendtner 367ef56224 refactor(language-service): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `language-service` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:20 -07:00
Paul Gschwendtner fdc6786b22 refactor(service-worker): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `service-worker` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:20 -07:00
Paul Gschwendtner b9c1604399 refactor(forms): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `forms` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner 859eb13f98 refactor(elements): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `elements` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner 1f84f01ff9 refactor(common): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `common` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner 462c157e8a refactor(benchpress): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `benchpress` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner 91366401f0 refactor(upgrade): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `upgrade` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner b98b0da37e refactor(router): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `router` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner dffb7c5218 refactor(platform-server): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `platform-server` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner a926402b4c refactor(platform-browser-dynamic): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `platform-browser-dynamic` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner 9067d362d4 refactor(platform-browser): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `platform-browser` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:19 -07:00
Paul Gschwendtner dc661ebda8 refactor(core): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `core` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:18 -07:00
Paul Gschwendtner c1f9d807e6 refactor(animations): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `animations` sources to ensure
 compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:18 -07:00
Paul Gschwendtner 2afaaf0bf9 refactor(dev-infra): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `dev-infra` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:18 -07:00
Paul Gschwendtner 0c9c8f51df refactor(compiler-cli): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `compiler-cli` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:18 -07:00
Paul Gschwendtner cf27076918 refactor(compiler): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `compiler` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:18 -07:00
Paul Gschwendtner 48010b3c73 build: enable noImplicitOverride in project (#42512)
Enables the `noImplicitOverride` option to improve
overall codehealth in the repository.

PR Close #42512
2021-07-12 13:11:18 -07:00
Arthur Ming 91a576db20 refactor(core): optimize the implementation about finding context from error in ErrorHandler (#42581)
in _findContext method, use conditional operator check whether the params 'error' exists and then us reccursion way to find context in original error  if getDebugContext's result does not exist.

PR Close #42581
2021-07-12 12:00:20 -07:00
Arthur Ming 2050d8408d build: update all symbol extractor (#42581)
update all symbol extractor by running 'yarn symbol-extractor:update' script

PR Close #42581
2021-07-12 12:00:19 -07:00
Arthur Ming e1d61243bd refactor(core): optimize the implementation about finding context from error in ErrorHandler (#42581)
in _findContext method, use conditional operator  check whether the params 'error' exists and then use nullish coalescing operator instead conditional operator when getDebugContext's result does not exist.

PR Close #42581
2021-07-12 12:00:19 -07:00
Kristiyan Kostadinov 65330f03a9 fix(compiler): incorrect context object being referenced from listener instructions inside embedded views (#42755)
Currently unless a listener inside of an embedded view tries to reference something from the parent view, or if the reference is a local ref, we don't generate the view restoration instructions and we allow for the value to be picked up from the context object in the function parameters. The problem is that the listener is only run during creation mode and the context object may have been swapped out afterwards.

These changes fix the issue by always generating the view restoration instructions for listeners inside templates.

Fixes #42698.

PR Close #42755
2021-07-12 11:58:19 -07:00
JoostK 17d3de25da fix(compiler-cli): properly emit literal types when recreating type parameters in a different file (#42761)
In #42492 the template type checker became capable of replicating a
wider range of generic type parameters for use in template type-check
files. Any literal types within a type parameter would however emit
invalid code, as TypeScript was emitting the literals using the text as
extracted from the template type-check file instead of the original
source file where the type node was taken from.

This commit works around the issue by cloning any literal types and
marking them as synthetic, signalling to TypeScript that the literal
text has to be extracted from the node itself instead from the source
file.

This commit also excludes `import()` type nodes from being supported,
as their module specifier may potentially need to be rewritten.

Fixes #42667

PR Close #42761
2021-07-12 11:48:34 -07:00
behrooz bozorg chami 2ed5a2db79 docs(core): fix ViewChildren code examples to avoid TS error (#42816)
Add a non-null assertion (`!`) in `ViewChildren` code examples to avoid
a TypeScript error due to uninitialized property.

Fixes #42811

PR Close #42816
2021-07-12 09:48:30 -07:00
Paul Gschwendtner 7dad7dfecd build: update to rules_nodejs v4.0.0-beta.0 (#42813)
Updates the Bazel NodeJS rules to v4.0.0-beta.0. This is necessary
so that the Angular components repo can update, and it's generally
good to stay as up-to-date as possible with the Bazel rules as it's
easy to fall behind, and updating early allows us to discover issues
affecting our tooling earlier (where they are easier to address due to
e.g. potential breaking change policy).

PR Close #42813
2021-07-12 09:46:34 -07:00
Paul Gschwendtner 88b2ff25d7 refactor(bazel): compatibility with rules_nodejs v4.0.0 (#42813)
This commit applies changes to `@angular/bazel` which are necessary
to support the Bazel NodeJS rules v4.0.0. The Bazel NodeJS rules
no longer support the `_tslibrary` option for the `LinkablePackageInfo`
provider and therefore we need to stop using it. Due to this removal,
we also need to add two new attributes called `package_name` and
`package_path` so that the API of `ng_module` matches `ts_library`.

Note: This is denoted as `refactor` as we currently are not able to
merge feature commits into patch branches, but we want the tooling
to not diverge significantly between the patch and next branch. It is
planned to update the merge tooling to allow for such changes to land.

PR Close #42813
2021-07-12 09:46:34 -07:00
Paul Gschwendtner 7b5405b070 build: remove skydoc and rules_sass from repository (#42813)
Skydoc is no longer used as `@angular/bazel` is no longer a
public API. The Sass rules were only used in a single place
in the repo where Sass is not really needed and has just been
added by accident most likely. We want to remove the Sass dependency
in preparation for Rules NodeJS v4.x where the Sass rules currently
still use an older version of `@bazel/worker` that is incompatible.

PR Close #42813
2021-07-12 09:46:34 -07:00
Paul Gschwendtner d8d7784b3a build: remove outdated note when updating bazel version (#42813)
We removed `bazel-toolchains` from the repository since dev-infra
provides the RBE platforms now (in a way where they are not reliant
on the Bazel version), so the comment in `.bazelversion` can be
removed.

PR Close #42813
2021-07-12 09:46:34 -07:00
Paul Gschwendtner f6957b24cd fix(dev-infra): ng_rollup_bundle rule should error if import cannot be resolved (#42813)
Rollup just prints a warning if an import cannot be resolved and ends up
being treated as an external dependency. This in combination with the
`silent = True` attribute for `rollup_bundle` means that bundles might
end up being extremely small without people noticing that it misses
actual imports.

To improve this situation, the warning is replaced by an error if
an import cannot be resolved.

This unveiles an issue with the `ng_rollup_bundle` macro from
dev-infra where imports in View Engine were not resolved but ended
up being treated as external. This did not prevent benchmarks using
this macro from working because the ConcatJS devserver had builtin
resolution for workspace manifest paths. Though given the new check
for no unresolved imports, this will now cause errors within Rollup, and
we need to fix the resolution. We can fix the issue by temporarily
enabling workspace linking. This does not have any performance
downsides.

To enable workspace linking (which we might need more often in the
future given the linker taking over patched module resolution), we
had to rename the `angular` dependency to a more specific one so
that the Angular linker could link into `node_modules/angular`.

PR Close #42813
2021-07-12 09:46:34 -07:00
Paul Gschwendtner 8267d25dfd build: no longer ship ecmascript module files within NPM packages (#42809)
We accidentally started shipping `.mjs` files for the following
modules (or module paths) as of the v12.1.0-next.2 tag:

- `@angular/compiler-cli`
- `@angular/common/locales`
- `@angular/bazel`
- `@angular/benchpress`
- `@angular/core/schematics`
- `@angular/elements/schematics`
- `@angular/language-service`
- `@angular/localize/schematics`,
- `@angular/localize/tools`
- `zone.js`

This did not cause any issues for consumers but we
want to not ship these files without having them wired
up in `package.json` files. We accidentally started shipping
these `.mjs` files due to a NodeJS update which wired up the
other JavaScript module output flavors in the `pkg_npm` rule.

https://github.com/bazelbuild/rules_nodejs/commit/911529fd364eb3ee1b8ecdc568a9fcf38a8b55ca

PR Close #42809
2021-07-12 09:42:02 -07:00
Paul Gschwendtner 71f428679b feat(dev-infra): add bazel rule for extracting JavaScript module flavors from targets (#42809)
Introduces a rule that collects declared JavaScript module output files
from a list of dependencies based on a configurable JavaScript module
provider. The extracted outputs are exposed within the `DefaultInfo` provider.

Targets defined using this rule can be used as input for rules that
require JavaScript sources, or if there are multiple JavaScript output
variants defined for a target while for example only the `JSModuleInfo`
outputs are of interest.

As an example: This rule is helpful in combination with `ts_library` and
`ng_module` as those rule expose multiple output flavors (which are
distinguishable by the JavaScript module providers as imported from `providers.bzl`).
i.e. these rules expose flavors for named AMD modules and ECMAScript module output.
If we want to ship a NPM package only using ECMAScript modules for
example, we could extract all `JSEcmaScriptModuleInfo`-denoted output
and feed that into the `pkg_npm` rule, compared to bringing in all
output flavors.

For reference:
https://github.com/bazelbuild/rules_nodejs/blob/stable/packages/typescript/internal/build_defs.bzl#L334-L337

PR Close #42809
2021-07-12 09:42:01 -07:00
dario-piotrowicz 12a9d2152e docs(core): edit and add docs for ng-template (#42704)
PR Close #42704
2021-07-12 09:39:30 -07:00
Andrew Scott 1c31828620 refactor(router): Adjust behavior for computed navigation restoration (#42751)
When another navigation is triggered during an in-process navigation and
the `canceledNavigationResolution` is `'computed'`, we should not
attempt to restore the browser history using `history.go`. Doing that
would trigger a third navigation through the router which would conflict
with the new navigation that we were trying to process. Instead, we
treat this as a redirect and skip the history restoration attempt. This
acts similarly to returning `UrlTree` from a guard.

Fixes issue described in https://github.com/angular/angular/pull/38884#issuecomment-863767152

PR Close #42751
2021-07-09 10:19:10 -07:00
George Kalpakas 51fd5e3742 fix(docs-infra): fix margin of social icon on small screens (#42790)
This commit fixes the margin of the social icons on small screens. This
mainly affects screens between 420px and 480px, where only one social
icon is show (due to limited space) but not necessarily the first one
(in DOM order).

**Before:** ![social icon before][1]
**After:** ![social icon after][2]

[1]: https://user-images.githubusercontent.com/8604205/124788616-2f5f0200-df52-11eb-9ec2-9e46b90cd286.png
[2]: https://user-images.githubusercontent.com/8604205/124788623-2ff79880-df52-11eb-90ec-31b04973de68.png

PR Close #42790
2021-07-09 10:15:28 -07:00
Bastian 723342a60a docs: fix http example to show actual message in console (#42773)
Previously, the error message in the console would print `[object Object]`
and not the actual error message. With this change, the error message is
printed in the console.

PR Close #42773
2021-07-09 10:14:35 -07:00
Gabriele Franchitto a8d5a31356 docs(core): initializeApp method should return function (#42743)
Update packages/core/src/application_init.ts

Update application_init.ts

Update application_init.ts

Co-Authored-By: George Kalpakas <kalpakas.g@gmail.com>

PR Close #42743
2021-07-08 14:50:18 -07:00
Borislav Ivanov 9ceadb0903 docs(core): fix spelling error (#42783)
Fix spelling error in migration schematics.

PR Close #42783
2021-07-08 14:49:47 -07:00
Joey Perrott f6bce3158a ci: use issue forms for issue creation (#42099)
Use new issue forms from Github for creating issues.

PR Close #42099
2021-07-08 14:07:31 -07:00
mgechev ca4df9c334 ci: update the feature request bot (#42791)
Introduce latest fixes in logging and labeling.

PR Close #42791
2021-07-08 14:06:10 -07:00
George Kalpakas d87917542a fix(service-worker): correctly handle unrecoverable state when a client no longer exists (#42736)
Previously, the ServiceWorker assumed that a client found in
`clientVersionMap` would exist (i.e. it could be retrieved via
`clients.get()`). However, if a browser tab had been closed, the
corresponding client (while present in `clientVersionMap`, which is only
updated on ServiceWorker initialization) would not be retrievable via
`clients.get()`.

This commit fixes it by checking whether the client exists before trying
to notify it about an unrecoverable state.

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas c7a2d76722 refactor(service-worker): switch to the official TypeScript typings (#42736)
Previously, we used custom typings for the ServiceWorker environment.
This was necessary back when the ServiceWorker package was introduced,
since there were no official typings.

Since there are now official typings for Web Workers (including
ServiceWorkers) offered by TypeScript as [lib.webworker.d.ts][1], this
commit gets rid of our custom typings in favor of using the official
ones.

[1]: https://github.com/microsoft/TypeScript/blob/v4.3.4/lib/lib.webworker.d.ts

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas 7b7dce358d test(service-worker): better align mock global scope implementation with actual implementation (#42736)
This commit better aligns the mock `ServiceWorkerGlobalScope`
implementation used in ServiceWorker tests (and the associated typings)
with the actual implementation (and the official TypeScript typings).
This allows verifying the ServiceWorker behavior in a slightly more
realistic environment.

This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas 1670798aa8 test(service-worker): better align mock client implementations with actual implementations (#42736)
This commit better aligns the mock client implementations used in
ServiceWorker tests (and the associated typings) with the actual
implementations (and the official TypeScript typings). This allows
verifying the ServiceWorker behavior in a slightly more realistic
environment.

This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas 305042a945 refactor(service-worker): move mock client classes to their own file (#42736)
In the ServiceWorker tests, we use mock implementations of the various
client APIs that the ServiceWorker interacts with. Previously, these
mock implementations were defined in the `testing/scope.ts` file. This
added several extra classes to a file that already contains a few,
making it harder to maintain.

Therefore, this commit moves these mock client classes to a separate
`testing/clients.ts` file.

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas 8493eb7e65 test(service-worker): better align mock event implementations with actual implementations (#42736)
This commit better aligns the mock event implementations used in
ServiceWorker tests (and the associated typings) with the actual
implementations (and the official TypeScript typings). This allows
verifying the ServiceWorker behavior in a slightly more realistic
environment.

This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas 7fe7836925 refactor(service-worker): move mock event classes to their own file (#42736)
In the ServiceWorker tests, we use mock implementations of the various
events emitted during the ServiceWorker lifecycle. Previously, these
mock implementations were defined in the `testing/scope.ts` file. This
added several extra classes to a file that already contains a few,
making it harder to maintain.

Therefore, this commit moves these mock event classes to a separate
`testing/events.ts` file.

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas 60104086ba refactor(service-worker): make SwTestHarness.envIsSupported() a standalone function (#42736)
This commit makes the `SwTestHarness.envIsSupported()` static method a
standalone function. This function is used to determine whether the
current environment provides the necessary APIs to run the SW tests and
is independent of `SwTestHarness`, so is no need for it to be a static
method of `SwTestHarness`.

This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas 8a79690fdc refactor(service-worker): remove duplicate Context type (in favor of ExtendableEvent) (#42736)
This commit removes the duplicate `Context` interface and uses the
`ExtendableEvent` interface instead.

This is in preparation of switching from our custom typings to the
official TypeScript typings (`lib.webworker.d.ts`).

PR Close #42736
2021-07-08 10:28:23 -07:00
George Kalpakas 0562eae68e refactor(service-worker): remove unused variables and imports from tests (#42736)
This commit removes some unused variables (and associated imports) from
`integration_spec.ts`.

PR Close #42736
2021-07-08 10:28:22 -07:00
David Gilson fbc53e7c2d docs(forms): add diff between add and set control (#42638)
PR Close #42638
2021-07-08 10:27:43 -07:00
George Kalpakas f2523a8fef fix(service-worker): avoid storing redundant metadata for hashed assets (#42606)
The ServiceWorker needs to keep track of some metadata for unhashed
asset resources to know if/when they might need to be revalidated. This
applies to resources that do not exist on the filesystem at build-time
(and thus cannot be hashed), such as fonts or images loaded from
external sources. For hashed resources, this metadata is irrelevant,
because the hash is enough to verify that the content hasn't changed and
no revalidation is necessary.

Previously, the ServiceWorker would store such metadata for hashed
resources as well, even though it would never be used (thus taking up
space unnecessarily).

This commit fixes it by not storing metadata for hashed resources, i.e.
those that are included in an asset-group's `hashes` array.

PR Close #42606
2021-07-08 10:27:16 -07:00
George Kalpakas e6088ab736 docs(service-worker): add missing comma in example JSON data (#42606)
PR Close #42606
2021-07-08 10:27:16 -07:00
JoostK 0a17e98ae2 fix(compiler-cli): inline type checking instructions no longer prevent incremental reuse (#42759)
Source files that contain directives or components that need an inline
type constructor or inline template type-check block would always be
considered as affected in incremental rebuilds. The inline operations
cause the source file to be updated in the TypeScript program that is
created for template type-checking, which becomes the reuse program
in a subsequent incremental rebuild.

In an incremental rebuild, the source files from the new user program
are compared to those from the reuse program. The updated source files
are not the same as the original source file from the user program, so
the incremental engine would mark the file which needed inline
operations as affected. This prevents incremental reuse for these files,
causing sub-optimal rebuild performance.

This commit attaches the original source file for source files that have
been updated with inline operations, such that the incremental engine
is able to compare source files using the original source file.

Fixes #42543

PR Close #42759
2021-07-07 15:17:25 -07:00
George Kalpakas fe602c9c4e fix(docs-infra): ensure the sidenav backdrop covers the floating ToC (#42787)
Previously, on narrow pages where the sidenav was in `over` mode, the
sidenav's backdrop only covered the main docs content but not the
floating Table of Contents (ToC) on the right. This was inconsistent and
confusing to the user, because they could interact with the ToC and
scroll to different area of the main content while the sidenav and
backdrop were still covering the content.

This commit fixes it by ensuring the sidenav backdrop covers both the
main content and the floating ToC (when present).

Fixes #42778

PR Close #42787
2021-07-07 13:40:01 -07:00
George Kalpakas b9ab8b99a1 fix(docs-infra): log more SW debug info (#42776)
This commit expands the info printed to the console to help diagnose
ServiceWorker issues to include the [internal debug info][1] retrieved
from `/ngsw/state`. This will provide more useful data, such as the
activated SW's version, state, clients, recent operations and any recent
errors.

NOTE:
This temporarily increases the payload size. Removing this code and
reclaiming the payload size is being tracked in #41117.

[1]: https://angular.io/guide/service-worker-devops#locating-and-analyzing-debugging-information

PR Close #42776
2021-07-07 13:37:06 -07:00
George Kalpakas 0540a0339e refactor(docs-infra): replace deprecated Sass / division with math.div() (#42776)
This commit replaces the deprecated `/` operators used for division in
Sass files with the [recommended][1] `math.div()` function to get rid of
build warnings ([example][2]).

[1]: https://sass-lang.com/documentation/breaking-changes/slash-div
[2]: https://circleci.com/gh/angular/angular/1017640

PR Close #42776
2021-07-07 13:37:06 -07:00
George Kalpakas 89e7e52041 test(docs-infra): prevent warning due to missing expectation (#42776)
Fix a unit test warning due to Jasmine not realizing that
`httpMock.expectOne()` is an expectation.

[Example][1]:

> WARN: 'Spec 'DocumentService currentDocument should encode the request
> path to be case-insensitive' has no expectations.'

[1]: https://circleci.com/gh/angular/angular/1017640

PR Close #42776
2021-07-07 13:37:06 -07:00
George Kalpakas bdac537852 build(docs-infra): update @angular/* to 12.1.1 (#42776)
Update `@angular/*` packages to latest 12.1.x versions (mainly to take
advantage of recent ServiceWorker improvements, such as #42607
and #42622).

PR Close #42776
2021-07-07 13:37:06 -07:00
George Kalpakas 80e602ca5c build(docs-infra): update payload sizes (#42776)
This commit updates the payload sizes for angular.io to make it easier
to identify payload size changes from an imminent update of `@angular/*`
packages.

PR Close #42776
2021-07-07 13:37:06 -07:00
dario-piotrowicz 9619255dd5 fix(docs-infra): slightly improve top-menu responsiveness (#42753)
make sure that the top-menu links don't get overlapped by
the search input, regardless on the browser's font-size and
the window's width

make also sure that the header's logo does not overlap the search
input on narrow windows, again regardless on the browser's font-size

PR Close #42753
2021-07-07 13:36:38 -07:00
Ryan Andersen eca48016c4 docs: add missing import to CartService tutorial instructions (#42701)
PR Close #42701
2021-07-07 09:54:55 -07:00
Theoklitos Bampouris ec60d10422 docs: change misspelled function (#42742)
Change the router.navigateUrl() to the correct function router.navigate() according to code example.
PR Close #42742
2021-07-07 09:54:24 -07:00
Paul Gschwendtner 9557e87ad8 fix(dev-infra): missing pkg_npm substitution for top-level targets being accessed (#42754)
Currently if a top-level target or file within `//dev-infra` is
being referenced. like `//dev-infra:tsconfig`, then the label
is not subsituted properly and breaks consumption of the built
NPM package.

PR Close #42754
2021-07-02 17:15:18 -07:00
Alan Agius 45116097c1 fix(compiler-cli): support reflecting namespace declarations (#42728)
DTS bundling, will cause originally namespaced imports become namespace declarations within the same file. Example:

Before bundling
```ts
import * as i1 from './router';

export declare class RouterModule {
    constructor(guard: any, router: Router);

    static ɵmod: i0.ɵɵNgModuleDeclaration<RouterModule, [typeof i1.RouterOutlet...]>;
}
```

After bundling
```
declare namespace i1 {
  export {
    RouterOutletContract,
    RouterOutlet
  }
}

export declare class RouterModule {
    constructor(guard: any, router: Router);

    static ɵmod: i0.ɵɵNgModuleDeclaration<RouterModule, [typeof i1.RouterOutlet...]>;
}
```

And therefore this commit adds support for reflecting types that are defined in such namespace declarations.

Closes #42064

PR Close #42728
2021-07-02 15:15:05 -07:00
Alan Agius 4a8ab4f149 fix(bazel): enable dts bundling for Ivy packages (#42728)
It is now possible to bundle DTS files of Ivy libraries since the blocker https://github.com/microsoft/rushstack/issues/1029 has been addressed upstream.

PR Close #42728
2021-07-02 15:15:04 -07:00
Alan Agius 9f8a256467 ci: remove @microsoft/api-extractor from ignoreDeps (#42728)
We can now allow Renovate to manage this dependency.

PR Close #42728
2021-07-02 15:15:04 -07:00
Paul Gschwendtner 6da24e6451 build: update API goldens after api-extractor update (#42749)
Given we have updated API extractor to the most recent
version, we need to update the API goldens because the
latest version uses alias exports to avoid collisions with
default library globals (like `Event`).

PR Close #42749
2021-07-02 12:32:23 -07:00
Paul Gschwendtner f78ab1ed43 build: update api-extractor dependency to support typescript 4.3 (#42749)
Updates the api-extractor dependencies of the repository, and within
the `@angular/bazel` package so that TypeScript 4.3 is supported when
a flattened typings file is generated. Without this update, the api
extractor could fail if a referenced tsconfig use a TS 4.3-only option such as
`noImplicitOverride`.

Note: This could also be considered a `feat:` for `@angular/bazel`,
but this package is not part of the public API anyway and we'd want
that change to land in the patch branches too (to keep the goldens
in sync between release branches as much as possible)

PR Close #42749
2021-07-02 12:32:23 -07:00
Paul Gschwendtner 3df4d898fa fix(dev-infra): api-golden tool does not specify a tsconfig and breaks for consumers (#42749)
Tools that are shipped as a Bazel rule with the shared dev-infra
tool require a specific `tsconfig` as otherwise `ts_library` will
accidentally look for a tsconfig in `@npm//:tsconfig` and the build
will fail. We bring in our dev-infra tsconfig and reference it
explicitly.

PR Close #42749
2021-07-02 12:32:23 -07:00
Paul Gschwendtner a1e9ccb340 fix(dev-infra): use API pagination for retrieving project branches (#42749)
We rely on a Github API `/branches` request to determine the active
release trains. Currently this logic is broken if more than 100
protected branches exist within a repository. This issue surfaced
recently where the `items_per_page` setting was set to `30`, causing
the merge tooling and release tooling to not detect the proper "latest"
release train.

This commit uses Github pagination for retrieving branches to determine
the active release trains, and makes the logic more long-term proof.

PR Close #42749
2021-07-02 12:32:23 -07:00
Paul Gschwendtner 7c9c54922c refactor(dev-infra): update octokit to latest version v18 (#42749)
We previously held off with updating Octokit to v18 due to
their more noticable issues with typings. This commit updates
us to the latest version in order to take advantage of the new
pagination API (which is also strongly-typed), and to not fall
behind too much over time (Octokit seems to change quite often..)

We work around the problem with the types for `getContent` by just
using a type cast with a TODO (and link to the issue). Similarly we
work around a problem where the Octokit types have an incorrect type
for the name of the labels array in an API response.

PR Close #42749
2021-07-02 12:32:23 -07:00
George Kalpakas aa261e7e01 fix(docs-infra): correctly configure top-menu nav-item in the sidenav (#42747)
Previously, the condition for showing the top-menu nav-menu in the
sidenav was the same as that for switching the sidenav mode from docked
(`mode: side`) to floating (`mode: over`). Therefore, the `isWide` input
of the corresponding `NavMenuComponent` could be hard-coded to `false`
(since the component would only be shown when the sidenav was in
floating mode).

In 61f6ed2fdf, these two desicions were
decoupled, which would result in the top-menu nav-item being shown in
the sidenav while the sidenav is in docked mode (and thus the `isWide`
input should be set to `true`).

This commit fixes it by setting the `isWide` input based on the value of
the `dockSideNav` property, as happens for the rest of the nav-menus.

PR Close #42747
2021-07-02 09:23:05 -07:00
George Kalpakas ee3fe6b8a2 refactor(docs-infra): simplify condition for determining sidenav mode (#42747)
Previously, the `AppComponent#showTopMenu` property was taken into
account when determining the `MatSidenav#mode` value. However, this was
redundant, because in the only case in which the use of `showTopMenu`
would make a difference (i.e. when `dockSideNav` was true and
`isSideNavDoc` was false) the sidenav would be closed and the hamburger
menu button would not be visible (thus there would be no way to open it
manually).

This commit simplifies the condition for determining the sidenav mode by
removing `showTopMenu` from the expression.

PR Close #42747
2021-07-02 09:23:05 -07:00
Andrew Scott 97c18f4527 fix(language-service): Do not override TS LS methods not supported by VE NgLS (#42727)
Historically, our Language Service was built with the potential to be a
drop-in replacement for the TypeScript Language Service with the added
benefit of being able to provide Angular-specific information as well.
While our VSCode extension does not use the Language Service in this
way, it appears that other community-contributed plugins do. We don't
really officially support this use-case but there's not real reason for
us to override the TypeScript Language Service's
implementation in the VE Angular Language Service so that it returns
`undefined`. As with other non-implemented methods, we can just allow
this to be deferred to TSLS.

fixes #42715

PR Close #42727
2021-07-01 15:23:50 -07:00
ivanwonder df5cc1fbbf fix(compiler-cli): return directives for an element on a microsyntax template (#42640)
When the template type checker try to get a symbol of a template node, it will
not return the directives intended for an element on a microsyntax template,
for example, `<div *ngFor="let user of users;" dir>`, the `dir` will be skipped,
but it's needed in language service.

Fixes https://github.com/angular/vscode-ng-language-service/issues/1420

PR Close #42640
2021-07-01 09:35:24 -07:00
dario-piotrowicz 723d21455a fix(docs-infra): move dots inside Usage Notes anchor tag (#42725)
in the html generated aio docs the dots of "Usage Notes..."
should be part of the anchor tag, same as it is for "See More..."

PR Close #42725
2021-07-01 09:34:05 -07:00
Renovate Bot 72073cfb16 build: update dependency husky to v7 (#42730)
PR Close #42730
2021-07-01 09:32:34 -07:00
Kristiyan Kostadinov 41c6877c01 fix(core): error in TestBed if module is reset mid-compilation in ViewEngine (#42669)
When `TestBed.compileComponents` is called under ViewEngine, we kick off a compilation and return a promise that resolves once the compilation is done. In most cases the consumer doesn't _have_ to await the returned promise, unless their components have external resources.

The problem is that the test could be over by the time the promise has resolved, in which case we still cache the factory of the test module. This becomes a problem if another compilation is triggered right afterwards, because it'll see that we still have a `_moduleFactory` and it won't recreate the factory.

These changes resolve the issue by saving a reference to the module type that is being compiled and checking against it when the promise resolves.

Note that while this problem was discovered while trying to roll out the new test module teardown behavior in the Components repo (https://github.com/angular/components/pull/23070), it has been there for a long time. The new test behavior made it more apparent.

PR Close #42669
2021-06-30 14:32:23 -07:00
Joey Perrott 12e0cfab54 release: cut the v12.1.1 release (#42721) 2021-06-30 13:13:53 -07:00
Paul Gschwendtner aab41ca42f build: update API goldens to reflect new tool (#42688)
Updates the TS API guardian goldens with their equivalents
based on the new shared dev-infra tool.

PR Close #42688
2021-06-30 11:43:49 -07:00
Paul Gschwendtner 3482636b5a build: use api-golden tool from dev-infra for testing public API (#42688)
Switches our TS API guardian targets to rather use the new tool from
dev-infra that relies on Microsoft's API extractor.

PR Close #42688
2021-06-30 11:43:49 -07:00
Paul Gschwendtner b11923cd7a feat(dev-infra): introduce shared tool for validating API signature (#42688)
For the last years the Angular repositories relied on `ts-api-guardian`
for testing the public API signature. This project worked well in
general but its another inconvenience to maintain if we could rely on
Microsoft's `api-extractor` tool.

Especially since with TypeScript 4.3 issues with export aliases appeared
that would require us to extend TS API guardian to support such exports.
This is not as straightforward as it sounds, given it requires rewriting
of declarations to show-case the proper name in the API golden. Microsoft's
API extractor has integrated support for this.

As of TypeScript 4.3, we want to start using the new `override` keyword.
We are not able to use that keyword currently because an old version of
API extractor is used in the `ng_module` rule to flatten the types into
a single file. To fix this, we need to update `api-extractor`, but this
unveils the issue with TS API guardian because the most recent version
of api-extractor uses alias exports to avoid potential conflicts
with globals available through the TypeScript default libraries (e.g.
`dom.d.ts`).

PR Close #42688
2021-06-30 11:43:48 -07:00
mgechev 0cf388e882 docs: add last updated date to roadmap (#42615)
PR Close #42615
2021-06-30 11:41:57 -07:00
Pete Bacon Darwin d19ddd1a87 fix(platform-browser): in Meta.addTag() do not add duplicate meta tags (#42703)
Previously, if there were two tags with the same "name" or "property" attribute selector,
then only the first was checked for duplicates when deciding whether to add a new meta
tag.

Fixes #42700
Fixes #19606

PR Close #42703
2021-06-30 10:35:30 -07:00
pavlenko c380d56c6d docs: setting context value inside an interceptor (#42699)
Usage of `get`/`set` methods should be done on a context object instead of a `HttpRequest` instance.

PR Close #42699
2021-06-30 09:13:46 -07:00
Alan Agius f84d826a3a fix(dev-infra): remove bots from special thanks section (#42697)
With this change we remove known used bots from special thanks section in the changelog.

PR Close #42697
2021-06-29 11:13:51 -07:00
George Kalpakas 78cf10b28b refactor(docs-infra): make angular.io and docs examples compatible with RxJS v7 (#42660)
This commit applies the necessary changes to make angular.io and (most)
docs examples compatible with both RxJS v6 and v7. It also adds new
steps to relevant CI jobs to test angular.io and docs examples against
RxJS v7 as well (to catch potential regressions).

NOTE:
Some of the docs examples are not compatible with RxJS v7 and are
therefore excluded from the tests. The SystemJS-based ngUpgrade
examples in particular are excluded, since they require a different
SystemJS configs to run against RxJS v6 and v7 and the extra complexity
of managing that is not worth it for the 4 affected examples.

PR Close #42660
2021-06-29 10:29:58 -07:00
George Kalpakas a0e5b85694 test(docs-infra): allow excluding certain docs examples from tests (#42660)
This commit adds support for excluding certain docs examples from the
command used to run tests. This is useful to run extra tests on CI that
might not be compatible with all examples (for example, run tests with
different versions of a dependency).

In a subsequent commit, this will be used to run tests against RxJS v7
as a quick way to catch potential regressions.

PR Close #42660
2021-06-29 10:29:58 -07:00
George Looshch ace0a50646 docs: remove duplicate link to guide/inputs-outputs.md (#42654)
When you click on `Understanding Angular > Components > Sharing data between
child and parent directives and components` in navigation sidebar, another
item gets selected: `Understanding Angular > Templates > Inputs and Outputs`
Both of them are linked to the same guide but the view cannot handle
situations when several entries point to the same guide.

This commit fixes that by removing the second entry.

Fixes #42652

PR Close #42654
2021-06-29 09:27:48 -07:00
Paul Gschwendtner 0f27f89d38 feat(dev-infra): add command for printing release train information (#42644)
Currently the active release trains are printed when a developer
runs `ng-dev publish release`. This is not ideal because it requires
the developer to provide an OAuth token, to be on the next branch, and
to have no uncommitted changes, while the actual release train
information is not dependent on these checks.

This commit introduces a new command called `ng-dev release info` that
can be used to retrieve relase information without the aforementioned
requirements. Note that this command provides more detailed information
about release branches than the `ng-dev caretaker check` command (which
also requires on authentication as a side note). The `release info`
command also prints active LTS branches for example.

PR Close #42644
2021-06-28 11:50:57 -07:00
Lars Gyrup Brink Nielsen a1e036cfd1 docs: correct literal string example (#42623)
Change literal string example `pi` to `'pi'`.

PR Close #42623
2021-06-28 10:05:10 -07:00
codebriefcase 7ea1d4720a fix(docs-infra): styling fix on error pages (#42627)
Add Center Aligment for heading texts and additional styles on 404 (not found) related pages

PR Close #42627
2021-06-28 09:50:24 -07:00
Dario Piotrowicz 560dd44de4 docs(core): add context jsdoc param to createEmbeddedView (#42675)
PR Close #42675
2021-06-28 09:34:17 -07:00
George Kalpakas 87cdd84c17 docs: update Roadmap section header from "Done" to "Completed" (#42620)
"Completed" just sounds better (to me).

PR Close #42620
2021-06-28 09:33:18 -07:00
George Kalpakas 4059ecaed1 fix(docs-infra): fix styling of <summary> elements on dark theme (#42620)
Previously, the color of `<summary>` elements was hard-coded to `black`.
This did not work well on the dark theme, where the background color of
the page is also very dark.

This commit fixes it by removing the explicit color style, thus letting
`<summary>` elements inherit the color of their container.

Closes #42616

PR Close #42620
2021-06-28 09:33:18 -07:00
George Kalpakas e03291bc34 fix(docs-infra): improve styling of completed Roadmap projects (#42620)
This commit improves the styling of the "Completed projects" section of
the Roadmap by (a) making it consistent with the rest of the Roadmap
sections and (b) making it more similar with `<details>` elements on
other pages.

**Before:**
  _Collapsed:_ ![completed projects collapsed (before)][1]
  _Expanded:_ ![completed projects expanded (before)][2]
**After:**
  _Collapsed:_ ![completed projects collapsed (after)][3]
  _Expanded:_ ![completed projects expanded (after)][4]

[1]: https://user-images.githubusercontent.com/8604205/122917101-50c2ca00-d366-11eb-8348-01efd69cedf2.png
[2]: https://user-images.githubusercontent.com/8604205/122917109-515b6080-d366-11eb-9f18-c794fcea8dd1.png
[3]: https://user-images.githubusercontent.com/8604205/122917115-528c8d80-d366-11eb-947a-2d7da3950069.png
[4]: https://user-images.githubusercontent.com/8604205/122917117-53252400-d366-11eb-93e7-9384a7431c0d.png

PR Close #42620
2021-06-28 09:33:18 -07:00
George Kalpakas ffebb3e785 refactor(docs-infra): make <details> styles more re-usable (#42620)
This commit makes the styling for `<details>` elements (including
expand/collapse actions in their `<summary>`) more re-usable.

PR Close #42620
2021-06-28 09:33:18 -07:00
George Kalpakas 0f435a3cf9 refactor(docs-infra): merge duplicate code.scss files (#42620)
PR #41129 reorganized the SCSS files of the angular.io app moving most
of them in sub-directories. Due to incorrectly resolved merge conflicts
for PRs targeting the SCSS files around that time, we ended up with
duplicate style files for `<code>` elements:
- `styles/2-modules/_code.scss`
- `styles/2-modules/code/_code.scss` +
  `styles/2-modules/code/_code-theme.scss`

This commit gets rid of the extra file (`styles/2-modules/_code.scss`)
and ports any changes from it to the correct files inside the `code/`
sub-directory.

PR Close #42620
2021-06-28 09:33:18 -07:00
dario-piotrowicz 1c50869792 docs(compiler): interally typo fixed (#42676)
PR Close #42676
2021-06-28 09:32:23 -07:00
Zach Arend f6b828e292 fix(compiler-cli): add support for partially evaluating types (#41661)
Add support to the partial evaluator for evaluating literal types and
tuples.

resolves #41338

PR Close #41661
2021-06-25 09:59:27 -07:00
marvinbeckert bd42b795f7 docs: remove default linting tool in workspace guide (#42655)
PR Close #42655
2021-06-25 09:55:53 -07:00
698 changed files with 14252 additions and 9600 deletions
-2
View File
@@ -1,3 +1 @@
4.0.0
# [NB: this comment has to be after the first line, see https://github.com/bazelbuild/bazelisk/issues/117]
# When updating the Bazel version you also need to update the RBE toolchains version in package.bzl
+15 -12
View File
@@ -24,19 +24,19 @@ version: 2.1
# **NOTE 2 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
# **NOTE 3 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
var_3: &cache_key v4-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
var_3: &cache_key v4-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
# We invalidate the cache if the Bazel version changes because otherwise the `bazelisk` cache
# folder will contain all previously used versions and ultimately cause the cache restoring to
# be slower due to its growing size.
var_4: &cache_key_fallback v4-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
# Windows needs its own cache key because binaries in node_modules are different.
var_3_win: &cache_key_win v4-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
var_3_win: &cache_key_win v4-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
var_4_win: &cache_key_win_fallback v4-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
# 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 v1-angular-components-{{ checksum "month.txt" }}-7cc42f5d835b7971e9ff73e220b801cf7834d515
var_5: &components_repo_unit_tests_cache_key v1-angular-components-{{ checksum "month.txt" }}-d090617912da8e70aa336aa5b4d804b1b535402e
var_6: &components_repo_unit_tests_cache_key_fallback v1-angular-components-{{ checksum "month.txt" }}
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
@@ -441,6 +441,9 @@ jobs:
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Check the bundle sizes.
- run: yarn --cwd aio payload-size aio-local
# Run tests with RxJS v7.
- run: yarn --cwd aio add rxjs@7.1.0
- run: yarn --cwd aio test --progress=false --watch=false
test_aio_tools:
executor: default-executor
@@ -469,6 +472,10 @@ jobs:
# Since the parallelism is set to "5", there will be five parallel CircleCI containers.
# with either "0", "1", etc as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
# Run tests with RxJS v7.
# (Exclude some examples that are not yet compatible with v7.)
- run: yarn --cwd aio/tools/examples/shared add rxjs@7.1.0 && yarn --cwd aio boilerplate:add
- run: yarn --cwd aio example-e2e --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL} --exclude=practical-observable-usage --exclude=upgrade-module --exclude=upgrade-phonecat
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview:
@@ -671,7 +678,7 @@ jobs:
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 packages/tsconfig-legacy-saucelabs.json --module UMD
- run: yarn tsc -p modules --module UMD
- run: yarn bazel build //packages/zone.js:npm_package
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
@@ -734,10 +741,6 @@ jobs:
# variable. It needs to be hardcoded here, because env variables interpolation is
# not supported.
- '/tmp/angular-components-repo'
- run:
# TODO(devversion): remove once https://github.com/angular/components/pull/23056 is available.
name: Replace RBE container instance name
command: sed -i "s#default_instance#primary_instance#g" ${COMPONENTS_REPO_TMP_DIR}/.bazelrc
- run:
# Updates the `angular/components` `package.json` file to refer to the release output
# inside the `packages-dist` directory.
@@ -784,11 +787,11 @@ jobs:
- setup_win
- run:
name: Build all windows CI targets
command: yarn bazel build --build_tag_filters=-ivy-only //packages/compiler-cli/... //tools/ts-api-guardian/...
command: yarn bazel build --build_tag_filters=-ivy-only //packages/compiler-cli/...
no_output_timeout: 15m
- run:
name: Test all windows CI targets
command: yarn bazel test --test_tag_filters="-ivy-only,-browser:chromium-local" //packages/compiler-cli/... //tools/ts-api-guardian/...
command: yarn bazel test --test_tag_filters="-ivy-only,-browser:chromium-local" //packages/compiler-cli/...
no_output_timeout: 15m
test_ivy_aot_win:
@@ -797,11 +800,11 @@ jobs:
- setup_win
- run:
name: Build all windows CI targets
command: yarn bazel build --config=ivy --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot //packages/compiler-cli/... //tools/ts-api-guardian/...
command: yarn bazel build --config=ivy --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot //packages/compiler-cli/...
no_output_timeout: 15m
- run:
name: Test all windows CI targets
command: yarn bazel test --config=ivy --test_tag_filters="-no-ivy-aot,-fixme-ivy-aot,-browser:chromium-local" //packages/compiler-cli/... //tools/ts-api-guardian/... //packages/localize/...
command: yarn bazel test --config=ivy --test_tag_filters="-no-ivy-aot,-fixme-ivy-aot,-browser:chromium-local" //packages/compiler-cli/... //packages/localize/...
no_output_timeout: 15m
# Save dependencies to use on subsequent runs.
- save_cache:
+1 -1
View File
@@ -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 "7cc42f5d835b7971e9ff73e220b801cf7834d515"
setPublicVar COMPONENTS_REPO_COMMIT "d090617912da8e70aa336aa5b4d804b1b535402e"
####################################################################################################
-3
View File
@@ -5,8 +5,5 @@
*.js eol=lf
*.ts eol=lf
# API guardian patch must always use LF for tests to work
*.patch eol=lf
# Must keep Windows line ending to be parsed correctly
scripts/windows/packages.txt eol=crlf
-66
View File
@@ -1,66 +0,0 @@
---
name: "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? -->
<!-- edit: --> Yes, the previous version in which this bug was not present was: ....
### Description
<!-- edit: --> 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
-->
<!-- edit: --> 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#submit-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. -->
+84
View File
@@ -0,0 +1,84 @@
name: Bug Report
description: Report a bug in the Angular Framework
body:
- type: dropdown
id: affected-packages
attributes:
label: Which @angular/* package(s) are the source of the bug?
options:
- animations
- bazel
- common
- compiler-cli
- compiler
- elements
- forms
- language-service
- localize
- platform-browser-dynamic
- platform-browser
- platform-server
- router
- service-worker
- upgrade
- Don't known / other
multiple: true
validations:
required: true
- type: dropdown
id: is-regression
attributes:
label: Is this a regression?
options:
- 'Yes'
- 'No'
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
validations:
required: true
- type: input
id: reproduction
attributes:
label: Please provide a link to a minimal reproduction of the bug
- type: textarea
id: exception-or-error
attributes:
label: Please provide the exception or error you saw
render: true
- type: textarea
id: environment
attributes:
label: Please provide the environment you discovered this bug in
render: true
placeholder: |
Angular CLI: 12.0.5
Node: 14.17.0
Package Manager: yarn 1.22.10
OS: linux x64
Angular: 12.0.5
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1200.5
@angular-devkit/build-angular 12.0.5
@angular-devkit/core 12.0.5
rxjs 6.6.7
typescript 4.2.4
- type: textarea
id: other
attributes:
label: Anything else?
@@ -1,31 +0,0 @@
---
name: "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
<!-- edit: --> A clear and concise description of the problem or missing capability...
### Describe the solution you'd like
<!-- edit: --> If you have a solution in mind, please describe it.
### Describe alternatives you've considered
<!-- edit: --> Have you considered any alternative solutions or workarounds?
@@ -0,0 +1,46 @@
name: 'Feature Request'
description: Suggest a feature for Angular Framework
body:
- type: dropdown
id: affected-packages
attributes:
label: Which @angular/* package(s) are relevant/releated to the feature request?
options:
- animations
- bazel
- common
- compiler-cli
- compiler
- elements
- forms
- language-service
- localize
- platform-browser-dynamic
- platform-browser
- platform-server
- router
- service-worker
- upgrade
multiple: true
- type: textarea
id: description
attributes:
label: Description
validations:
required: true
- type: textarea
id: proposed-solution
attributes:
label: Proposed solution
validations:
required: true
- type: textarea
id: alternatives-considered
attributes:
label: Alternatives considered
validations:
required: true
-48
View File
@@ -1,48 +0,0 @@
---
name: "Docs or angular.io Bug 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 -->
### Expected vs Actual Behavior**
<!-- If applicable please describe the difference between the expected and actual behavior after following the repro steps. -->
## 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. -->
+42
View File
@@ -0,0 +1,42 @@
name: 'Docs or angular.io Bug Report'
description: Report an issue in Angular's documentation or angular.io application
body:
- type: textarea
id: description
attributes:
label: Description
validations:
required: true
- type: input
id: affected-url
attributes:
label: What is the affected URL?
- type: textarea
id: reproduction-steps
attributes:
label: Please provide the steps to reproduce the issue
- type: textarea
id: expected-vs-actual-behavior
attributes:
label: Please provide the expected behavior vs the actual behavior you encountered
- type: textarea
id: screenshot
attributes:
label: Please provide a screenshot if possible
- type: textarea
id: exception-or-error
attributes:
label: Please provide the exception or error you saw
render: true
- type: textarea
id: browser-info
attributes:
label: Is this a browser-specific issue? If so, please specify the device, browser, and version.
render: true
+1 -1
View File
@@ -10,6 +10,6 @@ jobs:
if: github.repository == 'angular/angular'
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/feature-request@8467fd69f068914f8f25e10b1a80c183ee886de4
- uses: angular/dev-infra/github-actions/feature-request@f83903fe1ac848407ef81465f66588e5accb6537
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
-1
View File
@@ -1 +0,0 @@
_
+2 -1
View File
@@ -15,5 +15,6 @@ export const caretaker: CaretakerConfig = {
name: 'Initial Triage Queue',
query: `is:open no:milestone`,
}
]
],
caretakerGroup: 'angular-caretaker',
};
+4 -1
View File
@@ -25,6 +25,9 @@ export const merge: DevInfraMergeConfig['merge'] = async api => {
'master': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
'10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24',
},
targetLabelExemptScopes: ['dev-infra', 'docs-infra']
// `dev-infra` and `docs-infra` are not affecting the public NPM packages. Similarly,
// the `bazel` package is not considered part of the public API so that features
// can land in patch branches.
targetLabelExemptScopes: ['dev-infra', 'docs-infra', 'bazel']
};
};
+14 -60
View File
@@ -79,7 +79,6 @@ meta:
# 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'
@@ -97,22 +96,23 @@ meta:
# https://developer.github.com/v3/previews/#draft-pull-requests
github_api_version: 'shadow-cat-preview'
pullapprove_conditions:
# https://docs.pullapprove.com/config/overrides/
# Note that overrides are processed in order.
overrides:
# For PRs which are still being worked on, either still in draft mode or indicated through WIP in
# title or label, PullApprove stays in a pending state until its ready for review.
- condition: "'WIP' not in title"
unmet_status: pending
- if: "draft or 'WIP' in title or 'PR state: WIP' in labels"
status: pending
explanation: 'Waiting to send reviews as PR is WIP'
- condition: "'PR state: WIP' not in labels"
unmet_status: pending
explanation: 'Waiting to send reviews as PR is WIP'
- condition: 'not draft'
unmet_status: pending
explanation: 'Waiting to send reviews as PR is in draft'
# Disable PullApprove on specific PRs by adding the `PullApprove: disable` label
- condition: "'PullApprove: disable' not in labels"
unmet_status: success
- if: "'PullApprove: disable' in labels"
status: success
explanation: "PullApprove skipped because of 'PullApprove: disable' label"
# If no file matching based groups are active, report this pull request as failing. Most likely,
# the PR author would need to update the PullApprove config, or create new group.
- if: len(groups.active.exclude("required-minimum-review").exclude("global-*")) == 0 and len(groups.approved.include("global-*")) == 0
status: failure
explanation: 'At least one group must match this PR. Please update an existing review group, or create a new group.'
groups:
# =========================================================
@@ -246,8 +246,9 @@ groups:
])
reviewers:
users:
- alxhub
- AndrewKushnir
- alxhub
- atscott
- JoostK
# =========================================================
@@ -1177,7 +1178,6 @@ groups:
'tools/source-map-test/**',
'tools/symbol-extractor/**',
'tools/testing/**',
'tools/ts-api-guardian/**',
'tools/tslint/**',
'tools/utils/**',
'tools/yarn/**',
@@ -1305,49 +1305,3 @@ groups:
- atscott
- jelbourn
- josephperrott
# ====================================================
# Catch all for if no groups match the code change
# ====================================================
fallback:
<<: *defaults
# A group is considered to be `active` for a PR if at least one of group's
# conditions matches the PR.
#
# The PullApprove CI check should fail if a PR has no `active` groups, as
# this indicates the PR is modifying a file that has no owner.
#
# This is enforced through the pullapprove verification check done
# as part of the CircleCI lint job. Failures in this lint job should be
# fixed as part of the PR. This can be done by updating the
# `.pullapprove.yml` file cover the unmatched path.
# The pullapprove verification script is part of the ng-dev tool and can be
# run locally with the command: `yarn -s ng-dev pullapprove verify`
#
# For cases in which the verification check fails to ensure coverage, this
# group will be active. The expectation is that this should be remedied
# before merging the PR as described above. In an emergency situation
# `global-approvers` can still approve PRs that match this `fallback` rule,
# but that should be an exception and not an expectation.
conditions:
- *no-groups-above-this-active
# When any of the `global-*` groups is approved, they cause other groups to deactivate.
# In those cases, the condition above would evaluate to `true` while in reality, only a global
# approval has been provided. To ensure we don't activate the fallback group in such cases,
# ensure that no explicit global approval has been provided.
- *can-be-global-approved
- *can-be-global-docs-approved
# PullApprove uses a combination of users defined in the pullapprove configuration and the
# number of users who have performed reviews on Github in the recent past if the configuration
# does not specify it. Because, as an open source project, anyone on Github can perform a
# review we need to ensure that all groups, including the fallback group, have at least one user
# or group defined as reviewers.
reviewers:
users:
- josephperrott
reviews:
request: 0
required: 1
# Reviewed-for is required on fallback as it should not ever actually be reviewed, requiring
# Reviewed-for helps insure an accidental approval doesn't occur on the fallback group.
reviewed_for: required
+3 -3
View File
@@ -36,18 +36,18 @@ filegroup(
srcs = [
# We also declare the unminified 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",
"@npm//:node_modules/angular-1.5/angular.js",
"@npm//:node_modules/angular-1.5/angular.min.js",
"@npm//:node_modules/angular-1.6/angular.js",
"@npm//:node_modules/angular-1.6/angular.min.js",
"@npm//:node_modules/angular-1.7/angular.js",
"@npm//:node_modules/angular-1.7/angular.min.js",
"@npm//:node_modules/angular-mocks/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.5/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.6/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.7/angular-mocks.js",
"@npm//:node_modules/angular-mocks-1.8/angular-mocks.js",
"@npm//:node_modules/angular-1.8/angular.js",
"@npm//:node_modules/angular-1.8/angular.min.js",
],
)
+89
View File
@@ -1,3 +1,92 @@
<a name="12.1.4"></a>
# 12.1.4 (2021-07-28)
### compiler-cli
| Commit | Description |
| -- | -- |
| [77ae4459d3](https://github.com/angular/angular/commit/77ae4459d34515493ddf62c7ecdf237260176809) | fix(compiler-cli): use correct module resolution context for absolute imports in .d.ts files ([#42879](https://github.com/angular/angular/pull/42879)) |
| [f589b01672](https://github.com/angular/angular/commit/f589b01672d13c1a174b880437d00a910899f29d) | perf(compiler-cli): skip analysis in incremental builds for files without Angular behavior ([#42562](https://github.com/angular/angular/pull/42562)) |
### core
| Commit | Description |
| -- | -- |
| [a779a1029b](https://github.com/angular/angular/commit/a779a1029b90039ea39d579ecbc98812c301080a) | fix(core): correctly handle `null` or `undefined` in `ErrorHandler#handleError()` ([#42881](https://github.com/angular/angular/pull/42881)) |
## Special Thanks:
Andrew Scott, Daniel Trevino, Dylan Hunn, George Kalpakas, Joey Perrott, JoostK, Paul Gschwendtner, Pete Bacon Darwin, Teri Glover, Vladyslav, Yuvaraj and codebriefcase
<a name="12.1.3"></a>
# 12.1.3 (2021-07-21)
### animations
| Commit | Description |
| -- | -- |
| [3cddc3d6bc](https://github.com/angular/angular/commit/3cddc3d6bc1045b76980ba3e866350d58deb0718) | fix(animations): normalize final styles in buildStyles ([#42763](https://github.com/angular/angular/pull/42763)) |
### compiler-cli
| Commit | Description |
| -- | -- |
| [d207ea06d1](https://github.com/angular/angular/commit/d207ea06d1bb554e822bab2eadcf12ef50117bd4) | fix(compiler-cli): use correct module import for types behind a `forwardRef` ([#42887](https://github.com/angular/angular/pull/42887)) |
| [e6d520f3d9](https://github.com/angular/angular/commit/e6d520f3d9104c63129b94fbf5fe54b392715fc5) | perf(compiler-cli): optimize cycle detection using a persistent cache ([#41271](https://github.com/angular/angular/pull/41271)) |
### core
| Commit | Description |
| -- | -- |
| [a6db152c78](https://github.com/angular/angular/commit/a6db152c78bc82ef39e529ab5ea55f810b17fa2e) | fix(core): use correct injector when resolving DI tokens from within a directive provider factory ([#42886](https://github.com/angular/angular/pull/42886)) |
## Special Thanks:
Alan Agius, David Shevitz, George Kalpakas, Joey Perrott, JoostK, Krzysztof Kotowicz, Minko Gechev, Paul Gschwendtner and dario-piotrowicz
<a name="12.1.2"></a>
# 12.1.2 (2021-07-14)
### bazel
| Commit | Description |
| -- | -- |
| [4a8ab4f149](https://github.com/angular/angular/commit/4a8ab4f1499a560bb4373b088785e43f26384e1c) | fix(bazel): enable dts bundling for Ivy packages ([#42728](https://github.com/angular/angular/pull/42728)) |
### common
| Commit | Description |
| -- | -- |
| [d654c7933a](https://github.com/angular/angular/commit/d654c7933a732c23dc1e68b17766457d2d11a4d8) | fix(common): re-sort output of `KeyValuePipe` when `compareFn` changes ([#42821](https://github.com/angular/angular/pull/42821)) |
### compiler
| Commit | Description |
| -- | -- |
| [2566cbb48c](https://github.com/angular/angular/commit/2566cbb48cddd23c4b29d01ad557bc71ac716700) | fix(compiler): add mappings for all HTML entities ([#42818](https://github.com/angular/angular/pull/42818)) |
| [65330f03a9](https://github.com/angular/angular/commit/65330f03a92f2743719d0e0d4cedcaadbb8c5b21) | fix(compiler): incorrect context object being referenced from listener instructions inside embedded views ([#42755](https://github.com/angular/angular/pull/42755)) |
### compiler-cli
| Commit | Description |
| -- | -- |
| [17d3de25da](https://github.com/angular/angular/commit/17d3de25daf339612c267001f0c2237533d7c789) | fix(compiler-cli): properly emit literal types when recreating type parameters in a different file ([#42761](https://github.com/angular/angular/pull/42761)) |
| [0a17e98ae2](https://github.com/angular/angular/commit/0a17e98ae2813338f03e3e01bb7cfa6024f4632b) | fix(compiler-cli): inline type checking instructions no longer prevent incremental reuse ([#42759](https://github.com/angular/angular/pull/42759)) |
| [45116097c1](https://github.com/angular/angular/commit/45116097c1dafd902014e0f680e0d50023467883) | fix(compiler-cli): support reflecting namespace declarations ([#42728](https://github.com/angular/angular/pull/42728)) |
| [df5cc1fbbf](https://github.com/angular/angular/commit/df5cc1fbbf1b1f02f1f45603552a2530bb59688d) | fix(compiler-cli): return directives for an element on a microsyntax template ([#42640](https://github.com/angular/angular/pull/42640)) |
### core
| Commit | Description |
| -- | -- |
| [63013546e1](https://github.com/angular/angular/commit/63013546e130d823db26ad96e1d4cb346e633a03) | fix(core): associate the NgModule scope for an overridden component ([#42817](https://github.com/angular/angular/pull/42817)) |
| [9ebd41e39c](https://github.com/angular/angular/commit/9ebd41e39c597ef6df2de2fb63d6458337e2757d) | fix(core): allow proper type inference when `ngFor` is used with a `trackBy` function ([#42692](https://github.com/angular/angular/pull/42692)) |
| [41c6877c01](https://github.com/angular/angular/commit/41c6877c013ba84ba5e46309b2310c097ad9e354) | fix(core): error in TestBed if module is reset mid-compilation in ViewEngine ([#42669](https://github.com/angular/angular/pull/42669)) |
### language-service
| Commit | Description |
| -- | -- |
| [97c18f4527](https://github.com/angular/angular/commit/97c18f4527187206db8b0f5730b80d2220027f9f) | fix(language-service): Do not override TS LS methods not supported by VE NgLS ([#42727](https://github.com/angular/angular/pull/42727)) |
### service-worker
| Commit | Description |
| -- | -- |
| [d87917542a](https://github.com/angular/angular/commit/d87917542a00ed6f58c7b95e3eba6aeddc5eee01) | fix(service-worker): correctly handle unrecoverable state when a client no longer exists ([#42736](https://github.com/angular/angular/pull/42736)) |
| [f2523a8fef](https://github.com/angular/angular/commit/f2523a8fef549fab6ec480ecfc966c9d938a5423) | fix(service-worker): avoid storing redundant metadata for hashed assets ([#42606](https://github.com/angular/angular/pull/42606)) |
## Special Thanks:
Alan Agius, Andrew Kushnir, Andrew Scott, Arthur Ming, Bastian, Borislav Ivanov, David Gilson, David Shevitz, Gabriele Franchitto, George Kalpakas, Joey Perrott, JoostK, Kristiyan Kostadinov, Mark Goho, Meir Blumenfeld, Paul Gschwendtner, Pete Bacon Darwin, Ryan Andersen, Theoklitos Bampouris, behrooz bozorg chami, dario-piotrowicz, ivanwonder and mgechev
<a name="12.1.1"></a>
# 12.1.1 (2021-06-30)
### compiler-cli
| Commit | Description |
| -- | -- |
| f6b828e292 | fix(compiler-cli): add support for partially evaluating types (#41661) |
### platform-browser
| Commit | Description |
| -- | -- |
| d19ddd1a87 | fix(platform-browser): in `Meta.addTag()` do not add duplicate meta tags (#42703) |
## Special Thanks:
Alan Agius, Dario Piotrowicz, George Kalpakas, George Looshch, Lars Gyrup Brink Nielsen, Paul Gschwendtner, Pete Bacon Darwin, Zach Arend, codebriefcase, dario-piotrowicz, marvinbeckert, mgechev and pavlenko
<a name="12.1.0"></a>
# 12.1.0 (2021-06-24)
### compiler
+2 -17
View File
@@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Fetch rules_nodejs so we can install our npm dependencies
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "0fa2d443571c9e02fcb7363a74ae591bdcce2dd76af8677a95965edf329d778a",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.6.0/rules_nodejs-3.6.0.tar.gz"],
sha256 = "5c40083120eadec50a3497084f99bc75a85400ea727e82e0b2f422720573130f",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/4.0.0-beta.0/rules_nodejs-4.0.0-beta.0.tar.gz"],
)
# Check the rules_nodejs version and download npm dependencies
@@ -34,11 +34,6 @@ yarn_install(
yarn_lock = "//:yarn.lock",
)
# Load angular dependencies
load("//packages/bazel:package.bzl", "rules_angular_dev_dependencies")
rules_angular_dev_dependencies()
# Load protractor dependencies
load("@npm//@bazel/protractor:package.bzl", "npm_bazel_protractor_dependencies")
@@ -52,13 +47,3 @@ web_test_repositories()
load("//dev-infra/bazel/browsers:browser_repositories.bzl", "browser_repositories")
browser_repositories()
# Setup the rules_sass toolchain
load("@io_bazel_rules_sass//:defs.bzl", "sass_repositories")
sass_repositories()
# Setup the skydoc toolchain
load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
skydoc_repositories()
@@ -2,7 +2,7 @@
* 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
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.mjs` runs
* tests for this project.
*
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
@@ -50,5 +50,5 @@ export class PopupComponent {
private _message = '';
@Output()
closed = new EventEmitter();
closed = new EventEmitter<void>();
}
@@ -1,9 +1,9 @@
// #docplaster
// #docregion import-http
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
// #docregion props
import { Product } from './products';
// #enddocregion import-http
// #enddocregion props, import-http
@Injectable({
providedIn: 'root'
@@ -79,8 +79,7 @@ export class ConfigService {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong.
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
`Backend returned code ${error.status}, body was: `, error.error);
}
// Return an observable with a user-facing error message.
return throwError(
@@ -14,7 +14,7 @@ import { NoopInterceptor } from './noop-interceptor';
// #enddocregion interceptor-providers
import { TrimNameInterceptor } from './trim-name-interceptor';
import { UploadInterceptor } from './upload-interceptor';
import { RetryInterceptor } from './retry-interceptor';
// #docregion interceptor-providers
/** Http interceptor providers in outside-in order */
@@ -39,7 +39,7 @@ export class RetryInterceptor implements HttpInterceptor {
tap(null,
() => {
// An error has occurred, so increment this request's ERROR_COUNT.
req.set(ERROR_COUNT, req.get(ERROR_COUNT) + 1);
req.context.set(ERROR_COUNT, req.context.get(ERROR_COUNT) + 1);
}),
// #docregion reading-context
// Retry the request a configurable number of times.
@@ -2,7 +2,7 @@
* 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-in-angular/example-config.json`.
*
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.js` runs
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.mjs` runs
* tests for this project.
*
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
@@ -2,7 +2,7 @@
* 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
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.mjs` runs
* tests for this project.
*
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
@@ -2,7 +2,7 @@
* 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/practical-observable-usage/example-config.json`.
*
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.js` runs
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.mjs` runs
* tests for this project.
*
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
@@ -2,7 +2,7 @@
* 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/rx-libary/example-config.json`.
*
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.js` runs
* This is an empty placeholder file to ensure that `aio/tools/examples/run-example-e2e.mjs` runs
* tests for this project.
*
* TODO: Fix our infrastructure/tooling, so that this hack is not necessary.
@@ -6,11 +6,11 @@ describe('What is Angular', () => {
const paragraphs = element.all(by.css('p'));
const buttons = element.all(by.css('button'));
const templateButton = buttons.get(1);
const templateText = paragraphs.get(3);
const templateText = paragraphs.get(4);
const messageButton = buttons.get(0);
const messageText = paragraphs.get(2);
const ngIfButton = buttons.get(2);
const ngIfText = paragraphs.get(4);
const ngIfText = paragraphs.get(5);
const diButton = buttons.get(3);
beforeEach(() => browser.get(''));
@@ -4,3 +4,4 @@
<!-- #docregion bindings -->
<p [id]="sayHelloId" [style.color]="fontColor">You can set my color in the component!</p>
<!-- #enddocregion -->
<p>My color is {{ fontColor }}</p>
+1 -1
View File
@@ -1,7 +1,7 @@
<div class="center-layout-wide">
<div class="nf-container l-flex-wrap flex-center">
<img src="assets/images/support/angular-404.svg" width="300" height="300"/>
<div class="nf-response l-flex-wrap">
<div class="nf-response l-flex-wrap center">
<h1 class="no-anchor no-toc">Page Not Found</h1>
<p>We're sorry. The page you are looking for cannot be found.</p>
</div>
+1 -2
View File
@@ -173,7 +173,7 @@ Define metadata objects with the following limited syntax:
<td><code>`pie is ${multiplier} times better than cake`</code></td>
<tr>
<td>Literal string</td>
<td><code>pi</code></td>
<td><code>'pi'</code></td>
</tr>
<tr>
<td>Literal number</td>
@@ -558,7 +558,6 @@ In [Angular Ivy](guide/ivy), the template type checker has been completely rewri
As a result, templates that previously compiled under View Engine can fail type checking under Ivy. This can happen because Ivy's stricter checking catches genuine errors, or because application code is not typed correctly, or because the application uses libraries in which typings are inaccurate or not specific enough.
This stricter type checking is not enabled by default in version 9, but can be enabled by setting the `strictTemplates` configuration option.
We do expect to make strict type checking the default in the future.
For more information about type-checking options, and about improvements to template type checking in version 9 and above, see [Template type checking](guide/template-typecheck).
+9 -9
View File
@@ -13,7 +13,7 @@ See the <live-example></live-example> for a working example containing the code
It is recommended that you set an element property with a [property binding](guide/property-binding) whenever possible.
However, sometimes you don't have an element property to bind.
In those situations, you can use attribute binding.
In those situations, use attribute binding.
For example, [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG) are purely attributes.
@@ -58,7 +58,7 @@ To use attribute binding with the `<td>` attribute `colspan`:
1. Specify the `colspan` attribute by using the following syntax: `[attr.colspan]`.
1. Set `[attr.colspan]` equal to an expression.
In the following example, we bind the `colspan` attribute to the expression `1 + 1`.
In the following example, you bind the `colspan` attribute to the expression `1 + 1`.
<code-example path="attribute-binding/src/app/app.component.html" region="colspan" header="src/app/app.component.html"></code-example>
@@ -78,7 +78,7 @@ For more information on how to bind to the `colSpan` property, see the [`colspan
{@a class-binding}
## Binding to the `class` attribute
You can use class binding to add and remove CSS class names from an element's `class` attribute.
Use class binding to add and remove CSS class names from an element's `class` attribute.
### Binding to a single CSS `class`
@@ -161,7 +161,7 @@ The following table summarizes class binding syntax.
{@a style-binding}
## Binding to the style attribute
You can use style binding to set styles dynamically.
Use style binding to set styles dynamically.
### Binding to a single style
@@ -263,7 +263,7 @@ The following table summarizes style binding syntax.
<div class="alert is-helpful">
The [NgStyle](guide/built-in-directives/#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
However, using the preceding style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
</div>
@@ -294,7 +294,7 @@ When there are multiple bindings to the same class name or style property, Angul
The more specific a class or style binding is, the higher its precedence.
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding.
A binding to a specific class (for example, `[class.foo]`) takes precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) takes precedence over a generic `[style]` binding.
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
@@ -311,7 +311,7 @@ Directives often augment component behavior, so host bindings from components ha
In addition, bindings take precedence over static attributes.
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding takes precedence because it is dynamic.
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
@@ -319,14 +319,14 @@ In the following case, `class` and `[class]` have similar specificity, but the `
### Delegating to styles with lower precedence
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` causes Angular to fall back to the next-highest precedence binding to that style.
For example, consider the following template:
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property falls back to the value of the `comp-with-host-binding` host binding.
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.
+1 -1
View File
@@ -258,7 +258,7 @@ The `CountdownLocalVarParentComponent` that hosts the timer component is as foll
The parent component cannot data bind to the child's
`start` and `stop` methods nor to its `seconds` property.
You can place a local variable, `#timer`, on the tag `<countdown-timer>` representing the child component.
You can place a local variable, `#timer`, on the tag `<app-countdown-timer>` representing the child component.
That gives you a reference to the child component and the ability to access
*any of its properties or methods* from within the parent template.
+2 -2
View File
@@ -1,6 +1,6 @@
# Event binding
Event binding allows you to listen for and respond to user actions such as keystrokes, mouse movements, clicks, and touches.
Event binding lets you listen for and respond to user actions such as keystrokes, mouse movements, clicks, and touches.
<div class="alert is-helpful">
@@ -26,7 +26,7 @@ The event binding listens for the button's click events and calls the component'
## Binding to passive events
Angular also supports passive event listeners. For example, you can use the following steps to make a scroll event passive.
Angular also supports passive event listeners. For example, use the following steps to make a scroll event passive.
1. Create a file `zone-flags.ts` under `src` directory.
2. Add the following line into this file.
+1 -18
View File
@@ -111,20 +111,6 @@ Project-specific [TypeScript](https://www.typescriptlang.org/) configuration fil
| `tsconfig.spec.json` | [TypeScript](https://www.typescriptlang.org/) configuration for the application tests. See [TypeScript Configuration](guide/typescript-configuration). |
| `tslint.json` | Application-specific [TSLint](https://palantir.github.io/tslint/) configuration. |
### End-to-end test files
An `e2e/` folder at the top level contains source files for a set of end-to-end tests that correspond to the root-level application, along with test-specific configuration files.
For a multi-project workspace, application-specific end-to-end tests are in the project root, under `projects/project-name/e2e/`.
<code-example language="none">
e2e/
src/ (end-to-end tests for my-app)
app.e2e-spec.ts
app.po.ts
protractor.conf.js (test-tool config)
tsconfig.json (TypeScript config inherits from workspace)
</code-example>
{@a multiple-projects}
@@ -160,9 +146,6 @@ my-workspace/
projects/ (generated applications and libraries)
my-first-app/ --(an explicitly generated application)
... --(application-specific config)
e2e/ ----(corresponding e2e tests)
src/ ----(e2e tests source)
... ----(e2e-specific config)
src/ --(source and support files for application)
my-lib/ --(a generated library)
... --(library-specific config)
@@ -173,7 +156,7 @@ my-workspace/
When you generate a library using the CLI (with a command such as `ng generate library my-lib`), the generated files go into the `projects/` folder of the workspace. For more information about creating your own libraries, see [Creating Libraries](guide/creating-libraries).
Libraries (unlike applications and their associated e2e projects) have their own `package.json` configuration file.
Libraries unlike applications have their own `package.json` configuration file.
Under the `projects/` folder, the `my-lib` folder contains your library code.
+8 -8
View File
@@ -1,7 +1,7 @@
# Sharing data between child and parent directives and components
A common pattern in Angular is sharing data between a parent component and one or more child components.
You can implement this pattern by using the `@Input()` and `@Output()` directives.
To implement this pattern use the `@Input()` and `@Output()` decorators.
<div class="alert is-helpful">
@@ -21,8 +21,8 @@ Consider the following hierarchy:
The `<parent-component>` serves as the context for the `<child-component>`.
`@Input()` and `@Output()` give a child component a way to communicate with its parent component.
`@Input()` allows a parent component to update data in the child component.
Conversely, `@Output()` allows the child to send data to a parent component.
`@Input()` lets a parent component update data in the child component.
Conversely, `@Output()` lets the child send data to a parent component.
{@a input}
@@ -80,14 +80,14 @@ The binding source, the part to the right of the equal sign, is the data that th
### Watching for `@Input()` changes
To watch for changes on an `@Input()` property, you can use `OnChanges`, one of Angular's [lifecycle hooks](guide/lifecycle-hooks).
To watch for changes on an `@Input()` property, use `OnChanges`, one of Angular's [lifecycle hooks](guide/lifecycle-hooks).
See the [`OnChanges`](guide/lifecycle-hooks#onchanges) section of the [Lifecycle Hooks](guide/lifecycle-hooks) guide for more details and examples.
{@a output}
## Sending data to a parent component
The `@Output()` decorator in a child component or directive allows data to flow from the child to the parent.
The `@Output()` decorator in a child component or directive lets data flow from the child to the parent.
<div class="lightbox">
<img src="generated/images/guide/inputs-outputs/output.svg" alt="Output diagram of the data flow going from child to parent">
@@ -118,7 +118,7 @@ The following example features an `<input>` where a user can enter a value and c
<code-example path="inputs-outputs/src/app/item-output/item-output.component.ts" region="item-output" header="src/app/item-output/item-output.component.ts"></code-example>
The different parts of the above declaration are as follows:
The different parts of the preceding declaration are as follows:
* `@Output()`&mdash;a decorator function marking the property as a way for data to go from the child to the parent
* `newItemEvent`&mdash;the name of the `@Output()`
@@ -166,7 +166,7 @@ The `addItem()` method takes an argument in the form of a string and then adds t
The `$event` contains the data that the user types into the `<input>` in the child template UI.
To see the `@Output()` working, you can add the following to the parent's template:
To see the `@Output()` working, add the following to the parent's template:
```html
<ul>
@@ -180,7 +180,7 @@ The `addItem()` method takes an argument in the form of a string and then adds t
## Using `@Input()` and `@Output()` together
You can use `@Input()` and `@Output()` on the same child component as follows:
Use `@Input()` and `@Output()` on the same child component as follows:
<code-example path="inputs-outputs/src/app/app.component.html" region="together" header="src/app/app.component.html"></code-example>
+5 -5
View File
@@ -1,7 +1,7 @@
# Text interpolation
Text interpolation allows you to incorporate dynamic string values into your HTML templates.
With interpolation, you can dynamically change what appears in an application view, such as displaying a custom greeting that includes the user's name.
Text interpolation lets you incorporate dynamic string values into your HTML templates.
Use interpolation to dynamically change what appears in an application view, such as displaying a custom greeting that includes the user's name.
<div class="alert is-helpful">
@@ -18,7 +18,7 @@ To illustrate how interpolation works, consider an Angular component that contai
<code-example path="interpolation/src/app/app.component.ts" region="customer" header="src/app/app.component.ts"></code-example>
You can use interpolation to display the value of this variable in the corresponding component template:
Use interpolation to display the value of this variable in the corresponding component template:
<code-example path="interpolation/src/app/app.component.html" region="interpolation-example1" header="src/app/app.component.html"></code-example>
@@ -55,7 +55,7 @@ With interpolation, Angular performs the following tasks:
<div class="alert is-helpful">
You can configure the interpolation delimiter with the [interpolation](api/core/Component#interpolation) option in the `@Component()` metadata.
Configure the interpolation delimiter with the [interpolation](api/core/Component#interpolation) option in the `@Component()` metadata.
</div>
@@ -131,7 +131,7 @@ When using template expressions, follow these best practices:
* **Use short expressions**
Use property names or method calls whenever possible.
Keep application and business logic in the component, where it is easier to develop and test.
Keep application and business logic in the component, where it is accessible to develop and test.
* **Quick execution**
+16 -16
View File
@@ -1,7 +1,7 @@
# Transforming Data Using Pipes
Use [pipes](guide/glossary#pipe "Definition of a pipe") to transform strings, currency amounts, dates, and other data for display.
Pipes are simple functions you can use in [template expressions](/guide/glossary#template-expression "Definition of template expression") to accept an input value and return a transformed value. Pipes are useful because you can use them throughout your application, while only declaring each pipe once.
Pipes are simple functions to use in [template expressions](/guide/glossary#template-expression "Definition of template expression") to accept an input value and return a transformed value. Pipes are useful because you can use them throughout your application, while only declaring each pipe once.
For example, you would use a pipe to show a date as **April 15, 1988** rather than the raw string format.
<div class="alert is-helpful">
@@ -27,7 +27,7 @@ The following are commonly used built-in pipes for data formatting:
</div>
You can also create pipes to encapsulate custom transformations and use your custom pipes in template expressions.
Create pipes to encapsulate custom transformations and use your custom pipes in template expressions.
## Prerequisites
@@ -64,12 +64,12 @@ The component's `birthday` value flows through the pipe operator, `|` to the [`d
## Transforming data with parameters and chained pipes
Use optional parameters to fine-tune a pipe's output.
For example, you can use the [`CurrencyPipe`](api/common/CurrencyPipe "API reference") with a country code such as EUR as a parameter.
For example, use the [`CurrencyPipe`](api/common/CurrencyPipe "API reference") with a country code such as EUR as a parameter.
The template expression `{{ amount | currency:'EUR' }}` transforms the `amount` to currency in euros.
Follow the pipe name (`currency`) with a colon (`:`) and the parameter value (`'EUR'`).
If the pipe accepts multiple parameters, separate the values with colons.
For example, `{{ amount | currency:'EUR':'Euros '}}` adds the second parameter, the string literal `'Euros '`, to the output string. You can use any valid template expression as a parameter, such as a string literal or a component property.
For example, `{{ amount | currency:'EUR':'Euros '}}` adds the second parameter, the string literal `'Euros '`, to the output string. Use any valid template expression as a parameter, such as a string literal or a component property.
Some pipes require at least one parameter and allow more optional parameters, such as [`SlicePipe`](/api/common/SlicePipe "API reference for SlicePipe"). For example, `{{ slice:1:5 }}` creates a new array or string containing a subset of the elements starting with element `1` and ending with element `5`.
@@ -110,7 +110,7 @@ For `date` pipe format options, see [DatePipe](api/common/DatePipe "DatePipe API
### Example: Applying two formats by chaining pipes
You can chain pipes so that the output of one pipe becomes the input to the next.
Chain pipes so that the output of one pipe becomes the input to the next.
In the following example, chained pipes first apply a format to a date value, then convert the formatted date to uppercase characters.
The first tab for the `src/app/app.component.html` template chains `DatePipe` and `UpperCasePipe` to display the birthday as **APR 15, 1988**.
@@ -134,7 +134,7 @@ The second tab for the `src/app/app.component.html` template passes the `fullDat
## Creating pipes for custom data transformations
Create custom pipes to encapsulate transformations that are not provided with the built-in pipes.
You can then use your custom pipe in template expressions, the same way you use built-in pipes—to transform input values to output values for display.
Then, use your custom pipe in template expressions, the same way you use built-in pipes—to transform input values to output values for display.
### Marking a class as a pipe
@@ -160,9 +160,9 @@ Angular invokes the `transform` method with the value of a binding as the first
### Example: Transforming a value exponentially
In a game, you may want to implement a transformation that raises a value exponentially to increase a hero's power.
In a game, you might want to implement a transformation that raises a value exponentially to increase a hero's power.
For example, if the hero's score is 2, boosting the hero's power exponentially by 10 produces a score of 1024.
You can use a custom pipe for this transformation.
Use a custom pipe for this transformation.
The following code example shows two component definitions:
@@ -261,7 +261,7 @@ In other words, given the same input, a pure function should always return the s
With a pure pipe, Angular ignores changes within composite objects, such as a newly added element of an existing array, because checking a primitive value or object reference is much faster than performing a deep check for differences within objects.
Angular can quickly determine if it can skip executing the pipe and updating the view.
However, a pure pipe with an array as input may not work the way you want.
However, a pure pipe with an array as input might not work the way you want.
To demonstrate this issue, change the previous example to filter the list of heroes to just those heroes who can fly.
Use the `FlyingHeroesPipe` in the `*ngFor` repeater as shown in the following code.
The tabs for the example show the following:
@@ -290,16 +290,16 @@ This happens because the code that adds a hero does so by pushing it onto the `h
The change detector ignores changes to elements of an array, so the pipe doesn't run.
The reason Angular ignores the changed array element is that the *reference* to the array hasn't changed.
Since the array is the same, Angular does not update the display.
Because the array is the same, Angular does not update the display.
One way to get the behavior you want is to change the object reference itself.
You can replace the array with a new array containing the newly changed elements, and then input the new array to the pipe.
In the above example, you can create an array with the new hero appended, and assign that to `heroes`. Angular detects the change in the array reference and executes the pipe.
Replace the array with a new array containing the newly changed elements, and then input the new array to the pipe.
In the preceding example, create an array with the new hero appended, and assign that to `heroes`. Angular detects the change in the array reference and executes the pipe.
To summarize, if you mutate the input array, the pure pipe doesn't execute.
If you *replace* the input array, the pipe executes and the display is updated.
The above example demonstrates changing a component's code to accommodate a pipe.
The preceding example demonstrates changing a component's code to accommodate a pipe.
To keep your component independent of HTML templates that use pipes, you can, as an alternative, use an *impure* pipe to detect changes within composite objects such as arrays, as described in the next section.
@@ -341,7 +341,7 @@ The example shows that you don't have to change anything else—the only differe
<code-example path="pipes/src/app/flying-heroes.pipe.ts" header="src/app/flying-heroes.pipe.ts (filter)" region="filter"></code-example>
You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`.
As shown in the code below, only the pipe in the template changes.
As shown in the following code, only the pipe in the template changes.
<code-example path="pipes/src/app/flying-heroes-impure.component.html" header="src/app/flying-heroes-impure.component.html (excerpt)" region="template-flying-heroes"></code-example>
@@ -382,7 +382,7 @@ The following code example binds an observable of message strings
To [communicate with backend services using HTTP](/guide/http "Communicating with backend services using HTTP"), the `HttpClient` service uses observables and offers the `HttpClient.get()` method to fetch data from a server.
The asynchronous method sends an HTTP request, and returns an observable that emits the requested data for the response.
As shown in the previous section, you can use the impure `AsyncPipe` to accept an observable as input and subscribe to the input automatically.
As shown in the previous section, use the impure `AsyncPipe` to accept an observable as input and subscribe to the input automatically.
You can also create an impure pipe to make and cache an HTTP request.
Impure pipes are called whenever change detection runs for a component, which could be as often as every few milliseconds.
@@ -403,7 +403,7 @@ The tabs show the following:
</code-pane>
</code-tabs>
In the above example, a breakpoint on the pipe's request for data shows the following:
In the preceding example, a breakpoint on the pipe's request for data shows the following:
* Each binding gets its own pipe instance.
* Each pipe instance caches its own URL and data and calls the server only once.
+3 -3
View File
@@ -2,7 +2,7 @@
# Property binding
Property binding in Angular helps you set values for properties of HTML elements or directives.
With property binding, you can do things such as toggle button functionality, set paths programmatically, and share values between components.
Use property binding to do things such as toggle button functionality, set paths programmatically, and share values between components.
<div class="alert is-helpful">
@@ -77,7 +77,7 @@ You'd get this error:
<code-example language="bash">
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
Can't bind to 'colspan' because it isn't a known built-in property
</code-example>
As the message says, the `<td>` element does not have a `colspan` property. This is true
@@ -191,7 +191,7 @@ The following binding pairs do the same thing.
<code-example path="property-binding/src/app/app.component.html" region="property-binding-interpolation" header="src/app/app.component.html"></code-example>
You can use either form when rendering data values as strings, though interpolation is preferable for readability.
Use either form when rendering data values as strings, though interpolation is preferable for readability.
However, when setting an element property to a non-string data value, you must use property binding.
## What's next
+14 -5
View File
@@ -1,10 +1,12 @@
# Angular Roadmap
<p class="roadmap-last-updated">Last updated: 2021-05-19</p>
Angular receives a large number of feature requests, both from inside Google and from the broader open-source community. At the same time, our list of projects contains plenty of maintenance tasks, code refactorings, and potential performance improvements. We bring together representatives from developer relations, product management, and engineering to prioritize this list. As new projects come into the queue, we regularly position them based on relative priority to other projects. As work gets done, projects will move up in the queue.
The projects below are not associated with a particular Angular version. We'll release them on completion, and they will be part of a specific version based on our release schedule, following semantic versioning. For example, features are released in the next minor after they are complete, or the next major if they include breaking changes.
## In Progress
## In progress
### Improve test times and debugging with automatic test environment tear down
@@ -80,10 +82,16 @@ A long-standing feature request is to add the ability to add directives to host
A common problem with web applications is their slow initial load time. A way to improve it is to apply more granular code-splitting on a component level. To encourage this practice, we’ll be working on more ergonomic code-splitting APIs.
<details class="roadmap-done-details" open="true">
<summary class="roadmap-done-summary">
<h2>Done</h2>
<details class="completed-details" open="true">
<summary>
<h2>Completed</h2>
<span class="actions">
<span class="action-expand">Show all</span>
<span class="action-collapse">Hide all</span>
<i class="material-icons expand">expand_more</i>
</span>
</summary>
<div class="details-content">
### Accelerated debugging and performance profiling with Angular DevTools
@@ -157,10 +165,11 @@ _Completed Q4 2020_
With the deprecation of TSLint we will be moving to ESLint. As part of the process, we will work on ensuring backward compatibility with our current recommended TSLint configuration, implement a migration strategy for existing Angular applications and introduce new tooling to the Angular CLI toolchain.
### Operation Bye Bye Backlog (aka Operation Byelog)
### Operation Bye Bye Backlog (aka Operation Byelog)
_Completed Q4 2020_
We are actively investing up to 50% of our engineering capacity on triaging issues and PRs until we have a clear understanding of broader community needs. After that, we'll commit up to 20% of our engineering capacity to keep up with new submissions promptly.
</div>
</details>
+1 -1
View File
@@ -2528,7 +2528,7 @@ Add the `NavigationExtras` object to the `router.navigate()` method that navigat
<code-example path="router/src/app/auth/auth.guard.4.ts" header="src/app/auth/auth.guard.ts (v3)"></code-example>
You can also preserve query parameters and fragments across navigations without having to provide them again when navigating.
In the `LoginComponent`, you'll add an *object* as the second argument in the `router.navigateUrl()` function and provide the `queryParamsHandling` and `preserveFragment` to pass along the current query parameters and fragment to the next route.
In the `LoginComponent`, you'll add an *object* as the second argument in the `router.navigate()` function and provide the `queryParamsHandling` and `preserveFragment` to pass along the current query parameters and fragment to the next route.
<code-example path="router/src/app/auth/login/login.component.ts" header="src/app/auth/login/login.component.ts (preserve)" region="preserve"></code-example>
+6 -1
View File
@@ -34,9 +34,14 @@ Before creating a route, you should be familiar with the following:
<p>Add more routing features to the Tour of Heroes tutorial.</p>
<p class="card-footer">Routing Tour of Heroes</p>
</a>
<a href="guide/routing-with-urlmatcher" class="docs-card" title="Creating custom route matches tutorial">
<section>Creating custom route matches tutorial</section>
<p>A tutorial that covers how to use custom matching strategy patterns with Angular routing.</p>
<p class="card-footer">Custom route matches tutorial</p>
</a>
<a href="guide/router-reference" class="docs-card" title="Router reference">
<section>Router reference</section>
<p>Describes some core router API concepts.</p>
<p class="card-footer">Router reference</p>
</a>
</div>
</div>
+56 -1
View File
@@ -59,6 +59,8 @@ To systematically block XSS bugs, Angular treats all values as untrusted by defa
Unlike values to be used for rendering, Angular templates are considered trusted by default, and should be treated as executable code. Never generate templates by concatenating user input and template syntax. Doing this would enable attackers to [inject arbitrary code](https://en.wikipedia.org/wiki/Code_injection) into your application. To prevent these vulnerabilities, always use the default [AOT template compiler](/guide/security#offline-template-compiler) in production deployments.
An additional layer of protection can be provided through the use of Content security policy and Trusted Types. These web platform features operate at the DOM level which is the most effective place to prevent XSS issues because they can't be bypassed using other, lower-level APIs. For this reason, we strongly encourage developers to take advantage of these features by configuring the [content security policy](#content-security-policy) for their application and enabling [trusted types enforcement](#trusted-types).
### Sanitization and security contexts
_Sanitization_ is the inspection of an untrusted value, turning it into a value that's safe to insert into
@@ -100,7 +102,7 @@ Angular recognizes the value as unsafe and automatically sanitizes it, which rem
### Direct use of the DOM APIs and explicit sanitization calls
Built-in browser DOM APIs don't automatically protect you from security vulnerabilities.
Unless you enforce Trusted Types, the built-in browser DOM APIs don't automatically protect you from security vulnerabilities.
For example, `document`, the node available through `ElementRef`, and many third-party APIs
contain unsafe methods. In the same way, if you interact with other libraries that manipulate
the DOM, you likely won't have the same automatic sanitization as with Angular interpolations.
@@ -169,6 +171,59 @@ technique to prevent XSS. To enable CSP, configure your web server to return an
[Web Fundamentals guide](https://developers.google.com/web/fundamentals/security/csp) on the
Google Developers website.
{@a trusted-types}
### Enforcing Trusted Types
We recommend the use of [Trusted Types](https://w3c.github.io/webappsec-trusted-types/dist/spec/) as a way to help secure your applications from cross-site scripting attacks. Trusted Types is a [web platform](https://en.wikipedia.org/wiki/Web_platform)
feature that can help you prevent cross-site scripting attacks by enforcing
safer coding practices. Trusted Types can also help simplify the auditing of application code.
<div class="callout is-helpful">
Trusted Types might not yet be available in all browsers your application targets. In the case your Trusted-Types-enabled application runs in a browser that doesn't support Trusted Types, the functionality of the application will be preserved, and your application will be guarded against XSS by way of Angular's DomSanitizer. See [caniuse.com/trusted-types](https://caniuse.com/trusted-types) for the current browser support.
</div>
To enforce Trusted Types for your application, you must configure your application's web server to emit HTTP headers with one of the following Angular policies:
* `angular` - This policy is used in security-reviewed code that is internal to Angular, and is required for Angular to function when Trusted Types are enforced. Any inline template values or content sanitized by Angular is treated as safe by this policy.
* `angular#unsafe-bypass` - This policy is used for applications that use any of the methods in Angular's [DomSanitizer](api/platform-browser/DomSanitizer) that bypass security, such as `bypassSecurityTrustHtml`. Any application that uses these methods must enable this policy.
* `angular#unsafe-jit` - This policy is used by the [JIT compiler](api/core/Compiler). You must enable this policy if your application interacts directly with the JIT compiler or is running in JIT mode using the [platform browser dynamic](api/platform-browser-dynamic/platformBrowserDynamic).
You should configure the HTTP headers for Trusted Types in the following locations:
* Production serving infrastructure
* Angular CLI (`ng serve`), using the `headers` property in the `angular.json` file, for local development and end-to-end testing
* Karma (`ng test`), using the `customHeaders` property in the `karma.config.js` file, for unit testing
The following is an example of a header specifically configured for Trusted Types and Angular:
<code-example language="html">
Content-Security-Policy: trusted-types angular; require-trusted-types-for 'script';
</code-example>
The following is an example of a header specifically configured for Trusted Types and Angular applications that use any of the methods in Angular's [DomSanitizer](api/platform-browser/DomSanitizer) that bypasses security.
<code-example language="html">
Content-Security-Policy: trusted-types angular angular#unsafe-bypass; require-trusted-types-for 'script';
</code-example>
The following is an example of a header specifically configured for Trusted Types and Angular applications using JIT:
<code-example language="html">
Content-Security-Policy: trusted-types angular angular#unsafe-jit; require-trusted-types-for 'script';
</code-example>
<div class="callout is-helpful">
<header>Community contributions</header>
To learn more about troubleshooting Trusted Type configurations, the following resource might be helpful:
[Prevent DOM-based cross-site scripting vulnerabilities with Trusted Types](https://web.dev/trusted-types/#how-to-use-trusted-types)
</div>
{@a offline-template-compiler}
### Use the AOT template compiler
+3 -3
View File
@@ -6,7 +6,7 @@ It includes information about prerequisites, installing the CLI, creating an ini
<div class="callout is-helpful">
<header>Try Angular without local setup</header>
If you are new to Angular, you might want to start with [Try it now!](start), which introduces the essentials of Angular in the context of a ready-made basic online store app that you can examine and modify. This standalone tutorial takes advantage of the interactive [StackBlitz](https://stackblitz.com/) environment for online development. You don't need to set up your local environment until you're ready.
If you are new to Angular, you might want to start with [Try it now!](start), which introduces the essentials of Angular in the context of a ready-made basic online store app for you to examine and modify. This standalone tutorial takes advantage of the interactive [StackBlitz](https://stackblitz.com/) environment for online development. You don't need to set up your local environment until you're ready.
</div>
@@ -87,7 +87,7 @@ The CLI creates a new workspace and a simple Welcome app, ready to run.
## Run the application
The Angular CLI includes a server, so that you can build and serve your app locally.
The Angular CLI includes a server, for you to build and serve your app locally.
1. Navigate to the workspace folder, such as `my-app`.
@@ -118,6 +118,6 @@ If your installation and setup was successful, you should see a page similar to
* Work through the [Tour of Heroes Tutorial](tutorial), a complete hands-on exercise that introduces you to the app development process using the Angular CLI and walks through important subsystems.
* To learn more about using the Angular CLI, see the [CLI Overview](cli "CLI Overview"). In addition to creating the initial workspace and app scaffolding, you can use the CLI to generate Angular code such as components and services. The CLI supports the full development cycle, including building, testing, bundling, and deployment.
* To learn more about using the Angular CLI, see the [CLI Overview](cli "CLI Overview"). In addition to creating the initial workspace and app scaffolding, use the CLI to generate Angular code such as components and services. The CLI supports the full development cycle, including building, testing, bundling, and deployment.
* For more information about the Angular files generated by `ng new`, see [Workspace and Project File Structure](guide/file-structure).
+1 -1
View File
@@ -53,7 +53,7 @@ The guideline uses the shortcut `hero.component.ts|html|css|spec` to represent t
## Single responsibility
Apply the
<a href="https://wikipedia.org/wiki/Single_responsibility_principle"><i>single responsibility principle</i> (SRP)</a>
<a href="https://wikipedia.org/wiki/Single_responsibility_principle"><i>single responsibility principle (SRP)</i></a>
to all components, services, and other symbols.
This helps make the application cleaner, easier to read and maintain, and more testable.
+1 -1
View File
@@ -1,6 +1,6 @@
# SVG as templates
You can use SVG files as templates in your Angular applications. When you use an SVG as the template, you are able to use directives and bindings just like with HTML templates. With these features, you can dynamically generate interactive graphics.
You can use SVG files as templates in your Angular applications. When you use an SVG as the template, you are able to use directives and bindings just like with HTML templates. Use these features to dynamically generate interactive graphics.
<div class="alert is-helpful">
@@ -1,7 +1,7 @@
# Template variables
Template variables help you use data from one part of a template in another part of the template.
With template variables, you can perform tasks such as respond to user input or finely tune your application's forms.
Use template variables to perform tasks such as respond to user input or finely tune your application's forms.
A template variable can refer to the following:
@@ -24,7 +24,7 @@ The following template variable, `#phone`, declares a `phone` variable on an `<i
<code-example path="template-reference-variables/src/app/app.component.html" region="ref-var" header="src/app/app.component.html"></code-example>
You can refer to a template variable anywhere in the component's template.
Refer to a template variable anywhere in the component's template.
Here, a `<button>` further down the template refers to the `phone` variable.
<code-example path="template-reference-variables/src/app/app.component.html" region="ref-phone" header="src/app/app.component.html"></code-example>
@@ -59,12 +59,12 @@ There is, however, a difference between a `Component` and a `Directive` in that
With `NgForm`, `itemForm` is a reference to the [NgForm](api/forms/NgForm "API: NgForm") directive with the ability to track the value and validity of every control in the form.
Unlike the native `<form>` element, the `NgForm` directive has a `form` property.
The `NgForm` `form` property allows you to disable the submit button if the `itemForm.form.valid` is invalid.
The `NgForm` `form` property lets you disable the submit button if the `itemForm.form.valid` is invalid.
## Template variable scope
You can refer to a template variable anywhere within its surrounding template.
Refer to a template variable anywhere within its surrounding template.
[Structural directives](guide/built-in-directives), such as `*ngIf` and `*ngFor`, or `<ng-template>` act as a template boundary.
You cannot access template variables outside of these boundaries.
@@ -85,7 +85,7 @@ In the following example, changing the text in the `<input>` changes the value i
In this case, there is an implied `<ng-template>` around the `<span>` and the definition of the variable is outside of it.
Accessing a template variable from the parent template works because the child template inherits the context from the parent template.
Rewriting the above code in a more verbose form explicitly shows the `<ng-template>`.
Rewriting the preceding code in a more verbose form explicitly shows the `<ng-template>`.
```html
@@ -93,7 +93,7 @@ Rewriting the above code in a more verbose form explicitly shows the `<ng-templa
<!-- New template -->
<ng-template [ngIf]="true">
<!-- Since the context is inherited, the value is available to the new template -->
<!-- Because the context is inherited, the value is available to the new template -->
<span>Value: {{ ref1.value }}</span>
</ng-template>
@@ -157,13 +157,13 @@ __proto__: Function
{@a template-input-variables}
## Template input variable
A _template input variable_ is a variable you can reference within a single instance of the template.
A _template input variable_ is a variable to reference within a single instance of the template.
You declare a template input variable using the `let` keyword as in `let hero`.
There are several such variables in this example: `hero`, `i`, and `odd`.
The variable's scope is limited to a single instance of the repeated template.
You can use the same variable name again in the definition of other structural directives.
Use the same variable name again in the definition of other structural directives.
In contrast, you declare a template variable by prefixing the variable name with `#`, as in `#var`.
A template variable refers to its attached element, component, or directive.
+2 -2
View File
@@ -16,7 +16,7 @@ In the following example, the template statement `deleteHero()` appears in quote
When the user clicks the **Delete hero** button, Angular calls the `deleteHero()` method in the component class.
You can use template statements with elements, components, or directives in response to events.
Use template statements with elements, components, or directives in response to events.
<div class="alert is-helpful">
@@ -63,7 +63,7 @@ In the preceding `deleteHero(hero)`, the `hero` is the template input variable,
* **Conciseness**
Keep template statements minimal by using method calls or basic property assignments.
Use method calls or basic property assignments to keep template statements minimal.
* **Work within the context**
+6 -7
View File
@@ -1,7 +1,7 @@
# Template syntax
In Angular, a *template* is a chunk of HTML.
Within a template, you can use special syntax to leverage many of Angular's features.
Use special syntax within a template to build on many of Angular's features.
## Prerequisites
@@ -20,12 +20,12 @@ In Angular, the component plays the part of the controller/viewmodel, and the te
<hr />
Each Angular template in your application is a section of HTML that you can include as a part of the page that the browser displays.
Each Angular template in your application is a section of HTML to include as a part of the page that the browser displays.
An Angular HTML template renders a view, or user interface, in the browser, just like regular HTML, but with a lot more functionality.
When you generate an Angular application with the Angular CLI, the `app.component.html` file is the default template containing placeholder HTML.
The template syntax guides show you how you can control the UX/UI by coordinating data between the class and the template.
The template syntax guides show you how to control the UX/UI by coordinating data between the class and the template.
<div class="is-helpful alert">
@@ -37,12 +37,11 @@ To see all of them working together in one application, see the comprehensive <l
## Empower your HTML
With special Angular syntax in your templates, you can extend the HTML vocabulary of your applications.
Extend the HTML vocabulary of your applications With special Angular syntax in your templates.
For example, Angular helps you get and set DOM (Document Object Model) values dynamically with features such as built-in template functions, variables, event listening, and data binding.
Almost all HTML syntax is valid template syntax.
However, because an Angular template is part of an overall webpage, and not the entire page, you don't need to include elements such as `<html>`, `<body>`, or `<base>`.
You can focus exclusively on the part of the page you are developing.
However, because an Angular template is part of an overall webpage, and not the entire page, you don't need to include elements such as `<html>`, `<body>`, or `<base>`, and can focus exclusively on the part of the page you are developing.
<div class="alert is-important">
@@ -56,7 +55,7 @@ For more information, see the [Security](guide/security) page.
## More on template syntax
You may also be interested in the following:
You might also be interested in the following:
* [Interpolation](guide/interpolation)&mdash;learn how to use interpolation and expressions in HTML.
* [Template statements](guide/template-statements)&mdash;respond to events in your templates.
+1 -1
View File
@@ -344,6 +344,6 @@ After you've set up your application for testing, you may find the following tes
* [Basics of testing components](guide/testing-components-basics)&mdash;discover the basics of testing Angular components.
* [Component testing scenarios](guide/testing-components-scenarios)&mdash;read about the various kinds of component testing scenarios and use cases.
* [Testing attribute directives](guide/testing-attribute-directives)&mdash;learn about how to test your attribute directives.
* [Testing pipes](guide/testing-pipes)&mdash;find out how to test attribute directives.
* [Testing pipes](guide/testing-pipes)&mdash;find out how to test pipes.
* [Debugging tests](guide/test-debugging)&mdash;uncover common testing bugs.
* [Testing utility APIs](guide/testing-utility-apis)&mdash;get familiar with Angular testing features.
+2 -2
View File
@@ -38,7 +38,7 @@ For example, if the `@Input()` property is `size`, the `@Output()` property must
The following `sizerComponent` has a `size` value property and a `sizeChange` event.
The `size` property is an `@Input()`, so data can flow into the `sizerComponent`.
The `sizeChange` event is an `@Output()`, which allows data to flow out of the `sizerComponent` to the parent component.
The `sizeChange` event is an `@Output()`, which lets data flow out of the `sizerComponent` to the parent component.
Next, there are two methods, `dec()` to decrease the font size and `inc()` to increase the font size.
These two methods use `resize()` to change the value of the `size` property within min/max value constraints, and to emit an event that conveys the new `size` value.
@@ -75,7 +75,7 @@ Angular assigns the `$event` value to the `AppComponent.fontSizePx` when the use
<header>Two-way binding in forms</header>
Because no native HTML element follows the `x` value and `xChange` event pattern, two-way binding with form elements requires `NgModel`.
Because no built-in HTML element follows the `x` value and `xChange` event pattern, two-way binding with form elements requires `NgModel`.
For more information on how to use two-way binding in forms, see Angular [NgModel](guide/built-in-directives#ngModel).
</div>
+14 -14
View File
@@ -8,7 +8,7 @@ Angular is a development platform, built on [TypeScript](https://www.typescriptl
* A collection of well-integrated libraries that cover a wide variety of features, including routing, forms management, client-server communication, and more
* A suite of developer tools to help you develop, build, test, and update your code
With Angular, you're taking advantage of a platform that can scale from single-developer projects to enterprise-level applications. Angular is designed to make updating as easy as possible, so you can take advantage of the latest developments with a minimum of effort. Best of all, the Angular ecosystem consists of a diverse group of over 1.7 million developers, library authors, and content creators.
With Angular, you're taking advantage of a platform that can scale from single-developer projects to enterprise-level applications. Angular is designed to make updating as straightforward as possible, so take advantage of the latest developments with a minimum of effort. Best of all, the Angular ecosystem consists of a diverse group of over 1.7 million developers, library authors, and content creators.
<div class="alert is-helpful">
@@ -43,9 +43,9 @@ When Angular renders this component, the resulting DOM looks like this:
<code-example path="what-is-angular/src/app/hello-world-example.html" language="html"></code-example>
Angular's component model offers strong encapsulation and an intuitive application structure. Components also make your application easier to unit test and can improve the overall readability of your code.
Angular's component model offers strong encapsulation and an intuitive application structure. Components also make your application painless to unit test and can improve the overall readability of your code.
For more information on what you can do with components, see the [Components](guide/component-overview) section.
For more information on what to do with components, see the [Components](guide/component-overview) section.
{@a templates}
### Templates
@@ -74,7 +74,7 @@ Angular also supports property bindings, to help you set values for properties a
Notice the use of the square brackets--that syntax indicates that you're binding the property or attribute to a value in the component class.
You can also declare event listeners to listen for and respond to user actions such as keystrokes, mouse movements, clicks, and touches. You declare an event listener by specifying the event name in parentheses:
Declare event listeners to listen for and respond to user actions such as keystrokes, mouse movements, clicks, and touches. You declare an event listener by specifying the event name in parentheses:
<code-example path="what-is-angular/src/app/hello-world-bindings/hello-world-bindings.component.html" region="event-binding"></code-example>
@@ -82,7 +82,7 @@ The preceding example calls a method, which is defined in the component class:
<code-example path="what-is-angular/src/app/hello-world-bindings/hello-world-bindings.component.ts" region="method"></code-example>
The following is an example of interpolation and bindings within an Angular template:
The following is a combined example of Interpolation, Property Binding and Event Binding within an Angular template:
<code-tabs linenums="true">
<code-pane
@@ -96,7 +96,7 @@ The following is an example of interpolation and bindings within an Angular temp
</code-pane>
</code-tabs>
You can add additional functionality to your templates through the use of [directives](guide/built-in-directives). The most popular directives in Angular are `*ngIf` and `*ngFor`. You can use directives to perform a variety of tasks, such as dynamically modifying the DOM structure. And you can also create your own custom directives to create great user experiences.
Add additional functionality to your templates through the use of [directives](guide/built-in-directives). The most popular directives in Angular are `*ngIf` and `*ngFor`. Use directives to perform a variety of tasks, such as dynamically modifying the DOM structure. And create your own custom directives to create great user experiences.
The following code is an example of the `*ngIf` directive.
@@ -112,14 +112,14 @@ The following code is an example of the `*ngIf` directive.
</code-pane>
</code-tabs>
Angular's declarative templates allow you to cleanly separate your application's logic from its presentation. Templates are based on standard HTML, so they're easy to build, maintain, and update.
Angular's declarative templates let you cleanly separate your application's logic from its presentation. Templates are based on standard HTML, for ease in building, maintaining, and updating.
For more information on what you can do with templates, see the [Templates](guide/template-syntax) section.
For more information on templates, see the [Templates](guide/template-syntax) section.
{@a di}
### Dependency injection
Dependency injection allows you to declare the dependencies of your TypeScript classes without taking care of their instantiation. Instead, Angular handles the instantiation for you. This design pattern allows you to write more testable and flexible code. Even though understanding dependency injection is not critical to start using Angular, we strongly recommend it as a best practice and many aspects of Angular take advantage of it to some degree.
Dependency injection lets you declare the dependencies of your TypeScript classes without taking care of their instantiation. Instead, Angular handles the instantiation for you. This design pattern lets you write more testable and flexible code. Even though understanding dependency injection is not critical to start using Angular, we strongly recommend it as a best practice and many aspects of Angular take advantage of it to some degree.
To illustrate how dependency injection works, consider the following example. The first file, `logger.service.ts`, defines a `Logger` class. This class contains a `writeCount` function that logs a number to the console.
@@ -135,7 +135,7 @@ For more information about dependency injection and Angular, see the [Dependency
## Angular CLI
The Angular CLI is the fastest, easiest, and recommended way to develop Angular applications. The Angular CLI makes a number of tasks easy. Here are some examples:
The Angular CLI is the fastest, straightforward, and recommended way to develop Angular applications. The Angular CLI makes a number of tasks trouble-free. Here are some examples:
<table>
<tr>
@@ -167,7 +167,7 @@ For more information about the Angular CLI, see the [CLI Reference](/cli) sectio
{@a 1p-libraries}
## First-party libraries
The section, [Angular applications: The essentials](#essentials), provides a brief overview of a couple of the key architectural elements you'll use when building Angular applications. But the many benefits of Angular really become apparent when your application grows and you want to add additional functions such as site navigation or user input. That's when you can leverage the Angular platform to incorporate one of the many first-party libraries that Angular provides.
The section, [Angular applications: The essentials](#essentials), provides a brief overview of a couple of the key architectural elements you'll use when building Angular applications. But the many benefits of Angular really become apparent when your application grows and you want to add additional functions such as site navigation or user input. Use the Angular platform to incorporate one of the many first-party libraries that Angular provides.
Some of the libraries available to you include:
<table>
@@ -196,15 +196,15 @@ Some of the libraries available to you include:
</tr>
</table>
These libraries expand your application's functionality while also allowing you to focus more on the features that make your application unique. And you can add these libraries knowing that they're designed to integrate seamlessly into and update simultaneously with the Angular framework.
These libraries expand your application's functionality while also letting you focus more on the features that make your application unique. Add these libraries knowing that they're designed to integrate seamlessly into and update simultaneously with the Angular framework.
These libraries are only required if and when they can help you add functionality to your applications or solve a particular problem.
## Next steps
This topic is intended to give you a brief overview of what Angular is, the advantages it provides, and what you can expect as you start to build your applications.
This topic is intended to give you a brief overview of what Angular is, the advantages it provides, and what to expect as you start to build your applications.
To see Angular in action, see our [Getting Started](https://angular.io/start) tutorial. This tutorial uses [stackblitz.com](https://stackblitz.com/), so you can explore a working example of Angular without any installation requirements.
To see Angular in action, see our [Getting Started](https://angular.io/start) tutorial. This tutorial uses [stackblitz.com](https://stackblitz.com/), for you to explore a working example of Angular without any installation requirements.
To explore Angular's capabilities further, we recommend reading through the sections, Understanding Angular and Developer Guides.
+1 -1
View File
@@ -140,7 +140,7 @@ See [Build target](#build-target) below for more information.
* The `architect/test` section overrides build-option defaults for test builds and supplies additional test-running defaults for the `ng test` command.
* The `architect/lint` section configures defaults for options of the `ng lint` command, which performs code analysis on project source files. The default linting tool for Angular is [TSLint](https://palantir.github.io/tslint/).
* The `architect/lint` section configures defaults for options of the `ng lint` command, which performs code analysis on project source files.
* The `architect/extract-i18n` section configures defaults for options of the `ng extract-i18n` command, which extracts marked message strings from source code and outputs translation files.
+10 -10
View File
@@ -55,13 +55,19 @@
"Podcasts": {
"order": 3,
"resources": {
"sdfjkdkfj": {
"adventures-in-angular": {
"desc": "Adventures in Angular is a weekly podcast dedicated to the Angular platform and related technologies, tools, languages, and practices.",
"logo": "",
"title": "Adventures in Angular",
"url": "https://devchat.tv/adv-in-angular/"
},
"sdlkfjsldfkj": {
"angular-show": {
"desc": "ng-conf's official all-Angular podcast.",
"logo": "",
"title": "The Angular Show",
"url": "https://www.spreaker.com/show/angular-show"
},
"angular-air": {
"desc": "Weekly video podcast hosted by Jeff Whelpley with all the latest and greatest happenings in the wild world of Angular.",
"logo": "",
"title": "AngularAir",
@@ -73,10 +79,10 @@
"title": "Angular Rocks",
"url": "https://angularrocks.com"
},
"sdlkfjsldfkz": {
"happy-angular": {
"desc": "A weekly German podcast for Angular on the go",
"logo": "",
"title": "Happy Angular Podcast",
"title": "Happy Angular",
"url": "https://happy-angular.de/"
},
"ngruair": {
@@ -84,12 +90,6 @@
"logo": "",
"title": "NgRuAir",
"url": "https://github.com/ngRuAir/ngruair"
},
"the-deep-dive": {
"desc": "The advanced web development podcast about Angular, RxJS, TypeScript and other technologies. English, audio only.",
"logo": "https://i.imgur.com/mmE5Feq.jpg",
"title": "The Deep Dive",
"url": "https://thedeepdive.simplecast.com"
}
}
}
-5
View File
@@ -202,11 +202,6 @@
"title": "Template reference variables",
"tooltip": "Introductory guide to referring to DOM elements within a template."
},
{
"url": "guide/inputs-outputs",
"title": "Inputs and Outputs",
"tooltip": "Introductory guide to sharing data between parent and child directives or components."
},
{
"url": "guide/svg-in-templates",
"title": "SVG as templates",
@@ -1,3 +1,36 @@
Angular's `<ng-template>` element defines a template that doesn't render anything by default.
Angular's `<ng-template>` element defines a template that is not rendered by default.
With `<ng-template>`, you can render the content manually for full control over how the content displays.
With `<ng-template>`, you can define template content that is only being rendered by Angular when you, whether directly or indirectly, specifically instruct it to do so, allowing you to have full control over how and when the content is displayed.
@usageNotes
### Structural Directives
One of the main uses for `<ng-template>` is to hold template content that will be used by [Structural directives](/guide/structural-directives). Those directives can add and remove copies of the template content based on their own logic.
When using the [structural directive shorthand](/guide/structural-directives#structural-directive-shorthand), Angular creates an `<ng-template>` element behind the scenes.
### TemplateRef
`<ng-template>` elements are represented as instances of the `TemplateRef` class.
To add copies of the template to the DOM, pass this object to the `ViewContainerRef` method `createEmbeddedView()`.
### Template Variables
`<ng-template>` elements can be referenced in templates using [standard template variables](/guide/template-reference-variables#how-angular-assigns-values-to-template-variables).
_This is how `<ng-template>` elements are used as `ngIf` else clauses._
Such template variables can be used in conjunction with `ngTemplateOutlet` directives to render the content defined inside `<ng-template>` tags.
### Querying
A [Query](/api/core/Query) (such as `ViewChild`) can find the `TemplateRef` associated to an `<ng-template>` element so that it can be used programmatically; for instance, to pass it to the `ViewContainerRef` method `createEmbeddedView()`.
### Context
Inside the `<ng-template>` tags you can reference variables present in the surrounding outer template.
Additionally, a context object can be associated with `<ng-template>` elements.
Such an object contains variables that can be accessed from within the template contents via template (`let` and `as`) declarations.
+7 -7
View File
@@ -219,6 +219,13 @@ The Phone XL price is over $700, so the **Notify Me** button appears on that pro
To make the **Notify Me** button work, the child component needs to notify and pass the data to the parent component.
The `ProductAlertsComponent` needs to emit an event when the user clicks **Notify Me** and the `ProductListComponent` needs to respond to the event.
<div class="alert is-helpful">
In new components, the Angular Generator includes an empty `constructor()`, the `OnInit` interface, and the `ngOnInit()` method.
Since these steps don't use them, the following code examples omit them for brevity.
</div>
1. In `product-alerts.component.ts`, import `Output` and `EventEmitter` from `@angular/core`.
<code-example header="src/app/product-alerts/product-alerts.component.ts" path="getting-started/src/app/product-alerts/product-alerts.component.ts" region="imports"></code-example>
@@ -228,13 +235,6 @@ The `ProductAlertsComponent` needs to emit an event when the user clicks **Notif
<code-example path="getting-started/src/app/product-alerts/product-alerts.component.ts" header="src/app/product-alerts/product-alerts.component.ts" region="input-output"></code-example>
<div class="alert is-helpful">
In new components, the Angular Generator includes an empty `constructor()`, the `OnInit` interface, and the `ngOnInit()` method.
Since these steps don't use them, the following code example omits them for brevity.
</div>
1. In `product-alerts.component.html`, update the **Notify Me** button with an event binding to call the `notify.emit()` method.
<code-example header="src/app/product-alerts/product-alerts.component.html" path="getting-started/src/app/product-alerts/product-alerts.component.html"></code-example>
+1
View File
@@ -30,6 +30,7 @@ This section walks you through adding a **Buy** button and setting up a cart ser
<code-example header="src/app/cart.service.ts" path="getting-started/src/app/cart.service.1.ts"></code-example>
1. Import the `Product` interface from `./products.js`.
1. In the `CartService` class, define an `items` property to store the array of the current products in the cart.
<code-example path="getting-started/src/app/cart.service.ts" header="src/app/cart.service.ts" region="props"></code-example>
+1 -1
View File
@@ -22,7 +22,7 @@ To set up your development environment, follow the instructions in [Local Enviro
## Create a new workspace and an initial application
You develop applications in the context of an Angular [workspace](guide/glossary#workspace). A workspace contains the files for one or more [projects](guide/glossary#project). A project is the set of files that comprise an app, a library, or end-to-end (e2e) tests. For this tutorial, you will create a new workspace.
You develop applications in the context of an Angular [workspace](guide/glossary#workspace). A workspace contains the files for one or more [projects](guide/glossary#project). A project is the set of files that comprise an application or a library. For this tutorial, you will create a new workspace.
To create a new workspace and an initial application project:
+20 -20
View File
@@ -18,7 +18,7 @@
"build-local": "yarn ~~build",
"prebuild-local-ci": "yarn setup-local-ci",
"build-local-ci": "yarn ~~build --progress=false",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 18bbd044d",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 0ab046223",
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
"test": "yarn check-env && ng test",
"pree2e": "yarn check-env && yarn update-webdriver",
@@ -39,7 +39,7 @@
"test-a11y-score-localhost": "run-p --race \"~~light-server -s dist -p 4200 --quiet\" \"test-a11y-score http://localhost:4200\" --",
"test-pwa-score": "run-s \"~~audit-web-app {1} all:0,pwa:{2} {3}\" --",
"test-pwa-score-localhost": "run-p --race \"~~light-server -s dist -p 4200 --quiet\" \"test-pwa-score http://localhost:4200 {1} {2}\" --",
"example-e2e": "yarn example-check-local && node ./tools/examples/run-example-e2e",
"example-e2e": "yarn example-check-local && node ./tools/examples/run-example-e2e.mjs",
"example-lint": "tslint --config \"content/examples/tslint.json\" \"content/examples/**/*.ts\" --exclude \"content/examples/styleguide/**/*.avoid.ts\"",
"example-use-local": "node tools/ng-packages-installer overwrite ./tools/examples/shared --debug --force",
"example-use-npm": "node tools/ng-packages-installer restore ./tools/examples/shared",
@@ -63,8 +63,8 @@
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
"boilerplate:test": "node tools/examples/test.js",
"generate-stackblitz": "node ./tools/stackblitz-builder/generateStackblitz",
"generate-zips": "node ./tools/example-zipper/generateZips",
"generate-stackblitz": "node ./tools/stackblitz-builder/generateStackblitz.mjs",
"generate-zips": "node ./tools/example-zipper/generateZips.mjs",
"create-example": "node ./tools/examples/create-example.js",
"build-404-page": "node scripts/build-404-page",
"update-webdriver": "node ../scripts/webdriver-manager-update.js",
@@ -86,27 +86,27 @@
},
"private": true,
"dependencies": {
"@angular/animations": "12.0.5",
"@angular/cdk": "12.0.5",
"@angular/common": "12.0.5",
"@angular/compiler": "12.0.5",
"@angular/core": "12.0.5",
"@angular/elements": "12.0.5",
"@angular/forms": "12.0.5",
"@angular/material": "12.0.5",
"@angular/platform-browser": "12.0.5",
"@angular/platform-browser-dynamic": "12.0.5",
"@angular/router": "12.0.5",
"@angular/service-worker": "12.0.5",
"@angular/animations": "12.1.1",
"@angular/cdk": "12.1.1",
"@angular/common": "12.1.1",
"@angular/compiler": "12.1.1",
"@angular/core": "12.1.1",
"@angular/elements": "12.1.1",
"@angular/forms": "12.1.1",
"@angular/material": "12.1.1",
"@angular/platform-browser": "12.1.1",
"@angular/platform-browser-dynamic": "12.1.1",
"@angular/router": "12.1.1",
"@angular/service-worker": "12.1.1",
"@webcomponents/custom-elements": "1.4.3",
"rxjs": "^6.6.7",
"tslib": "^2.2.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "12.0.4",
"@angular/cli": "12.0.4",
"@angular/compiler-cli": "12.0.5",
"@angular-devkit/build-angular": "12.1.1",
"@angular/cli": "12.1.1",
"@angular/compiler-cli": "12.1.1",
"@swc/cli": "^0.1.36",
"@swc/core": "^1.2.51",
"@types/jasmine": "~3.7.0",
@@ -132,7 +132,7 @@
"find-free-port": "^2.0.0",
"firebase-tools": "^9.8.0",
"fs-extra": "^10.0.0",
"globby": "^11.0.3",
"globby": "^12.0.0",
"hast-util-is-element": "^1.1.0",
"hast-util-to-string": "^1.0.4",
"html": "^1.0.0",
+1 -1
View File
@@ -28,7 +28,7 @@
<div class="content">
<div class="nf-container l-flex-wrap flex-center">
<img src="assets/images/support/angular-404.svg" width="300" height="300" />
<div class="nf-response l-flex-wrap">
<div class="nf-response l-flex-wrap center">
<h1 class="no-toc" id="page-not-found">Resource Not Found</h1>
<p>We're sorry. The resource you are looking for cannot be found.</p>
</div>
+5 -5
View File
@@ -46,7 +46,7 @@
<mat-sidenav-container class="sidenav-container" [class.starting]="isStarting" [class.has-floating-toc]="hasFloatingToc" role="main">
<mat-sidenav [ngClass]="{'collapsed': !dockSideNav}" #sidenav class="sidenav" [mode]="mode" [opened]="isOpened" (openedChange)="updateHostClasses()">
<aio-nav-menu *ngIf="!showTopMenu" [nodes]="topMenuNarrowNodes" [currentNode]="currentNodes?.TopBarNarrow" [isWide]="false"></aio-nav-menu>
<aio-nav-menu *ngIf="!showTopMenu" [nodes]="topMenuNarrowNodes" [currentNode]="currentNodes?.TopBarNarrow" [isWide]="dockSideNav"></aio-nav-menu>
<aio-nav-menu [nodes]="sideNavNodes" [currentNode]="currentNodes?.SideNav" [isWide]="dockSideNav"></aio-nav-menu>
<div class="doc-version">
@@ -61,11 +61,11 @@
<aio-dt *ngIf="dtOn" [(doc)]="currentDocument"></aio-dt>
</main>
</mat-sidenav-container>
<div *ngIf="hasFloatingToc" class="toc-container no-print" [style.max-height.px]="tocMaxHeight" (wheel)="restrainScrolling($event)">
<aio-lazy-ce selector="aio-toc"></aio-lazy-ce>
</div>
<div *ngIf="hasFloatingToc" class="toc-container no-print" [style.max-height.px]="tocMaxHeight" (wheel)="restrainScrolling($event)">
<aio-lazy-ce selector="aio-toc"></aio-lazy-ce>
</div>
</mat-sidenav-container>
<footer class="no-print">
<aio-footer [nodes]="footerNodes" [versionInfo]="versionInfo"></aio-footer>
+2 -2
View File
@@ -14,7 +14,7 @@ import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { first, map } from 'rxjs/operators';
const sideNavView = 'SideNav';
export const showTopMenuWidth = 1048;
export const showTopMenuWidth = 1150;
export const dockSideNavWidth = 992;
export const showFloatingTocWidth = 800;
@@ -79,7 +79,7 @@ export class AppComponent implements OnInit {
private currentUrl: string;
get isOpened() { return this.dockSideNav && this.isSideNavDoc; }
get mode() { return this.dockSideNav && (this.isSideNavDoc || this.showTopMenu) ? 'side' : 'over'; }
get mode() { return this.isOpened ? 'side' : 'over'; }
// Search related properties
showSearchResults = false;
@@ -30,7 +30,7 @@ export class ApiService implements OnDestroy {
private apiBase = DOC_CONTENT_URL_PREFIX + 'api/';
private apiListJsonDefault = 'api-list.json';
private firstTime = true;
private onDestroy = new Subject();
private onDestroy = new Subject<void>();
private sectionsSubject = new ReplaySubject<ApiSection[]>(1);
private _sections = this.sectionsSubject.pipe(takeUntil(this.onDestroy));
@@ -8,7 +8,9 @@ import { SearchService } from 'app/search/search.service';
@Component({
selector: 'aio-file-not-found-search',
template:
`<p>Let's see if any of these search results help...</p>
`<div class="alert is-helpful">
<p>Let's see if any of these search results help...</p>
</div>
<aio-search-results class="embedded" [searchResults]="searchResults | async"></aio-search-results>`
})
export class FileNotFoundSearchComponent implements OnInit {
@@ -19,7 +19,7 @@ export class TocComponent implements OnInit, AfterViewInit, OnDestroy {
isCollapsed = true;
isEmbedded = false;
@ViewChildren('tocItem') private items: QueryList<ElementRef>;
private onDestroy = new Subject();
private onDestroy = new Subject<void>();
primaryMax = 4;
tocList: TocItem[];
+10 -7
View File
@@ -70,13 +70,16 @@ describe('DocumentService', () => {
it('should encode the request path to be case-insensitive', () => {
const { docService, locationService } = getServices('initial/Doc');
docService.currentDocument.subscribe();
httpMock.expectOne(CONTENT_URL_PREFIX + 'initial/d_oc.json').flush({});
locationService.go('NEW/Doc');
httpMock.expectOne(CONTENT_URL_PREFIX + 'n_e_w_/d_oc.json').flush({});
locationService.go('doc_with_underscores');
httpMock.expectOne(CONTENT_URL_PREFIX + 'doc__with__underscores.json').flush({});
locationService.go('DOC_WITH_UNDERSCORES');
httpMock.expectOne(CONTENT_URL_PREFIX + 'd_o_c___w_i_t_h___u_n_d_e_r_s_c_o_r_e_s_.json').flush({});
expect(() => {
httpMock.expectOne(CONTENT_URL_PREFIX + 'initial/d_oc.json').flush({});
locationService.go('NEW/Doc');
httpMock.expectOne(CONTENT_URL_PREFIX + 'n_e_w_/d_oc.json').flush({});
locationService.go('doc_with_underscores');
httpMock.expectOne(CONTENT_URL_PREFIX + 'doc__with__underscores.json').flush({});
locationService.go('DOC_WITH_UNDERSCORES');
httpMock.expectOne(CONTENT_URL_PREFIX + 'd_o_c___w_i_t_h___u_n_d_e_r_s_c_o_r_e_s_.json').flush({});
}).not.toThrow();
});
it('should emit the not-found document if the document is not found on the server', () => {
+3 -2
View File
@@ -18,10 +18,11 @@ export const DOC_CONTENT_URL_PREFIX = CONTENT_URL_PREFIX + 'docs/';
const FETCHING_ERROR_CONTENTS = (path: string) => `
<div class="nf-container l-flex-wrap flex-center">
<div class="nf-icon material-icons">error_outline</div>
<div class="nf-response l-flex-wrap">
<h1 class="no-toc">Request for document failed.</h1>
<div class="nf-response l-flex-wrap center">
<h1 class="no-toc">Request for document failed</h1>
<p>
We are unable to retrieve the "${path}" page at this time.
<br/>
Please check your connection and try again later.
</p>
</div>
@@ -260,10 +260,13 @@ export class DocViewerComponent implements OnDestroy {
* (See https://github.com/angular/angular/issues/28114.)
*/
async function printSwDebugInfo(): Promise<void> {
console.log(`\nServiceWorker: ${navigator.serviceWorker?.controller?.state ?? 'N/A'}`);
const sep = '\n----------';
const swState = navigator.serviceWorker?.controller?.state ?? 'N/A';
console.log(`\nServiceWorker: ${swState}`);
if (typeof caches === 'undefined') {
console.log('\nCaches: N/A');
console.log(`${sep}\nCaches: N/A`);
} else {
const allCacheNames = await caches.keys();
const swCacheNames = allCacheNames.filter(name => name.startsWith('ngsw:/:'));
@@ -273,11 +276,28 @@ async function printSwDebugInfo(): Promise<void> {
await findCachesAndPrintEntries(swCacheNames, 'assets:app-shell:meta', true);
}
if (swState === 'activated') {
console.log(sep);
await fetchAndPrintSwInternalDebugInfo();
}
console.warn(
'\nIf you see this error, please report an issue at ' +
`${sep}\nIf you see this error, please report an issue at ` +
'https://github.com/angular/angular/issues/new?template=3-docs-bug.md including the above logs.');
// Internal helpers
async function fetchAndPrintSwInternalDebugInfo() {
try {
const res = await fetch('/ngsw/state');
if (!res.ok) {
throw new Error(`Response ${res.status} ${res.statusText}`);
}
console.log(await res.text());
} catch (err) {
console.log(`Failed to retrieve debug info from '/ngsw/state': ${err.message || err}`);
}
}
async function findCachesAndPrintEntries(
swCacheNames: string[], nameSuffix: string, includeValues: boolean,
ignoredKeys: string[] = []): Promise<void> {
@@ -23,7 +23,7 @@ export class NotificationComponent implements OnInit {
@Input() dismissOnContentClick: boolean;
@Input() notificationId: string;
@Input() expirationDate: string;
@Output() dismissed = new EventEmitter();
@Output() dismissed = new EventEmitter<void>();
@HostBinding('@hideAnimation')
showNotification: 'show'|'hide';
@@ -56,10 +56,40 @@ describe('ReportingErrorHandler service', () => {
expect(onerrorSpy).toHaveBeenCalledWith(error.message, undefined, undefined, undefined, error);
});
it('should send a non-error object to window.onerror', () => {
const error = {reason: 'this is an error message'};
handler.handleError(error);
expect(onerrorSpy).toHaveBeenCalledWith(JSON.stringify(error));
});
it('should send a non-error object with circular references to window.onerror', () => {
const error = {
reason: 'this is an error message',
get self() { return this; },
toString() { return `{reason: ${this.reason}}`; },
};
handler.handleError(error);
expect(onerrorSpy).toHaveBeenCalledWith('{reason: this is an error message}');
});
it('should send an error string to window.onerror', () => {
const error = 'this is an error message';
handler.handleError(error);
expect(onerrorSpy).toHaveBeenCalledWith(error);
});
it('should send a non-object, non-string error stringified to window.onerror', () => {
handler.handleError(404);
handler.handleError(false);
handler.handleError(null);
handler.handleError(undefined);
expect(onerrorSpy.calls.allArgs()).toEqual([
['404'],
['false'],
['null'],
['undefined'],
]);
});
});
});
+12 -6
View File
@@ -17,8 +17,7 @@ export class ReportingErrorHandler extends ErrorHandler {
* Send error info to Google Analytics, in addition to the default handling.
* @param error Information about the error.
*/
handleError(error: string | Error) {
handleError(error: any) {
try {
super.handleError(error);
} catch (e) {
@@ -27,12 +26,19 @@ export class ReportingErrorHandler extends ErrorHandler {
this.reportError(error);
}
private reportError(error: string | Error) {
private reportError(error: unknown) {
if (this.window.onerror) {
if (typeof error === 'string') {
this.window.onerror(error);
} else {
if (error instanceof Error) {
this.window.onerror(error.message, undefined, undefined, undefined, error);
} else {
if (typeof error === 'object') {
try {
error = JSON.stringify(error);
} catch {
// Ignore the error and just let it be stringified.
}
}
this.window.onerror(`${error}`);
}
}
}
+1 -1
View File
@@ -118,7 +118,7 @@ export class ScrollSpiedElementGroup {
@Injectable()
export class ScrollSpyService {
private spiedElementGroups: ScrollSpiedElementGroup[] = [];
private onStopListening = new Subject();
private onStopListening = new Subject<void>();
private resizeEvents = fromEvent(window, 'resize').pipe(auditTime(300), takeUntil(this.onStopListening));
private scrollEvents = fromEvent(window, 'scroll').pipe(auditTime(10), takeUntil(this.onStopListening));
private lastContentHeight: number;
@@ -1,4 +1,4 @@
import { ApplicationRef, Injector } from '@angular/core';
import { ApplicationRef, ErrorHandler, Injector } from '@angular/core';
import { discardPeriodicTasks, fakeAsync, tick } from '@angular/core/testing';
import { SwUpdate } from '@angular/service-worker';
import { Subject } from 'rxjs';
@@ -13,6 +13,7 @@ import { SwUpdatesService } from './sw-updates.service';
describe('SwUpdatesService', () => {
let injector: Injector;
let appRef: MockApplicationRef;
let errorHandler: ErrorHandler;
let location: MockLocationService;
let service: SwUpdatesService;
let swu: MockSwUpdate;
@@ -27,13 +28,15 @@ describe('SwUpdatesService', () => {
const setup = (isSwUpdateEnabled: boolean) => {
injector = Injector.create({providers: [
{ provide: ApplicationRef, useClass: MockApplicationRef, deps: [] },
{ provide: ErrorHandler, useValue: {handleError: jasmine.createSpy('handlerError')} },
{ provide: LocationService, useFactory: () => new MockLocationService(''), deps: [] },
{ provide: Logger, useClass: MockLogger, deps: [] },
{ provide: SwUpdate, useFactory: () => new MockSwUpdate(isSwUpdateEnabled), deps: [] },
{ provide: SwUpdatesService, deps: [ApplicationRef, LocationService, Logger, SwUpdate] }
{ provide: SwUpdatesService, deps: [ApplicationRef, ErrorHandler, LocationService, Logger, SwUpdate] }
]});
appRef = injector.get(ApplicationRef) as unknown as MockApplicationRef;
errorHandler = injector.get(ErrorHandler);
location = injector.get(LocationService) as unknown as MockLocationService;
service = injector.get(SwUpdatesService);
swu = injector.get(SwUpdate) as unknown as MockSwUpdate;
@@ -129,6 +132,24 @@ describe('SwUpdatesService', () => {
expect(location.reloadPage).toHaveBeenCalledTimes(2);
}));
it('should notify the `ErrorHandler` when an unrecoverable state has been detected', run(() => {
expect(errorHandler.handleError).not.toHaveBeenCalled();
swu.$$unrecoverableSubj.next({reason: 'Something bad happened'});
expect(errorHandler.handleError).toHaveBeenCalledBefore(location.reloadPage);
expect(errorHandler.handleError)
.toHaveBeenCalledWith('Unrecoverable state: Something bad happened');
(errorHandler.handleError as jasmine.Spy).calls.reset();
location.reloadPage.calls.reset();
swu.$$unrecoverableSubj.next({reason: 'Something worse happened'});
expect(errorHandler.handleError).toHaveBeenCalledBefore(location.reloadPage);
expect(errorHandler.handleError)
.toHaveBeenCalledWith('Unrecoverable state: Something worse happened');
}));
describe('when `SwUpdate` is not enabled', () => {
const runDeactivated = (specFn: VoidFunction) => run(specFn, false);
@@ -165,6 +186,7 @@ describe('SwUpdatesService', () => {
swu.$$unrecoverableSubj.next({reason: 'Something bad happened'});
swu.$$unrecoverableSubj.next({reason: 'Something worse happened'});
expect(errorHandler.handleError).not.toHaveBeenCalled();
expect(location.reloadPage).not.toHaveBeenCalled();
}));
});
@@ -221,12 +243,15 @@ describe('SwUpdatesService', () => {
it('should stop requesting page reloads when unrecoverable states are detected', run(() => {
swu.$$unrecoverableSubj.next({reason: 'Something bad happened'});
expect(errorHandler.handleError).toHaveBeenCalledTimes(1);
expect(location.reloadPage).toHaveBeenCalledTimes(1);
service.ngOnDestroy();
(errorHandler.handleError as jasmine.Spy).calls.reset();
location.reloadPage.calls.reset();
swu.$$unrecoverableSubj.next({reason: 'Something worse happened'});
expect(errorHandler.handleError).not.toHaveBeenCalled();
expect(location.reloadPage).not.toHaveBeenCalled();
}));
});
+8 -4
View File
@@ -1,4 +1,4 @@
import { ApplicationRef, Injectable, OnDestroy } from '@angular/core';
import { ApplicationRef, ErrorHandler, Injectable, OnDestroy } from '@angular/core';
import { SwUpdate } from '@angular/service-worker';
import { concat, interval, Subject } from 'rxjs';
import { first, takeUntil, tap } from 'rxjs/operators';
@@ -21,8 +21,8 @@ export class SwUpdatesService implements OnDestroy {
private onDestroy = new Subject<void>();
constructor(
appRef: ApplicationRef, location: LocationService, private logger: Logger,
private swu: SwUpdate) {
appRef: ApplicationRef, errorHandler: ErrorHandler, location: LocationService,
private logger: Logger, private swu: SwUpdate) {
if (!swu.isEnabled) {
return;
}
@@ -55,7 +55,11 @@ export class SwUpdatesService implements OnDestroy {
// Request an immediate page reload once an unrecoverable state has been detected.
this.swu.unrecoverable
.pipe(
tap(evt => this.log(`Unrecoverable state: ${evt.reason}\nReloading...`)),
tap(evt => {
const errorMsg = `Unrecoverable state: ${evt.reason}`;
errorHandler.handleError(errorMsg);
this.log(`${errorMsg}\nReloading...`);
}),
takeUntil(this.onDestroy),
)
.subscribe(() => location.reloadPage());
+1 -1
View File
@@ -69,7 +69,7 @@
function formatError(msg, url, line, col, e) {
var stack;
msg = msg.replace(/^Error: /, '');
if (e) {
if (e && e.stack) {
stack = e.stack
// strip the leading "Error: " from the stack trace
.replace(/^Error: /, '')
@@ -9,12 +9,13 @@
mat-sidenav-container.sidenav-container {
min-height: 100%;
height: auto !important;
max-width: 100%;
margin: 0;
transform: none;
&.has-floating-toc {
max-width: 82%;
.mat-sidenav-content {
margin-right: 18vw;
}
}
.sidenav-content {
@@ -1,7 +1,7 @@
@use '../../mixins';
// VARIABLES
$showTopMenuWidth: 1048px;
$showTopMenuWidth: 1150px;
$hideTopMenuWidth: $showTopMenuWidth - 1;
$hamburgerShownMargin: 0 8px 0 0;
$hamburgerHiddenMargin: 0 16px 0 -64px;
@@ -132,7 +132,10 @@ mat-toolbar.app-toolbar {
.nav-link-inner {
border-radius: 4px;
font-size: 1.3rem;
font-size: clamp(10px, 1.6rem, 20px);
padding: 8px 16px;
padding: 8px clamp(5px, 0.7vw, 16px);
}
&:focus {
@@ -183,7 +186,7 @@ mat-toolbar.app-toolbar {
}
}
@media (max-width: 480px) {
@media (max-width: 515px) {
width: 150px;
}
}
@@ -200,11 +203,7 @@ mat-toolbar.app-toolbar {
.toolbar-external-icons-container {
a {
@media screen and (max-width: 480px) {
margin: 0;
&:not(:first-child) {
margin-left: -8px;
}
margin: 0 -8px 0 0;
}
@media screen and (max-width: 420px) {
-254
View File
@@ -1,254 +0,0 @@
@use 'sass:color';
@use '../constants';
@use '../mixins';
code-example,
code-tabs {
clear: both;
display: block;
code {
overflow: auto;
}
ol {
list-style: decimal;
}
.mat-card {
padding: 0;
border-radius: 5px;
}
}
code-example {
&:not(.no-box) {
background-color: rgba($backgroundgray, 0.2);
border: 0.5px solid $lightgray;
border-radius: 5px;
color: $darkgray;
margin: 16px auto;
}
&.no-box {
pre.prettyprint {
margin: 0;
}
code {
background-color: transparent;
}
}
code {
overflow: auto;
}
// TERMINAL / SHELL TEXT STYLES
&[language=sh], &[language=bash] {
background-color: $darkgray;
}
header {
background-color: $accentblue;
border-radius: 5px 5px 0 0;
color: $offwhite;
@include mixins.font-size(16);
padding: 8px 16px;
}
}
code-tabs {
margin: 16px 0;
.code-tab-group {
.mat-tab-label {
&:hover {
background: rgba(black, 0.04);
}
}
.mat-tab-body {
overflow-y: hidden;
.mat-tab-body-content {
height: auto;
transform: none;
.fadeIn {
animation: opacity 2s ease-in;
}
}
}
}
}
code-example.avoid header,
code-example.avoidFile header {
border: 2px solid $anti-pattern;
background: $anti-pattern;
}
code-example.avoid,
code-example.avoidFile,
code-tabs.avoid mat-tab-body,
code-tabs.avoidFile mat-tab-body {
border: 0.5px solid $anti-pattern;
}
aio-code {
pre.prettyprint {
position: relative;
display: flex;
min-height: 32px;
margin: 16px 24px;
white-space: pre-wrap;
align-items: center;
code {
a {
color: inherit;
}
span {
@include mixins.line-height(24);
}
ol.linenums {
margin: 0;
color: color.adjust($mediumgray, $lightness: 25%);
li {
margin: 0;
font-family: $code-font;
font-size: 90%;
@include mixins.line-height(24);
&::marker {
color: color.adjust($mediumgray, $lightness: 25%);
}
}
}
.code-missing {
color: $darkred;
}
}
.copy-button {
position: absolute;
top: -7px;
right: -19px;
padding: 0;
overflow: visible; // This is required for the button to be displayed correctly in IE11.
color: $blue-grey-200;
background-color: transparent;
border: none;
cursor: pointer;
&:hover {
color: $mediumgray;
}
}
&.lang-sh, &.lang-bash {
.copy-button {
color: $mediumgray;
&:hover {
color: $lightgray;
}
}
}
}
}
.sidenav-content {
code {
a {
color: $darkblue;
font-size: inherit;
font-weight: inherit;
}
}
:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(pre) {
> code {
background-color: rgba($lightgray, 0.3);
border-radius: 4px;
color: $deepgray;
padding: 0 4px;
}
&:not(a) > code {
padding: 4px;
}
}
.page-guide-cheatsheet & {
td:first-of-type,
th {
code {
background-color: inherit;
padding: 0;
white-space: pre-wrap;
}
}
}
.code-anchor {
cursor: pointer;
text-decoration: none;
font-size: inherit;
&:hover {
text-decoration: underline;
}
}
}
/* PRETTY PRINTING STYLES for prettify.js. */
/* The following class|color styles are derived from https://github.com/google/code-prettify/blob/master/src/prettify.css*/
/* SPAN elements with the classes below are added by prettyprint. */
.pln { color: #000 } /* plain text */
@media screen {
.str { color: #800 } /* string content */
.kwd { color: #00f } /* a keyword */
.com { color: #060 } /* a comment */
.typ { color: red } /* a type name */
.lit { color: #08c } /* a literal value */
/* punctuation, lisp open bracket, lisp close bracket */
.pun, .opn, .clo { color: #660 }
.tag { color: #008 } /* a markup tag name */
.atn { color: #606 } /* a markup attribute name */
.atv { color: #800 } /* a markup attribute value */
.dec, .var { color: #606 } /* a declaration; a variable name */
.fun { color: red } /* a function name */
}
/* Use higher contrast and text-weight for printable form. */
@media print, projection {
.str { color: #060 }
.kwd { color: #006; font-weight: bold }
.com { color: #600; font-style: italic }
.typ { color: #404; font-weight: bold }
.lit { color: #044 }
.pun, .opn, .clo { color: #440 }
.tag { color: #006; font-weight: bold }
.atn { color: #404 }
.atv { color: #060 }
}
/* SHELL / TERMINAL CODE BLOCKS */
code-example {
&[language=sh], &[language=bash] {
.pnk, .blk, .pln, .otl, .kwd, .typ, .tag, .str, .atv, .atn, .com, .lit, .pun, .dec {
color: $codegreen;
}
}
}
@@ -10,53 +10,23 @@
details.overloads {
box-shadow: none;
.icon-action-header {
display: flex;
flex-direction: row;
align-items: center;
> summary {
justify-content: space-between;
a {
display: flex;
}
}
.detail-contents {
padding: 0;
border-radius: 2px;
box-shadow: none;
> *:not(hr) {
margin: 16px 24px;
}
}
summary {
height: inherit;
padding: 0;
h4 {
margin: 0;
clear: left;
}
.actions {
display: flex;
@include mixins.font-size(14);
}
.show-all {
display: initial;
}
.collapse-all {
display: none;
}
}
&[open] > summary {
.show-all {
display: none;
}
.collapse-all {
display: initial;
> .details-content {
padding: 0;
border-radius: 2px;
box-shadow: none;
> *:not(hr) {
margin: 16px 24px;
}
}
}
@@ -1,7 +1,7 @@
.cli-name {
font-weight: bold;
.kwd { color: initial } /* override code format */
.kwd { color: inherit; } /* override code format */
}
.cli-option-syntax {
@@ -13,7 +13,6 @@
}
// TERMINAL / SHELL TEXT STYLES
&.code-shell,
&[language="sh"],
&[language="bash"] {
background-color: constants.$darkgray;
@@ -96,7 +95,7 @@
:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(pre) {
> code {
background-color: if($is-dark-theme, constants.$darkgray, rgba(constants.$lightgray, 0.5));
background-color: if($is-dark-theme, constants.$darkgray, rgba(constants.$lightgray, 0.3));
color: if($is-dark-theme, constants.$white, constants.$darkgray);
}
}
@@ -200,7 +199,6 @@
/* SHELL / TERMINAL CODE BLOCKS */
code-example {
&.code-shell,
&[language="sh"],
&[language="bash"] {
.pnk,
@@ -1,3 +1,4 @@
@use 'sass:math';
@use '~@angular/cdk' as cdk;
@use '~@angular/material' as mat;
@@ -12,13 +13,13 @@ aio-cookies-popup {
position: fixed;
margin: 24px;
max-width: 430px;
padding: $inner-spacing $inner-spacing $inner-spacing / 2;
padding: $inner-spacing $inner-spacing math.div($inner-spacing, 2);
z-index: cdk.$overlay-container-z-index + 1;
.actions {
display: flex;
justify-content: flex-end;
margin: $inner-spacing $inner-spacing / -2 0 0;
margin: $inner-spacing math.div($inner-spacing, -2) 0 0;
.mat-button {
text-transform: uppercase;
@@ -3,9 +3,5 @@
@mixin theme($theme) {
details {
box-shadow: 0 1px 4px 0 rgba(constants.$black, 0.37);
> summary {
color: constants.$black;
}
}
}
+50 -13
View File
@@ -14,6 +14,19 @@
* </div>
* </details>
* ```
*
* Optionally, you can use an `.actions` container inside `<summary>` to show expand/collapse
* actions and/or a rotating icon:
* ```html
* <summary>
* <span>Some title</span>
* <span class="actions">
* <span class="action-expand">Show more</span>
* <span class="action-collapse">Show less</span>
* <i class="material-icons expand">expand_more</i>
* </span>
* </summary>
* ```
*/
details {
@@ -21,33 +34,57 @@ details {
cursor: pointer;
@include mixins.font-size(16);
position: relative;
padding: 16px 24px;
height: 16px;
display: block; // Remove the built in details marker in FF
padding: 16px;
height: inherit;
display: flex; // Remove the built in details marker in FF
align-items: center;
overflow: hidden;
&::-webkit-details-marker {
display: none; // Remove the built in details marker in webkit
}
// Rotate the icon
i.material-icons.expand {
@include mixins.rotate(0deg);
@at-root #{selector.replace(&, 'details', 'details[open]')} {
@include mixins.rotate(180deg);
}
}
> h2 {
margin: 0;
padding: 0;
border: none;
display: inline;
}
.actions {
align-items: center;
display: flex;
@include mixins.font-size(14);
// Show/hide expand and collapse actions.
.action-expand {
display: initial;
@at-root #{selector.replace(&, 'details', 'details[open]')} {
display: none;
}
}
.action-collapse {
display: none;
@at-root #{selector.replace(&, 'details', 'details[open]')} {
display: initial;
}
}
// Rotate the expand/collapse icon.
.material-icons.expand {
@include mixins.rotate(0deg);
@at-root #{selector.replace(&, 'details', 'details[open]')} {
@include mixins.rotate(180deg);
}
}
}
}
.detail-contents {
.details-content {
padding: 16px 24px;
}
}
@@ -1,11 +1,12 @@
@use 'sass:color';
@use 'sass:map';
@use '../../constants';
@mixin theme($theme) {
$is-dark-theme: map.get($theme, is-dark);
.roadmap-done-summary::marker {
color: if($is-dark-theme, constants.$offwhite, color.adjust(constants.$darkgray, $lightness: 10%));
.page-guide-roadmap {
.completed-details {
border-top: 1px solid if($is-dark-theme, constants.$mediumgray, constants.$lightgray);
}
}
}
+18 -11
View File
@@ -1,13 +1,20 @@
.roadmap-done-details {
padding: 0 20px 20px;
margin: 0 -20px;
}
.page-guide-roadmap {
.completed-details {
box-shadow: none;
margin-top: 4rem;
padding: 4rem 0 2rem;
.roadmap-done-summary {
margin: 0 -20px;
font-size: 3.2rem;
height: 40px;
padding-bottom: 0;
display: list-item;
user-select: none;
> summary {
justify-content: space-between;
padding: 0;
}
> .details-content {
padding: 0;
}
}
.roadmap-last-updated {
font-style: italic;
}
}
+9 -8
View File
@@ -1,3 +1,4 @@
@use 'sass:math';
@use '../../mixins';
$tocItemLineHeight: 24;
@@ -9,15 +10,15 @@ $tocMarkerSize: 6;
border-radius: 50%;
content: "";
height: #{$tocMarkerSize}px;
left: -#{($tocMarkerSize - $tocMarkerRailSize) / 2}px;
left: -#{math.div($tocMarkerSize - $tocMarkerRailSize, 2)}px;
position: absolute;
top: calc(#{$tocItemTopPadding}px + #{$tocItemLineHeight / 2}px - #{$tocMarkerSize / 2}px);
top: calc(#{$tocItemTopPadding}px + #{$tocItemLineHeight / 2 / 10}rem - #{$tocMarkerSize / 2}px);
top: calc(#{$tocItemTopPadding}px + #{math.div($tocItemLineHeight, 2)}px - #{math.div($tocMarkerSize, 2)}px);
top: calc(#{$tocItemTopPadding}px + #{math.div($tocItemLineHeight, 2 * 10)}rem - #{math.div($tocMarkerSize, 2)}px);
width: #{$tocMarkerSize}px;
}
.toc-container {
width: 18%;
width: 18vw;
position: fixed;
top: 76px;
right: 0;
@@ -158,13 +159,13 @@ aio-toc {
}
&:first-child:before {
top: calc(#{$tocItemTopPadding}px + #{$tocItemLineHeight / 2}px - #{$tocMarkerSize / 2}px);
top: calc(#{$tocItemTopPadding}px + #{$tocItemLineHeight / 2 / 10}rem - #{$tocMarkerSize / 2}px);
top: calc(#{$tocItemTopPadding}px + #{math.div($tocItemLineHeight, 2)}px - #{math.div($tocMarkerSize, 2)}px);
top: calc(#{$tocItemTopPadding}px + #{math.div($tocItemLineHeight, 2 * 10)}rem - #{math.div($tocMarkerSize, 2)}px);
}
&:last-child:before {
bottom: calc(100% - (#{$tocItemTopPadding}px + #{$tocItemLineHeight / 2}px + #{$tocMarkerSize / 2}px));
bottom: calc(100% - (#{$tocItemTopPadding}px + #{$tocItemLineHeight / 2 / 10}rem + #{$tocMarkerSize / 2}px));
bottom: calc(100% - (#{$tocItemTopPadding}px + #{math.div($tocItemLineHeight, 2)}px + #{math.div($tocMarkerSize, 2)}px));
bottom: calc(100% - (#{$tocItemTopPadding}px + #{math.div($tocItemLineHeight, 2 * 10)}rem + #{math.div($tocMarkerSize, 2)}px));
}
&:not(.active):hover {
+4 -3
View File
@@ -1,21 +1,22 @@
@use 'sass:list';
@use 'sass:math';
@use 'sass:selector';
@use './constants';
// REM Font Adjustments
@mixin font-size($sizeValue) {
font-size: ($sizeValue) + px;
font-size: ($sizeValue / 10) + rem;
font-size: math.div($sizeValue, 10) + rem;
}
@mixin letter-spacing($spacingValue) {
letter-spacing: ($spacingValue) + px;
letter-spacing: ($spacingValue / 10) + rem;
letter-spacing: math.div($spacingValue, 10) + rem;
}
@mixin line-height($heightValue) {
line-height: ($heightValue) + px;
line-height: ($heightValue / 10) + rem;
line-height: math.div($heightValue, 10) + rem;
}
// PLACEHOLDER
+3 -1
View File
@@ -5,7 +5,9 @@ describe('site App', () => {
let page: SitePage;
beforeEach(async () => {
await SitePage.setWindowWidth(1050); // Make the window wide enough to show the SideNav side-by-side.
// Make the window wide enough to show the SideNav side-by-side
// (bigger than the app component's showTopMenuWidth).
await SitePage.setWindowWidth(1200);
page = new SitePage();
});
+1 -1
View File
@@ -33,7 +33,7 @@ This `examples` tool folder contains three utilities:
* example-boilerplate.js - install/remove the npm dependencies and boilerplate files into/from each of the
examples' subfolders.
* run-example-e2e.js - run the e2e tests for one or more examples
* run-example-e2e.mjs - run the e2e tests for one or more examples
* create-example.js - create a new example from the `example-scaffold/` directory or by importing files from a CLI project.
See the [README.md](examples/README.md) for more details.
+3 -3
View File
@@ -5,7 +5,7 @@ These zip files are generated by the utility in this folder.
## Example zipper
The `exampleZipper.js` tool is very similar to the Stackblitz's `builder.js`.
The `exampleZipper.mjs` tool is very similar to the Stackblitz's `builder.mjs`.
The latter creates an HTML file with all the examples' files and the former creates a zip file instead.
They both use the `stackblitz.json` file to flag an example as something to stackblitz or zip.
For example:
@@ -35,7 +35,7 @@ These example types have separate boilerplate directories with the files that ar
There are appropriate `package.json` files for each type of example in the boilerplate directories.
If there is no special `package.json` file for an example type, the one from the `cli` boilerplate directory will be used instead.
The `exampleZipper.js` won't include any `System.js` related files for CLI-based projects.
The `exampleZipper.mjs` won't include any `System.js` related files for CLI-based projects.
## The zipper.json
@@ -46,7 +46,7 @@ In those cases, you can create a `zipper.json` file with the same syntax. It wil
## Executing the zip generation
`generateZips.js` will create a zip for each `stackblitz.json` or `zipper.json` it finds.
`generateZips.mjs` will create a zip for each `stackblitz.json` or `zipper.json` it finds.
Where? At `src/generated/zips/`.
@@ -1,16 +1,16 @@
'use strict';
// Canonical path provides a consistent path (i.e. always forward slashes) across different OSes
const path = require('canonical-path');
const archiver = require('archiver');
const fs = require('fs-extra');
const globby = require('globby');
import archiver from 'archiver';
import path from 'canonical-path';
import fs from 'fs-extra';
import {globbySync} from 'globby';
import {fileURLToPath} from 'url';
const regionExtractor = require('../transforms/examples-package/services/region-parser');
import regionExtractor from '../transforms/examples-package/services/region-parser.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const EXAMPLE_CONFIG_NAME = 'example-config.json';
class ExampleZipper {
export class ExampleZipper {
constructor(sourceDirName, outputDirName) {
this.examplesPackageJson = path.join(__dirname, '../examples/shared/package.json');
this.examplesSystemjsConfig = path.join(__dirname, '../examples/shared/boilerplate/systemjs/src/systemjs.config.js');
@@ -19,7 +19,7 @@ class ExampleZipper {
let gpathStackblitz = path.join(sourceDirName, '**/*stackblitz.json');
let gpathZipper = path.join(sourceDirName, '**/zipper.json');
let configFileNames = globby.sync([gpathStackblitz, gpathZipper], { ignore: ['**/node_modules/**'] });
let configFileNames = globbySync([gpathStackblitz, gpathZipper], { ignore: ['**/node_modules/**'] });
configFileNames.forEach((configFileName) => {
this._zipExample(configFileName, sourceDirName, outputDirName);
});
@@ -46,12 +46,16 @@ class ExampleZipper {
_getExampleType(sourceFolder) {
const filePath = path.join(sourceFolder, EXAMPLE_CONFIG_NAME);
try {
return require(filePath, 'utf-8').projectType || 'cli';
return this._loadJson(filePath).projectType || 'cli';
} catch (err) { // empty file, so it is cli
return 'cli';
}
}
_loadJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
// rename a custom main.ts or index.html file
_renameFile(file, exampleType) {
if (/src\/main[-.]\w+\.ts$/.test(file) && exampleType !== 'universal') {
@@ -66,7 +70,7 @@ class ExampleZipper {
}
_zipExample(configFileName, sourceDirName, outputDirName) {
let json = require(configFileName, 'utf-8');
let json = this._loadJson(configFileName);
const basePath = json.basePath || '';
const jsonFileName = configFileName.replace(/^.*[\\\/]/, '');
let relativeDirName = path.dirname(path.relative(sourceDirName, configFileName));
@@ -149,7 +153,7 @@ class ExampleZipper {
gpaths.push(...alwaysExcludes);
let fileNames = globby.sync(gpaths, { ignore: ['**/node_modules/**'] });
let fileNames = globbySync(gpaths, { ignore: ['**/node_modules/**'] });
let zip = this._createZipArchive(outputFileName);
fileNames.forEach((fileName) => {
@@ -176,5 +180,3 @@ class ExampleZipper {
zip.finalize();
}
}
module.exports = ExampleZipper;
@@ -1,6 +1,8 @@
const ExampleZipper = require('./exampleZipper');
const path = require('canonical-path');
import path from 'canonical-path';
import {fileURLToPath} from 'url';
import {ExampleZipper} from './exampleZipper.mjs';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const EXAMPLES_PATH = path.join(__dirname, '../../content/examples');
const ZIPS_PATH = path.join(__dirname, '../../src/generated/zips');
+2 -2
View File
@@ -135,9 +135,9 @@ It will remove all files that are not tracked by git, **including any new files
So, be sure to commit your work before removing the boilerplate.
### `run-example-e2e.js`
### `run-example-e2e.mjs`
The [run-example-e2e.js](./run-example-e2e.js) script will find and run the e2e tests for all examples.
The [run-example-e2e.mjs](./run-example-e2e.mjs) script will find and run the e2e tests for all examples.
Although it only runs e2e tests by default, it can be configured to run any test command (for CLI-based examples) by using the `tests` property of the [example-config.json](#example-config) file.
It is named `*-e2e` for historical reasons, but it is not limited to running e2e tests.
@@ -1,16 +1,22 @@
const path = require('canonical-path');
const fs = require('fs-extra');
const argv = require('yargs').argv;
const globby = require('globby');
const xSpawn = require('cross-spawn');
const treeKill = require('tree-kill');
const shelljs = require('shelljs');
const findFreePort = require('find-free-port');
import path from 'canonical-path';
import {spawn} from 'cross-spawn';
import findFreePort from 'find-free-port';
import fs from 'fs-extra';
import {globby} from 'globby';
import puppeteer from 'puppeteer';
import shelljs from 'shelljs';
import treeKill from 'tree-kill';
import {fileURLToPath} from 'url';
import yargs from 'yargs';
import {hideBin} from 'yargs/helpers'
shelljs.set('-e');
// Set `CHROME_BIN` as an environment variable for Karma to pick up in unit tests.
process.env.CHROME_BIN = require('puppeteer').executablePath();
process.env.CHROME_BIN = puppeteer.executablePath();
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const {argv} = yargs(hideBin(process.argv));
const AIO_PATH = path.join(__dirname, '../../');
const EXAMPLES_PATH = path.join(AIO_PATH, './content/examples/');
@@ -25,9 +31,15 @@ const IGNORED_EXAMPLES = [];
* Run Protractor End-to-End Tests for Doc Samples
*
* Flags
* --filter to filter/select _example app subdir names
* --filter to filter/select example app subdir names
* Can be used multiple times to include multiple patterns.
* e.g. --filter=foo // all example apps with 'foo' in their folder names.
*
* --exclude to exclude example app subdir names
* Can be used multiple times to exclude multiple patterns.
* NOTE: `--exclude` is always cosidered after `--filter`.
* e.g. --exclude=bar // Exclude all example apps with 'bar' in their folder names.
*
* --setup to run yarn install, copy boilerplate and update webdriver
* e.g. --setup
*
@@ -60,7 +72,7 @@ function runE2e() {
return Promise.resolve()
.then(
() => findAndRunE2eTests(
argv.filter, outputFile, argv.shard,
argv.filter, argv.exclude, outputFile, argv.shard,
argv.cliSpecsConcurrency || DEFAULT_CLI_SPECS_CONCURRENCY, argv.retry || 1))
.then((status) => {
reportStatus(status, outputFile);
@@ -76,7 +88,9 @@ function runE2e() {
// Finds all of the *e2e-spec.tests under the examples folder along with the corresponding apps
// that they should run under. Then run each app/spec collection sequentially.
function findAndRunE2eTests(filter, outputFile, shard, cliSpecsConcurrency, maxAttempts) {
function findAndRunE2eTests(
includeFilter, excludeFilter, outputFile, shard, cliSpecsConcurrency, maxAttempts) {
const filter = {include: includeFilter, exclude: excludeFilter};
const shardParts = shard ? shard.split('/') : [0, 1];
const shardModulo = parseInt(shardParts[0], 10);
const shardDivider = parseInt(shardParts[1], 10);
@@ -84,7 +98,8 @@ function findAndRunE2eTests(filter, outputFile, shard, cliSpecsConcurrency, maxA
// create an output file with header.
const startTime = new Date().getTime();
let header = `Doc Sample Protractor Results on ${new Date().toLocaleString()}\n`;
header += ` Filter: ${filter ? filter : 'All tests'}\n\n`;
header += ` Include: ${filter.include || 'All tests'}\n`;
header += ` Exclude: ${filter.exclude || 'No tests'}\n\n`;
fs.writeFileSync(outputFile, header);
const status = {passed: [], failed: []};
@@ -331,7 +346,7 @@ function spawnExt(
let processOutput = '';
printMessage(`running: ${descr}\n`);
try {
proc = xSpawn.spawn(command, args, options);
proc = spawn(command, args, options);
} catch (e) {
console.log(e);
reject(e);
@@ -378,16 +393,23 @@ function getE2eSpecs(basePath, filter) {
// Find all e2e specs in a given example folder.
function getE2eSpecsFor(basePath, specFile, filter) {
// Only get spec file at the example root.
// The formatter doesn't understand nested template string expressions (honestly, neither do I).
// clang-format off
const e2eSpecGlob = `${filter ? `*${filter}*` : '*'}/${specFile}`;
// clang-format on
const e2eSpecGlob = [
`${filter.include ? filterToGlob(filter.include) : '*'}/${specFile}`,
`!${filter.exclude ? filterToGlob(filter.exclude) : ''}/${specFile}`,
];
return globby(e2eSpecGlob, {cwd: basePath, nodir: true})
.then(
paths => paths.filter(file => !IGNORED_EXAMPLES.some(ignored => file.startsWith(ignored)))
.map(file => path.join(basePath, file)));
}
function filterToGlob(filter) {
// `filter` can be either a string (if there is one occurrence of the corresponding option) or an
// array (if there are two or more occurrences of the corresponding option). In other words, if
// `filter` is an array, it will have more than one element.
return Array.isArray(filter) ? `*{${filter.join(',')}}*` : `*${filter}*`;
}
// Load configuration for an example. Used for SystemJS
function loadExampleConfig(exampleFolder) {
// Default config.
+5 -5
View File
@@ -4,11 +4,11 @@
In AIO we use it to share one or more runnable versions of our examples.
Stackblitz can be used both on a separate page and in an embedded form.
* `generateStackblitz.js` - executes each of the StackblitzBuilder to generate a stackblitz file for each example.
* `generateStackblitz.mjs` - executes each of the StackblitzBuilder to generate a stackblitz file for each example.
## Stackblitz generation
Both forms are created within `builder.js`.
Both forms are created within `builder.mjs`.
How is a stackblitz created?
What is the process from a directory with files to a link with a stackblitz.
@@ -17,13 +17,13 @@ It contains an `<input>` element for each file we need in the stackblitz.
The form will be submitted on load, so you can either double click the HTML file or open it with an anchor tag to open the stackblitz.
So the `builder.js` job is to get all the needed files from an example and build this HTML file for you.
So the `builder.mjs` job is to get all the needed files from an example and build this HTML file for you.
## Customizing the generation per example basis
How does this tool know what is an example and what is not?
It will look for all folders containing a `stackblitz.json` file.
If found, all files within the folder and subfolders will be used in the stackblitz, with a few generic exceptions that you can find at `builder.js`.
If found, all files within the folder and subfolders will be used in the stackblitz, with a few generic exceptions that you can find at `builder.mjs`.
You can use the `stackblitz.json` to customize the stackblitz generation.
For example:
@@ -44,7 +44,7 @@ Here you can specify a description for the stackblitz, some tags and also a file
## Executing the stackblitz generation
`generateStackblitz.js` will create a stackblitz for each `stackblitz.json` it finds.
`generateStackblitz.mjs` will create a stackblitz for each `stackblitz.json` it finds.
Where?
At `src/generated/live-examples/`.
@@ -1,15 +1,16 @@
'use strict';
// Canonical path provides a consistent path (i.e. always forward slashes) across different OSes
const path = require('canonical-path');
const fs = require('fs-extra');
const globby = require('globby');
const jsdom = require('jsdom');
const json5 = require('json5');
import path from 'canonical-path';
import fs from 'fs-extra';
import {globbySync} from 'globby';
import jsdom from 'jsdom';
import json5 from 'json5';
import {fileURLToPath} from 'url';
const regionExtractor = require('../transforms/examples-package/services/region-parser');
import regionExtractor from '../transforms/examples-package/services/region-parser.js';
class StackblitzBuilder {
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export class StackblitzBuilder {
constructor(basePath, destPath) {
this.basePath = basePath;
this.destPath = destPath;
@@ -24,7 +25,7 @@ class StackblitzBuilder {
// When testing it sometimes helps to look a just one example directory like so:
// const stackblitzPaths = path.join(this.basePath, '**/testing/*stackblitz.json');
const stackblitzPaths = path.join(this.basePath, '**/*stackblitz.json');
const fileNames = globby.sync(stackblitzPaths, { ignore: ['**/node_modules/**'] });
const fileNames = globbySync(stackblitzPaths, { ignore: ['**/node_modules/**'] });
let failed = false;
fileNames.forEach((configFileName) => {
try {
@@ -64,7 +65,9 @@ class StackblitzBuilder {
_getBoilerplatePackageJson(exampleType) {
if (!this._boilerplatePackageJsons.hasOwnProperty(exampleType)) {
const pkgJsonPath = `${__dirname}/../examples/shared/boilerplate/${exampleType}/package.json`;
this._boilerplatePackageJsons[exampleType] = fs.existsSync(pkgJsonPath) ? require(pkgJsonPath) : null;
this._boilerplatePackageJsons[exampleType] = fs.existsSync(pkgJsonPath)
? JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'))
: null;
}
return this._boilerplatePackageJsons[exampleType];
@@ -123,7 +126,7 @@ class StackblitzBuilder {
_checkForOutdatedConfig() {
// Ensure that nobody is trying to use the old config filenames (i.e. `plnkr.json`).
const plunkerPaths = path.join(this.basePath, '**/*plnkr.json');
const fileNames = globby.sync(plunkerPaths, { ignore: ['**/node_modules/**'] });
const fileNames = globbySync(plunkerPaths, { ignore: ['**/node_modules/**'] });
if (fileNames.length) {
const readmePath = path.join(__dirname, 'README.md');
@@ -325,7 +328,7 @@ class StackblitzBuilder {
gpaths.push(...defaultExcludes);
config.fileNames = globby.sync(gpaths, { ignore: ['**/node_modules/**'] });
config.fileNames = globbySync(gpaths, { ignore: ['**/node_modules/**'] });
return config;
}
@@ -341,5 +344,3 @@ class StackblitzBuilder {
}
}
}
module.exports = StackblitzBuilder;
@@ -1,8 +0,0 @@
const path = require('path');
const StackblitzBuilder = require('./builder');
const EXAMPLES_PATH = path.join(__dirname, '../../content/examples');
const LIVE_EXAMPLES_PATH = path.join(__dirname, '../../src/generated/live-examples');
new StackblitzBuilder(EXAMPLES_PATH, LIVE_EXAMPLES_PATH).build();

Some files were not shown because too many files have changed in this diff Show More