Compare commits

..

293 Commits

Author SHA1 Message Date
Andrew Scott 4736c6d133 release: cut the v17.3.12 release 2024-07-17 12:06:23 -07:00
Kristiyan Kostadinov 327bae473b fix(compiler): JIT mode incorrectly interpreting host directive configuration in partial compilation (#57002) (#57003)
Fixes that the runtime implementation of `ɵɵngDeclareDirective` was interpreting the `hostDirectives` mapping incorrectly. Instead of treating the inputs/outputs as `['binding', 'alias']` arrays, it was parsing them as `['binding: alias']`. This was leading to runtime errors if a user is consuming a partially-compiled library in JIT mode.

Fixes #54096.

PR Close #57002

PR Close #57003
2024-07-16 09:35:33 -07:00
Matthieu Riegler 27e6936912 docs: add api links redirect (#56881)
fixes #56879

PR Close #56881
2024-07-09 09:43:26 +02:00
Jens Kuehlers ce9e67932c fix(docs-infra): Fix redirects for signals (#56825)
Fix redirects from aio to adev for
Signal inputs/queries and model inputs

PR Close #56825
2024-07-03 16:11:49 +00:00
Jens Kuehlers b7af42433c fix(docs-infra): update some aio to adev redirects (#56808)
Update some redirects from a.io to a.dev that are more specific.

PR Close #56808
2024-07-02 14:19:16 +00:00
Matthieu Riegler bba82754c3 docs: fix NgModule LazyLoading link in aio to adev (#56778)
fixes #56777

PR Close #56778
2024-07-01 13:47:24 +00:00
Joey Perrott b6c0f13ee2 test: correct node version to allow tests to pass again (#56744)
Update node version.

PR Close #56744
2024-06-27 18:53:15 +00:00
Joey Perrott 801b8c219e docs: update robots.txt to crawl aio again (#56741)
To allow improving search reputation for a.dev we added canonical
links on a.io to point to a.dev and self-referential links on
a.dev. For search engines to pick up these canonical links, we
need to allow crawling on a.io again.

PR Close #56741
2024-06-27 18:25:51 +00:00
Jens Kuehlers 9ec3cd0166 docs: update robots.txt to crawl aio again (#56574)
To allow improving search reputation for a.dev we added canonical
links on a.io to point to a.dev and self-referential links on
a.dev. For search engines to pick up these canonical links, we
need to allow crawling on a.io again.

PR Close #56574
2024-06-26 12:33:26 -07:00
Matthieu Riegler f25e77b83e docs(docs-infra): canonical link to ADEV (#56535)
Also fixes the mode-banner link when changing pages

PR Close #56535
2024-06-20 16:05:20 -07:00
Sasidharan SD 81892b1676 docs: update aio versions to include 17.3.x (#56453)
PR Close #56453
2024-06-14 10:08:25 -07:00
Matthieu Riegler 9209678719 docs(docs-infra): fix redirect to from guide/control_flow (#56338)
PR Close #56338
2024-06-11 17:12:32 -07:00
Matthieu Riegler 0ad308ef26 docs(docs-infra): remove service worker related code from the firebase deploy. (#56210)
PR Close #56210
2024-06-11 08:24:25 -07:00
Jessica Janiuk 182138e74b release: cut the v17.3.11 release 2024-06-05 12:05:21 -07:00
Matthieu Riegler 8e44f07ddf docs: change adev redirect for the security guide (#56275)
PR Close #56275
2024-06-05 18:42:59 +00:00
Matthieu Riegler 76f7c5c1b7 docs(docs-infra): fix mode banner link (#56245)
PR Close #56245
2024-06-03 20:10:02 +00:00
Matthieu Riegler acea887f16 docs(docs-infra): fix redirected link in banner. (#56222)
Fixes #56216

PR Close #56222
2024-06-03 15:27:15 +00:00
Matthieu Riegler 20ab57abc4 docs(docs-infra): disable the service worker for aio. (#56167)
This is will the issues we have with the v17 direction to adev.

PR Close #56167
2024-05-31 16:25:02 -07:00
Matthieu Riegler 4c7964c970 docs(docs-infra): prevent the index.html from v17 to redirect to ADEV. (#56087)
The redirection of index.html to adev broke the service-worker as the request is blocked by CORS.

PR Close #56087
2024-05-29 12:53:30 +02:00
Matthieu Riegler baa6c3c514 docs: archive banner link to adev (#56083)
fixes #56082

PR Close #56083
2024-05-29 12:48:44 +02:00
Joey Perrott 1ed8ec6d90 ci: remove web audit checks for deprecated site (#56011)
Remove web audit checks for aio now that its deprecated.

PR Close #56011
2024-05-22 15:10:30 -07:00
Dylan Hunn 9774ebe1da release: cut the v17.3.10 release 2024-05-22 11:15:22 -07:00
twerske c421d8a9d4 docs: update links in redirect for non adev (#55997)
PR Close #55997
2024-05-22 17:11:15 +00:00
Joey Perrott faf922b24e build: set up redirect from angular.io to v17.angular.io when v17 moves into LTS (#55998)
Sets up a redirect so that all requests to angular.io are redirected to v17.angular.io when it is
deployed after v18 is released.

PR Close #55998
2024-05-22 16:59:13 +00:00
Joey Perrott 5941419cd4 ci: remove aio payload checks for deprecated site (#56000)
Remove payload checks for aio now that its deprecated.

PR Close #56000
2024-05-22 16:48:15 +00:00
Joey Perrott 418a35f3fb fix(docs-infra): fix failing tests related to redirects (#55994)
Correct failing tests created by redirect changes

PR Close #55994
2024-05-22 15:58:33 +00:00
twerske b10e031f52 docs: add redirect banner to adev page (#55626)
PR Close #55626
2024-05-21 14:16:17 -07:00
Emma Twersky d83dda560f docs: remove AIO from search indexing (#55618)
PR Close #55618
2024-05-21 14:09:53 -07:00
Joey Perrott 8734b8fd34 feat(docs-infra): set up redirect of all requests to the root of angular.io to angular.dev (#55620)
With the promotion of adev to stable and being the official docs site for angular.  Requests to angular.io root, but not its
subpages, should be redirected to angular.dev.  Requests to paths on angular.io however will still serve as requested.

PR Close #55620
2024-05-21 13:37:16 -07:00
Angular Robot 41bd844b4e build: update actions/checkout digest to a5ac7e5 (#55889)
See associated pull request for more information.

PR Close #55889
2024-05-21 12:19:30 -07:00
Ben Hong a7ef3aa170 docs: add missing border on embedded editor (#55926)
PR Close #55926
2024-05-21 12:14:14 -07:00
garrettld fc5e032be2 docs(common): fix FormatWidth.Short description (#55821)
PR Close #55821
2024-05-20 23:39:15 -07:00
Pawel Kozlowski 2a7089bdfc refactor(docs-infra): notify on data change inside OnPush component (#55830)
The SecondaryNavigation component was updating state outside of an event handler
without notifying about this change. Modeling state as signal should take
care of proper UI updates (note that I did just a mechanical change here, maybe
there are better ways of dealing with this animations case).

PR Close #55830
2024-05-20 23:33:38 -07:00
arturovt 2f1530b5f3 docs: update zone-pollution.md (#55876)
Provide a thorough explanation of why third-party libraries should be created outside
of the Angular zone. Using a statement like "authored with Zone.js in mind" may seem
unusual because third-party libraries typically do not have knowledge of Zone.js, nor
should they be developed with it in mind. Therefore, we revise this explanation accordingly.
Additionally, include a section on handling events originating from third-party APIs.

PR Close #55876
2024-05-20 23:30:26 -07:00
Alan Agius 349f24af56 refactor(zone.js): remove tslib from dependencies (#55827)
Iif needed `tslib` code is included directly in the bundled FESM2015 hence making the dependency redundant.

PR Close #55827
2024-05-16 09:15:27 -07:00
Andrew Scott 45badde88c release: cut the v17.3.9 release 2024-05-15 13:43:02 -07:00
Pawel Kozlowski d0d83960f3 refactor(docs-infra): mark more components as OnPush (#55775)
Use the OnPush change detection strategy in more components to
improve performance and enable zoneless in the future.

PR Close #55775
2024-05-15 08:50:22 -07:00
Angular Robot 5a93df9f18 build: update scorecard action dependencies (#55786)
See associated pull request for more information.

PR Close #55786
2024-05-15 08:48:27 -07:00
Angular Robot 71f8bca9a7 build: update io_bazel_rules_sass digest to fcce061 (#55755)
See associated pull request for more information.

PR Close #55755
2024-05-13 11:20:28 -07:00
Doug Parker 84f70cc1f1 release: bump Angular DevTools to version 1.0.16 (#55715)
PR Close #55715
2024-05-08 11:11:36 -07:00
Doug Parker 9d36a2d998 refactor(devtools): remove --config snapshot-build and leave a note for Firefox (#55717)
We removed display of the Git SHA in Angular DevTools in https://github.com/angular/angular/pull/55694, so there is no longer a need to stamp release builds in Chrome or Firefox.

I opted to leave a `--config snapshot-build-firefox` option as a no-op which a reader could follow to a comment explaining exactly _why_ we can't stamp Firefox releases. This should hopefully make it less likely that we forget and attempt to re-add this feature in the future only to encounter the same release problems.

PR Close #55717
2024-05-08 11:08:59 -07:00
Andrew Kushnir 99bf2cd524 release: cut the v17.3.8 release 2024-05-08 08:46:41 -07:00
Angular Robot 7725b70a0a build: update io_bazel_rules_sass digest to 9a4a4be (#55700)
See associated pull request for more information.

PR Close #55700
2024-05-07 13:36:34 -07:00
Andrew Kushnir a5c3857a7b Revert "build: update dependency typescript to v5.4.5 (#55042)" (#55716)
This reverts commit bd4dbdd2bd.

PR Close #55716
2024-05-07 13:35:03 -07:00
Paul Gschwendtner 5e0d2bc143 docs: properly link to developer preview section (#55711)
Fixes an invalid link to the developer preview section.
PR Close #55711
2024-05-07 08:06:46 -07:00
AleksanderBodurri b86a81136d refactor(devtools): remove git sha stamping from devtools build (#55694)
This stamping is interfering with publishing to the Firefox addons store by brining in the entirety of the `.git` directory as part of the source code necessary for a reproducible build, which Firefox requires as part of it's approval process.

In it's place, we are now using the extension version pulled from the manifest.

PR Close #55694
2024-05-06 16:02:41 -07:00
Andrew Scott 0fa674ba50 refactor(router): resolve view transition promise in a timeout when unsupported (#55327)
Related to #51131, this change ensures that the router navigation exits
the current event loop before rendering the route when the view transition
feature is enabled, when the browser does not support view transitions.

PR Close #55327
2024-05-06 16:00:56 -07:00
Angular Robot bd4dbdd2bd build: update dependency typescript to v5.4.5 (#55042)
See associated pull request for more information.

PR Close #55042
2024-05-03 08:06:38 -07:00
Doug Parker 436111f661 refactor(devtools): set key in manifest.chrome.json (#55639)
This key comes from the release build of the Chrome extension. Setting it here configures the extension ID of a local build to match the extension ID of the public release. This makes Chrome recognize that local builds are the same extension leading to more intuitive behavior. It's also useful for allowlists of extension IDs to keep the local ID consistent.

PR Close #55639
2024-05-02 14:46:28 -07:00
Kristiyan Kostadinov c21b459ba6 fix(compiler): add math elements to schema (#55631) (#55645)
Fixes that we didn't have the MathML elements in the schema. Note that we can't discover which tag names are available by looking at globally-available classes, because all MathML elements are `MathMLElement` rather than something like `SVGCircleElement`. As such, I ended up having to hardcode the currently-available tags.

Fixes #55608.

PR Close #55631

PR Close #55645
2024-05-02 13:38:46 -07:00
Doug Parker ec5807cbdc release: bump Angular DevTools to 1.0.15 (#55643)
PR Close #55643
2024-05-02 13:37:39 -07:00
Angular Robot f978e9caf1 build: update io_bazel_rules_sass digest to 9f8be59 (#55602)
See associated pull request for more information.

PR Close #55602
2024-05-02 11:06:50 -07:00
Andrew Scott 760e284428 Revert "fix(core): render hooks should not specifically run outside the Angular zone (#55399)" (#55624)
This reverts commit 7e89753eef.

Running render hooks inside the zone is specifically problematic for
`afterRender` hooks. If the callback has async task, it would cause an
infinite change detection. In addition, updating state in render hooks
is generally discourages and certainly should update state in a way that
notifies Angular of the change (either via signal or with `markForCheck`) rather
than relying on ZoneJS to pick it up (which would only work if the
change is done inside an async task).

PR Close #55624
2024-05-02 11:00:34 -07:00
Kristiyan Kostadinov 3818436ebc fix(core): don't schedule timer triggers on the server (#55605)
Fixes that even though we weren't rendering the deferred block the server, we were still triggering the timeout which can delay the response.

Fixes #55475.

PR Close #55605
2024-05-01 15:10:29 -07:00
Emma Twersky c9f27b434a docs: update press kit to reduce confusion (#55611)
PR Close #55611
2024-05-01 15:09:36 -07:00
Angular Robot 0e6fbfb758 build: update actions/checkout digest to 0ad4b8f (#55537)
See associated pull request for more information.

PR Close #55537
2024-05-01 15:07:21 -07:00
Andrew Kushnir 4c50e1e7cb release: cut the v17.3.7 release 2024-05-01 11:39:28 -07:00
Doug Parker 82bbcde843 release: bump DevTools to 1.0.14 (#55545)
PR Close #55545
2024-04-30 17:01:57 -07:00
Andrew Scott 266ad40e62 docs: Reference page anchor scroll consistency (#55566)
The docs-viewer loads asynchronously and can happen after the scroll
event has happened and the Router has attempted to scroll to the
requested position/anchor. This commit saves the scroll event and
handles it again if the cards are loaded after scrolling happens.

PR Close #55566
2024-04-30 14:03:06 -07:00
Paul Gschwendtner 4261fd367e build: improve incremental rebuilds of compliance tests (#55594)
Currently whenever a compliance test case TS file is modified, all
compliance tests in repository are rebuilt in partial compilation mode.
This is inefficient and also slows down local development where one may
use a wildcard to run all test targets inside `/test/compliance/...`.

This commit fixes this.

PR Close #55594
2024-04-30 09:22:42 -07:00
Angular Robot 6250269f1f build: update scorecard action dependencies (#55589)
See associated pull request for more information.

PR Close #55589
2024-04-30 09:20:10 -07:00
Andrew Scott 3eea50da64 fix(router): Scroller should scroll as soon as change detection completes (#55105)
Using `setTimeout` to delay scrolling can result in scrolling in the
next frame and cause noticeable flicker. This commit scrolls as soon as
the next render happens (or in `setTimeout` if a render does not happen
before then).

fixes #53985

PR Close #55105
2024-04-30 09:19:09 -07:00
Matthieu Riegler e5d58d250d docs: add mention of the HTTP client for interceptors (#55551)
fixes #53911

PR Close #55551
2024-04-29 13:41:08 -07:00
Matthieu Riegler ac4e8f7bca docs: remove non existing link (#55562)
This link only exist on adev.

PR Close #55562
2024-04-26 12:36:48 -07:00
Kristiyan Kostadinov 51ac883167 fix(compiler-cli): don't type check the bodies of control flow nodes in basic mode (#55558)
Angular only checks the contents of template nodes in full type checking mode. After v17, the new control flow always had its body checked, even in basic mode, which started revealing compilation errors for apps that were using the schematic to automatically switch to the new syntax.

These changes mimic the old behavior by not checking the bodies of `if`, `switch` and `for` blocks in basic mode. Note that the expressions of the blocks are still going to be checked.

Fixes #52969.

PR Close #55558
2024-04-26 09:33:39 -07:00
Matthieu Riegler 9bb3446e35 docs: update ChangeDetectionStrategy links (#55553)
fixes #54227
fixes #50943

PR Close #55553
2024-04-26 09:31:45 -07:00
Matthieu Riegler 04d77d5a1c docs: remove mention of style sanitization. (#55553)
fixes #49566

PR Close #55553
2024-04-26 09:31:44 -07:00
Matthieu Riegler 1ca24cb936 docs: remove image (#55553)
The image was replaced by the following mermaid chart.

PR Close #55553
2024-04-26 09:31:44 -07:00
Matthieu Riegler 967bbc1e3e docs: update app-shell to reflect actual content (#55550)
fixes #55507

PR Close #55550
2024-04-26 09:29:35 -07:00
Matthieu Riegler 507d83d5ed refactor(devtools): hide hydration error when the component tree is collapsed (#54912)
This commit improves the devtools UX.

PR Close #54912
2024-04-25 14:57:21 -07:00
Matthieu Riegler 4a33efaa3e refactor(devtools): prevent dblclick on the expand arrow to show the element panel (#54912)
This will improve the UX

PR Close #54912
2024-04-25 14:57:21 -07:00
Matthieu Riegler 5530c5e505 refactor(devtools): improve signal support. (#54912)
In some cases signals weren't unwraped thus not reading the value correctly. This commit fixes this issue.

PR Close #54912
2024-04-25 14:57:20 -07:00
Matthieu Riegler ce094b227c refactor(devtools): fix issue with virtual scroll viewport in the directive forest (#54912)
In some cases the height of the viewport wasn't calculated correctly because of extension tabs quirks. This commit fixes this issue.

Fixes #53704

PR Close #54912
2024-04-25 14:57:20 -07:00
Kirk Larkin 9258160598 docs: Update di-in-action.md (#55489)
PR Close #55489
2024-04-25 12:55:15 -07:00
Alan Agius 3ee861835a refactor(core): set up framework injector profile exclusively in browser environment (#55530)
This commit modifies the setup of the injector profiler to occur solely when the application is running in a browser context. This adjustment is made because the injector profile serves no purpose when the application is running on the server.

PR Close #55530
2024-04-25 12:53:23 -07:00
Kirk Larkin 9cd633e1b8 docs: Update what-is-angular.md (#55536)
PR Close #55536
2024-04-25 12:52:33 -07:00
Matthieu Riegler 75db462d8b refactor(common): increment test coverage (#55532)
Ahead of #55283 and with what we learned from it,  let's improve our test coverage on the i18n subsystem.

PR Close #55532
2024-04-25 12:50:44 -07:00
Matthieu Riegler c3d077cca1 docs: fix the file naming for the NG05000 error (#55519)
PR Close #55519
2024-04-25 12:49:54 -07:00
Andrew Scott af0eb846a5 fix(core): render hooks should not specifically run outside the Angular zone (#55399)
The timing of render hook execution is almost entirely identical to
`ngZone.onMicrotaskEmpty`. Developers working towards zoneless
compatibility will need to migrate `onMicrotaskEmpty` calls to use
`afterNextRender`/`afterRender` instead. This, however, would lead to
confusing issues if there are promises in the callbacks because
`onMicrotaskEmpty` emits inside the Angular zone while render hooks
execute outside today. This is problematic because it's not documented
and does not produce any notification or error message when async work
is done inside the hooks that requires change detection. Instead, change detection
simply does not run, and this behavior has proven to be surprising to
developers who are used to ZoneJS change detection behavior.

fixes #55299

PR Close #55399
2024-04-25 09:06:37 -07:00
Andrew Kushnir 544aedee6f release: cut the v17.3.6 release 2024-04-25 08:25:55 -07:00
Alan Agius add11c6854 build: make scripts for compatibility with Node.js 18.20+ (#55526)
This commit enhances the ng-dev and other local scripts to ensure compatibility with Node.js 18.20+. This adjustment is essential for releasing this branch, as it would otherwise lack compatibility with that version.

PR Close #55526
2024-04-25 08:11:41 -07:00
Angular Robot 5083d893a9 build: update scorecard action dependencies (#55473)
See associated pull request for more information.

PR Close #55473
2024-04-23 15:17:43 -07:00
Andrew Scott 826861b1fa fix(core): DeferBlockFixture.render should not wait for stability (#55271)
The `DeferBlockFixture.render` function should not await the
`whenStable` promise of the fixture. This does not allow developers to
test any intermediate states that might occur between rendering the
initial content and the full app stability.

fixes #55235

PR Close #55271
2024-04-23 15:12:43 -07:00
Kirk Larkin 9cb003ac3d docs: Update dependency-injection.md (#55432)
PR Close #55432
2024-04-23 13:29:15 -07:00
Kirk Larkin efb9eb4fa9 docs: Update dependency-injection-context.md (#55455)
PR Close #55455
2024-04-23 13:27:17 -07:00
vladboisa 79a29e4f14 docs(docs-infra): fix broken links (#55446)
Add the missing folder's for links

Fixes #55442

docs(docs-infra): fix template reference link

Change the broken link

PR Close #55446
2024-04-23 13:21:49 -07:00
Drew Mares eda03d4b89 docs: Fix typo in waitForAsync example (#55407)
The previous example had an incomplete code snippet that would not work if copied and pasted as is. There were two missing closing parentheses, one for the `inject` function, and the other for the `waitForAsync` function.

PR Close #55407
2024-04-23 13:16:17 -07:00
Kristiyan Kostadinov 8979fba2c5 fix(core): skip defer timers on the server (#55480)
Adds a check that disables the timer scheduling for `placeholder` and `loading` blocks on the server since the underlying timer will delay the server response.

Fixes #55475.

PR Close #55480
2024-04-23 13:06:53 -07:00
Alan Agius d5ee04edc1 build: remove no longer required bazel windows patch (#55477)
This patch is no longer required.

PR Close #55477
2024-04-23 13:06:04 -07:00
Matthieu Riegler 87921d7fff docs: fix links to packages. (#55469)
fixes #55458

PR Close #55469
2024-04-23 13:04:22 -07:00
Angular Robot d38135a12d build: update actions/checkout digest to 1d96c77 (#55464)
See associated pull request for more information.

PR Close #55464
2024-04-23 13:03:51 -07:00
Doug Parker 775476b9ac docs(devtools): update README to be more clear for extension reviewers (#55406)
Mozilla requires add-ons to have reproducible builds and this is managed directly by human reviewers and need to understand how to build Angular DevTools correctly. This commit defines a reproducible way of building Angular DevTools which is useful for reviewers and contributers.

The actual changes I made include:
1. Moving local development content into `devtools/README` (deleting `devtools/DEVELOPING.md`) and explicitly stating the Node version as well as global Yarn install to be clear about the correct way to build the extension. This should make it easier for reviewers to understand and reproduce builds.
2. Moving release instructions to a separate doc to reduce noise as well as making some minor clean ups there.

I briefly considered pointing reviewers at a new `devtools/docs/reviewers.md` doc, but decided against it because I want these instructions to be maintained in a single location where contributors and reviewers use the same content. This way any changes don't miss one of these sets of users. If reviewers have trouble with this format (dev builds isn't useful to reviewers and some content is repeated from other docs for contributors) then we can consider splitting out to a separate `reviewers.md` file. But until then, I'd like to try sharing this content and see how it works out in practice.

PR Close #55406
2024-04-23 13:02:51 -07:00
Andrew Kushnir 5cf14da35c fix(core): make ActivatedRoute inject correct instance inside @defer blocks (#55374)
`RouterOutlet` uses a unique injector logic that returns a value that correspond to the `ActivatedRoute` token dynamically. This logic breaks when a component/directive/pipe that injects the `ActivatedRoute` is located within a `@defer` block, because defer creates an `EnvironmentInjector` instance, which doesn't have that dynamic logic.

We've added some special handling of the `OutletInjector` in one of the previous commits, but it was incomplete and it was not covering cases when different routes use the same component. This commit updates defer logic to re-establish this dynamic behavior for `ActivatedRoute` by creating an instance of the `OutletInjector` when a parent injector was also an instance of `OutletInjector`.

This fix is a short-term solution and longer term we should find a way to achieve the dynamic behavior that Router relies on, but without adding a special case logic into defer.

Resolves #54864.

PR Close #55374
2024-04-22 12:01:39 -07:00
Matthieu Riegler aeeb38a546 docs: fix link to inject-based-di tutorial. (#55453)
Fixes #55451

PR Close #55453
2024-04-22 11:57:37 -07:00
Kristiyan Kostadinov 2c66afe857 docs: remove performance warning for directive composition (#55448)
Removes the warning about performance from the directive composition API docs since some recent benchmarks have snown that their effect is negligible.

PR Close #55448
2024-04-22 11:52:43 -07:00
Angular Robot a19e214cbe build: update actions/cache digest to 0c45773 (#54950)
See associated pull request for more information.

PR Close #54950
2024-04-22 11:26:54 -07:00
AleksanderBodurri d4c103ae08 fix(devtools): allow DevTools to fail gracefully for unsupported versions of Angular. (#55233)
Angular DevTools depends on many modern Angular features in order to function. As a result, at present the last officially supported version is v12. Angular DevTools may function for some Angular 9, 10 and 11 applications, but they are not officially supported.

This commit fixes an issue where DevTools would not inject a backend script into an Angular application if it detected it was below version 12. This backend script is important because it's used to inform the DevTools panel that the inspected application is in fact Angular, but that it is not on a supported version.

Angular 9, 10 and 11 applications that successfully have Angular DevTools initialize will now have a red highlight and tooltip on their version number, informing the user that they are using Angular DevTools on a version of Angular that is no longer supported.

Angular DevTools for applications that are below version 9 will continue to display the "Angular Devtools supports Angular versions 12 and above" message.

PR Close #55233
2024-04-22 11:25:21 -07:00
Angular Robot 39b7bdabec build: update scorecard action dependencies (#55419)
See associated pull request for more information.

PR Close #55419
2024-04-19 13:26:43 -07:00
Alan Agius 99df5a8ba2 build: update Domino to 8f228f8862540c6ccd14f76b5a1d9bb5458618af (#55426)
This contains the fix for #55416

PR Close #55426
2024-04-19 13:25:21 -07:00
Angular Robot 8ae4783d9b build: update github/codeql-action action to v3.25.0 (#55358)
See associated pull request for more information.

PR Close #55358
2024-04-17 18:02:50 +02:00
Pawel Kozlowski cc57d4c499 release: cut the v17.3.5 release 2024-04-17 17:43:14 +02:00
Doug Parker 8c6f261fa3 release: bump Angular DevTools version to 1.0.13 (#55371)
PR Close #55371
2024-04-17 07:53:12 +02:00
Matthieu Riegler c67cbe98a6 docs: use 17.3.x branch for aio quick start (#55328)
PR Close #55328
2024-04-15 17:27:16 +02:00
Paul Gschwendtner 9bf9864e79 build(docs-infra): fix playground lezer parsing (#55349)
When we started fixing the version mismatch with local 1st-party
packages, we also re-routed all dependencies like `@lezer/javascript`
into `adev/node_modules`. This works fine, but results in a different
version mismatch because the codemirror dependencies may resolve the
Angular version from `/node_modules`- causing some subtle complex
runtime error.

This commit fixes this by only re-routing dependencies that have
dependency on e.g. `@angular/core` into `adev/node_modules`.

Fixes #55298.

PR Close #55349
2024-04-15 16:36:41 +02:00
Mo Ibrahim a3b1dc005d docs: fix repeated note in "Add an Input to the component" section (#55306)
PR Close #55306
2024-04-12 10:14:08 -07:00
Jeremy Elbourn 8bd9ad02a4 docs: add team docs for when to use dev preview and experimental (#55308)
Adds a brief team doc for when to use developer preview and experimental
API tags.

PR Close #55308
2024-04-12 10:10:56 -07:00
Angular Robot 8a670e6bc5 build: update io_bazel_rules_sass digest to c3f163f (#55307)
See associated pull request for more information.

PR Close #55307
2024-04-12 10:34:41 +02:00
Leon Senft afdcff3f71 test(core): fix expectations that accidentally used incorrect matchers (#55294)
Expect that the number of template executions is `===` to a number, rather than expect that it
does not contain a number. As they were, these expectations would pass regardless of the expected
value.

PR Close #55294
2024-04-12 07:38:55 +02:00
Matthieu Riegler 051c140cc3 build(http): Mark the http tests as flaky because of one particular transferCache test. (#55255)
There is one particular transfer cache test that seldom fails. Let's mark it as flaky for now as this issue is non-obvious.

PR Close #55255
2024-04-11 20:50:20 +02:00
ehlemur c77ebb6f51 docs(core): add missing space (#55287)
Add missing space after period in section describing producers and consumers.

PR Close #55287
2024-04-11 17:25:35 +02:00
Chinthoorie b955999d29 refactor(compiler-cli): move config initialization into constructor (#54975)
refactor(compiler-cli): move config initialization into constructor
PR Close #54975
2024-04-11 11:20:18 +02:00
Andrew Scott 268a26f1b6 release: cut the v17.3.4 release 2024-04-10 15:13:53 -07:00
Andrew Scott ca8969b946 Revert "docs(docs-infra): move CLI docs to ADEV (#55242)" (#55291)
This reverts commit 4d2a8005e8.

PR Close #55291
2024-04-10 13:06:44 -07:00
Rahat Ahmed ce231fb271 ci: Merge primitives-shared and primitives-event-dispatch groups (#55273)
This simplifies the approvals necessary for the event dispatch directory

PR Close #55273
2024-04-10 10:59:46 -07:00
Angular Robot 888360a6b0 build: update github/codeql-action action to v3.24.10 (#55258)
See associated pull request for more information.

PR Close #55258
2024-04-10 10:50:52 -07:00
Paul Gschwendtner 1713d31026 build: do not clear stdout of architect-cli when building adev (#55282)
Similar to what we did for aio, we should not clear the architect CLI
output in Bazel. This messes up with the output and makes debugging
hard.

PR Close #55282
2024-04-10 10:48:40 -07:00
Paul Gschwendtner 4390d09d58 build(docs-infra): disable caching of adev inside bazel (#55282)
Similar to `aio`, disables caching inside Bazel as it would be discarded
anyway and is likely a source of slowness then.

PR Close #55282
2024-04-10 10:48:40 -07:00
Paul Gschwendtner 7676d8fc2d build(docs-infra): fix version mismatch of local built packages (#55282)
There is quite some trickery going on with the adev build related to
local packages:

- Adev builds using npm packages from `/node_modules`
- At runtime, we are adding `HEAD` packages for e.g. `@angular/core` to
  the bundles.
- At build time, the CLI, or Angular devkit may accidentally resolve to
  `@angular/core` from `/node_modules/`— which is the core version from
  npm, transitively installed via `@angular/docs`.

This causes a version mismatch, leading to issues like:

- CLI throwing because of a mismatch. https://github.com/angular/angular/issues/54858#issuecomment-2047188739
- Compiler changes not being picked up. https://github.com/angular/angular/issues/54858#issuecomment-2041322427

This commit attempts to fix this by:

- Linking all Angular `HEAD` packages into `adev/node_modules`. The
  current logic attempts to link into `/node_modules`, but this does not
  override existing `@angular/core`!
- Linking all direct external NPM packages, like
  `@angular_devkit/build-angular` into `adev/node_modules` without their
  transitive deps. This allows proper resolution of e.g. compiler as
  node looks in `adev/node_modules` first, and falls back for the rest
  to the execroot `node_modules`, or symlink target destination (if
  `preserveSymlinks=false`).

Note: This is still not 100% ideal because a direct external NPM
dependency may have a transitive dependency that has another transitive
dependency on `@angular/core`. In those cases, the may be a conflict
that is not resolvable until we switch to a Bazel toolchain with better
first party resolution support.

PR Close #55282
2024-04-10 10:48:40 -07:00
Paul Gschwendtner e9e8960e76 docs: add guide for the output() function (#54946)
Adds a guide for angular.io that introduces the new `output()` function
(and `outputFromObservable`).

PR Close #54946
2024-04-10 10:40:43 -07:00
Jeffrey Smith 766548c3ec fix(common): skip transfer cache on client (#55012)
transfer cache interceptor should not run again on the client as it is intended for server to client handoff

PR Close #55012
2024-04-09 14:45:39 -07:00
Martin Machava 545fb0d88b docs(forms): validate email field with proper validator (#55142)
PR Close #55142
2024-04-09 12:15:31 -07:00
Matthieu Riegler 9a2295fcee refactor(core): Remove zone assertion from hydration cleanup. (#55214)
In zoneless apps with hydration, this assertion was throwing.

Fixes #52160

PR Close #55214
2024-04-09 12:13:01 -07:00
Martin Machava d0ae5561b0 docs: fix input name (#55141)
This commit fixes the name of the input used for the email.

PR Close #55141
2024-04-09 11:21:09 -07:00
Matthieu Riegler 9d6effcec9 docs: update readme link (#55155)
fixes#55153

PR Close #55155
2024-04-09 10:32:52 -07:00
Boris Pouw 5587dde5d5 docs: add back dynamic form image to fix adev broken link (#55247)
This commit adds back the dynamic form image that was previously removed. This fixes the broken link in the adev documentation.

PR Close #55247
2024-04-08 14:33:30 -07:00
Mahdi Lazraq 650101e19d docs: add closing tag in hierarchical injectors documentation (#54954)
PR Close #54954
2024-04-08 14:11:32 -07:00
Andrew Mayer 36e8f4d5c8 docs: update links to calling-compilecomponents intesting-utility-apis (#55055)
PR Close #55055
2024-04-08 14:08:40 -07:00
Andrew Mayer 766db6a069 docs: update links to the calling-compilecomponents section (#55055)
PR Close #55055
2024-04-08 14:08:40 -07:00
gwario 5826d8cb52 docs: fix typo in event-binding documentation (#55189)
PR Close #55189
2024-04-08 13:47:38 -07:00
Angular Robot a7c1115c3d build: update io_bazel_rules_sass digest to 147f7fa (#55208)
See associated pull request for more information.

PR Close #55208
2024-04-08 13:41:26 -07:00
lilbeqiri 5c0004bb62 refactor: do cleanups to theme, version and content loader services at adev (#55234)
Keep theme constants in sync betwee index.html file and theme manager. Move versions config static data to their own file, and replace the deprecated toPromise() api with the new firstValueFrom() api

PR Close #55234
2024-04-08 13:38:12 -07:00
Matthieu Riegler 9f0691577e docs: replace code-example with docs-code (#55186)
PR Close #55186
2024-04-08 11:49:29 -07:00
Matthieu Riegler 4d2a8005e8 docs(docs-infra): move CLI docs to ADEV (#55242)
Previously located in the `aio` directory, the commit moves the docs file into `adev` and also moves the `script` used to generated them from the `angular-cli` repo.

PR Close #55242
2024-04-08 11:35:13 -07:00
Matthieu Riegler 13404d5107 docs(docs-infra): remove compiler import (#55229)
PR Close #55229
2024-04-08 11:31:58 -07:00
Matthieu Riegler 68d51f08a3 build: update licence date. (#55129)
Wasn't done last year, let's do it in 2024

PR Close #55129
2024-04-08 11:31:14 -07:00
Mohamed 422e9754b0 docs: fix broken logo link (#55239)
replace logo in main readme

PR Close #55239
2024-04-08 11:26:10 -07:00
Johnny Gérard 80d1094a4e test(common): update ImageKit low quality test (#55193)
For commit cd911a8008

PR Close #55193
2024-04-05 14:55:14 +00:00
Johnny Gérard 53427d875d fix(common): invalid ImageKit quality parameter (#55193)
The current quality parameter is ignored by ImageKit.

PR Close #55193
2024-04-05 14:55:14 +00:00
Jessica Janiuk 9cb1d27406 ci: pullapprove is case sensitive (#55220)
This fixes thePunderWoman for case sensitivity

PR Close #55220
2024-04-04 21:27:19 -07:00
Matthieu Riegler ee0412fb29 docs: use structural directives workflow for structural directives docs. (#55212)
fixes #53078

PR Close #55212
2024-04-04 16:03:44 +00:00
Jessica Janiuk 05e7bf8734 ci: jessicajaniuk is thePunderWoman (#55205)
this swaps jessica for jessica.

PR Close #55205
2024-04-03 16:05:21 -07:00
Jessica Janiuk 16eba152c4 release: cut the v17.3.3 release 2024-04-03 13:39:43 -07:00
Jessica Janiuk 4ac78fb846 ci: remove event-dispatch in pullapprove (#55200)
patch does not include event-dispatch paths, which was causing pullapprove to fail.

PR Close #55200
2024-04-03 18:45:56 +00:00
Jessica Janiuk 5ba2a48f49 ci: fixes jsaction path name (#55199)
This updates the jsaction path to be event-dispatch.

PR Close #55199
2024-04-03 18:27:46 +00:00
Jessica Janiuk 88f0545e8e refactor(core): remove unnecessary folder (#55197)
This removes a temporary folder for jsaction.

PR Close #55197
2024-04-03 18:08:16 +00:00
Jessica Janiuk eb9a5f5bbe ci: Add primitives groups to pullapprove (#53404)
This adds the shared primitives reviewers groups and list of reviewers
to the pullapprove rules.

PR Close #53404
2024-04-03 17:06:05 +00:00
Andrew Kushnir 158ceaf062 fix(core): handle ChainedInjectors in injector debug utils (#55144)
The fix from PR #55079 introduced a configuration of the injector chain, which wasn't properly handled by the injector debug utils, thus resulting in JS exceptions in DevTools. This commit updates injector debug utils logic that calculates injector resolution path to also handle `ChainedInjector`s.

Resolves #55137.

PR Close #55144
2024-04-03 15:26:48 +00:00
James 816ddf4539 docs: fix typo in first-app/steps/06-property-binding/README.md (#55181)
PR Close #55181
2024-04-03 00:14:15 +00:00
Matthieu Riegler f4e9768da2 docs: fix aio job (#55179)
PR Close #55179
2024-04-02 20:33:20 +00:00
ivanwonder 7b67ad2fc5 refactor(language-service): support showing tags info in the completion (#51140)
The Angular VSCode extension will support showing the tags info in this

[PR][1], so the language service can return the tags info now.

[1]: https://github.com/angular/vscode-ng-language-service/pull/1904

PR Close #51140
2024-04-02 16:21:02 +00:00
garrettld 129c973934 fix(devtools): fix padding in property tree view (#54648)
This import was missed when switching devtools to standalone.

fixes #54622

PR Close #54648
2024-04-01 10:52:45 -07:00
Jessica Janiuk bc429baa92 ci: Update workflows to use latest dev infra hash (#55128)
This bumps the hash for dev-infra dependencies to utilize the latest build and changes

PR Close #55128
2024-04-01 10:00:11 -07:00
Paweł Kubiak a84beaa4a7 fix(docs-infra): scrolling experience in API Reference (#55133)
Fix scrolling experience in API Reference:
- set correct margin top for members container (right side) which is aligned with tabs (left side)
- prevent scroll on focus
- remove redundant blur calls

PR Close #55133
2024-03-29 19:05:56 -07:00
Matthieu Riegler fd45d03d2f docs(docs-infra): Use monospace font for API reference (#54558)
fixes #52612

PR Close #54558
2024-03-29 16:46:25 -07:00
Kristiyan Kostadinov 949dec26b8 fix(migrations): avoid conflicts with some greek letters in control flow migration (#55113)
The control flow migration was using a couple of Greek letters as placeholders. This ended up conflicting with templates authored in Greek.

These changes use a more obscure placeholder to make conflicts less likely. It also moves the placeholder generation to a centralized function so it's easier to make changes if we decide to update the pattern again.

Fixes #55085.

PR Close #55113
2024-03-29 13:10:55 -07:00
Matthieu Riegler fc034137ab docs(docs-infra): move Features APIs above the filter section & rename to "Most Common (#54557)
Fixes #52705

PR Close #54557
2024-03-29 13:08:31 -07:00
vladboisa ca60d9dd3f refactor(docs-infra): move gif to display (#54795)
To display the image correctly, swap the image from the folders

Fixes  #54778

feat(docs-infra): change path for correct ADEV

Changing path for correctly displaying in adev

PR Close #54795
2024-03-29 13:06:43 -07:00
Johnny Gérard 10851d27cc docs(common): clean up comment (#55088)
PR Close #55088
2024-03-29 13:02:50 -07:00
Andrew Scott d10dc5c85c Revert "refactor(compiler): add support for the new search element (#54945)" (#55127)
This reverts commit 367b3ee6e9.
The search element is not a void element but existing components may use
the same selector and be used as a void element.

PR Close #55127
2024-03-29 12:56:33 -07:00
Andrew Scott cb95e2f8ab Revert "ci: Update workflows to use latest dev infra hash (#55123)" (#55126)
This reverts commit e4fde98279.

PR Close #55126
2024-03-29 12:48:28 -07:00
Jessica Janiuk eb0ccfc40c ci: Update workflows to use latest dev infra hash (#55123)
This bumps the hash for dev-infra dependencies to utilize the latest build and changes

PR Close #55123
2024-03-29 11:51:32 -07:00
Matthieu Riegler a8a20ad238 refactor(compiler): add support for the new search element (#54945)
See #whatwg/html#5811
Spec: https://html.spec.whatwg.org/multipage/grouping-content.html#the-search-element

fixes #54944

PR Close #54945
2024-03-29 10:02:03 -07:00
reafernandes10 e53d02df85 docs(http): Update the Setup for testing in Http Client to include provideHttpClient() (#53716)
It is not enough to use provideHttpClientTesting() for HTTP Client Testing, it will throw a dependency injection error. Update the docs to include both provideHttpClient() and provideHttpClientTesting()

Fixes #53390

PR Close #53716
2024-03-29 09:40:13 -07:00
vladboisa 109df125c8 docs(docs-infra): rephrase sentence to make sense (#54914)
Remove the confuse sentences with 2 categories, and rephrase

Fixes #54792

PR Close #54914
2024-03-29 09:34:50 -07:00
Matthieu Riegler 17f2181299 docs: fix API tabs height to allow overflow/scrolling (#55109)
fixes #53294

PR Close #55109
2024-03-29 09:33:15 -07:00
Matthieu Riegler 0bcea6c928 docs: document why undefined is usefull and does not remove classes (#55112)
Fixes #54601

PR Close #55112
2024-03-29 09:22:11 -07:00
Matthieu Riegler 2c325d46b0 docs(docs-infra): improve styling for deprecated CLI option (#54794)
Related to #54770

PR Close #54794
2024-03-28 15:48:26 -07:00
Matthieu Riegler 54a8fc3b19 docs(docs-infra): add margin for command aliases (#54794)
PR Close #54794
2024-03-28 15:48:24 -07:00
Matthieu Riegler 555696635e docs(docs-infra): improve space between cli command options (#54794)
fixes #54767

PR Close #54794
2024-03-28 15:48:23 -07:00
Allan Barrantes 878f581961 docs: remove broken link from CONTRIBUTING.md (#54953)
PR Close #54953
2024-03-28 15:06:59 -07:00
Garrett Darnell 9cef0d210f docs(core): fix toSignal docs (#54964)
PR Close #54964
2024-03-28 13:06:45 -07:00
Angular Robot 346a555e93 build: update github/codeql-action action to v3.24.9 (#55039)
See associated pull request for more information.

PR Close #55039
2024-03-28 13:05:59 -07:00
Ben Hong fa837a393e docs: fix outdated security guide reference (#55069)
PR Close #55069
2024-03-28 13:02:00 -07:00
Andrew Scott 4d043992e5 fix(core): test cleanup should not throw if Zone is not present (#55096)
The test hooks should not throw if applications choose not to load ZoneJS.

fixes #48198

PR Close #55096
2024-03-28 12:12:31 -07:00
Ben Hong 2abcb040eb docs: add missing h1 to page for skip to main content on home page (#55052)
PR Close #55052
2024-03-28 12:09:59 -07:00
Dylan Hunn 67f0cf5fc8 release: cut the v17.3.2 release 2024-03-28 09:56:43 -07:00
Kristiyan Kostadinov 2f9d94bc4a fix(migrations): account for variables in imports initializer (#55081)
Fixes that the control flow migration was throwing an error if the `imports` of a component are initialized to an identifier.

Fixes #55080.

PR Close #55081
2024-03-28 09:40:33 -07:00
Paul Gschwendtner ee76001431 refactor(compiler-cli): support ignoring specific doc entries during extraction (#55053)
This commit adds support for ignoring specific doc entries when
extracting doc entries. This allows us to drop e.g. `InputFunction` from
the API docs, given that the `input` API entry holds all the relevant
information.

`InputFunction` only exists for type purposes in the `.d.ts`.

PR Close #55053
2024-03-28 09:38:43 -07:00
Paul Gschwendtner b63afb9e93 refactor(core): improve API documentation for query initializer APIs (#55053)
Similar to `input`, `model`, `output`, the query initializer APIs are
also explicitly denoted as such. This allows angular.dev to display them
more readable and compactly.

PR Close #55053
2024-03-28 09:38:43 -07:00
Paul Gschwendtner 658fb0a17f refactor(core): improve API documentation for output (#55053)
This improves the API documentatino for `output` in angular.dev,
similar to how we improved the API for `input`.

Angular.dev can now show these documentation entries more
readable if annotated explicitly as initializer API.

Note: output API is short enough that we want to include
the types in the code snippet previews.

PR Close #55053
2024-03-28 09:38:42 -07:00
Paul Gschwendtner f8aa778b70 refactor(core): improve API documentation for model (#55053)
Improves the API documentation for `model`, similarly to how
we updated the `input` function.

PR Close #55053
2024-03-28 09:38:41 -07:00
Paul Gschwendtner 60ed00a601 refactor(core): improve API documentation for input after angular.dev support (#55053)
This commit improves the API documentation for `input` after
we added support for initializer APIs in angular.dev docs generation.

Changes:

- Rename `ReadT` to `T`. This conceptually makes it easy to talk about
  inputs of type `T` if there is no transform involved. The common case.
- Rename `WriteT` to `TransformT`. This makes it clear that this is the
  type that the "transform" needs to handle.
- Improves the "overall" description of the input function so that it
  can be shown as a general overview for the API site.
- Improves usage notes to be a little more helpful, yielding more useful
  content in the API docs usage notes section.
- Add short JSDoc description for each individual overload.

PR Close #55053
2024-03-28 09:38:40 -07:00
Paul Gschwendtner c7ff3d158a refactor(docs-infra): support initializer API functions (#55053)
This commit ensures that extracted initializer API functions are
showing up in angular.dev and can be filtered.

PR Close #55053
2024-03-28 09:38:39 -07:00
Paul Gschwendtner aeb20f95d2 refactor(compiler-cli): support extracting initializer API functions (#55053)
This commit adds support for extracting initializer API functions.
Initialixer API functions are functions conceptually that can are
intended to be used as class member initializers.

Angular started introducing a few of these for the new signal
APIs, like `input`, `model` or signal-based queries.

These APIs are currently confusingly represented in the API docs because
the API extraction:

- does not properly account for call signatures of interfaces
- does not expose information about sub-property objects and call
  signatures (e.g. `input.required`)
- the docs rendering syntax highlighting is too bloated and confusing
  with all types being included.

This commit adds support for initializer API functions, namely two
variants:

- interface-based initializer APIs. e.g. `export const input:
  InputFunction`- which is a pattern for `input` and `input.required`.
- function-based simpler initializer APIs with overloads. e.g.
  `contentChildren` has many signatures but doesn't need to be an
  interface as there are no sub-property call signatures.

PR Close #55053
2024-03-28 09:38:38 -07:00
Andrew Kushnir 708ba8115f fix(core): establish proper injector resolution order for @defer blocks (#55079)
This commit updates the `@defer` logic to establish proper injector resolution order. More specifically:

- Makes node injectors to be inspected first, similar to how it happens when `@defer` block is not used.
- Adds extra handling for the Router's `OutletInjector`, until we replace it with an `EnvironmentInjector`.

Resolves #54864.
Resolves #55028.
Resolves #55036.

PR Close #55079
2024-03-28 09:23:42 -07:00
Matthieu Riegler fb5a28858d refactor(devtools): prevent exeception on state serializer (#55061)
`Object.getPrototypeOf(obj)` returns `null` if `obj` is an empty object. `Object.getOwnPropertyDescriptors` throws on `null`/`undefined`

PR Close #55061
2024-03-28 09:14:25 -07:00
Paul Gschwendtner 5b67c94775 refactor(compiler-cli): improve error message for uncaught FatalDiagnosticError (#55070)
For `FatalDiagnosticError` we are currently hiding the `message` string
field in favor of the actual TS `diagnosticMessage`.

This works as expected, but makes these errors hard to debug in certain
environments (e.g. Jasmine). That is because `null` is the value of
`message` at runtime. We fix this by just overriding the type, like we
originally intended to do.

In addition, we properly render message chains in the `Error#message`
field— so that these errors, when uncaught, are somewhat reasonable and
can be useful.

PR Close #55070
2024-03-28 09:13:09 -07:00
Paul Gschwendtner b478dfbfda fix(compiler-cli): report errors when initializer APIs are used on private fields (#55070)
This commit ensures that the new APIs like `input`, `model`, `output`,
or signal-based queries are not accidentally used on fields that have a
problematic visibility/access level that won't work.

For example, queries defined using a private identifier (e.g. `#bla`)
will not be accessible by the Angular runtime and therefore _dont_ work.

This commit ensures:

- `input` is only declared via public and protected fields.
- `output` is only declared via public and protected fields.
- `model` is only declared via public and protected fields.
- signal queries are only declared via public, protected and TS private
  fields (`private` works, while `#bla` does not).

Fixes #54863.

PR Close #55070
2024-03-28 09:13:08 -07:00
Paul Gschwendtner 75d1cae616 refactor(compiler-cli): support enforcing field access for initializer APIs (#55070)
An initializer API like `input`, `output`, or signal queries may not be
compatible with certain access levels. E.g. queries cannot work with ES
private class fields.

This commit introduces a check for access levels into the initializer
API recognition— enforcing that every initializer API *clearly*
specifies what type of access is allowed.

PR Close #55070
2024-03-28 09:13:07 -07:00
Paul Gschwendtner 53fe455630 refactor(compiler-cli): reflection should inspect ES private fields and visibility (#55070)
This commit changes the TypeScript reflection host to:

* inspect / process ES private fields. e.g. `#someField` — those are
  ignored right now and we would want to check them to issue
  diagnostics.

* determine an access level of a class member. E.g. a member may be
  public, may be private, may be ES private, or public readonly. This
  can then be used in various checks later.

PR Close #55070
2024-03-28 09:13:06 -07:00
Kristiyan Kostadinov 1470b7d40e refactor(compiler-cli): expand type of initializer parsing function (#55070)
Updates the function that parses initializer APIs to check any `Expression`, instead of expecting a class member. This will be useful for the upcoming changes.

PR Close #55070
2024-03-28 09:13:05 -07:00
Matthieu Riegler 76631995e1 docs: link to http security now at best-practices/security (#55060)
fixes #55058

PR Close #55060
2024-03-27 11:32:09 -07:00
Esteban Luchsinger 519e781701 docs: explain difference between @placeholder and @loading (#54779)
Add a sentence to the `@loading` block documentation that emphasizes more that the `@loading` block will replace the `@placeholder` block once the deferred view starts loading.

PR Close #54779
2024-03-27 11:09:17 -07:00
vladboisa 1af2be9b23 docs(docs-infra): replace link by HTTPsecurity tab (#55029)
Replace a broke link by content of HTTP Client Security Tab.

Fixes #54918 & #54922

PR Close #55029
2024-03-27 10:50:25 -07:00
JiaLiPassion a893f0b60d fix(zone.js): should not clear onhandler when remove capture listener (#54602)
Close #54581

Should not clear `onHandler` when remove capture event listeners.

PR Close #54602
2024-03-27 10:40:06 -07:00
Paul Gschwendtner 93ce4d0483 refactor(compiler-cli): properly preserve file overview comments (#54983)
This commit updates the logic for preserving file overview comments
to be more reliable and less dependent on previous transforms.

Previously, with the old import manager, we had a utility called
`addImport` that always separated import statements and non-import
statements. This meant that the non-emitted statement from Tsickle
for the synthetic file-overview comments no longer lived at the
beginning of the file.

`addImports` tried to overcome this by adding another new non-emitted
statement *before* all imports. This then was later used by the
transform (or was assumed!) to attach the synthetic file overview
comments if the original tsickle AST Node is no longer at the top.

This logic can be improved, because the import manager shouldn't need to
bother about this fileoverview non-emitted statement, and the logic for
re-attaching the fileoverview comment should be local. This commit fixes
this and makes it a local transform.

PR Close #54983
2024-03-27 10:18:30 -07:00
Paul Gschwendtner ed271ebb37 test(compiler-cli): add tests to verify import generation in TCB files/blocks (#54983)
This commit adds some unit tests verifying the import generation in TCB
files and inline blocks. We don't seem to have any unit tests for these
in general. This commit adds some, verifying some characteristics we
would like to guarantee.

PR Close #54983
2024-03-27 10:18:30 -07:00
Paul Gschwendtner 6734b59b35 refactor(compiler-cli): rename ImportManagerV2 to ImportManager (#54983)
To ease review and to allow for both instances to co-exist, `ImportManagerV2`
was introduced. This commit renames it to `ImportManager` now that we
deleted the older one.

PR Close #54983
2024-03-27 10:18:29 -07:00
Paul Gschwendtner 789326d483 refactor(compiler-cli): delete old unused ImportManager (#54983)
This commit deletes the older and now unused `ImportManager`.

PR Close #54983
2024-03-27 10:18:29 -07:00
Paul Gschwendtner 4b63716b4a test(compiler-cli): enable incremental re-use type checking with signal inputs (#54983)
Enables the incremental type-checking test that we never enabled when we
landed signal inputs. Now that we fixed incremental re-use by re-using
the existing user imports for inline type check blocks, the test is
passing and can be enabled.

PR Close #54983
2024-03-27 10:18:29 -07:00
Paul Gschwendtner 308b194ee3 refactor(compiler-cli): switch jit transforms to use new import manager (#54983)
Switches the JIT transforms to use the new import manager.

PR Close #54983
2024-03-27 10:18:29 -07:00
Paul Gschwendtner 62510a7b4d refactor(compiler-cli): update type check generation code to use new import manager (#54983)
Updates the type-check block generation code (also for inline type check
blocks) to use the new import manager.

This is now a requirement because the translator utilities from the
reference emit environment expect an import manager that follows the
new contract established via `ImportGenerator<TFile, TExpression>`.

For type check files, we can simply print new imports as we don't expect
existing imports to be updated. That is because type check files do not
have any _original_ source files (or in practice— those are empty).

For type check blocks inline, or constructors, imports _may_ be re-used.
This is great as it helps fixing some incrementality bugs that we were
seeing in the type check code. That is, sometimes the type check block
code may generate imports conditionally for e.g. `TemplateRef`, or
animations. Those then **prevent** incremental re-use if TCB code
switches between those continously. We tried to account for that with
signal inputs by always pre-generating such imports. This fixed the
issue for type-check files, but for inline type check blocks this is
different as we would introduce new imports in user code that would then
be changed back in subsequential edit iterations. See:
https://github.com/angular/angular/pull/53521#pullrequestreview-1778130879.

In practice, the assumption was that we would be fine since user code is
most likely containing imports to `@angular/core` already. That is a
true assumption, but unfortunately it doesn't help with incremental
re-use because TypeScript's structural change detection does not dedupe
and expects 1:1 exact imports from their old source files.

https://github.com/microsoft/TypeScript/pull/56845

To improve incremental re-use for the type check integration, we should
re-use original source file imports when possible. This commit enables
this.

To update imports and execute inline operations, we are now uisng
`magic-string` (which is then bundled) as it simplifies the string
manipulatuons.

PR Close #54983
2024-03-27 10:18:29 -07:00
Paul Gschwendtner ece2deeab6 refactor(compiler-cli): use new import manager for ngtsc transforms (#54983)
This commit switches ngtsc's JS and DTS transform to use the new import
manager. This is a drop-in replacement as we've updated the translator
helpers in the previous commit to align with the new API suggested by
the `ImportManagerV2` (to be renamed then).

PR Close #54983
2024-03-27 10:18:29 -07:00
Paul Gschwendtner 4d8d324ea6 refactor(compiler-cli): update ImportGenerator abstraction for new manager (#54983)
`ImportGenerator` is the abstraction used by the translator functions to
insert imports for `ExternalExpr` in an AST-agnostic way.

This was built specifically for the linker which does not use any of the
complex import managers- but rather re-uses `ngImport` or uses
`ngImport.Bla`.

This commit also switches the linker AST-agnostic generator to follow
the new signatures. This was rather trivial.

PR Close #54983
2024-03-27 10:18:29 -07:00
Paul Gschwendtner 3253576db8 refactor(compiler-cli): introduce new implementation of ImportManager (#54983)
This commit introduces a new implementation of `ImportManager` that has
numerous benefits:

- It allows efficient re-use of original source file imports.
  * either fully re-using original imports if matching
  * updating existing import declarations to include new symbols.
- It allows efficient re-use of previous generated imports.
- The manager can be used for schematics and migrations.

The implementation is a rework of the import manager that we originally
built for schematics in Angular Material, but this commit improved it
to be more flexible, more readable, and "correct".

In follow-ups we can use this for schematics/migrations.

PR Close #54983
2024-03-27 10:18:29 -07:00
Andrew Scott 365fd50407 fix(router): RouterLinkActive will always remove active classes when links are not active (#54982)
Previously, `RouterLinkActive` would only add or remove the active classes when
its active state changed. This means that if you accidentally add one of
the active classes to the static class attribute, it won't get removed
until the link becomes active and then deactives (because the class is
added at creation time and never removed until the `RouterLinkActive`
state changes from active to inactive).

fixes #54978

PR Close #54982
2024-03-27 10:16:23 -07:00
Matthieu Riegler d1d9f5569f docs: update compat table with 17.3 (#54882)
PR Close #54882
2024-03-27 09:58:11 -07:00
Ben Hong 7763387253 docs: reduce confusion on tutorial intro and reorder how resources are introduced (#55051)
PR Close #55051
2024-03-27 09:56:44 -07:00
Doug Parker 0ec68a2a40 release: bump Angular DevTools version to 1.0.12 (#55056)
Also fixes a typo in release docs for the Firefox `zip` command.

PR Close #55056
2024-03-27 09:55:41 -07:00
Paul Gschwendtner 2ad5dcf3f0 [17.3.x]: build: follow-up fixes for AIO lighthouse checks (#55065)
* build: follow-up fixes for AIO lighthouse checks

Looks like the latest versions of Lighthouse and puppeteer
are not compatible with our Chromium version from dev-infra.

This commit reverts the updates, and fixes the jobs.

Update payload size; now matching — seems expected
2024-03-27 15:46:46 +01:00
Paul Gschwendtner 9aff43b5e8 ci: fix build failures in patch branch (#55064)
This commit fixes various issues that seem to cause the 17.3.x patch
to be red for weeks:

- Eslint checking a file for aio/tools that is not part of a tsconfig—
  hence an error is being reported.

- Audit-web-app importing some Lighthouse APIs that aren't available
  under the given path.

PR Close #55064
2024-03-27 11:58:46 +00:00
AleksanderBodurri fa46844f5c fix(devtools): issue where backendReady race condition causes Angular not detected error (#54805)
Previously, a race condition could cause DevTools to enter a state where it can't detect an application on reload. This was caused by a sequencing issue between the content script connection, the devtools panel connection and an event "backendReady" that lets DevTools know when a particular frame is ready to be inspected.

This commit replaces the previously stored backendReady boolean with a promise, so that the devtools panel can eventually run a callback to connect to a content script when that content script emits it's backendReady message.

PR Close #54805
2024-03-26 09:19:16 -07:00
AleksanderBodurri cd00ec582b Revert "Revert "refactor(devtools): implement multiframe support in devtools page (#53934)" (#54629)" (#54805)
This reverts commit 133319eba0.

PR Close #54805
2024-03-26 09:19:14 -07:00
AleksanderBodurri 821012d0f7 Revert "Revert "refactor(devtools): implement iframe support for Angular DevTools' browser code (#53934)" (#54629)" (#54805)
This reverts commit dd9f9d7d44.

PR Close #54805
2024-03-26 09:19:14 -07:00
Alan Agius 8958e0bf70 Revert "fix(http): exclude caching for authenticated HTTP requests (#54746)" (#55033)
This reverts commit 2258ac7a32.

Closes: #55031

PR Close #55033
2024-03-26 09:16:34 -07:00
Matthieu Riegler 4bb332ef08 refactor(common): request low quality placeholder images (#54899)
For every built-in load, this commit adds a parameter to load low quality placeholder images. Using 20/100 as base value.

PR Close #54899
2024-03-25 11:17:34 -07:00
Alan Agius 64f202cab9 fix(http): manage different body types for caching POST requests (#54980)
This update enhances the encoding handling of request bodies to generate the necessary cache key for transfer cache functionality.

Closes #54956

PR Close #54980
2024-03-25 11:17:03 -07:00
Matthieu Riegler cf34d2b87f docs: unescape html entities (#55016)
adev supports regular characters in place of entity. Let's use them to make the ease the work for the editors.

PR Close #55016
2024-03-25 11:16:35 -07:00
Andrea Canciani ec4483c471 test(zone.js): fix zone.js test listener removal (#55017)
The test was checking the wrong set of listeners because of a typo.

PR Close #55017
2024-03-25 11:16:06 -07:00
Mahdi Lazraq 1f7e81aef9 refactor(http): use nullish coalescing operator in HttpRequest.clone() (#54939)
Refactor how boolean options are handled in HttpRequest.clone() method by using nullish coalescing operator

PR Close #54939
2024-03-21 22:13:45 -07:00
Mahdi Lazraq cb433af0e1 fix(http): include transferCache when cloning HttpRequest (#54939)
Fixes a bug where HttpRequest.clone() does not include the transferCache property.

Fixes #54924.

PR Close #54939
2024-03-21 22:13:44 -07:00
Joey Perrott 3cf70e26ba ci: change label set by renovate to be merge ready immediately (#54947)
Since the PR is always expected to be ready to merge as renovate won't make changes in response to any sort of comment, it should already be marked as merge ready

PR Close #54947
2024-03-21 22:11:10 -07:00
Kristiyan Kostadinov 2b7bad5151 fix(compiler): invoke method-based tracking function with context (#54960)
Previously we assumed that if a `for` loop tracking function is in the form of `someMethod($index, $item)`, it will be pure so we didn't pass the parameter to bind the context to it. This appears to be risky, because we don't know if the method is trying to access `this`.

These changes play it safe by always binding method-based tracking functions.

Fixes #53628.

PR Close #54960
2024-03-21 22:08:41 -07:00
Andrew Scott 78d4ad20e6 ci: temporarily disable failing test (#54970)
this test is failing after #54711

PR Close #54970
2024-03-20 13:31:35 -07:00
Andrew Scott c2149dfaa8 release: cut the v17.3.1 release 2024-03-20 12:49:30 -07:00
Alex Rickabaugh 99e9474aa2 fix(compiler-cli): symbol feature detection for the compiler (#54711)
Use the actual symbol presence in the .d.ts to detect whether two-way
binding to writable signals should be template type-checked.

PR Close #54711
2024-03-20 12:14:42 -07:00
Angular Robot 766bdf3207 build: update dependency google-closure-compiler to v20240317 (#54931)
See associated pull request for more information.

PR Close #54931
2024-03-19 17:00:46 +00:00
Angular Robot 2a1ea5a22b build: update github/codeql-action action to v3.24.8 (#54932)
See associated pull request for more information.

PR Close #54932
2024-03-19 16:59:49 +00:00
Joey Perrott 529a5f434d refactor(docs-infra): don't rely on aio_npm in adev (#54928)
Use @npm// instead of @aio_npm// in adev BUILD files

PR Close #54928
2024-03-19 09:55:45 -07:00
Matthieu Riegler e70228afa9 refactor(core): Add hydration missmatch on the component rather than the node. (#54671)
In some cases the hydration mismatch is nested within a component.

As the devTool only reports issues on the component level, we need to mark the component node rather than the actual mismatched node.

PR Close #54671
2024-03-18 16:52:19 -07:00
Angular Robot 4ab3a9afad docs: update Angular CLI help [17.3.x] (#54911)
Updated Angular CLI help contents.

PR Close #54911
2024-03-18 16:51:28 -07:00
Andrew Kushnir 1f5ab960ef refactor(core): allow passing an environment injector while creating a view (#54903)
This commit updates the name of an internal function argument that represents an embedded view injector. Also it introduces a new config option that allows passing an environment injector to be used in the underlying LView. There are no changes to the behavior, just some initial cleanup for upcoming changes.

PR Close #54903
2024-03-18 16:37:36 -07:00
Joey Perrott 860eccef48 ci: move saucelabs to regular CI job (#54926)
Move the saucelabs job to regular CI instead of the priviledged CI to prevent cache poisoning/overload

PR Close #54926
2024-03-18 11:02:39 -07:00
Joey Perrott e61ccd2ac5 build: update to latest angular/dev-infra/github-actions/create-pr-for-changes (#54904)
Update to latest to correct node verison issue

PR Close #54904
2024-03-17 00:41:31 +00:00
Paul Gschwendtner 80e5a0a03d test(compiler-cli): add unit tests for output() JIT transform (#54841)
We are already testing the JIT transforms via integration tests, but
this commit adds dedicated unit tests for the transform behavior for
proper test coverage (planned follow-up).

PR Close #54841
2024-03-15 15:14:32 -07:00
Kristiyan Kostadinov c0788200e2 fix(compiler): capture data bindings for content projection purposes in blocks (#54876)
Fixes a regression in the template pipeline where data bindings weren't being captured for content projection purposes.

Fixes #54872.

PR Close #54876
2024-03-15 15:11:19 -07:00
Chinthoorie 42318e7c3d refactor(compiler-cli): move DelegatingPerfRecorder initialization into constructor (#54834)
Move the initialization of class field `DelegatingPerfRecorder` into the constructor.

This fixes the error : `TypeError: Cannot read properties of undefined (reading 'eventCount')`

This is blocking the roll-out of public class.

PR Close #54834
2024-03-15 15:10:46 -07:00
Angular Robot 33dc072b70 build: update dependency google-closure-compiler to v20231112 (#54893)
See associated pull request for more information.

PR Close #54893
2024-03-15 18:31:23 +00:00
Angular Robot 209632e64d build: update dependency archiver to v7 (#54892)
See associated pull request for more information.

PR Close #54892
2024-03-15 18:18:35 +00:00
Angular Robot e78dd31cea build: update actions/cache digest to ab5e6d0 (#54886)
See associated pull request for more information.

PR Close #54886
2024-03-15 17:28:14 +00:00
Angular Robot 91029aa082 build: update dependency @octokit/graphql to v8 (#54888)
See associated pull request for more information.

PR Close #54888
2024-03-15 17:24:52 +00:00
Angular Robot 52296bc29d build: update dependency lighthouse to v11 (#54292)
See associated pull request for more information.

PR Close #54292
2024-03-15 17:22:55 +00:00
Angular Robot 64862cbff2 build: update io_bazel_rules_sass digest to 79bd239 (#54887)
See associated pull request for more information.

PR Close #54887
2024-03-15 17:16:23 +00:00
Angular Robot 90bbc68d44 build: update cross-repo angular dependencies (#54883)
See associated pull request for more information.

PR Close #54883
2024-03-15 17:06:44 +00:00
Angular Robot a5cc82ee84 docs: update events (#54749)
Generated `events.json` with the latest events retrieved from the Firebase DB.

PR Close #54749
2024-03-15 16:38:14 +00:00
Angular Robot 855b8e046c build: update dependency puppeteer-core to v22 (#54298)
See associated pull request for more information.

PR Close #54298
2024-03-15 16:31:26 +00:00
Angular Robot 35e8184935 build: update peter-evans/create-or-update-comment action to v4 (#54299)
See associated pull request for more information.

PR Close #54299
2024-03-15 16:30:52 +00:00
Angular Robot 74506e76a8 build: update eslint dependencies (#50993)
See associated pull request for more information.

PR Close #50993
2024-03-15 16:30:11 +00:00
Andrew Scott c22c5c4543 release: cut the v17.3.0 release 2024-03-13 14:05:31 -07:00
JoostK 5d41ab9cd1 refactor(core): restructure logic in isCssClassMatching function (#54800)
The logic in `isCssClassMatching` is only interested in two areas in the attributes:
implicit attributes and the `AttributeMarker.Classes` area, with the first area only
of interest for projection matching, not directive matching. This commit splits these
two searches to make this more apparent.

PR Close #54800
2024-03-12 14:05:19 -07:00
JoostK 243ccce624 fix(core): exclude class attribute intended for projection matching from directive matching (#54800)
This commit resolves a regression that was introduced when the compiler switched from
`TemplateDefinitionBuilder` (TDB) to the template pipeline (TP) compiler. The TP compiler
has changed the output of

```html
if (false) { <div class="test"></div> }
```

from

```ts
defineComponent({
  consts: [['class', 'test'], [AttributeMarker.Classes, 'test']],
  template: function(rf) {
    if (rf & 1) {
      ɵɵtemplate(0, App_Conditional_0_Template, 2, 0, "div", 0)
    }
  }
});
```

to

```ts
defineComponent({
  consts: [[AttributeMarker.Classes, 'test']],
  template: function(rf) {
    if (rf & 1) {
      ɵɵtemplate(0, App_Conditional_0_Template, 2, 0, "div", 0)
    }
  }
});
```

The last argument to the `ɵɵtemplate` instruction (0 in both compilation outputs) corresponds with
the index in `consts` of the element's attribute's, and we observe how TP has allocated only a single
attribute array for the `div`, where there used to be two `consts` entries with TDB. Consequently,
the `ɵɵtemplate` instruction is now effectively referencing a different attributes array, where the
distinction between the `"class"` attribute vs. the `AttributeMarker.Classes` distinction affects
the behavior: TP's emit causes the runtime to incorrectly match a directive with `selector: '.foo'` to
be instantiated on the `ɵɵtemplate` instruction as if it corresponds with a structural directive!

Instead of changing TP to align with TDB's emit, this commit updates the runtime instead. This uncovered
an inconsistency in selector matching for class names, where there used to be two paths dealing with
class matching:

1. The first check was commented to be a special-case for class matching, implemented in `isCssClassMatching`.
2. The second path was part of the main selector matching algorithm, where `findAttrIndexInNode` was being used
   to find the start position in `tNode.attrs` to match the selector's value against.

The second path only considers `AttributeMarker.Classes` values if matching for content projection, OR of the
`TNode` is not an inline template. The special-case in path 1 however does not make that distinction, so it
would consider the `AttributeMarker.Classes` binding as a selector match, incorrectly causing a directive to
match on the `ɵɵtemplate` itself.

The second path was also buggy for class bindings, as the return value of `classIndexOf` was incorrectly
negated: it considered a matching class attribute as non-matching and vice-versa. This bug was not observable
because of another issue, where the class-handling in part 2 was never relevant because of the special-case
in part 1.

This commit separates path 1 entirely from path 2 and removes the buggy class-matching logic in part 2, as
that is entirely handled by path 1 anyway. `isCssClassMatching` is updated to exclude class bindings from
being matched for inline templates.

Fixes #54798

PR Close #54800
2024-03-12 14:05:18 -07:00
Ben Hong e8badecf4f docs: fix missing security guide in navigation (#54830)
The paths for the security guide were flipped in the original PR. As a result, it looked for a markdown file in the best-practices directory when it should have looked for it in the guide directory instead.

PR Close #54830
2024-03-12 13:13:03 -07:00
Gerald Monaco cdfcb779df refactor(core): add internal API to enable i18n hydration (#54784)
Add an internal API to enable and use i18n hydration for testing and development. This helps ensure that we don't accidentally break the current behavior until we are completely ready to roll out i18n support.

PR Close #54784
2024-03-12 11:39:03 -07:00
cexbrayat ac395d0f68 refactor(compiler-cli): cleanup unused code (#54775)
The initializer api no longer needs to take care of `ɵoutput`.

PR Close #54775
2024-03-12 11:31:39 -07:00
Ben Hong e75a9a4d83 docs: improve in-depth guides information architecture (#54365)
PR Close #54365
2024-03-12 10:25:40 -07:00
Joey Perrott 41f28f88b1 fix(docs-infra): remove the prerender directory from adev (#54820)
Remove the prerender directory as it is entirely unused and unneeded

PR Close #54820
2024-03-12 10:24:08 -07:00
Paul Gschwendtner 7df0a8a278 refactor(core): report subscription errors for OutputEmitterRef to ErrorHandler (#54821)
Currently if an `(output)` listener fails, it will be handled gracefully
by Angular and reported to the `ErrorHandler`.

For programmatic subscriptions with `OutputEmitterRef`, this is not the case.
Instead, as soon as any subscription is failing, all other subsequent
subscription callbacks are not firing anymore.

This commit intends to make this more consistent by gracefully
reporting errors from `OutputEmitterRef#emit` to `ErrorHandler`,
allowing for listener execution to continue.

PR Close #54821
2024-03-12 10:21:50 -07:00
cexbrayat 9889346620 docs: typo in output documentation (#54773)
PR Close #54773
2024-03-12 09:15:05 -07:00
Kristiyan Kostadinov 39a50f9a8d fix(core): ensure all initializer functions run in an injection context (#54761)
Ensures that all of the functions intended to be run in initializers are in an injection context. This is a stop-gap until we have a compiler diagnostic for it.

PR Close #54761
2024-03-12 09:08:08 -07:00
Pawel Kozlowski 1f77083a2d refactor(core): assert presence of the track function (#54814)
This commits assert that the repeater instruction gets a reference
to a tracking function. This change will allow us to better track
occurences of https://github.com/angular/angular/issues/53628 -
in certain situations a reference to a tracking function might be
undefiened.

We are not fixing the underlying issue here, just getting better
visibility.

PR Close #54814
2024-03-11 16:33:01 -07:00
Paul Gschwendtner bb35414a38 perf(core): speed up retrieval of DestroyRef in EventEmitter (#54748)
Speeds up the retrieval of `DestroyRef` in `EventEmitter` because
`try/catch` is expensive if there is no injection context.

We saw a script time regression in Cloud.

The goldens had to be updated because `getInjectImplementation` is now
referenced. `inject` also references the underlying field, but directly.
This is super minimal overhead of a function exposing the internal
field.

PR Close #54748
2024-03-11 16:31:03 -07:00
Matthieu Riegler fcfb42a8ba docs: use the right path for first-app images (#54694)
PR Close #54694
2024-03-11 16:30:28 -07:00
Joey Perrott 57e54e29e7 docs: bump to 2024 for copyright text (#54822)
Bump copyright text to 2024

PR Close #54822
2024-03-11 13:39:49 -07:00
Andrew Kushnir 2909e9817d fix(core): prevent infinite loops in clobbered elements check (#54425)
This commit updates HTML sanitization logic to avoid infinite loops in case clobbered elements contain fields like `nextSibling` or `parentNode`. Those fields are used for DOM traversal and this update makes sure that those calls return valid results.

Also this commit fixes an issue when clobbering `nodeName` causes JS exceptions.

PR Close #54425
2024-03-11 12:46:26 -07:00
Gerald Monaco 619f3c8792 refactor(core): add i18nNodes in preparation for i18n hydration (#54750)
An i18n message effectively acts as a dynamic template: two elements with contiguous instruction indices won't necessarily be contiguous in the DOM.

For that reason, we need to maintain a mapping from instruction index to a physical DOM node in order to hydrate views with i18n, pointing to where hydration for that view should begin.

PR Close #54750
2024-03-11 11:12:46 -07:00
Andrew Scott 0ee1a1419d refactor(core): Remove isG3 usages in patch branch (#54816)
This commit removes uses of isG3 in the patch branch. G3 always executes
against main so any references in patch are unused.

PR Close #54816
2024-03-11 11:11:32 -07:00
Kristiyan Kostadinov f386a04c9d fix(compiler): handle two-way bindings to signal-based template variables in instruction generation (#54714)
Updates the instruction generation for two-way bindings to only emit the `twoWayBindingSet` call when writing to template variables. Since template variables are constants, it's only allowed to write to them when they're signals. Non-signal values are flagged during template type checking.

Fixes #54670.

PR Close #54714
2024-03-11 11:01:43 -07:00
Kristiyan Kostadinov 492e03f699 fix(compiler-cli): flag two-way bindings to non-signal values in templates (#54714)
We have a diagnostic that reports writes to template variables which worked both for regular event bindings and two-way bindings, however the latter was broken by #54154 because two-way bindings no longer had a `PropertyWrite` AST.

These changes fix the diagnostic and expand it to allow two-way bindings to template variables that are signals.

PR Close #54714
2024-03-11 11:01:43 -07:00
Kristiyan Kostadinov ba9ddd7ac2 refactor(compiler-cli): move illegal template assignment check into template semantics checker (#54714)
Moves the check which ensures that there are no writes to template variables into the `TemplateSemanticsChecker` to prepare for the upcoming changes.

PR Close #54714
2024-03-11 11:01:43 -07:00
Kristiyan Kostadinov 5d23e601d1 refactor(compiler-cli): move signal identification function (#54714)
Moves the function that identifies signals into a separate file so that it can be reused outside of extended diagnostics.

PR Close #54714
2024-03-11 11:01:43 -07:00
Kristiyan Kostadinov a7872ca77a refactor(compiler-cli): introduce template semantics checker (#54714)
Introduces a new `TemplateSemanticsChecker` that will be used to flag semantic errors in the user's template. Currently we do some of this in the type check block, but the problem is that it doesn't have access to the template type checker which prevents us from properly checking cases like #54670. This pass is also distinct from the extended template checks, because we don't want users to be able to turn the checks off and we want them to run even if `strictTemplates` are disabled.

PR Close #54714
2024-03-11 11:01:43 -07:00
Matthieu Riegler 10314787d6 docs: adding signal inputs and model to ADEV. (#54753)
Those docs are a copy from AIO.

PR Close #54753
2024-03-11 11:01:01 -07:00
theRealc0d3c 40a94b3ab6 docs: fix typo in tutorial (#54817)
PR Close #54817
2024-03-11 10:59:53 -07:00
Kristiyan Kostadinov 1f129f114e fix(compiler): not catching for loop empty tracking expressions (#54772)
Fixes that the template parser wasn't catching empty expressions in the `track` parameter of for loops.

Fixes #54763.

PR Close #54772
2024-03-11 09:17:43 -07:00
Kristiyan Kostadinov 962934bc4f build: update to TypeScript 5.4 stable (#54743)
Updates the repo to the stable version of TypeScript 5.4.

PR Close #54743
2024-03-11 09:16:55 -07:00
JoostK 6ce8fc8637 refactor(core): avoid additional closure for queued microtask callback (#54801)
The `runCallbackOnce` closure is declared not to have any parameters itself, so it is
compatible as `queueMicrotask` callback without the extra closure. This reduces the call
stack by a frame and avoids the extra closure allocation.

PR Close #54801
2024-03-11 08:59:55 -07:00
JoostK e82173e8c4 refactor(core): properly type withBody and withHead testing helpers (#54801)
This commit addresses a typing mismatch, where these functions were declared to return whichever
value their callback returned, but this was inaccurate: it's always a test callback function
with `done` argument.

PR Close #54801
2024-03-11 08:59:55 -07:00
JoostK b6a7d509fe test(core): ensure async tests are awaited properly (#54801)
The assertion in `packages/core/test/acceptance/after_render_hook_spec.ts:165` was prone to flakes,
where Jasmine could frequently report an error:

```
Error: 'expect' was used when there was no current spec, this could be because an asynchronous test timed out
    at Env.expect (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1945:15)
    at expect (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8267:18)
    at file:///packages/core/test/acceptance/after_render_hook_spec.ts:165:12
```

This happens because `wrapTestFn` checks for an exact type of `Promise`, which may have been patched by zone.js
such that the `instanceof` condition is dependent on whether zone.js has patched the `Promise` constructor.

PR Close #54801
2024-03-11 08:59:55 -07:00
Kristiyan Kostadinov 01722ee637 build: fix size failure (#54756)
Fixes a broken size CI check.

PR Close #54756
2024-03-07 16:13:44 -08:00
Andrew Scott 7225485311 fix(router): Navigations triggered by cancellation events should cancel previous navigation (#54710)
There is an edge case where synchronous navigations caused in
response to navigation events can result in a previous navigation not
being unsubscribed from. b/328219996

PR Close #54710
2024-03-07 13:07:10 -08:00
Andrew Scott a45e69f627 refactor(core): render hooks should always run on node attach or detach (#54083)
This commit ensures that render hooks are rerun when a node is attached
or detached. We do not necessarily need to run change detection but DOM
did change so render hooks should execute.

PR Close #54083
2024-03-07 12:59:11 -08:00
Andrew Scott a7d6c64a47 refactor(core): Skip refresh views if render hooks are the only notification source (#54083)
Do not refresh views if the only thing that notified the scheduler was
registration of a new render hook.

PR Close #54083
2024-03-07 12:59:10 -08:00
Andrew Scott 2f7c7b3833 refactor(core): registering afterRender hooks notify scheduler (#54083)
This commit updates the `afterRender` and `afterNextRender` hooks to
notify the scheduler (which subsequently schedules change detection)
when created. This makes the hooks similar to `requestAnimationFrame`,
which requests that the browser schedule a rendering operation. This
reqeust is not conditional. Even if there was nothing to repaint, the
`requestAnimationFrame` callback will execute.

In Angular, this is useful because callers of `afterNextRender` don't
necessarily have any way of knowing whether a change detection is even
scheduled. For example, the anchor scrolling with the Angular Router
needs to wait for rendering to complete before attempting to scroll
because rendering can affect the size of the page. However, if the user
is already on the page that the navigation is targeting, such as
navigating to an anchor on the page, there is nothing new for the Router
to render so a render might not even be scheduled.

Related to https://github.com/angular/angular/issues/53985, which
could use `afterNextRender` instead of `setTimeout` to ensure the
scrolling happens in the same frame as the page rendering, but would not
necessarily work without this change (as described above). Note that the
scrolling _cannot_ use a microtask to ensure scrolling happens in the
same frame because `NgZone` will ensure microtasks flush before
change detection, so it would cause the scroll to happen before rendering.

PR Close #54083
2024-03-07 12:59:10 -08:00
Gerald Monaco 0daa1ea19d refactor(core): refactor i18n node creation to prepare for hydration (#54722)
Adds a `locateOrCreateNode` helper and uses it for all DOM operations in preparation for supporting hydration.

PR Close #54722
2024-03-07 12:41:46 -08:00
Leonardo Ortiz 658ae699d8 docs: update content readme link (#53763)
PR Close #53763
2024-03-07 11:07:09 -08:00
Leonardo Ortiz 9cf6b9369e docs: readme from blossom (#53763)
PR Close #53763
2024-03-07 11:07:09 -08:00
Angular Robot 9ea0d69275 docs: update events (#54721)
Generated `events.json` with the latest events retrieved from the Firebase DB.

PR Close #54721
2024-03-07 11:05:39 -08:00
Gerald Monaco f1991d49b0 refactor(core): don't hydrate detached nodes (#54723)
In preparation for hydration support, make sure that we don't attempt to hydrate detached nodes and instead, always newly create them.

PR Close #54723
2024-03-07 11:01:31 -08:00
Gerald Monaco 198f2ff5f2 refactor(core): add i18n AST to prepare for hydration (#54724)
In order to serialize and hydrate i18n blocks, we need to be able to walk an AST for the translated message. This AST is generated during normal parsing of the message.

PR Close #54724
2024-03-07 11:00:38 -08:00
Alan Agius 8d37ed035c fix(http): exclude caching for authenticated HTTP requests (#54746)
This update modifies the transfer cache logic to prevent caching of HTTP requests that require authorization.

Closes: #54745

PR Close #54746
2024-03-07 11:00:03 -08:00
Andrew Scott 365955322f refactor(core): Remove isInternal flag (#54740)
This is not needed any longer since the changes that used it have
landed.

PR Close #54740
2024-03-07 09:07:01 -08:00
Andrew Scott d870856840 refactor(core): Fix internal test util types (#54736)
This fixes and error that has been seen recently where compilation fails
due to domino.impl type not being recognized

PR Close #54736
2024-03-06 13:34:55 -08:00
Pawel Kozlowski 7bfa3610c5 release: cut the v17.3.0-rc.0 release 2024-03-06 20:40:30 +01:00
618 changed files with 35817 additions and 21184 deletions
+7
View File
@@ -65,6 +65,13 @@ build:aio_local_deps --workspace_status_command="yarn -s --cwd aio local-workspa
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
build:snapshot-build --stamp
# Angular DevTools for Firefox releases *cannot* be stamped and `--config snapshot-build-firefox` is a no-op.
# This is because Mozilla requires add-on source code to be uploaded and then they manually reproduce the build.
# If we stamp the build based on Git information such as the current commit, then reproducing the build would require
# uploading the entire `.git` directory. We already must upload the entire monorepo, and uploading `.git` as well
# exceeds the max source file size. To address this, we just *don't* stamp Firefox builds of Angular DevTools.
build:snapshot-build-firefox --nostamp
##########################################################
# AIO architect build configuration #
# See aio/angular.json for available configurations. #
+1 -1
View File
@@ -4,7 +4,7 @@ description: 'Installs the dependencies using Yarn'
runs:
using: 'composite'
steps:
- uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4
with:
path: |
./node_modules/
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
with:
token: '${{secrets.GITHUB_TOKEN}}'
+42
View File
@@ -0,0 +1,42 @@
# This workflow builds the AIO previews for pull requests when a certain label is applied.
# The actual deployment happens as part of a dedicated second workflow to avoid security
# issues where the building would otherwise occur in an authorized context where secrets
# could be leaked. More details can be found here:
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
name: Build AIO app for preview deployment
on:
pull_request:
types: [synchronize, labeled]
permissions: read-all
jobs:
aio-build:
runs-on: ubuntu-latest
# We only want to build and deploy the AIO app if the `aio: preview` label has been
# added, or if the label is already applied and new changes have been made in the PR.
if: |
(github.event.action == 'labeled' && github.event.label.name == 'aio: preview') ||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'aio: preview'))
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: ./.github/actions/yarn-install
- uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
with:
bazelrc: ./.bazelrc.user
# Build the web package. Note: We run Bazel from a low-resource Github action container,
# so we manually need to instruct Bazel to run more actions concurrently as by default
# the number of concurrent actions is determined based on the host resources.
- run: bazel build //aio:build --jobs=32 --announce_rc --verbose_failures
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@c83e99a12397014162531ca125c94549db55dd84
with:
workflow-artifact-name: 'aio'
pull-number: '${{github.event.pull_request.number}}'
artifact-build-revision: '${{github.event.pull_request.head.sha}}'
deploy-directory: './dist/bin/aio/build'
+44
View File
@@ -0,0 +1,44 @@
# This workflow runs whenever the AIO build workflow has completed. Deployment happens
# as part of a dedicated second workflow to avoid security issues where the building would
# otherwise occur in an authorized context where secrets could be leaked.
#
# More details can be found here:
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
name: Deploying AIO preview to Firebase
on:
workflow_run:
workflows: ['Build AIO app for preview deployment']
types: [completed]
permissions:
# Needed in order to be able to comment on the pull request.
pull-requests: write
env:
PREVIEW_PROJECT: ng-dev-previews
PREVIEW_SITE: ng-dev-previews-fw
jobs:
aio-deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- name: Configure Firebase deploy target
working-directory: aio/
run: |
# We can use `npx` as the Firebase deploy actions uses it too.
npx -y firebase-tools@latest target:clear --project ${{env.PREVIEW_PROJECT}} hosting aio
npx -y firebase-tools@latest target:apply --project ${{env.PREVIEW_PROJECT}} hosting aio ${{env.PREVIEW_SITE}}
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@c83e99a12397014162531ca125c94549db55dd84
with:
github-token: '${{secrets.GITHUB_TOKEN}}'
workflow-artifact-name: 'aio'
firebase-config-dir: './aio/'
firebase-public-dir: './aio/dist'
firebase-project-id: '${{env.PREVIEW_PROJECT}}'
firebase-service-key: '${{secrets.FIREBASE_PREVIEW_SERVICE_TOKEN}}'
@@ -16,6 +16,6 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
persist-credentials: false
- uses: angular/dev-infra/github-actions/branch-manager@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/branch-manager@4b433074a806bbbd4d319264430740cd46e62f27
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+112 -24
View File
@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
with:
cache-node-modules: true
node-module-directories: |
@@ -35,6 +35,8 @@ jobs:
run: yarn install --frozen-lockfile --cwd aio
- name: Check code lint
run: yarn -s tslint
- name: Check code lint in aio
run: yarn -s --cwd aio lint
- name: Check for circular dependencies
run: yarn -s ts-circular-deps:check
- name: Validate pull approve configuration
@@ -58,13 +60,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@4b433074a806bbbd4d319264430740cd46e62f27
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
@@ -76,46 +78,132 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@4b433074a806bbbd4d319264430740cd46e62f27
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
run: yarn test:ci
aio:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules for aio
run: yarn install --cwd aio --frozen-lockfile
- name: Run AIO tests with upstream packages
run: yarn --cwd aio test:ci
- name: Check generated bundle sizes
run: yarn --cwd aio payload-size
adev:
runs-on:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@4b433074a806bbbd4d319264430740cd46e62f27
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel test --config=aio_local_deps //adev:test
aio-local:
runs-on:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules
run: yarn install --cwd aio --frozen-lockfile
- name: Run AIO tests with local packages
run: yarn --cwd aio test-local:ci
- name: Check generated bundle sizes
run: yarn --cwd aio payload-size aio-local
aio-deploy:
needs: [aio]
if: needs.aio.result == 'success' && github.event_name == 'push'
runs-on:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules for aio
run: yarn install --cwd aio --frozen-lockfile
- name: Set the stable branch environment variable
id: latest_version
run: |
echo "CI_STABLE_BRANCH=$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')" >> $GITHUB_OUTPUT
echo "CI_BRANCH=$(echo ${{ github.event.ref }} | cut -d '/' -f 3)" >> $GITHUB_OUTPUT
- name: Deploy aio to production
env:
CI_AIO_MIN_PWA_SCORE: '95'
CI_COMMIT: ${{ github.event.after }}
CI_REPO_NAME: 'angular'
CI_PULL_REQUEST: 'false'
CI_REPO_OWNER: 'angular'
CI_BUILD_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
CI_STABLE_BRANCH: ${{ steps.latest_version.outputs.CI_STABLE_BRANCH }}
CI_BRANCH: ${{ steps.latest_version.outputs.CI_BRANCH }}
CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN: ${{ secrets.AIO_DEPLOY_TOKEN }}
CI_SECRET_PAYLOAD_FIREBASE_TOKEN: ${{ secrets.AIO_PAYLOAD_TOKEN }}
run: yarn --cwd aio deploy-production
- name: Notify about failed deployment
if: ${{ failure() }}
uses: slackapi/slack-github-action@2a8087d4af6f83146a87539a70defe909fe6dbe6 # v=v1.24.0
with:
channel-id: 'C07DT5M6V,CKV1F72BG'
slack-message: 'Deploy to aio job failed for ${{ github.base_ref }} branch failed on build ${{ github.event.after }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
env:
SLACK_BOT_TOKEN: ${{ secrets.ANGULAR_ROBOT_SLACK_TOKEN }}
publish-snapshots:
if: github.event_name == 'push'
runs-on:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@4b433074a806bbbd4d319264430740cd46e62f27
- name: Install node modules
run: yarn install --frozen-lockfile
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
@@ -127,7 +215,7 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
with:
cache-node-modules: true
node-module-directories: |
@@ -135,9 +223,9 @@ jobs:
./packages/zone.js/node_modules
./packages/zone.js/test/typings/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@4b433074a806bbbd4d319264430740cd46e62f27
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
@@ -176,7 +264,7 @@ jobs:
JOBS: 2
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
with:
cache-node-modules: true
# Checking out the pull request commit is intended here as we need to run the changed code tests.
@@ -184,9 +272,9 @@ jobs:
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@50bb71e51d3372ca2e359adb9069f89beeac4ae7
- name: Set up Sauce Tunnel Daemon
@@ -204,13 +292,13 @@ jobs:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
with:
cache-node-modules: true
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@50bb71e51d3372ca2e359adb9069f89beeac4ae7
- name: Starting Saucelabs tunnel service
@@ -253,11 +341,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@4b433074a806bbbd4d319264430740cd46e62f27
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@4b433074a806bbbd4d319264430740cd46e62f27
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
+2 -2
View File
@@ -13,13 +13,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/commit-message-based-labels@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/commit-message-based-labels@4b433074a806bbbd4d319264430740cd46e62f27
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
post_approval_changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/post-approval-changes@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/post-approval-changes@4b433074a806bbbd4d319264430740cd46e62f27
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/google-internal-tests@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/google-internal-tests@4b433074a806bbbd4d319264430740cd46e62f27
with:
run-tests-guide-url: http://go/angular-g3sync-start
github-token: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
status:
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/unified-status-check@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/unified-status-check@4b433074a806bbbd4d319264430740cd46e62f27
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+4 -4
View File
@@ -25,12 +25,12 @@ jobs:
steps:
- name: 'Checkout code'
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
persist-credentials: false
- name: 'Run analysis'
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
with:
results_file: results.sarif
results_format: sarif
@@ -39,7 +39,7 @@ jobs:
# Upload the results as artifacts.
- name: 'Upload artifact'
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: SARIF file
path: results.sarif
@@ -47,6 +47,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: 'Upload to code-scanning'
uses: github/codeql-action/upload-sarif@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
uses: github/codeql-action/upload-sarif@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5
with:
sarif_file: results.sarif
+48
View File
@@ -0,0 +1,48 @@
# Update the `events.json` file that powers the [AIO events page](https://angular.io/events) (if
# necessary) and create a pull request.
#
# For more details on the overall process, see
# [aio/scripts/generate-events/README.md](../../aio/scripts/generate-events/README.md).
name: Update AIO events
on:
workflow_dispatch:
inputs: {}
schedule:
# Run every day at 15:00.
- cron: '0 15 * * *'
# Declare default permissions as read only.
permissions:
contents: read
jobs:
update_events:
name: Update `events.json` (if necessary)
if: github.repository == 'angular/angular'
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
# Setting `persist-credentials: false` prevents the github-action account from being the
# account that is attempted to be used for authentication, instead the remote is set to
# an authenticated URL.
persist-credentials: false
# This is needed as otherwise the PR creation will fail with `shallow update not allowed` when the forked branch is not in sync.
fetch-depth: 0
- name: Generate `events.json`
run: node aio/scripts/generate-events/index.mjs --ignore-invalid-dates
- name: Create a PR (if necessary)
uses: angular/dev-infra/github-actions/create-pr-for-changes@c83e99a12397014162531ca125c94549db55dd84
with:
branch-prefix: docs-update-events
pr-title: 'docs: update events'
pr-description: |
Generated `events.json` with the latest events retrieved from the Firebase DB.
pr-labels: |
action: review
area: docs
target: patch
angular-robot-token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}
+1 -1
View File
@@ -1 +1 @@
18.18.2
18.19.1
+84 -23
View File
@@ -140,7 +140,7 @@ groups:
- alxhub
- crisbeto
- ~jelbourn
- jessicajaniuk
- thePunderWoman
# =========================================================
# Framework: Compiler
@@ -183,7 +183,7 @@ groups:
- crisbeto
- devversion
- dylhunn
- jessicajaniuk
- thePunderWoman
- AndrewKushnir
# =========================================================
@@ -193,7 +193,7 @@ groups:
<<: *defaults
conditions:
- >
contains_any_globs(files.exclude("packages/core/schematics/*"), [
contains_any_globs(files.exclude("packages/core/schematics/*").exclude('packages/core/primitives/*'), [
'packages/core/**/{*,.*}',
'packages/examples/core/**/{*,.*}',
'packages/platform-browser/**/{*,.*}',
@@ -358,7 +358,7 @@ groups:
- crisbeto
- devversion
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -378,7 +378,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -415,7 +415,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -438,7 +438,7 @@ groups:
- andrewseguin
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -536,7 +536,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -615,7 +615,7 @@ groups:
reviewers:
users:
- alxhub
- jessicajaniuk
- thePunderWoman
# =========================================================
# Framework: Testing
@@ -644,7 +644,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -663,7 +663,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -682,7 +682,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -778,7 +778,7 @@ groups:
- atscott
- crisbeto
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -813,7 +813,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- josephperrott
- pkozlowski-opensource
@@ -867,7 +867,7 @@ groups:
reviewers:
users:
- AndrewKushnir
- jessicajaniuk
- thePunderWoman
# =========================================================
# Docs: Marketing
@@ -946,7 +946,7 @@ groups:
- alxhub
- AndrewKushnir
- atscott
- jessicajaniuk
- thePunderWoman
- jelbourn
# =========================================================
@@ -1078,11 +1078,12 @@ groups:
- josephperrott
- jelbourn
- bencodezen
- jessicajaniuk
- thePunderWoman
- dylhunn
- AndrewKushnir
- alxhub
- crisbeto
- devversion
- atscott
- pkozlowski-opensource
- ~JeanMeche
@@ -1143,7 +1144,7 @@ groups:
reviewers:
users:
- AndrewKushnir
- jessicajaniuk
- thePunderWoman
- josephperrott
# =========================================================
@@ -1200,7 +1201,7 @@ groups:
'tools/gulp-tasks/**/{*,.*}',
'tools/legacy-saucelabs/**/{*,.*}',
'tools/manual_api_docs/**/{*,.*}',
'tools/npm-patches/**/{*,.*}',
'tools/npm-patches*/**/{*,.*}',
'tools/rxjs/**/{*,.*}',
'tools/saucelabs-daemon/**/{*,.*}',
'tools/saucelabs/**/{*,.*}',
@@ -1242,7 +1243,7 @@ groups:
- atscott
- dylhunn
- ~jelbourn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
reviews:
request: 3 # Request reviews from 3 people
@@ -1268,7 +1269,7 @@ groups:
- atscott
- dylhunn
- ~jelbourn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
reviews:
request: 2 # Request reviews from 2 people
@@ -1294,7 +1295,7 @@ groups:
- atscott
- dylhunn
- ~jelbourn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
####################################################################################
@@ -1318,9 +1319,69 @@ groups:
- andrewseguin
- dgp1130
- ~jelbourn
- jessicajaniuk
- thePunderWoman
- josephperrott
# =========================================================
# Primitives
# =========================================================
# Angular team required reviews
primitives:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'packages/core/primitives/**/{*,.*}',
])
reviewers:
users:
- pkozlowski-opensource # Pawel Kozlowski
- alxhub # Alex Rickabaugh
- thePunderWoman # Jessica Janiuk
- dylhunn # Dylan Hunn
- AndrewKushnir # Andrew Kushnir
- atscott # Andrew Scott
reviews:
required: 1
reviewed_for: required
labels:
pending: 'requires: TGP'
approved: 'requires: TGP'
rejected: 'requires: TGP'
# External team required reviews
primitives-shared:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'packages/core/primitives/**/{*,.*}',
])
reviewers:
users:
- csmick # Cameron Smick
- lannka # Hongfei Ding
- eduhmc # Eduardo Huerta-Mercado
- ehlemur # Edward Lesmes
- ellenyuan # Ellen Yuan
- jatraman # Jatin Ramanathan
- jesse-good # Jesse Costello-Good
- mturco # Matt Turco
- neonstalwart # Ben Hockey
- nicholasyu-google # Nicholas Yu
- emspishak # Eric Spishak-Thomas
- iteriani # Thomas Nguyen
- tbondwilkinson # Tom Wilkinson
- rahatarmanahmed # Rahat Ahmed
reviews:
required: 1
reviewed_for: required
labels:
pending: 'requires: TGP'
approved: 'requires: TGP'
rejected: 'requires: TGP'
####################################################################################
# Override managed result groups
#
+5
View File
@@ -5,7 +5,12 @@
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"BazelBuild.vscode-bazel",
"gkalpak.aio-docs-utils",
"ms-vscode.vscode-typescript-tslint-plugin",
"xaver.clang-format",
// The following extensions are useful when working on angular.io (i.e. inside the `aio/` directory).
//"angular.ng-template",
//"dbaeumer.vscode-eslint",
//"errata-ai.vale-server",
],
}
+108 -104
View File
@@ -1,49 +1,126 @@
<a name="18.0.0-next.1"></a>
# 18.0.0-next.1 (2024-03-20)
## Breaking Changes
### platform-browser-dynamic
- No longer used `RESOURCE_CACHE_PROVIDER` APIs have been removed.
### platform-server
- deprecated `platformDynamicServer` has been removed. Add an `import @angular/compiler` and replace the usage with `platformServer`
- deprecated `ServerTransferStateModule` has been removed. `TransferState` can be use without providing this module.
- deprecated `useAbsoluteUrl` and `baseUrl` been removed from `PlatformConfig`. Provide and absolute `url` instead.
- Legacy handling or Node.js URL parsing has been removed from `ServerPlatformLocation`.
The main differences are;
- `pathname` is always suffixed with a `/`.
- `port` is empty when `http:` protocol and port in url is `80`
- `port` is empty when `https:` protocol and port in url is `443`
### router
- This change allows `Route.redirectTo` to be a function
in addition to the previous string. Code which expects `redirectTo` to
only be a string on `Route` objects will need to be adjusted.
<a name="17.3.12"></a>
# 17.3.12 (2024-07-17)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [879bd80b57](https://github.com/angular/angular/commit/879bd80b571368bdc6e65c5415d98ad0f546267a) | fix | capture data bindings for content projection purposes in blocks ([#54876](https://github.com/angular/angular/pull/54876)) |
### compiler-cli
| [327bae473b](https://github.com/angular/angular/commit/327bae473b4ed430efefb4663312a01f59304081) | fix | JIT mode incorrectly interpreting host directive configuration in partial compilation ([#57002](https://github.com/angular/angular/pull/57002)) ([#57003](https://github.com/angular/angular/pull/57003)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.11"></a>
# 17.3.11 (2024-06-05)
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.10"></a>
# 17.3.10 (2024-05-22)
This release includes some internal updates for Angular's documentation infrastructure.
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.9"></a>
# 17.3.9 (2024-05-15)
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.8"></a>
# 17.3.8 (2024-05-08)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [6aff144232](https://github.com/angular/angular/commit/6aff14423238f8995da8104e60c0baca26df2020) | fix | symbol feature detection for the compiler ([#54711](https://github.com/angular/angular/pull/54711)) |
| [c21b459ba6](https://github.com/angular/angular/commit/c21b459ba6520fd5835e23800338ac9c997fee91) | fix | add math elements to schema ([#55631](https://github.com/angular/angular/pull/55631)) ([#55645](https://github.com/angular/angular/pull/55645)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [314112de99](https://github.com/angular/angular/commit/314112de99bb97475a0d8bdbddf84a3b3ce4a8fb) | fix | Prevent `markForCheck` during change detection from causing infinite loops ([#54900](https://github.com/angular/angular/pull/54900)) |
### platform-browser-dynamic
| [3818436ebc](https://github.com/angular/angular/commit/3818436ebc649267bb39b976b6b567b7f2b06a64) | fix | don't schedule timer triggers on the server ([#55605](https://github.com/angular/angular/pull/55605)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.7"></a>
# 17.3.7 (2024-05-01)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [eb20c1a8b1](https://github.com/angular/angular/commit/eb20c1a8b18e2e080c856e3e1bf7bcd02f3bfd28) | refactor | unused `RESOURCE_CACHE_PROVIDER` API has been removed ([#54875](https://github.com/angular/angular/pull/54875)) |
### platform-server
| [51ac883167](https://github.com/angular/angular/commit/51ac8831670637b562dfa135bec1e27a0b49f21d) | fix | don't type check the bodies of control flow nodes in basic mode ([#55558](https://github.com/angular/angular/pull/55558)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [07ac017731](https://github.com/angular/angular/commit/07ac017731f0e08ea3736f1f212093a28648a304) | refactor | remove deprecated `platformDynamicServer` API ([#54874](https://github.com/angular/angular/pull/54874)) |
| [e8b588d8b7](https://github.com/angular/angular/commit/e8b588d8b7fc014aaef99d4b0c1e4567b4aa195d) | refactor | remove deprecated `ServerTransferStateModule` API ([#54874](https://github.com/angular/angular/pull/54874)) |
| [3b1967ca64](https://github.com/angular/angular/commit/3b1967ca64479df9137b3ad7a0d04dbaff6496f4) | refactor | remove deprecated `useAbsoluteUrl` and `baseUrl` from `PlatformConfig` ([#54874](https://github.com/angular/angular/pull/54874)) |
| [2357d3566c](https://github.com/angular/angular/commit/2357d3566c4d18dc40cbda6644ed459ef7703893) | refactor | remove legacy URL handling logic ([#54874](https://github.com/angular/angular/pull/54874)) |
| [af0eb846a5](https://github.com/angular/angular/commit/af0eb846a572d0e9de2c6bb7016ddd339473dc00) | fix | render hooks should not specifically run outside the Angular zone ([#55399](https://github.com/angular/angular/pull/55399)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [2b802587f2](https://github.com/angular/angular/commit/2b802587f27186baa493c1dd01f42d568b652f38) | feat | Allow Route.redirectTo to be a function which returns a string or UrlTree ([#52606](https://github.com/angular/angular/pull/52606)) |
| [3eea50da64](https://github.com/angular/angular/commit/3eea50da644f6023e7f001b8738c54cb89aece4c) | fix | Scroller should scroll as soon as change detection completes ([#55105](https://github.com/angular/angular/pull/55105)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.6"></a>
# 17.3.6 (2024-04-25)
### core
| Commit | Type | Description |
| -- | -- | -- |
| [826861b1fa](https://github.com/angular/angular/commit/826861b1fa7693010743f5dd881fb31ec33eee52) | fix | DeferBlockFixture.render should not wait for stability ([#55271](https://github.com/angular/angular/pull/55271)) |
| [5cf14da35c](https://github.com/angular/angular/commit/5cf14da35cce1ea4456bae4365d3dbe6667b1881) | fix | make `ActivatedRoute` inject correct instance inside `@defer` blocks ([#55374](https://github.com/angular/angular/pull/55374)) |
| [8979fba2c5](https://github.com/angular/angular/commit/8979fba2c5813673767a133caeec9ac768d17329) | fix | skip defer timers on the server ([#55480](https://github.com/angular/angular/pull/55480)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.5"></a>
# 17.3.5 (2024-04-17)
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.4"></a>
# 17.3.4 (2024-04-10)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [53427d875d](https://github.com/angular/angular/commit/53427d875d33de16b1dbb04e76a9fe32a2b8a445) | fix | invalid ImageKit quality parameter ([#55193](https://github.com/angular/angular/pull/55193)) |
| [766548c3ec](https://github.com/angular/angular/commit/766548c3ecc06ffd8f06ed9a7d0cbb3db6f1b0f6) | fix | skip transfer cache on client ([#55012](https://github.com/angular/angular/pull/55012)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.3"></a>
# 17.3.3 (2024-04-03)
### core
| Commit | Type | Description |
| -- | -- | -- |
| [158ceaf062](https://github.com/angular/angular/commit/158ceaf062036bde2a828ee769580f99433a31a8) | fix | handle `ChainedInjector`s in injector debug utils ([#55144](https://github.com/angular/angular/pull/55144)) |
| [4d043992e5](https://github.com/angular/angular/commit/4d043992e5635a2f841b633fb38d0009a39f05d0) | fix | test cleanup should not throw if Zone is not present ([#55096](https://github.com/angular/angular/pull/55096)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [949dec26b8](https://github.com/angular/angular/commit/949dec26b860a500e90874ad778da74549d21d7e) | fix | avoid conflicts with some greek letters in control flow migration ([#55113](https://github.com/angular/angular/pull/55113)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.2"></a>
# 17.3.2 (2024-03-28)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [2b7bad5151](https://github.com/angular/angular/commit/2b7bad515100cbfa40b3e8d844bae13d43fd5602) | fix | invoke method-based tracking function with context ([#54960](https://github.com/angular/angular/pull/54960)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [b478dfbfda](https://github.com/angular/angular/commit/b478dfbfda3f32fbe723a1e8725e86490422520d) | fix | report errors when initializer APIs are used on private fields ([#55070](https://github.com/angular/angular/pull/55070)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [708ba8115f](https://github.com/angular/angular/commit/708ba8115f7ad05201db5c529aefe4dd48fc64c5) | fix | establish proper injector resolution order for `@defer` blocks ([#55079](https://github.com/angular/angular/pull/55079)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [cb433af0e1](https://github.com/angular/angular/commit/cb433af0e1ba61073eb4a02ccd75cf360e9fd409) | fix | include transferCache when cloning HttpRequest ([#54939](https://github.com/angular/angular/pull/54939)) |
| [64f202cab9](https://github.com/angular/angular/commit/64f202cab9e7a5c873b17bbddd02368006426152) | fix | manage different body types for caching POST requests ([#54980](https://github.com/angular/angular/pull/54980)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [2f9d94bc4a](https://github.com/angular/angular/commit/2f9d94bc4ab5a94e620a13404aba4e094f8b2344) | fix | account for variables in imports initializer ([#55081](https://github.com/angular/angular/pull/55081)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [365fd50407](https://github.com/angular/angular/commit/365fd504077d0e7509efc3077ea4ae8bbafb01f7) | fix | RouterLinkActive will always remove active classes when links are not active ([#54982](https://github.com/angular/angular/pull/54982)) |
<!-- CHANGELOG SPLIT MARKER -->
@@ -60,79 +137,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.0"></a>
# 18.0.0-next.0 (2024-03-14)
## Breaking Changes
### core
- `OnPush` views at the root of the application need to
be marked dirty for their host bindings to refresh. Previously, the host
bindings were refreshed for all root views without respecting the
`OnPush` change detection strategy.
- The `ComponentFixture` `autoDetect` feature will no
longer refresh the component's host view when the component is `OnPush`
and not marked dirty. This exposes existing issues in components which
claim to be `OnPush` but do not correctly call `markForCheck` when they
need to be refreshed. If this change causes test failures, the easiest
fix is to change the component to `ChangeDetectionStrategy.Default`.
- When Angular runs change detection, it will continue to
refresh any views attached to `ApplicationRef` that are still marked for
check after one round completes. In rare cases, this can result in infinite
loops when certain patterns continue to mark views for check using
`ChangeDetectorRef.detectChanges`. This will be surfaced as a runtime
error with the `NG0103` code.
- The `ComponentFixture.autoDetect` feature now executes
change detection for the fixture within `ApplicationRef.tick`. This more
closely matches the behavior of how a component would refresh in
production. The order of component refresh in tests may be slightly
affected as a result, especially when dealing with additional components
attached to the application, such as dialogs. Tests sensitive to this
type of change (such as screenshot tests) may need to be updated.
Concretely, this change means that the component will refresh _before_
additional views attached to `ApplicationRef` (i.e. dialog components).
Prior to this change, the fixture component would refresh _after_ other
views attached to the application.
- The exact timing of change detection execution when
using event or run coalescing with `NgZone` is now the first of either
`setTimeout` or `requestAnimationFrame`. Code which relies on this
timing (usually by accident) will need to be adjusted. If a callback
needs to execute after change detection, we recommend `afterNextRender`
instead of something like `setTimeout`.
- Newly created and views marked for check and reattached
during change detection are now guaranteed to be refreshed in that same
change detection cycle. Previously, if they were attached at a location
in the view tree that was already checked, they would either throw
`ExpressionChangedAfterItHasBeenCheckedError` or not be refreshed until
some future round of change detection. In rare circumstances, this
correction can cause issues. We identified one instance that relied on
the previous behavior by reading a value on initialization which was
queued to be updated in a microtask instead of being available in the
current change detection round. The component only read this value during
initialization and did not read it again after the microtask updated it.
### router
- Guards can now return `RedirectCommand` for redirects
in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree`
values in `Route` types will need to be adjusted.
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [9b424d7224](https://github.com/angular/angular/commit/9b424d7224db46edb16c81979c7e231d5e3db5e9) | fix | preserve original reference to non-deferrable dependency ([#54759](https://github.com/angular/angular/pull/54759)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [64f870c12b](https://github.com/angular/angular/commit/64f870c12bae1ad66509f0d65f8d3e051aae6eaa) | fix | `ApplicationRef.tick` should respect OnPush for host bindings ([#53718](https://github.com/angular/angular/pull/53718)) ([#53718](https://github.com/angular/angular/pull/53718)) |
| [8cad4e8cbe](https://github.com/angular/angular/commit/8cad4e8cbe2baf20dae7b7ef1f4253a4940cbba0) | fix | `ComponentFixture` `autoDetect` respects `OnPush` flag of host view ([#54824](https://github.com/angular/angular/pull/54824)) |
| [ba8e465974](https://github.com/angular/angular/commit/ba8e46597435a827670f10b971b2c58f7033b180) | fix | Change Detection will continue to refresh views while marked for check ([#54734](https://github.com/angular/angular/pull/54734)) |
| [24bc0ed4f2](https://github.com/angular/angular/commit/24bc0ed4f2de47bd998338d73cba394fb45dd497) | fix | ComponentFixture autodetect should detect changes within ApplicationRef.tick ([#54733](https://github.com/angular/angular/pull/54733)) |
| [10c5cdb49c](https://github.com/angular/angular/commit/10c5cdb49c51c95086febd37f4d88a9b944d7e1c) | fix | ensure change detection runs in a reasonable timeframe with zone coalescing ([#54578](https://github.com/angular/angular/pull/54578)) |
| [ad045efd4b](https://github.com/angular/angular/commit/ad045efd4b1565e01c14399998143538ebfbfd99) | fix | Ensure views marked for check are refreshed during change detection ([#54735](https://github.com/angular/angular/pull/54735)) |
| [700c0520bb](https://github.com/angular/angular/commit/700c0520bb638952ba41a8d8260cf12afb078c0e) | fix | Update ApplicationRef.tick loop to only throw in dev mode ([#54848](https://github.com/angular/angular/pull/54848)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [8735af08b9](https://github.com/angular/angular/commit/8735af08b976b30cf236a83f9e8b64b5ff62e9f3) | feat | Add ability to return `UrlTree` with `NavigationBehaviorOptions` from guards ([#45023](https://github.com/angular/angular/pull/45023)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.0"></a>
# 17.3.0 (2024-03-13)
### compiler
-5
View File
@@ -389,7 +389,6 @@ The following documents can help you sort out issues with GitHub accounts and mu
[angular-group]: https://groups.google.com/forum/#!forum/angular
[coc]: https://github.com/angular/code-of-conduct/blob/main/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[corporate-cla]: https://cla.developers.google.com/about/google-corporate
@@ -398,7 +397,3 @@ The following documents can help you sort out issues with GitHub accounts and mu
[discord]: https://discord.gg/angular
[individual-cla]: https://cla.developers.google.com/about/google-individual
[js-style-guide]: https://google.github.io/styleguide/jsguide.html
[jsfiddle]: https://jsfiddle.net/
[plunker]: https://plnkr.co/edit
[runnable]: https://runnable.com/
[stackoverflow]: https://stackoverflow.com/questions/tagged/angular
+3 -3
View File
@@ -1,7 +1,7 @@
<h1 align="center">Angular - The modern web developer's platform</h1>
<p align="center">
<img src="aio/src/assets/images/logos/angular/angular_renaissance.png" alt="angular-logo" width="120px" height="120px"/>
<img src="adev/src/assets/images/press-kit/angular_icon_gradient.gif" alt="angular-logo" width="120px" height="120px"/>
<br>
<em>Angular is a development platform for building mobile and desktop web applications
<br> using TypeScript/JavaScript and other languages.</em>
@@ -167,8 +167,8 @@ Join the conversation and help the community.
[angularmaterial]: https://material.angular.io/
[cli]: https://angular.dev/tools/cli
[architecture]: https://angular.dev/essentials
[componentstemplates]: https://angular.dev/tutorials/learn-angular/components-in-angular
[forms]: https://angular.dev/tutorials/learn-angular/forms
[componentstemplates]: https://angular.dev/tutorials/learn-angular/1-components-in-angular
[forms]: https://angular.dev/tutorials/learn-angular/15-forms
[api]: https://angular.dev/api
[angularelements]: https://angular.dev/guide/elements
[ssr]: https://angular.dev/guide/ssr
+11 -25
View File
@@ -9,20 +9,6 @@ workspace(
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("//:yarn.bzl", "YARN_LABEL")
# Add a patch fix for rules_webtesting v0.3.5 required for enabling runfiles on Windows.
# TODO: Remove the http_archive for this transitive dependency when a release is cut
# for https://github.com/bazelbuild/rules_webtesting/commit/581b1557e382f93419da6a03b91a45c2ac9a9ec8
# and the version is updated in rules_nodejs.
http_archive(
name = "io_bazel_rules_webtesting",
patch_args = ["-p1"],
patches = [
"//:tools/bazel-repo-patches/rules_webtesting__windows_runfiles_fix.patch",
],
sha256 = "e9abb7658b6a129740c0b3ef6f5a2370864e102a5ba5ffca2cea565829ed825a",
urls = ["https://github.com/bazelbuild/rules_webtesting/releases/download/0.3.5/rules_webtesting.tar.gz"],
)
http_archive(
name = "build_bazel_rules_nodejs",
patches = [
@@ -65,16 +51,16 @@ load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
nodejs_register_toolchains(
name = "nodejs",
node_repositories = {
"18.18.2-darwin_arm64": ("node-v18.18.2-darwin-arm64.tar.gz", "node-v18.18.2-darwin-arm64", "9f982cc91b28778dd8638e4f94563b0c2a1da7aba62beb72bd427721035ab553"),
"18.18.2-darwin_amd64": ("node-v18.18.2-darwin-x64.tar.gz", "node-v18.18.2-darwin-x64", "5bb8da908ed590e256a69bf2862238c8a67bc4600119f2f7721ca18a7c810c0f"),
"18.18.2-linux_arm64": ("node-v18.18.2-linux-arm64.tar.xz", "node-v18.18.2-linux-arm64", "2e630e18548627f61eaf573233da7949dc0a1df5eef3f486fa9820c5f6c121aa"),
"18.18.2-linux_ppc64le": ("node-v18.18.2-linux-ppc64le.tar.xz", "node-v18.18.2-linux-ppc64le", "b0adff5cf5938266b711d6c724fb134d802e0dee40b3a3f73d162de1b3d11880"),
"18.18.2-linux_s390x": ("node-v18.18.2-linux-s390x.tar.xz", "node-v18.18.2-linux-s390x", "c70ec2074b5e2b42c55bb4b8105418b67bf8a61c500d9376a07430dfcc341fdb"),
"18.18.2-linux_amd64": ("node-v18.18.2-linux-x64.tar.xz", "node-v18.18.2-linux-x64", "75aba25ae76999309fc6c598efe56ce53fbfc221381a44a840864276264ab8ac"),
"18.18.2-windows_amd64": ("node-v18.18.2-win-x64.zip", "node-v18.18.2-win-x64", "3bb0e51e579a41a22b3bf6cb2f3e79c03801aa17acbe0ca00fc555d1282e7acd"),
"18.19.1-darwin_arm64": ("node-v18.19.1-darwin-arm64.tar.gz", "node-v18.19.1-darwin-arm64", "0c7249318868877032ed21cc0ed450015ee44b31b9b281955521cd3fc39fbfa3"),
"18.19.1-darwin_amd64": ("node-v18.19.1-darwin-x64.tar.gz", "node-v18.19.1-darwin-x64", "ab67c52c0d215d6890197c951e1bd479b6140ab630212b96867395e21d813016"),
"18.19.1-linux_arm64": ("node-v18.19.1-linux-arm64.tar.xz", "node-v18.19.1-linux-arm64", "228ad1eee660fba3f9fd2cccf02f05b8ebccc294d27f22c155d20b233a9d76b3"),
"18.19.1-linux_ppc64le": ("node-v18.19.1-linux-ppc64le.tar.xz", "node-v18.19.1-linux-ppc64le", "2e5812b8fc00548e2e8ab9daa88ace13974c16b6ba5595a7a50c35f848f7d432"),
"18.19.1-linux_s390x": ("node-v18.19.1-linux-s390x.tar.xz", "node-v18.19.1-linux-s390x", "15106acf4c9e3aca02416dd89fb5c71af77097042455a73f9caa064c1988ead5"),
"18.19.1-linux_amd64": ("node-v18.19.1-linux-x64.tar.xz", "node-v18.19.1-linux-x64", "f35f24edd4415cd609a2ebc03be03ed2cfe211d7333d55c752d831754fb849f0"),
"18.19.1-windows_amd64": ("node-v18.19.1-win-x64.zip", "node-v18.19.1-win-x64", "ff08f8fe253fba9274992d7052e9d9a70141342d7b36ddbd6e84cbe823e312c6"),
},
# We need at least Node 18.17 due to some transitive dependencies.
node_version = "18.18.2",
node_version = "18.19.1",
)
# Download npm dependencies.
@@ -206,10 +192,10 @@ cldr_xml_data_repository(
# sass rules
http_archive(
name = "io_bazel_rules_sass",
sha256 = "5633816e996a79c77f44306f6228b9ef18fc2ecb412d63b4e314a132225facba",
strip_prefix = "rules_sass-79bd239ce77c101ea1aed575678020bd2999f17d",
sha256 = "e50e1ca1b0a737d2c09efbbb886e0194d99caed617337a766b17c1ee4bae93f2",
strip_prefix = "rules_sass-fcce06104e072bbebbf92c1a244ea9f8c2fc8402",
urls = [
"https://github.com/bazelbuild/rules_sass/archive/79bd239ce77c101ea1aed575678020bd2999f17d.zip",
"https://github.com/bazelbuild/rules_sass/archive/fcce06104e072bbebbf92c1a244ea9f8c2fc8402.zip",
],
)
+29 -18
View File
@@ -1,8 +1,9 @@
load("//:packages.bzl", "link_packages")
load("@npm//@angular/build-tooling/bazel/remote-execution:index.bzl", "ENABLE_NETWORK")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
load("@npm//@angular-devkit/architect-cli:index.bzl", "architect", "architect_test")
load("@bazel_skylib//lib:collections.bzl", "collections")
load("//adev/tools/local_deps:index.bzl", "ensure_local_package_deps", "link_local_packages")
package(default_visibility = ["//visibility:public"])
@@ -30,7 +31,17 @@ TEST_FILES = APPLICATION_FILES + [
["**/*.spec.ts"],
)
APPLICATION_DEPS = link_packages([
APPLICATION_ASSETS = [
"//adev/src/assets/images",
"//adev/src/assets/textures",
"//adev/src/assets/previews",
"//adev/src/assets:tutorials",
"//adev/src/assets/icons",
"//adev/src/assets:api",
"//adev/src/assets:content",
]
APPLICATION_DEPS = [
"@npm//@angular-devkit/build-angular",
"@npm//@angular/animations",
"@npm//@angular/cdk",
@@ -50,13 +61,6 @@ APPLICATION_DEPS = link_packages([
"@npm//ogl",
"@npm//rxjs",
"@npm//typescript",
"//adev/src/assets/images",
"//adev/src/assets/textures",
"//adev/src/assets/previews",
"//adev/src/assets:tutorials",
"//adev/src/assets/icons",
"//adev/src/assets:api",
"//adev/src/assets:content",
"@npm//@typescript/vfs",
"@npm//@codemirror/state",
"@npm//@codemirror/view",
@@ -73,14 +77,13 @@ APPLICATION_DEPS = link_packages([
"@npm//@lezer/highlight",
"@npm//@lezer/javascript",
"@npm//@lezer/common",
"@npm//@xterm/xterm",
"@npm//xterm",
"@npm//xterm-addon-fit",
"@npm//angular-split",
])
]
TEST_DEPS = APPLICATION_DEPS + link_packages([
TEST_DEPS = APPLICATION_DEPS + [
"@npm//@angular/platform-browser-dynamic",
"@npm//@angular/build-tooling/bazel/browsers/chromium",
"@npm//@types/jasmine",
"@npm//@types/node",
"@npm//assert",
@@ -90,8 +93,13 @@ TEST_DEPS = APPLICATION_DEPS + link_packages([
"@npm//karma-coverage",
"@npm//karma-jasmine",
"@npm//karma-jasmine-html-reporter",
"//aio/tools:windows-chromium-path",
])
]
# Create `npm_link` targets for all dependencies that correspond to a
# first-party Angular package that can be built from `HEAD`.
link_local_packages(
all_deps = collections.uniq(APPLICATION_DEPS + TEST_DEPS),
)
copy_to_bin(
name = "application_files_bin",
@@ -129,7 +137,7 @@ architect(
"--output-path=build",
] + config_based_architect_flags,
chdir = "$(RULEDIR)",
data = APPLICATION_DEPS + [
data = ensure_local_package_deps(APPLICATION_DEPS) + APPLICATION_ASSETS + [
":application_files_bin",
],
# Network is required to inline fonts.
@@ -149,7 +157,7 @@ architect(
"--watch",
],
chdir = package_name(),
data = APPLICATION_DEPS + [
data = ensure_local_package_deps(APPLICATION_DEPS) + APPLICATION_ASSETS + [
":application_files_bin",
],
tags = [
@@ -164,7 +172,10 @@ architect_test(
"--no-watch",
],
chdir = package_name(),
data = TEST_DEPS + TEST_FILES,
data = ensure_local_package_deps(TEST_DEPS) + TEST_FILES + APPLICATION_ASSETS + [
"//aio/tools:windows-chromium-path",
"@npm//@angular/build-tooling/bazel/browsers/chromium",
],
env = {
"CHROME_BIN": "../$(CHROMIUM)",
},
+8 -9
View File
@@ -19,9 +19,7 @@
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"externalDependencies": [
"path"
],
"externalDependencies": ["path"],
"outputPath": "dist/angular-dev",
"index": "src/index.html",
"browser": "src/main.ts",
@@ -29,11 +27,7 @@
"polyfills": ["src/polyfills.ts", "zone.js"],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/robots.txt",
"src/assets"
],
"assets": ["src/favicon.ico", "src/robots.txt", "src/assets"],
"styles": ["@angular/docs/styles/global-styles.scss"],
"scripts": [],
"webWorkerTsConfig": "tsconfig.worker.json",
@@ -99,6 +93,11 @@
}
},
"cli": {
"analytics": "dca119a9-da31-47f7-a6cb-b60541037021"
"analytics": "dca119a9-da31-47f7-a6cb-b60541037021",
"cache": {
// Disable build caching as the cache folder will just be dropped
// when run under Bazel sandboxed execution.
"enabled": false
}
}
}
+74
View File
@@ -0,0 +1,74 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export const VERSIONS_CONFIG = {
currentVersion: 'stable',
historicalVersionsLinkPattern: 'https://v{{version}}.angular.dev',
mainVersions: [
{
version: 'stable',
url: 'https://angular.dev',
},
{
version: 'v16',
url: 'https://v16.angular.io/docs',
},
{
version: 'v15',
url: 'https://v15.angular.io/docs',
},
{
version: 'v14',
url: 'https://v14.angular.io/docs',
},
{
version: 'v13',
url: 'https://v13.angular.io/docs',
},
{
version: 'v12',
url: 'https://v12.angular.io/docs',
},
{
version: 'v11',
url: 'https://v11.angular.io/docs',
},
{
version: 'v10',
url: 'https://v10.angular.io/docs',
},
{
version: 'v9',
url: 'https://v9.angular.io/docs',
},
{
version: 'v8',
url: 'https://v8.angular.io/docs',
},
{
version: 'v7',
url: 'https://v7.angular.io/docs',
},
{
version: 'v6',
url: 'https://v6.angular.io/docs',
},
{
version: 'v5',
url: 'https://v5.angular.io/docs',
},
{
version: 'v4',
url: 'https://v4.angular.io/docs',
},
{
version: 'v2',
url: 'https://v2.angular.io/docs',
},
],
};
@@ -1,5 +1,5 @@
<div [attr.id]="SECONDARY_NAV_ID" class="adev-secondary-nav-mask" [class.docs-nav-secondary--open]="isSecondaryNavVisible()" (docsClickOutside)="close()" [docsClickOutsideIgnore]="[PRIMARY_NAV_ID]">
<div class="docs-nav-secondary docs-scroll-track-transparent" [style.transform]="translateX()" [style.transition]="transition">
<div class="docs-nav-secondary docs-scroll-track-transparent" [style.transform]="translateX()" [style.transition]="transition()">
<!-- Secondary Nav -->
@if (navigationItems && navigationItems.length > 0) {
<docs-navigation-list
@@ -14,6 +14,7 @@ import {
PLATFORM_ID,
computed,
inject,
signal,
} from '@angular/core';
import {takeUntilDestroyed, toObservable} from '@angular/core/rxjs-interop';
import {
@@ -76,7 +77,7 @@ export class SecondaryNavigation implements OnInit {
const level = this.navigationState.expandedItems()?.length ?? 0;
return `translateX(${-level * 100}%)`;
});
transition: string = '0ms';
transition = signal('0ms');
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
@@ -182,7 +183,7 @@ export class SecondaryNavigation implements OnInit {
return;
}
setTimeout(() => {
this.transition = `${ANIMATION_DURATION}ms`;
this.transition.set(`${ANIMATION_DURATION}ms`);
}, ANIMATION_DURATION);
}
@@ -10,6 +10,7 @@ import {HttpClient} from '@angular/common/http';
import {Injectable, inject} from '@angular/core';
import {DocContent, DocsContentLoader} from '@angular/docs';
import {Router} from '@angular/router';
import {firstValueFrom} from 'rxjs';
import {map} from 'rxjs/operators';
@Injectable()
@@ -27,12 +28,13 @@ export class ContentLoader implements DocsContentLoader {
try {
this.cache.set(
path,
this.httpClient
.get(`assets/content/${path}`, {
responseType: 'text',
})
.pipe(map((contents) => ({contents, id: path})))
.toPromise(),
firstValueFrom(
this.httpClient
.get(`assets/content/${path}`, {
responseType: 'text',
})
.pipe(map((contents) => ({contents, id: path}))),
),
);
} catch {
this.router.navigateByUrl('/404');
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {Component, Inject} from '@angular/core';
import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
import {MAT_SNACK_BAR_DATA, MatSnackBarAction, MatSnackBarRef} from '@angular/material/snack-bar';
export interface ErrorSnackBarData {
@@ -16,6 +16,7 @@ export interface ErrorSnackBarData {
@Component({
selector: 'error-snack-bar',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
{{ message }}
<button
@@ -28,8 +29,8 @@ export interface ErrorSnackBarData {
{{ actionText }}
</button>
`,
imports: [MatSnackBarAction],
standalone: true,
imports: [MatSnackBarAction],
styles: `:host { display: flex; align-items: center; button { margin-left: 16px }}`,
})
export class ErrorSnackBar {
@@ -82,7 +82,7 @@ export class ThemeManager {
}
private watchPreferredColorScheme() {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {
window.matchMedia(PREFERS_COLOR_SCHEME_DARK).addEventListener('change', (event) => {
const preferredScheme = event.matches ? 'dark' : 'light';
this.setThemeBodyClasses(preferredScheme);
});
@@ -90,5 +90,5 @@ export class ThemeManager {
}
function preferredScheme(): 'dark' | 'light' {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
return window.matchMedia(PREFERS_COLOR_SCHEME_DARK).matches ? 'dark' : 'light';
}
@@ -7,74 +7,7 @@
*/
import {Injectable, VERSION, computed, signal} from '@angular/core';
// TODO(josephperrott): extract this out of the file into a managed location.
const VERSIONS_CONFIG = {
currentVersion: 'stable',
historicalVersionsLinkPattern: 'https://v{{version}}.angular.dev',
mainVersions: [
{
version: 'stable',
url: 'https://angular.dev',
},
{
version: 'v16',
url: 'https://v16.angular.io/docs',
},
{
version: 'v15',
url: 'https://v15.angular.io/docs',
},
{
version: 'v14',
url: 'https://v14.angular.io/docs',
},
{
version: 'v13',
url: 'https://v13.angular.io/docs',
},
{
version: 'v12',
url: 'https://v12.angular.io/docs',
},
{
version: 'v11',
url: 'https://v11.angular.io/docs',
},
{
version: 'v10',
url: 'https://v10.angular.io/docs',
},
{
version: 'v9',
url: 'https://v9.angular.io/docs',
},
{
version: 'v8',
url: 'https://v8.angular.io/docs',
},
{
version: 'v7',
url: 'https://v7.angular.io/docs',
},
{
version: 'v6',
url: 'https://v6.angular.io/docs',
},
{
version: 'v5',
url: 'https://v5.angular.io/docs',
},
{
version: 'v4',
url: 'https://v4.angular.io/docs',
},
{
version: 'v2',
url: 'https://v2.angular.io/docs',
},
],
};
import {VERSIONS_CONFIG} from '../constants/versions';
export interface Version {
displayName: string;
+2 -2
View File
@@ -115,7 +115,7 @@ The following steps are executed on project change:
5. The previous project dependencies are compared with the new project dependencies.
1. If there are differences, a `npm install` is triggered, hiding the preview and going to the install loading step.
2. If there are no differences, the project is ready.
6. Some states are reset, for example the "reveal answer" state if the previous project was in the "reveal answer" state.
6. Some states are resetted, for example the "reveal answer" state if the previous project was in the "reveal answer" state.
## Components and services
@@ -200,7 +200,7 @@ Responsible for handling the download button in the embedded editor, fetching th
#### [`AlertManager`](./alert-manager.service.ts)
Manage the alerts displayed in the embedded editor, being the out of memory alert when multiple tabs are opened, and unsupported environments alerts.
Manage the alerts displayed in the embedded editor, being the out of memory alert when multiple tabs are opened, and unsupported enviroments alerts.
#### [`TypingsLoader`](./typings-loader.service.ts)
@@ -8,6 +8,7 @@ $width-breakpoint: 950px;
container-name: embedded-editor;
height: 100%;
position: relative;
border: 1px solid var(--senary-contrast);
}
// The entire thing - editor, terminal, console
@@ -8,7 +8,7 @@
import {inject} from '@angular/core';
import {Subject} from 'rxjs';
import {Terminal} from '@xterm/xterm';
import {Terminal} from 'xterm';
import {WINDOW} from '@angular/docs';
@@ -7,7 +7,7 @@
*/
import {Injectable} from '@angular/core';
import {Terminal} from '@xterm/xterm';
import {Terminal} from 'xterm';
import {FitAddon} from 'xterm-addon-fit';
import {InteractiveTerminal} from './interactive-terminal';
+2 -1
View File
@@ -8,13 +8,14 @@
import {CommonModule} from '@angular/common';
import {DocContent, DocViewer} from '@angular/docs';
import {Component, inject} from '@angular/core';
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import {toSignal} from '@angular/core/rxjs-interop';
import {ActivatedRoute} from '@angular/router';
import {map} from 'rxjs/operators';
@Component({
selector: 'docs-docs',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, DocViewer],
styleUrls: ['./docs.component.scss'],
File diff suppressed because one or more lines are too long
@@ -36,6 +36,7 @@
box-sizing: border-box;
transition: background 0.3s ease, border 0.3s ease;
h1,
p {
display: inline;
font-size: 0.875rem;
@@ -108,7 +108,6 @@
& > .docs-code {
box-sizing: border-box;
width: 100%;
max-height: 93vh;
overflow: hidden;
padding: 0;
@@ -119,6 +118,7 @@
button {
transition: background-color 0.3s ease;
font-family: monospace;
&.hljs-ln-line {
font-weight: 400;
@@ -154,6 +154,10 @@
}
}
.docs-reference-cli-toc {
margin-bottom: 1rem;
}
.adev-reference-tab {
min-width: 50ch;
margin-block-start: 2.5rem;
@@ -267,7 +271,9 @@
background-color: var(--octonary-contrast);
position: relative;
z-index: 10;
transition: background-color 0.3s ease, border 0.3s ease;
transition:
background-color 0.3s ease,
border 0.3s ease;
// h3 + code || # of overloads
.docs-reference-header {
@@ -404,4 +410,17 @@
margin-block-start: 0;
}
}
.docs-ref-content {
padding: 1rem 0;
&:not(:first-child) {
border-block-start: 1px solid var(--senary-contrast);
}
.docs-param-keyword {
display: block;
margin: 0 0 0.5rem 0;
}
}
}
@@ -16,12 +16,12 @@ import {
inject,
signal,
} from '@angular/core';
import {DOCUMENT, NgFor, NgIf} from '@angular/common';
import {DOCUMENT, NgFor, NgIf, ViewportScroller} from '@angular/common';
import {MatTabGroup, MatTabsModule} from '@angular/material/tabs';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {distinctUntilChanged, map} from 'rxjs/operators';
import {takeUntilDestroyed, toSignal} from '@angular/core/rxjs-interop';
import {distinctUntilChanged, filter, map, take} from 'rxjs/operators';
import {DocContent, DocViewer} from '@angular/docs';
import {ActivatedRoute, Router, RouterLink} from '@angular/router';
import {ActivatedRoute, Router, RouterLink, Scroll} from '@angular/router';
import {ApiItemType} from './../interfaces/api-item-type';
import {ReferenceScrollHandler} from '../services/reference-scroll-handler.service';
import {
@@ -51,6 +51,15 @@ export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
private readonly document = inject(DOCUMENT);
private readonly router = inject(Router);
private readonly scrollHandler = inject(ReferenceScrollHandler);
private readonly scroller = inject(ViewportScroller);
private scrollEvent = toSignal(
this.router.events.pipe(
filter((e): e is Scroll => e instanceof Scroll),
take(1),
),
{initialValue: null},
);
private cardsDisplayedOnInit = false;
ApiItemType = ApiItemType;
@@ -67,10 +76,22 @@ export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
ngAfterViewInit(): void {
this.setActiveTab();
if (this.canDisplayCards()) {
this.cardsDisplayedOnInit = true;
}
this.listenToTabChange();
}
membersCardsLoaded(): void {
const event = this.scrollEvent();
if (this.cardsDisplayedOnInit && event) {
// Cards loaded after scroll event happened. We have to handle the scroll event manually
if (event.position) {
this.scroller.scrollToPosition(event.position);
} else if (event.anchor) {
this.scroller.scrollToAnchor(event.anchor);
}
}
this.scrollHandler.setupListeners(API_TAB_CLASS_NAME);
}
@@ -3,6 +3,11 @@
<h6>Getting Started</h6>
<h1 tabindex="-1">API Reference</h1>
</header>
@if (featuredGroup().items.length) {
<adev-api-items-section [group]="featuredGroup()" class="adev-featured-list" />
}
<form class="adev-reference-list-form">
<docs-text-field
name="query"
@@ -34,12 +39,8 @@
</ul>
</form>
@if (featuredGroup().items.length) {
<adev-api-items-section [group]="featuredGroup()" class="adev-featured-list" />
}
@for (group of filteredGroups(); track group) {
<adev-api-items-section [group]="group" />
}
<span id="deprecated-description" class="docs-deprecated-description">Deprecated</span>
</div>
@@ -77,8 +77,9 @@
justify-content: flex-start;
flex-wrap: wrap-reverse;
gap: 1.5rem;
padding-block-start: 0;
padding-block-start: 1.5rem;
padding-block-end: 2rem;
border-block: 1px solid var(--senary-contrast);
}
.adev-reference-list-form-part-two {
@@ -89,15 +90,10 @@
.adev-featured-list {
display: block;
padding-block-end: 2rem;
padding-block-start: 1.5rem;
padding-block-end: 1rem;
margin-block: 1rem;
border-block: 1px solid var(--senary-contrast);
}
.docs-deprecated-description {
display: none;
border-top: 0;
margin-top: -1.5rem;
}
.docs-api-item-label-full {
@@ -14,7 +14,7 @@ import {ApiItemsGroup} from '../interfaces/api-items-group';
import {ApiManifest} from '../interfaces/api-manifest';
export const FEATURED_API_ITEMS_KEY = 'apiFeaturedItems';
export const FEATURED_GROUP_TITLE = 'Featured';
export const FEATURED_GROUP_TITLE = 'Most Common';
export type FeaturedItemsByGroup = Record<string, ApiItem[]>;
@@ -160,9 +160,6 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
for (const line of Array.from(activeLines)) {
line.classList.remove(API_TAB_ACTIVE_CODE_LINE);
}
this.getAllMemberCards().forEach((card) => {
card.blur();
});
} else {
const lines = this.document.querySelectorAll<HTMLButtonElement>(
`button[${MEMBER_ID_ATTRIBUTE}="${currentActiveMemberId}"]`,
@@ -170,7 +167,7 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
for (const line of Array.from(lines)) {
line.classList.add(API_TAB_ACTIVE_CODE_LINE);
}
this.document.getElementById(`${currentActiveMemberId}`)?.focus();
this.document.getElementById(`${currentActiveMemberId}`)?.focus({preventScroll: true});
}
}
@@ -179,7 +176,9 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
return;
}
card.focus();
if (card !== <HTMLElement>document.activeElement) {
(<HTMLElement>document.activeElement).blur();
}
this.window.scrollTo({
top: card!.offsetTop - this.membersMarginTopInPx(),
@@ -211,8 +210,9 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
this.resizeObserver = new ResizeObserver((_) => {
this.ngZone.run(() => {
if (tabBody.offsetTop) {
this.membersMarginTopInPx.set(tabBody.offsetTop);
const offsetTop = tabBody.getBoundingClientRect().top;
if (offsetTop) {
this.membersMarginTopInPx.set(offsetTop);
}
});
});
@@ -41,7 +41,7 @@ class FakeDocViewer {
@Input('documentFilePath') documentFilePath: string | undefined;
}
// TODO: export this class, it's a helpful mock we could you on other tests.
// TODO: export this class, it's a helpfull mock we could you on other tests.
class FakeNodeRuntimeSandbox {
loadingStep = signal(0);
previewUrl$ = of();
+8 -3
View File
@@ -117,6 +117,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/components/outputs',
contentPath: 'guide/components/outputs',
},
{
label: 'output() function',
path: 'guide/components/output-fn',
contentPath: 'guide/components/output-function',
},
{
label: 'Content projection with ng-content',
path: 'guide/components/content-projection',
@@ -1143,9 +1148,9 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'reference/errors/NG3003',
},
{
label: 'NG5000: Hydration with unsupported Zone.js instance.',
path: 'errors/NG5000',
contentPath: 'reference/errors/NG5000',
label: 'NG05000: Hydration with unsupported Zone.js instance.',
path: 'errors/NG05000',
contentPath: 'reference/errors/NG05000',
},
{
label: 'NG6100: NgModule.id Set to module.id anti-pattern',

Before

Width:  |  Height:  |  Size: 3.4 MiB

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

@@ -59,8 +59,6 @@ If Angular handles an event within a component with OnPush strategy, the framewo
As an example, if Angular handles an event within `MainComponent`, the framework will run change detection in the entire component tree. Angular will ignore the subtree with root `LoginComponent` because it has `OnPush` and the event happened outside of its scope.
<img alt="Change detection propagation from OnPush component" src="assets/images/best-practices/runtime-performance/on-push-trigger.svg">
```mermaid
graph TD;
app[AppComponent] --- header[HeaderComponent];
@@ -35,7 +35,7 @@ class AppComponent implements OnInit {
The preceding snippet instructs Angular to call `setInterval` outside the Angular Zone and skip running change detection after `pollForUpdates` runs.
Third-party libraries commonly trigger unnecessary change detection cycles because they weren't authored with Zone.js in mind. Avoid these extra cycles by calling library APIs outside the Angular zone:
Third-party libraries commonly trigger unnecessary change detection cycles when their APIs are invoked within the Angular zone. This phenomenon particularly affects libraries that setup event listeners or initiate other tasks (such as timers, XHR requests, etc.). Avoid these extra cycles by calling library APIs outside the Angular zone:
<docs-code header="Move the plot initialization outside of the Zone" language='ts' linenums>
import { Component, NgZone, OnInit } from '@angular/core';
@@ -57,3 +57,67 @@ class AppComponent implements OnInit {
Running `Plotly.newPlot('chart', data);` within `runOutsideAngular` instructs the framework that it shouldn’t run change detection after the execution of tasks scheduled by the initialization logic.
For example, if `Plotly.newPlot('chart', data)` adds event listeners to a DOM element, Angular does not run change detection after the execution of their handlers.
But sometimes, you may need to listen to events dispatched by third-party APIs. In such cases, it's important to remember that those event listeners will also execute outside of the Angular zone if the initialization logic was done there:
<docs-code header="Check whether the handler is called outside of the Zone" language='ts' linenums>
import { Component, NgZone, OnInit, output } from '@angular/core';
import * as Plotly from 'plotly.js-dist-min';
@Component(...)
class AppComponent implements OnInit {
plotlyClick = output<Plotly.PlotMouseEvent>();
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.createPlotly();
});
}
private async createPlotly() {
const plotly = await Plotly.newPlot('chart', data);
plotly.on('plotly_click', (event: Plotly.PlotMouseEvent) => {
// This handler will be called outside of the Angular zone because
// the initialization logic is also called outside of the zone. To check
// whether we're in the Angular zone, we can call the following:
console.log(NgZone.isInAngularZone());
this.plotlyClick.emit(event);
});
}
}
</docs-code>
If you need to dispatch events to parent components and execute specific view update logic, you should consider re-entering the Angular zone to instruct the framework to run change detection or run change detection manually:
<docs-code header="Re-enter the Angular zone when dispatching event" language='ts' linenums>
import { Component, NgZone, OnInit, output } from '@angular/core';
import * as Plotly from 'plotly.js-dist-min';
@Component(...)
class AppComponent implements OnInit {
plotlyClick = output<Plotly.PlotMouseEvent>();
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.createPlotly();
});
}
private async createPlotly() {
const plotly = await Plotly.newPlot('chart', data);
plotly.on('plotly_click', (event: Plotly.PlotMouseEvent) => {
this.ngZone.run(() => {
this.plotlyClick.emit(event);
});
});
}
}
</docs-code>
The scenario of dispatching events outside of the Angular zone may also arise. It's important to remember that triggering change detection (for example, manually) may result to the creation/update of views outside of the Angular zone.
@@ -5,6 +5,8 @@ It can improve the user experience by quickly launching a static rendered page (
This gives users a meaningful first paint of your application that appears quickly because the browser can render the HTML and CSS without the need to initialize any JavaScript.
Learn more in [The App Shell Model](https://developers.google.com/web/fundamentals/architecture/app-shell).
<docs-workflow>
<docs-step title="Prepare the application">
Do this with the following Angular CLI command:
@@ -15,7 +17,7 @@ ng new my-app --routing
</docs-code>
For an existing application, you have to manually add the `RouterModule` and defining a `<router-outlet>` within your application.
For an existing application, you have to manually add the `Router` and defining a `<router-outlet>` within your application.
</docs-step>
<docs-step title="Create the application shell">
Use the Angular CLI to automatically create the application shell.
@@ -28,57 +30,24 @@ ng generate app-shell
For more information about this command, see [App shell command](cli/generate#app-shell-command).
After running this command you can see that the `angular.json` configuration file has been updated to add two new targets, with a few other changes.
The command updates the application code and adds extra files to the project structure.
<docs-code language="json">
<code-example language="text">
src
├── app
│ ├── app.config.server.ts # server application configuration
│ └── app-shell # app-shell component
│ ├── app-shell.component.html
│ ├── app-shell.component.scss
│ ├── app-shell.component.spec.ts
│ └── app-shell.component.ts
└── main.server.ts # main server application bootstrapping
</code-example>
"server": {
"builder": "@angular-devkit/build-angular:server",
"defaultConfiguration": "production",
"options": {
"outputPath": "dist/my-app/server",
"main": "src/main.server.ts",
"tsConfig": "tsconfig.server.json"
},
"configurations": {
"development": {
"outputHashing": "none",
},
"production": {
"outputHashing": "media",
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"sourceMap": false,
"optimization": true
}
}
},
"app-shell": {
"builder": "@angular-devkit/build-angular:app-shell",
"defaultConfiguration": "production",
"options": {
"route": "shell"
},
"configurations": {
"development": {
"browserTarget": "my-app:build:development",
"serverTarget": "my-app:server:development",
},
"production": {
"browserTarget": "my-app:build:production",
"serverTarget": "my-app:server:production"
}
}
}
</docs-code>
</docs-step>
<docs-step title="Verify the application is built with the shell content">
Use the Angular CLI to build the `app-shell` target.
<docs-code language="shell">
@@ -6,32 +6,28 @@
<blockquote>
<!-- #docregion asterisk -->
@if (hero) {<div class="name">{{ hero.name }}</div>}
<div *ngIf="hero" class="name">{{hero.name}}</div>
<!-- #enddocregion asterisk -->
</blockquote>
<p>List of heroes</p>
<ul>
@for (hero of heroes; track hero) {<li>{{ hero.name }}</li>}
<li *ngFor="let hero of heroes">{{hero.name}}</li>
</ul>
<hr>
<h2 id="ngIf">NgIf</h2>
@if (true) {
<p>
Expression is true and ngIf is true.
This paragraph is in the DOM.
</p>
}
@if (false) {
<p>
Expression is false and ngIf is false.
This paragraph is not in the DOM.
</p>
}
<p *ngIf="true">
Expression is true and ngIf is true.
This paragraph is in the DOM.
</p>
<p *ngIf="false">
Expression is false and ngIf is false.
This paragraph is not in the DOM.
</p>
<p [style.display]="'block'">
Expression sets display to "block".
@@ -46,7 +42,7 @@
<p>&lt;ng-template&gt; element</p>
<!-- #docregion ngif-template -->
<ng-template [ngIf]="hero">
<div class="name">{{ hero.name }}</div>
<div class="name">{{hero.name}}</div>
</ng-template>
<!-- #enddocregion ngif-template -->
@@ -61,18 +57,18 @@
<!-- #docregion ngif-ngcontainer -->
<p>
I turned the corner
@if (hero) {
and saw {{ hero.name }}. I waved
}
<ng-container *ngIf="hero">
and saw {{hero.name}}. I waved
</ng-container>
and continued on my way.
</p>
<!-- #enddocregion ngif-ngcontainer -->
<p>
I turned the corner
@if (hero) {
<span>and saw {{ hero.name }}. I waved</span>
}
<span *ngIf="hero">
and saw {{hero.name}}. I waved
</span>
and continued on my way.
</p>
@@ -83,15 +79,11 @@
(<label for="show-sad"><input id="show-sad" type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
@for (h of heroes; track h) {
<span>
@if (showSad || h.emotion !== 'sad') {
<span>
<option [ngValue]="h">{{ h.name }} ({{ h.emotion }})</option>
</span>
}
<span *ngFor="let h of heroes">
<span *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</span>
}
</span>
</select>
<p><em>&lt;select&gt; with &lt;ng-container&gt;</em></p>
@@ -101,11 +93,11 @@
(<label for="showSad"><input id="showSad" type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
@for (h of heroes; track h) {
@if (showSad || h.emotion !== 'sad') {
<option [ngValue]="h">{{ h.name }} ({{ h.emotion }})</option>
}
}
<ng-container *ngFor="let h of heroes">
<ng-container *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</ng-container>
</ng-container>
</select>
<!-- #enddocregion select-ngcontainer -->
<br><br>
@@ -118,12 +110,11 @@
<p class="code">&lt;div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd"&gt;</p>
<!--#docregion inside-ngfor -->
@for (hero of heroes; track hero; let odd = $odd; let i = $index) {
<div
[class.odd]="odd">
({{ i }}) {{ hero.name }}
</div>
}
<div
*ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById"
[class.odd]="odd">
({{i}}) {{hero.name}}
</div>
<!--#enddocregion inside-ngfor -->
<p class="code">&lt;ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById"/&gt;</p>
@@ -131,7 +122,7 @@
<ng-template ngFor let-hero [ngForOf]="heroes"
let-i="index" let-odd="odd" [ngForTrackBy]="trackById">
<div [class.odd]="odd">
({{ i }}) {{ hero.name }}
({{i}}) {{hero.name}}
</div>
</ng-template>
<!--#enddocregion inside-ngfor -->
@@ -143,46 +134,35 @@
<div>Pick your favorite hero</div>
<p>
@for (h of heroes; track h) {
<label for="hero-{{ h }}">
<input id="hero-{{ h }}" type="radio" name="heroes" [(ngModel)]="hero" [value]="h">{{ h.name }}
</label>
}
<label for="hero-{{h}}" *ngFor="let h of heroes">
<input id="hero-{{h}}" type="radio" name="heroes" [(ngModel)]="hero" [value]="h">{{h.name}}
</label>
<label for="none-of-the-above"><input id="none-of-the-above" type="radio" name="heroes" (click)="hero = null">None of the above</label>
</p>
<h4>NgSwitch</h4>
<div>
@switch (hero?.emotion) {
@case ('happy') {
<app-happy-hero [hero]="hero!"></app-happy-hero>
} @case ('sad') {
<app-sad-hero [hero]="hero!"></app-sad-hero>
} @case ('confused') {
<app-confused-hero [hero]="hero!"></app-confused-hero>
} @default {
<app-unknown-hero [hero]="hero!"></app-unknown-hero>
}
}
<div [ngSwitch]="hero?.emotion">
<app-happy-hero *ngSwitchCase="'happy'" [hero]="hero!"></app-happy-hero>
<app-sad-hero *ngSwitchCase="'sad'" [hero]="hero!"></app-sad-hero>
<app-confused-hero *ngSwitchCase="'confused'" [hero]="hero!"></app-confused-hero>
<app-unknown-hero *ngSwitchDefault [hero]="hero!"></app-unknown-hero>
</div>
<h4>NgSwitch with &lt;ng-template&gt;</h4>
<div>
@switch (hero?.emotion) {
@case ('happy') {
<app-happy-hero [hero]="hero!"></app-happy-hero>
}
@case ('sad') {
<app-sad-hero [hero]="hero!"></app-sad-hero>
}
@case ('confused') {
<app-confused-hero [hero]="hero!"></app-confused-hero>
}
@default {
<app-unknown-hero [hero]="hero!"></app-unknown-hero>
}
}
<div [ngSwitch]="hero?.emotion">
<ng-template ngSwitchCase="happy">
<app-happy-hero [hero]="hero!"></app-happy-hero>
</ng-template>
<ng-template ngSwitchCase="sad">
<app-sad-hero [hero]="hero!"></app-sad-hero>
</ng-template>
<ng-template ngSwitchCase="confused">
<app-confused-hero [hero]="hero!"></app-confused-hero>
</ng-template >
<ng-template ngSwitchDefault>
<app-unknown-hero [hero]="hero!"></app-unknown-hero>
</ng-template>
</div>
<hr>
@@ -192,12 +172,12 @@
<!-- #docregion toggle-info -->
<p>
The condition is currently
<span [ngClass]="{ 'a': !condition, 'b': condition, 'unless': true }">{{ condition }}</span>.
<span [ngClass]="{ 'a': !condition, 'b': condition, 'unless': true }">{{condition}}</span>.
<button
type="button"
(click)="condition = !condition"
[ngClass]="{ 'a': condition, 'b': !condition }" >
Toggle condition to {{ condition ? 'false' : 'true' }}
[ngClass] = "{ 'a': condition, 'b': !condition }" >
Toggle condition to {{condition ? 'false' : 'true'}}
</button>
</p>
<!-- #enddocregion toggle-info -->
@@ -266,7 +266,7 @@ Learn about more advanced features in Angular animations under the Animation sec
## Animations API summary
The functional API provided by the `@angular/animations` module provides a domain-specific language \(DSL\) for creating and controlling animations in Angular applications.
See the [API reference](api/animations) for a complete listing and syntax details of the core functions and related data structures.
See the [API reference](api#animations) for a complete listing and syntax details of the core functions and related data structures.
| Function name | What it does |
|:--- |:--- |
@@ -0,0 +1,109 @@
# Function-based outputs
The `output()` function declares an output in a directive or component.
Outputs allow you to emit values to parent components.
HELPFUL: The `output()` function is currently in [developer preview](/reference/releases#developer-preview).
<docs-code language="ts" highlight="[[5], [8]]">
import {Component, output} from '@angular/core';
@Component({...})
export class MyComp {
onNameChange = output<string>() // OutputEmitterRef<string>
setNewName(newName: string) {
this.onNameChange.emit(newName);
}
}
</docs-code>
An output is automatically recognized by Angular whenever you use the `output` function as an initializer of a class member.
Parent components can listen to outputs in templates by using the event binding syntax.
```html
<my-comp (onNameChange)="showNewName($event)" />
```
## Aliasing an output
Angular uses the class member name as the name of the output.
You can alias outputs to change their public name to be different.
```typescript
class MyComp {
onNameChange = output({alias: 'ngxNameChange'});
}
```
This allows users to bind to your output using `(ngxNameChange)`, while inside your component you can access the output emitter using `this.onNameChange`.
## Subscribing programmatically
Consumers may create your component dynamically with a reference to a `ComponentRef`.
In those cases, parents can subscribe to outputs by directly accessing the property of type `OutputRef`.
```ts
const myComp = viewContainerRef.createComponent(...);
myComp.instance.onNameChange.subscribe(newName => {
console.log(newName);
});
```
Angular will automatically clean up the subscription when `myComp` is destroyed.
Alternatively, an object with a function to explicitly unsubscribe earlier is returned.
## Using RxJS observables as source
In some cases, you may want to emit output values based on RxJS observables.
Angular provides a way to use RxJS observables as source for outputs.
The `outputFromObservable` function is a compiler primitive, similar to the `output()` function, and declares outputs that are driven by RxJS observables.
<docs-code language="ts" highlight="[7]">
import {Directive} from '@angular/core';
import {outputFromObservable} from '@angular/core/rxjs-interop';
@Directive(...)
class MyDir {
nameChange$ = this.dataService.get(); // Observable<Data>
nameChange = outputFromObservable(this.nameChange$);
}
</docs-code>
Angular will forward subscriptions to the observable, but will stop forwarding values when the owning directive is destroyed.
In the example above, if `MyDir` is destroyed, `nameChange` will no longer emit values.
HELPFUL: Most of the time, using `output()` is sufficient and you can emit values imperatively.
## Converting an output to an observable
You can subscribe to outputs by calling `.subscribe` method on `OutputRef`.
In other cases, Angular provides a helper function that converts an `OutputRef` to an observable.
<docs-code language="ts" highlight="[11]">
import {outputToObservable} from '@angular/core/rxjs-interop';
@Component(...)
class MyComp {
onNameChange = output<string>();
}
// Instance reference to `MyComp`.
const myComp: MyComp;
outputToObservable(this.myComp.instance.onNameChange) // Observable<string>
.pipe(...)
.subscribe(...);
</docs-code>
## Why you should use `output()` over decorator-based `@Output()`?
The `output()` function provides numerous benefits over decorator-based `@Output` and `EventEmitter`:
1. Simpler mental model and API:
<br/>• No concept of error channel, completion channels, or other APIs from RxJS.
<br/>• Outputs are simple emitters. You can emit values using the `.emit` function.
2. More accurate types.
<br/>• `OutputEmitterRef.emit(value)` is now correctly typed, while `EventEmitter` has broken types and can cause runtime errors.
+3 -1
View File
@@ -56,7 +56,9 @@ Note: Certain triggers may require the presence of either a `@placeholder` or a
### `@loading`
The `@loading` block is an optional block that allows you to declare content that will be shown during the loading of any deferred dependencies. For example, you could show a loading spinner. Similar to `@placeholder`, the dependencies of the `@loading` block are eagerly loaded.
The `@loading` block is an optional block that allows you to declare content that will be shown during the loading of any deferred dependencies. Its dependences are eagerly loaded (similar to `@placeholder`).
For example, you could show a loading spinner. Once loading has been triggered, the `@loading` block replaces the `@placeholder` block.
The `@loading` block accepts two optional parameters to specify the `minimum` amount of time that this placeholder should be shown and amount of time to wait `after` loading begins before showing the loading template. `minimum` and `after` parameters are specified in time increments of milliseconds (ms) or seconds (s). Just like `@placeholder`, these parameters exist to prevent fast flickering of content in the case that the deferred dependencies are fetched quickly. Both the `minimum` and `after` timers for the `@loading` block begins immediately after the loading has been triggered.
@@ -1,21 +1,21 @@
# Injection context
The dependency injection (DI) system relies internally on a runtime context where the current injector is available.
This means that injectors can only work when code is executed in this context.
This means that injectors can only work when code is executed in such a context.
The injection context is available in these situations:
* Construction (via the `constructor`) of a class being instantiated by the DI system, such as an `@Injectable` or `@Component`.
* During construction (via the `constructor`) of a class being instantiated by the DI system, such as an `@Injectable` or `@Component`.
* In the initializer for fields of such classes.
* In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
* In the `factory` function specified for an `InjectionToken`.
* Within a stack frame that is run in a injection context.
* Within a stack frame that runs in an injection context.
Knowing when you are in an injection context, will allow you to use the [`inject`](api/core/inject) function to inject instances.
Knowing when you are in an injection context will allow you to use the [`inject`](api/core/inject) function to inject instances.
## Class constructors
Everytime the DI system instantiates a class, this is done in an injection context. This is being handled by the framework itself. The constructor of the class is executed in that runtime context thus allowing to inject a token using the [`inject`](api/core/inject) function.
Every time the DI system instantiates a class, it does so in an injection context. This is handled by the framework itself. The constructor of the class is executed in that runtime context, which also allows injection of a token using the [`inject`](api/core/inject) function.
<docs-code language="typescript" highlight="[[3],[6]]">
class MyComponent {
@@ -30,7 +30,7 @@ class MyComponent {
## Stack frame in context
Some APIs are designed to be run in an injection context. This is the case, for example, of the router guards. It allows the use of [`inject`](api/core/inject) to access a service within the guard function.
Some APIs are designed to be run in an injection context. This is the case, for example, with router guards. This allows the use of [`inject`](api/core/inject) within the guard function to access a service.
Here is an example for `CanActivateFn`
@@ -43,8 +43,8 @@ const canActivateTeam: CanActivateFn =
## Run within an injection context
When you want to run a given function in an injection context without being in one, you can do it with `runInInjectionContext`.
This requires to have access to a given injector like the `EnvironmentInjector` for example.
When you want to run a given function in an injection context without already being in one, you can do so with `runInInjectionContext`.
This requires access to a given injector, like the `EnvironmentInjector`, for example:
<docs-code header="src/app/heroes/hero.service.ts" language="typescript"
highlight="[9]">
@@ -66,7 +66,7 @@ Note that `inject` will return an instance only if the injector can resolve the
## Asserts the context
Angular provides `assertInInjectionContext` helper function to assert that the current context is an injection context.
Angular provides the `assertInInjectionContext` helper function to assert that the current context is an injection context.
## Using DI outside of a context
@@ -4,13 +4,13 @@ Dependency injection, or DI, is one of the fundamental concepts in Angular. DI i
Two main roles exist in the DI system: dependency consumer and dependency provider.
Angular facilitates the interaction between dependency consumers and dependency providers using an abstraction called `Injector`. When a dependency is requested, the injector checks its registry to see if there is an instance already available there. If not, a new instance is created and stored in the registry. Angular creates an application-wide injector (also known as "root" injector) during the application bootstrap process. In most cases you don't need to manually create injectors, but you should know that there is a layer that connects providers and consumers.
Angular facilitates the interaction between dependency consumers and dependency providers using an abstraction called `Injector`. When a dependency is requested, the injector checks its registry to see if there is an instance already available there. If not, a new instance is created and stored in the registry. Angular creates an application-wide injector (also known as the "root" injector) during the application bootstrap process. In most cases you don't need to manually create injectors, but you should know that there is a layer that connects providers and consumers.
This topic covers basic scenarios of how a class can act as a dependency. Angular also allows you to use functions, objects, primitive types such as string or Boolean, or any other types as dependencies. For more information, see [Dependency providers](/guide/di/dependency-injection-providers).
## Providing dependency
## Providing a dependency
Consider there is a class called `HeroService` that needs to act as a dependency in a component.
Consider a class called `HeroService` that needs to act as a dependency in a component.
The first step is to add the `@Injectable` decorator to show that the class can be injected.
@@ -24,7 +24,7 @@ A dependency can be provided in multiple places:
* [**Preferred**: At the application root level using `providedIn`.](#preferred-at-the-application-root-level-using-providedin)
* [At the Component level.](#at-the-component-level)
* [At application root level using `ApplicationConfig`.](#at-application-root-level-using-applicationconfig)
* [At the application root level using `ApplicationConfig`.](#at-the-application-root-level-using-applicationconfig)
* [`NgModule` based applications.](#ngmodule-based-applications)
### **Preferred**: At the application root level using `providedIn`
@@ -64,11 +64,11 @@ When you register a provider at the component level, you get a new instance of t
Note: Declaring a service like this causes `HeroService` to always be included in your application— even if the service is unused.
### At application root level using `ApplicationConfig`
### At the application root level using `ApplicationConfig`
You can use the `providers` field of the `ApplicationConfig` (passed to the `bootstrapApplication` function) to provide a service or other `Injectable` at the application level.
In the example below, the `HeroService` is available to all components, directives, and pipes.
In the example below, the `HeroService` is available to all components, directives, and pipes:
<docs-code language="typescript" highlight="[3]">
export const appConfig: ApplicationConfig = {
@@ -136,5 +136,5 @@ style componentConstructor text-align: left
## What's next
<docs-pill-row>
<docs-pill href="/guide/di/creating-injectable-service" title="Creating and injecting services"/>
<docs-pill href="/guide/di/creating-injectable-service" title="Creating an injectable service"/>
</docs-pill-row>
+7 -8
View File
@@ -5,7 +5,7 @@ This guide explores additional features of dependency injection in Angular.
## Custom providers with `@Inject`
Using a custom provider allows you to provide a concrete implementation for implicit dependencies, such as built-in browser APIs.
The following example uses an `InjectionToken` to provide the [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) browser API as a dependency in the `BrowserStorageService`.
The following example uses an `InjectionToken` to provide the [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) browser API as a dependency in the `BrowserStorageService`:
<docs-code header="src/app/storage.service.ts" language="typescript"
highlight="[[3,6],[12]]">
@@ -32,8 +32,8 @@ export class BrowserStorageService {
}
</docs-code>
The `factory` function returns the `localStorage` property that is attached to the browser window object.
The `Inject` decorator is a constructor parameter used to specify a custom provider of a dependency.
The `factory` function returns the `localStorage` property that is attached to the browser's window object.
The `Inject` decorator is applied to the `storage` constructor parameter and specifies a custom provider of the dependency.
This custom provider can now be overridden during testing with a mock API of `localStorage` instead of interacting with real browser APIs.
@@ -42,7 +42,7 @@ This custom provider can now be overridden during testing with a mock API of `lo
Although developers strive to avoid it, some visual effects and third-party tools require direct DOM access.
As a result, you might need to access a component's DOM element.
Angular exposes the underlying element of a `@Component` or `@Directive` via injection using the `ElementRef` injection token.
Angular exposes the underlying element of a `@Component` or `@Directive` via injection using the `ElementRef` injection token:
<docs-code language="typescript" highlight="[7]">
import { Directive, ElementRef } from '@angular/core';
@@ -66,14 +66,13 @@ You can't refer directly to a class until it's been defined.
This isn't usually a problem, especially if you adhere to the recommended *one class per file* rule.
But sometimes circular references are unavoidable.
For example, when class 'A' refers to class 'B' and 'B' refers to 'A'.
One of them has to be defined first.
For example, when class 'A' refers to class 'B' and 'B' refers to 'A', one of them has to be defined first.
The Angular `forwardRef()` function creates an *indirect* reference that Angular can resolve later.
You face a similar problem when a class makes *a reference to itself*.
For example in its `providers` array.
The `providers` array is a property of the `@Component()` decorator function which must appear before the class definition.
For example, in its `providers` array.
The `providers` array is a property of the `@Component()` decorator function, which must appear before the class definition.
You can break such circular references by using `forwardRef`.
<docs-code header="app.component.ts" language="typescript" highlight="[4]">
@@ -338,8 +338,8 @@ The following is an example of how the `<app-root>` and `<app-child>` view trees
…content goes here…
</#VIEW>
</app-child>
<#VIEW>
<app-root>
</#VIEW>
</app-root>
</docs-code>
Understanding the idea of the `<#VIEW>` demarcation is especially significant when you configure services in the component class.
@@ -195,33 +195,3 @@ providers.
If a component or directive with `hostDirectives` and those host directives both provide the same
injection token, the providers defined by class with `hostDirectives` take precedence over providers
defined by the host directives.
### Performance
While the directive composition API offers a powerful tool for reusing common behaviors, excessive
use of host directives can impact your application's memory use. If you create components or
directives that use *many* host directives, you may inadvertently balloon the memory used by your
application.
The following example shows a component that applies several host directives.
```typescript
@Component({
standalone: true,
hostDirectives: [
DisabledState,
RequiredState,
ValidationState,
ColorState,
RippleBehavior,
],
})
export class CustomCheckbox { }
```
This example declares a custom checkbox component that includes five host directives. This
means that Angular will create six objects each time a `CustomCheckbox` renders— one for the
component and one for each host directive. For a few checkboxes on a page, this won't pose any
significant issues. However, if your page renders *hundreds* of checkboxes, such as in a table, then
you could start to see an impact of the additional object allocations. Always be sure to profile
your application to determine the right composition pattern for your use case.
+3 -1
View File
@@ -8,12 +8,13 @@ At the end, tests can verify that the app made no unexpected requests.
## Setup for testing
To begin testing usage of `HttpClient`, configure `TestBed` and include `provideHttpClientTesting` in your test's setup. This configures `HttpClient` to use a test backend instead of the real network. It also provides `HttpTestingController`, which you'll use to interact with the test backend, set expectations about which requests have been made, and flush responses to those requests. `HttpTestingController` can be injected from `TestBed` once configured.
To begin testing usage of `HttpClient`, configure `TestBed` and include `provideHttpClient()` and `provideHttpClientTesting` in your test's setup. This configures `HttpClient` to use a test backend instead of the real network. It also provides `HttpTestingController`, which you'll use to interact with the test backend, set expectations about which requests have been made, and flush responses to those requests. `HttpTestingController` can be injected from `TestBed` once configured.
<docs-code language="ts">
TestBed.configureTestingModule({
providers: [
// ... other test providers
provideHttpClient(),
provideHttpClientTesting(),
],
});
@@ -31,6 +32,7 @@ For example, you can write a test that expects a GET request to occur and provid
TestBed.configureTestingModule({
providers: [
ConfigService,
provideHttpClient(),
provideHttpClientTesting(),
],
});
+8 -8
View File
@@ -118,17 +118,17 @@ IMPORTANT: For the "fill" image to render properly, its parent element **must**
NgOptimizedImage can display an automatic low-resolution placeholder for your image if you're using a CDN or image host that provides automatic image resizing. Take advantage of this feature by adding the `placeholder` attribute to your image:
<code-example format="typescript" language="typescript">
<docs-code format="typescript" language="typescript">
<img ngSrc="cat.jpg" width="400" height="200" placeholder>
</code-example>
</docs-code>
Adding this attribute automatically requests a second, smaller version of the image using your specified image loader. This small image will be applied as a `background-image` style with a CSS blur while your image loads. If no image loader is provided, no placeholder image can be generated and an error will be thrown.
The default size for generated placeholders is 30px wide. You can change this size by specifying a pixel value in the `IMAGE_CONFIG` provider, as seen below:
<code-example format="typescript" language="typescript">
<docs-code format="typescript" language="typescript">
providers: [
{
provide: IMAGE_CONFIG,
@@ -137,7 +137,7 @@ providers: [
}
},
],
</code-example>
</docs-code>
If you want sharp edges around your blurred placeholder, you can wrap your image in a containing `<div>` with the `overflow: hidden` style. As long as the `<div>` is the same size as the image (such as by using the `width: fit-content` style), the "fuzzy edges" of the placeholder will be hidden.
@@ -145,11 +145,11 @@ If you want sharp edges around your blurred placeholder, you can wrap your image
You can also specify a placeholder using a base64 [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs) without an image loader. The data url format is `data:image/[imagetype];[data]`, where `[imagetype]` is the image format, just as `png`, and `[data]` is a base64 encoding of the image. That encoding can be done using the command line or in JavaScript. For specific commands, see [the MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs#encoding_data_into_base64_format). An example of a data URL placeholder with truncated data is shown below:
<code-example format="typescript" language="typescript">
<docs-code format="typescript" language="typescript">
<img ngSrc="cat.jpg" width="400" height="200" placeholder="data:image/png;base64,iVBORw0K...">
</code-example>
</docs-code>
However, large data URLs increase the size of your Angular bundles and slow down page load. If you cannot use an image loader, the Angular team recommends keeping base64 placeholder images smaller than 4KB and using them exclusively on critical images. In addition to decreasing placeholder dimensions, consider changing image formats or parameters used when saving images. At very low resolutions, these parameters can have a large effect on file size.
@@ -157,11 +157,11 @@ However, large data URLs increase the size of your Angular bundles and slow dow
By default, NgOptimizedImage applies a CSS blur effect to image placeholders. To render a placeholder without blur, provide a `placeholderConfig` argument with an object that includes the `blur` property, set to false. For example:
<code-example format="typescript" language="typescript">
<docs-code format="typescript" language="typescript">
<img ngSrc="cat.jpg" width="400" height="200" placeholder [placeholderConfig]="{blur: false}">
</code-example>
</docs-code>
## Adjusting image styling
@@ -168,12 +168,6 @@ set id(heroId: string) {
```
NOTE: You can bind all route data with key, value pairs to component inputs: static or resolved route data, path parameters, matrix parameters, and query parameters.
If you want to use the parent components route info you will need to set the router paramsInheritanceStrategy option: withRouterConfig({paramsInheritanceStrategy: 'always'})
</docs-step>
Note: You can bind all route data with key, value pairs to component inputs: static or resolved route data, path parameters, matrix parameters, and query parameters.
If you want to use the parent components route info you will need to set the router `paramsInheritanceStrategy` option:
`withRouterConfig({paramsInheritanceStrategy: 'always'})`
@@ -170,7 +170,7 @@ These events are shown in the following table.
| [`ChildActivationEnd`](api/router/ChildActivationEnd) | Triggered when the Router finishes activating a route's children. |
| [`ActivationEnd`](api/router/ActivationEnd) | Triggered when the Router finishes activating a route. |
| [`NavigationEnd`](api/router/NavigationEnd) | Triggered when navigation ends successfully. |
| [`NavigationCancel`](api/router/NavigationCancel) | Triggered when navigation is canceled. This can happen when a Route Guard returns false during navigation, or redirects by returning a `UrlTree` or `RedirectCommand`. |
| [`NavigationCancel`](api/router/NavigationCancel) | Triggered when navigation is canceled. This can happen when a Route Guard returns false during navigation, or redirects by returning a `UrlTree`. |
| [`NavigationError`](api/router/NavigationError) | Triggered when navigation fails due to an unexpected error. |
| [`Scroll`](api/router/Scroll) | Represents a scrolling event. |
+1 -1
View File
@@ -63,7 +63,7 @@ Angular defines the following security contexts:
| URL | Used for URL properties, such as `<a href>`. |
| Resource URL | A URL that is loaded and executed as code, for example, in `<script src>`. |
Angular sanitizes untrusted values for HTML, styles, and URLs. Sanitizing resource URLs isn't possible because they contain arbitrary code.
Angular sanitizes untrusted values for HTML and URLs. Sanitizing resource URLs isn't possible because they contain arbitrary code.
In development mode, Angular prints a console warning when it has to change a value during sanitization.
### Sanitization example
+26 -4
View File
@@ -28,10 +28,6 @@ Like the `async` pipe, `toSignal` subscribes to the Observable immediately, whic
IMPORTANT: `toSignal` creates a subscription. You should avoid calling it repeatedly for the same Observable, and instead reuse the signal it returns.
### Injection context
`toSignal` by default needs to run in an [injection context](guide/di/dependency-injection-context), such as during construction of a component or service. If an injection context is not available, you can manually specify the `Injector` to use instead.
### Initial values
Observables may not produce a value synchronously on subscription, but signals always require a current value. There are several ways to deal with this "initial" value of `toSignal` signals.
@@ -102,3 +98,29 @@ mySignal.set(3);
```
Here, only the last value (3) will be logged.
### `outputFromObservable`
`outputFromObservable(...)` declares an Angular output that emits values based on an RxJS observable.
```ts
class MyDir {
nameChange$ = new Observable<string>(/* ... */);
nameChange = outputFromObservable(this.nameChange$); // OutputRef<string>
}
```
See more details in the [output() API guide](/guide/output-function).
### `outputToObservable`
`outputToObservable(...)` converts an Angular output to an observable.
This allows you use integrate Angular outputs conveniently into RxJS streams.
```ts
outputToObservable(myComp.instance.onNameChange)
.pipe(...)
.subscribe(...)
```
See more details in the [output() API guide](/guide/output-function).
@@ -8,7 +8,7 @@ To create a single class binding, type the following:
`[class.sale]="onSale"`
Angular adds the class when the bound expression, `onSale` is truthy, and it removes the class when the expression is falsy—with the exception of `undefined`.
Angular adds the class when the bound expression, `onSale` is truthy, and it removes the class when the expression is falsy—with the exception of `undefined`. The behavior of `undefined` is specifically useful when multiple bindings to the same class exist across different directives on an element.
## Binding to multiple CSS classes
@@ -31,7 +31,7 @@ If the target event name, `myClick` fails to match an output property of `ClickD
## Binding to keyboard events
You can bind to keyboard events using Angular's binding syntax. You can specify the key or code that you would like to bind to keyboard events. They `key` and `code` fields are a native part of the browser keyboard event object. By default, event binding assumes you want to use the `key` field on the keyboard event. You can also use the `code` field.
You can bind to keyboard events using Angular's binding syntax. You can specify the key or code that you would like to bind to keyboard events. The `key` and `code` fields are a native part of the browser keyboard event object. By default, event binding assumes you want to use the `key` field on the keyboard event. You can also use the `code` field.
Combinations of keys can be separated by a `.` (period). For example, `keydown.enter` will allow you to bind events to the `enter` key. You can also use modifier keys, such as `shift`, `alt`, `control`, and the `command` keys from Mac. The following example shows how to bind a keyboard event to `keydown.shift.t`.
@@ -126,7 +126,7 @@ Please call "TestBed.compileComponents" before your test.
You get this test failure message when the runtime environment compiles the source code *during the tests themselves*.
To correct the problem, call `compileComponents()` as explained in the following [Calling compileComponents](#compile-components) section.
To correct the problem, call `compileComponents()` as explained in the following [Calling compileComponents](#calling-compilecomponents) section.
## Component with a dependency
@@ -1015,7 +1015,7 @@ One approach is to configure the testing module from the individual pieces as in
HELPFUL: Notice that the `beforeEach()` is asynchronous and calls `TestBed.compileComponents` because the `HeroDetailComponent` has an external template and css file.
As explained in [Calling `compileComponents()`](#compile-components), these tests could be run in a non-CLI environment where Angular would have to compile them in the browser.
As explained in [Calling `compileComponents()`](#calling-compilecomponents), these tests could be run in a non-CLI environment where Angular would have to compile them in the browser.
### Import a shared module
@@ -60,7 +60,7 @@ Here are the most important static methods, in order of likely utility.
| Methods | Details |
|:--- |:--- |
| `configureTestingModule` | The testing shims \(`karma-test-shim`, `browser-test-shim`\) establish the [initial test environment](guide/testing) and a default testing module. The default testing module is configured with basic declaratives and some Angular service substitutes that every tester needs. <br /> Call `configureTestingModule` to refine the testing module configuration for a particular set of tests by adding and removing imports, declarations \(of components, directives, and pipes\), and providers. |
| `compileComponents` | Compile the testing module asynchronously after you've finished configuring it. You **must** call this method if *any* of the testing module components have a `templateUrl` or `styleUrls` because fetching component template and style files is necessarily asynchronous. See [compileComponents](guide/testing/components-scenarios#compile-components). <br /> After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec. |
| `compileComponents` | Compile the testing module asynchronously after you've finished configuring it. You **must** call this method if *any* of the testing module components have a `templateUrl` or `styleUrls` because fetching component template and style files is necessarily asynchronous. See [compileComponents](guide/testing/components-scenarios#calling-compilecomponents). <br /> After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec. |
| `createComponent<T>` | Create an instance of a component of type `T` based on the current `TestBed` configuration. After calling `createComponent`, the `TestBed` configuration is frozen for the duration of the current spec. |
| `overrideModule` | Replace metadata for the given `NgModule`. Recall that modules can import other modules. The `overrideModule` method can reach deeply into the current testing module to modify one of these inner modules. |
| `overrideComponent` | Replace metadata for the given component class, which could be nested deeply within an inner module. |
@@ -2,7 +2,7 @@
Handle user interaction in your application.
</docs-decorative-header>
One of the key aspects of making applications dynamic is the ability to handle user interaction. In this guide, we'll take a look at two primary categories of user interaction: event handling and forms.
The ability to handle user interaction and then work with - it is one of the key aspects of building dynamic applications. In this guide, we'll take a look at simple user interaction - event handling.
## Event Handling
@@ -25,8 +25,7 @@ system" href="guide/components" link="Get started with Components">
testable.
</docs-card>
<docs-card title="Get fast state updates with fine-grained reactivity based on Signals" href="guide/signals" link="Explore Angular Signals">
Our fine-grained reactivity model, combined with compile-time optimizations, simplify development,
and helps build faster apps by default.
Our fine-grained reactivity model, combined with compile-time optimizations, simplifies development and helps build faster apps by default.
Granularly track how and where state is used throughout an application, giving the framework the power to render fast updates via highly optimized instructions.
</docs-card>
@@ -81,7 +80,7 @@ more">
<docs-card title="Clear support policies and predictable release schedule" href="reference/releases" link="Versioning & releasing">
Angular's predictable, time-based release schedule gives your organization confidence in the
stability and backwards compatibility of the framework. Long Term Support (LTS) windows make sure
you get critical security fixes when you need them. First party update tools, guides and automated
you get critical security fixes when you need them. First-party update tools, guides and automated
migration schematics help keep your apps up-to-date with the latest advancements to the framework
and the web platform.
</docs-card>
@@ -91,7 +90,7 @@ more">
<docs-card-container>
<docs-card title="Reach users everywhere with internationalization support" href="guide/i18n" link="Internationalization">
Angular's internationalization features handles message translations and formatting, including
Angular's internationalization features handle message translations and formatting, including
support for unicode standard ICU syntax.
</docs-card>
<docs-card title="Protect your users with security by default" href="guide/security" link="Security">
@@ -125,20 +124,20 @@ more">
<docs-card-container>
<docs-card title="Courses, blogs and resources" href="https://devlibrary.withgoogle.com/products/angular?sort=added" link="Check out DevLibrary">
Our community is composed of talented developers, writers, instructors, podcasters and more. The Google for Developers library is just a sample of the high quality resources available for new and experienced developers to continue developing.
Our community is composed of talented developers, writers, instructors, podcasters, and more. The Google for Developers library is just a sample of the high quality resources available for new and experienced developers to continue developing.
</docs-card>
<docs-card title="Open Source" href="https://github.com/angular/angular/blob/main/CONTRIBUTING.md" link="Contribute to Angular">
We are thankful for the open source contributors who make Angular a better framework for everyone. From fixing a typo in the docs, to adding major features, we encourage anyone interested to get started on our GitHub.
</docs-card>
<docs-card title="Community partnerships" href="https://developers.google.com/community/experts/directory?specialization=angular" link="Meet the Angular GDEs">
Our team partners with individuals, educators and enterprises to ensure we consistently are supporting developers. Angular Google Developer Experts (GDEs) represent community leaders around the world educating, organizing and developing with Angular. Enterprise partnerships help ensure that Angular scales well for technology industry leaders.
Our team partners with individuals, educators, and enterprises to ensure we consistently are supporting developers. Angular Google Developer Experts (GDEs) represent community leaders around the world educating, organizing, and developing with Angular. Enterprise partnerships help ensure that Angular scales well for technology industry leaders.
</docs-card>
<docs-card title="Partnering with other Google technologies">
Angular partners closely with other Google technologies and teams to improve the web.
Our ongoing partnership with Chrome’s Aurora actively explores improvements to user experience across the web developing built-in performance optimizations like NgOptimizedImage and improvements to Angular’s Core Web Vitals.
Our ongoing partnership with Chrome’s Aurora actively explores improvements to user experience across the web, developing built-in performance optimizations like NgOptimizedImage and improvements to Angular’s Core Web Vitals.
We are also working with [Firebase](https://firebase.google.com/), [Tensorflow](https://www.tensorflow.org/), [Flutter](https://flutter.dev/), [Material Design](https://m3.material.io/) and [Google Cloud](https://cloud.google.com/) to ensure we provide meaningful integrations across the developer workflow.
We are also working with [Firebase](https://firebase.google.com/), [Tensorflow](https://www.tensorflow.org/), [Flutter](https://flutter.dev/), [Material Design](https://m3.material.io/), and [Google Cloud](https://cloud.google.com/) to ensure we provide meaningful integrations across the developer workflow.
</docs-card>
</docs-card-container>
@@ -27,15 +27,15 @@ For a complete list of Angular packages, see the [API reference](api).
| Package name | Details |
|:--- |:--- |
| [`@angular/animations`](api/animations) | Angular's animations library makes it easy to define and apply animation effects such as page and list transitions. For more information, see the [Animations guide](guide/animations). |
| [`@angular/common`](api/common) | The commonly-needed services, pipes, and directives provided by the Angular team. |
| [`@angular/animations`](api#animations) | Angular's animations library makes it easy to define and apply animation effects such as page and list transitions. For more information, see the [Animations guide](guide/animations). |
| [`@angular/common`](api#common) | The commonly-needed services, pipes, and directives provided by the Angular team. |
| `@angular/compiler` | Angular's template compiler. It understands Angular templates and can convert them to code that makes the application run. |
| `@angular/compiler-cli` | Angular's compiler which is invoked by the Angular CLI's `ng build` and `ng serve` commands. It processes Angular templates with `@angular/compiler` inside a standard TypeScript compilation. |
| [`@angular/core`](api/core) | Critical runtime parts of the framework that are needed by every application. Includes all metadata decorators such as `@Component`, dependency injection, and component lifecycle hooks. |
| [`@angular/forms`](api/forms) | Support for both [template-driven](guide/forms) and [reactive forms](guide/forms/reactive-forms). See [Introduction to forms](guide/forms). |
| [`@angular/platform-browser`](api/platform-browser) | Everything DOM and browser related, especially the pieces that help render into the DOM. |
| [`@angular/platform-browser-dynamic`](api/platform-browser-dynamic) | Includes [providers](api/core/Provider) and methods to compile and run the application on the client using the [JIT compiler](tools/cli/aot-compiler#choosing-a-compiler). |
| [`@angular/router`](api/router) | The router module navigates among your application pages when the browser URL changes. For more information, see [Routing and Navigation](guide/routing). |
| [`@angular/core`](api#core) | Critical runtime parts of the framework that are needed by every application. Includes all metadata decorators such as `@Component`, dependency injection, and component lifecycle hooks. |
| [`@angular/forms`](api#forms) | Support for both [template-driven](guide/forms) and [reactive forms](guide/forms/reactive-forms). See [Introduction to forms](guide/forms). |
| [`@angular/platform-browser`](api#platform-browser) | Everything DOM and browser related, especially the pieces that help render into the DOM. |
| [`@angular/platform-browser-dynamic`](api#platform-browser-dynamic) | Includes [providers](api/core/Provider) and methods to compile and run the application on the client using the [JIT compiler](tools/cli/aot-compiler#choosing-a-compiler). |
| [`@angular/router`](api#router) | The router module navigates among your application pages when the browser URL changes. For more information, see [Routing and Navigation](guide/routing). |
| [`@angular/cli`](https://github.com/angular/angular-cli) | Contains the Angular CLI binary for running `ng` commands. |
| [`@angular-devkit/build-angular`](https://github.com/angular/angular-cli) | Contains default CLI builders for bundling, testing, and serving Angular applications and libraries. |
| `rxjs` | A library for reactive programming using `Observables`. |
@@ -27,7 +27,7 @@
| `NG01203` | [Missing value accessor](errors/NG01203) |
| `NG02200` | [Missing Iterable Differ](errors/NG02200) |
| `NG02800` | [JSONP support in HttpClient configuration](errors/NG02800) |
| `NG5000` | [Hydration with unsupported Zone.js instance.](errors/NG5000) |
| `NG05000` | [Hydration with unsupported Zone.js instance.](errors/NG5000) |
| `NG05104` | [Root element was not found.](errors/NG05104) |
## Compiler errors
@@ -3,7 +3,7 @@
[Control flow syntax](guide/templates/control-flow) is available from Angular 17 and simplified way to use the control-flow directives like *ngFor, *ngIf and *ngSwitch.
The new syntax is baked into the template, so you don't need to import `CommonModule` anymore. But wait there is more to it, there is an migration available for migrating all your old code to use new Control Flow Syntax with Angular 17 release. Run the schematic with the following command:
The new syntax is baked into the template, so you don't need to import `CommonModule` anymore. But wait there is more to it, there is an migration availble for migrating all your old code to use new Control Flow Syntax with Angular 17 release. Run the schematic with the following command:
<docs-code language="shell">
+4 -1
View File
@@ -46,7 +46,10 @@ In this example, we’ve adapted the shield to create an Angular Signals logo va
![Angular Signals logo](assets/images/press-kit/angular_signals.png#medium "Angular Signals logo")
</docs-step>
<docs-step title="Do’s and don’ts of adapting the brand">
<docs-step title="Do’s and don’ts of using Angular's brand">
If you are creating your own logo, we encourage differentiating your logo from ours to not cause confusion. When adapting the logo, you are free to change and adapt the colors and shape to make it your own.
When representing Angular with the original logo, please follow these guidelines:
![Rhubarb the small cat](assets/images/press-kit/do_and_dont.png "Rhubarb the small cat")
</docs-step>
+1 -1
View File
@@ -22,7 +22,7 @@ Start developing with the latest Angular features from our roadmap. This list re
| [Explore Angular Signals](guide/signals) | [Migrate your Angular Material to MDC](https://material.angular.io/guide/mdc-migration) |
| [Learn about Hydration](guide/hydration) | [Migrate to Standalone APIs](reference/migrations/standalone) |
| [Deferrable views](https://github.com/angular/angular/discussions/50716) | [Improve image performance with NgOptimizedImage](guide/image-optimization) |
| [Built-in control flow](https://github.com/angular/angular/discussions/50719) | [Try out Inject](tutorials/learn-angular/inject-based-di) |
| [Built-in control flow](https://github.com/angular/angular/discussions/50719) | [Try out Inject](/tutorials/learn-angular/20-inject-based-di) |
| | [New CDK directives](https://material.angular.io/cdk/categories) |
## Improving the Angular developer experience
File diff suppressed because it is too large Load Diff
@@ -30,7 +30,7 @@ In the code editor:
When adding a property binding to a component tag, we use the `[attribute] = "value"` syntax to notify Angular that the assigned value should be treated as a property from the component class and not a string value.
The value on the right handside is the name of the property from the `HomeComponent`.
The value on the right-hand side is the name of the property from the `HomeComponent`.
</docs-step>
<docs-step title="Confirm the code still works">
@@ -196,6 +196,8 @@ The server is now reading data from the HTTP request but the components that rel
</docs-workflow>
Note: This lesson relies on the `fetch` browser API. For the support of interceptors, please refer to the [Http Client documentation](/guide/http)
Summary: In this lesson, you updated your app to use a local web server (`json-server`), and use asynchronous service methods to retrieve data.
Congratulations! You've successfully completed this tutorial and are ready to continue your journey with building even more complex Angular Apps.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -23,12 +23,14 @@ export class AppComponent {}
<docs-step title="Add validation to form">
Every `FormControl` can be passed the `Validators` you want to use for validating the `FormControl` values. For example, if you want to make the fields for the `profileForm` required then use `Validators.required`. Update the `name` and `email` `FormControl` to be required:
Every `FormControl` can be passed the `Validators` you want to use for validating the `FormControl` values. For example, if you want to make the `name` field in `profileForm` required then use `Validators.required`.
For the `email` field in our Angular form, we want to ensure it's not left empty and follows a valid email address structure. We can achieve this by combining the `Validators.required` and `Validators.email` validators in an array.
Update the `name` and `email` `FormControl`:
```ts
profileForm = new FormGroup({
name: new FormControl('', Validators.required),
email: new FormControl('', Validators.required),
email: new FormControl('', [Validators.required, Validators.email]),
});
```
@@ -7,7 +7,7 @@ import {ReactiveFormsModule} from '@angular/forms';
template: `
<form [formGroup]="profileForm">
<input type="text" formControlName="name" name="name" />
<input type="email" formControlName="email" name="password" />
<input type="email" formControlName="email" name="email" />
<button type="submit">Submit</button>
</form>
`,
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -9,10 +9,12 @@
const THEME_PREFERENCE_LOCAL_STORAGE_KEY = 'themePreference';
const DARK_MODE_CLASS_NAME = 'docs-dark-mode';
const LIGHT_MODE_CLASS_NAME = 'docs-light-mode';
const PREFERS_COLOR_SCHEME_DARK = '(prefers-color-scheme: dark)';
const theme = localStorage.getItem(THEME_PREFERENCE_LOCAL_STORAGE_KEY) ?? 'auto';
const prefersDark =
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
window.matchMedia && window.matchMedia(PREFERS_COLOR_SCHEME_DARK).matches;
const documentClassList = this.document.documentElement.classList;
// clearing classes before setting them.
-3
View File
@@ -6,9 +6,6 @@
* found in the LICENSE file at https://angular.dev/license
*/
// TODO(josephperrott): Figure out why this is needed now.
import '@angular/compiler';
import {bootstrapApplication} from '@angular/platform-browser';
import {appConfig} from './app/app.config';
import {AppComponent} from './app/app.component';
View File
@@ -0,0 +1,55 @@
"""Rule for filtering external NPM dependency targets to not include
transitive dependencies onto first-party linked `HEAD` dependencies."""
load("@build_bazel_rules_nodejs//:providers.bzl", "ExternalNpmPackageInfo", "LinkablePackageInfo")
def _filter_external_npm_deps_impl(ctx):
problematic_paths = ["external/npm/node_modules/%s" % pkg for pkg in ctx.attr.angular_packages]
package_name = ctx.attr.target.label.package
has_problematic_transitive_dep = package_name.startswith("@angular-devkit/")
filtered_deps = []
# Note: to_list() is expensive; we need to invoke it here to get the path
# of each transitive dependency to check if it's an angular npm package.
for file in ctx.attr.target[DefaultInfo].default_runfiles.files.to_list():
if not any([file.path.startswith(path) for path in problematic_paths]):
filtered_deps.append(file)
else:
has_problematic_transitive_dep = True
filtered_depset = depset(filtered_deps)
providers = [
DefaultInfo(files = filtered_depset),
]
# Re-route all problematic direct dependency external NPM packages into `adev/node_modules`
# without their transitive packages. This allows transitive dependency resolution to first look for
# e.g. `@angular/core` in `adev/node_modules`, and falls back to top-level node modules.
# Note: This does not handle cases where Angular dependencies are transitive in deeper layers.
# This is something to be addressed separately via https://github.com/angular/angular/issues/54858.
if has_problematic_transitive_dep and ctx.attr.target.label.workspace_name == "npm":
providers.append(LinkablePackageInfo(
package_name = package_name,
package_path = "adev",
path = "external/npm/node_modules/%s" % package_name,
files = ctx.attr.target[ExternalNpmPackageInfo].direct_sources,
))
return providers
filter_external_npm_deps = rule(
doc = "Filter out transitive angular dependencies from a target",
implementation = _filter_external_npm_deps_impl,
attrs = {
"angular_packages": attr.string_list(
mandatory = True,
doc = "Angular packages to filter (useful for sandbox environments without linker)",
),
"target": attr.label(
mandatory = True,
doc = "Target to filter",
providers = [ExternalNpmPackageInfo],
),
},
)
+84
View File
@@ -0,0 +1,84 @@
load("//:packages.bzl", "ALL_PACKAGES", "to_package_label")
load("@build_bazel_rules_nodejs//internal/linker:npm_link.bzl", "npm_link")
load("//adev/tools/local_deps:filter_external_npm_deps.bzl", "filter_external_npm_deps")
def ensure_local_package_deps(deps):
"""Replaces dependencies with their local-linked variants."""
return [":%s" % _filtered_transitives_name(dep) for dep in deps]
def link_local_packages(all_deps):
"""Create targets needed for building adev against local angular packages.
Creates targets that link Angular packages, as well as targets to be used
in place of any deps required to build and test adev. These targets filter
out any transitive deps on the npm packages and must be used in place of
any original list of deps.
Use the helper `ensure_local_package_deps()` to translate a list of deps
to the equivalent "filtered" target that this rule creates.
Args:
all_deps: label list of all deps required to build and test adev
"""
local_angular_deps = [dep for dep in all_deps if _is_angular_dep(dep)]
local_angular_package_names = [_angular_dep_to_pkg_name(dep) for dep in local_angular_deps]
# Link local angular packages in place of their npm equivalent
for dep in local_angular_deps:
pkg_name = _angular_dep_to_pkg_name(dep)
npm_link(
name = _npm_link_name(pkg_name),
target = to_package_label(pkg_name),
package_name = pkg_name,
package_path = native.package_name(),
tags = ["manual"],
)
# Special case deps that must be testonly
testonly_deps = [
"@npm//@angular/build-tooling/bazel/browsers/chromium",
]
# Stamp a corresponding target for each dep that filters out transitive
# dependencies on external npm packages. This help the rules_nodejs linker,
# which fails to link local packages into transitive dependencies of npm deps.
for dep in all_deps:
target = dep
if dep in local_angular_deps:
pkg_name = _angular_dep_to_pkg_name(dep)
# We don't need to filter transitives on local packages as they
# depend on each other locally.
native.alias(
name = _filtered_transitives_name(dep),
actual = ":%s" % _npm_link_name(pkg_name),
tags = ["manual"],
)
else:
filter_external_npm_deps(
name = _filtered_transitives_name(dep),
target = target,
testonly = True if dep in testonly_deps else False,
angular_packages = local_angular_package_names,
tags = ["manual"],
)
def _is_angular_dep(dep):
"""Check if a dep , e.g., @npm//@angular/core corresonds to a local Angular pacakge."""
return dep.startswith("@npm//") and (_angular_dep_to_pkg_name(dep) in ALL_PACKAGES)
def _angular_dep_to_pkg_name(dep):
"""E.g., @npm//@angular/core => '@angular/core'"""
label = Label(dep)
return label.package
def _npm_link_name(pkg_name):
return "local_head_%s" % pkg_name.replace("@", "_").replace("/", "_")
def _filtered_transitives_name(dep):
if dep.startswith(":"):
return "%s_without_transitive_deps" % dep[1:]
else:
label = Label(dep)
return "%s_without_transitive_deps" % label.package.replace("@", "_").replace("/", "_")
+4 -9
View File
@@ -37,7 +37,6 @@
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": ["zone.js"],
"ngswConfigPath": "src/generated/ngsw-config.json",
"tsConfig": "tsconfig.app.json",
"webWorkerTsConfig": "tsconfig.worker.json",
"optimization": {
@@ -132,8 +131,7 @@
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.next.ts"
}
],
"serviceWorker": true
]
},
"rc": {
"fileReplacements": [
@@ -141,8 +139,7 @@
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.rc.ts"
}
],
"serviceWorker": true
]
},
"stable": {
"fileReplacements": [
@@ -150,8 +147,7 @@
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.stable.ts"
}
],
"serviceWorker": true
]
},
"archive": {
"fileReplacements": [
@@ -159,8 +155,7 @@
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.archive.ts"
}
],
"serviceWorker": true
]
},
"ci": {
"progress": false
+2 -2
View File
@@ -1,4 +1,4 @@
{
"branchName": "refs/heads/main",
"sha": "76a340c895b3fb124b07aa8a12f78202f5b8ea98"
"branchName": "refs/heads/17.3.x",
"sha": "792fb318cd201df2afed5512e4fdd434e0faf41c"
}
+1 -1
View File
@@ -3,7 +3,7 @@
"command": "ng completion",
"shortDescription": "Set up Angular CLI autocompletion for your terminal.",
"longDescriptionRelativePath": "@angular/cli/src/commands/completion/long-description.md",
"longDescription": "Setting up autocompletion configures your terminal, so pressing the `<TAB>` key while in the middle\nof typing will display various commands and options available to you. This makes it very easy to\ndiscover and use CLI commands without lots of memorization.\n\n![A demo of Angular CLI autocompletion in a terminal. The user types several partial `ng` commands,\nusing autocompletion to finish several arguments and list contextual options.\n](generated/images/guide/cli/completion.gif)\n\n## Automated setup\n\nThe CLI should prompt and ask to set up autocompletion for you the first time you use it (v14+).\nSimply answer \"Yes\" and the CLI will take care of the rest.\n\n```\n$ ng serve\n? Would you like to enable autocompletion? This will set up your terminal so pressing TAB while typing Angular CLI commands will show possible options and autocomplete arguments. (Enabling autocompletion will modify configuration files in your home directory.) Yes\nAppended `source <(ng completion script)` to `/home/my-username/.bashrc`. Restart your terminal or run:\n\nsource <(ng completion script)\n\nto autocomplete `ng` commands.\n\n# Serve output...\n```\n\nIf you already refused the prompt, it won't ask again. But you can run `ng completion` to\ndo the same thing automatically.\n\nThis modifies your terminal environment to load Angular CLI autocompletion, but can't update your\ncurrent terminal session. Either restart it or run `source <(ng completion script)` directly to\nenable autocompletion in your current session.\n\nTest it out by typing `ng ser<TAB>` and it should autocomplete to `ng serve`. Ambiguous arguments\nwill show all possible options and their documentation, such as `ng generate <TAB>`.\n\n## Manual setup\n\nSome users may have highly customized terminal setups, possibly with configuration files checked\ninto source control with an opinionated structure. `ng completion` only ever appends Angular's setup\nto an existing configuration file for your current shell, or creates one if none exists. If you want\nmore control over exactly where this configuration lives, you can manually set it up by having your\nshell run at startup:\n\n```bash\nsource <(ng completion script)\n```\n\nThis is equivalent to what `ng completion` will automatically set up, and gives power users more\nflexibility in their environments when desired.\n\n## Platform support\n\nAngular CLI supports autocompletion for the Bash and Zsh shells on MacOS and Linux operating\nsystems. On Windows, Git Bash and [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/)\nusing Bash or Zsh are supported.\n\n## Global install\n\nAutocompletion works by configuring your terminal to invoke the Angular CLI on startup to load the\nsetup script. This means the terminal must be able to find and execute the Angular CLI, typically\nthrough a global install that places the binary on the user's `$PATH`. If you get\n`command not found: ng`, make sure the CLI is installed globally which you can do with the `-g`\nflag:\n\n```bash\nnpm install -g @angular/cli\n```\n",
"longDescription": "Setting up autocompletion configures your terminal, so pressing the `<TAB>` key while in the middle\nof typing will display various commands and options available to you. This makes it very easy to\ndiscover and use CLI commands without lots of memorization.\n\n![A demo of Angular CLI autocompletion in a terminal. The user types several partial `ng` commands,\nusing autocompletion to finish several arguments and list contextual options.\n](generated/images/guide/cli/completion.gif)\n\n## Automated setup\n\nThe CLI should prompt and ask to set up autocompletion for you the first time you use it (v14+).\nSimply answer \"Yes\" and the CLI will take care of the rest.\n\n```\n$ ng serve\n? Would you like to enable autocompletion? This will set up your terminal so pressing TAB while typing Angular CLI commands will show possible options and autocomplete arguments. (Enabling autocompletion will modify configuration files in your home directory.) Yes\nAppended `source <(ng completion script)` to `/home/my-username/.bashrc`. Restart your terminal or run:\n\nsource <(ng completion script)\n\nto autocomplete `ng` commands.\n\n# Serve output...\n```\n\nIf you already refused the prompt, it won't ask again. But you can run `ng completion` to\ndo the same thing automatically.\n\nThis modifies your terminal environment to load Angular CLI autocompletion, but can't update your\ncurrent terminal session. Either restart it or run `source <(ng completion script)` directly to\nenable autocompletion in your current session.\n\nTest it out by typing `ng ser<TAB>` and it should autocomplete to `ng serve`. Ambiguous arguments\nwill show all possible options and their documentation, such as `ng generate <TAB>`.\n\n## Manual setup\n\nSome users may have highly customized terminal setups, possibly with configuration files checked\ninto source control with an opinionated structure. `ng completion` only ever appends Angular's setup\nto an existing configuration file for your current shell, or creates one if none exists. If you want\nmore control over exactly where this configuration lives, you can manually set it up by having your\nshell run at startup:\n\n```bash\nsource <(ng completion script)\n```\n\nThis is equivalent to what `ng completion` will automatically set up, and gives power users more\nflexibility in their environments when desired.\n\n## Platform support\n\nAngular CLI supports autocompletion for the Bash and Zsh shells on MacOS and Linux operating\nsystems. On Windows, Git Bash and [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/)\nusing Bash or Zsh are supported.\n\n## Global install\n\nAutocompletion works by configuring your terminal to invoke the Angular CLI on startup to load the\nsetup script. This means the terminal must be able to find and execute the Angular CLI, typically\nthrough a global install that places the binary on the user's `$PATH`. If you get\n`command not found: ng`, make sure the CLI is installed globally which you can do with the `-g`\nflag:\n\n```bash\nnpm install -g @angular/cli\n```\n",
"aliases": [],
"deprecated": false,
"options": [
-1
View File
@@ -3,7 +3,6 @@
"command": "ng serve [project]",
"shortDescription": "Builds and serves your application, rebuilding on file changes.",
"aliases": [
"dev",
"s"
],
"deprecated": false,
@@ -1,6 +1,6 @@
/*
* 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-library/example-config.json`.
* 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.mjs` runs
* tests for this project.
+2 -2
View File
@@ -259,7 +259,7 @@ Then, import the file in the initial view of the profiler by clicking the **Choo
### View the injector hierarchy of your application
The **Injector Tree** tab lets you explore the structure of the Injectors configured in your application. Here you will see two trees representing the [injector hierarchy](guide/hierarchical-dependency-injection) of your application. One tree is your environment hierarchy, the other is your element hierarchy.
The **Injector Tree** tab lets you explore the structure of the Injectors configured in your application. Here you will see two trees representing the [injector hiearchy](guide/hierarchical-dependency-injection) of your application. One tree is your environment hierarchy, the other is your element hierachy.
<div class="lightbox">
@@ -269,7 +269,7 @@ The **Injector Tree** tab lets you explore the structure of the Injectors config
### Visualize resolution paths
When a specific injector is selected, the path that Angular's dependency injection algorithm traverses from that injector to the root is highlighted. For element injectors, this includes highlighting the environment injectors that the dependency injection algorithm jumps to when a dependency cannot be resolved in the element hierarchy. See [resolution rules](guide/hierarchical-dependency-injection#resolution-rules) for more details about how Angular resolves resolution paths.
When a specific injector is selected, the path that Angular's depenedency injection algorithm traverses from that injector to the root is highlighted. For element injectors, this includes highlighting the environment injectors that the dependency injection algorithm jumps to when a dependency cannot be resolved in the element hierarchy. See [resolution rules](guide/hierarchical-dependency-injection#resolution-rules) for more details about how Angular resolves resolution paths.
<div class="lightbox">
+1 -1
View File
@@ -41,7 +41,7 @@ If the `application` builder is difficult for your project to adopt, `browser-es
A builder named `browser-esbuild` is available within the `@angular-devkit/build-angular` package that is present in an Angular CLI generated application. The builder is a drop-in replacement for the existing `browser` builder that provides the preexisting browser application build system.
The compatibility option was implemented to minimize the amount of changes necessary to initially migrate your applications.
The compatiblity option was implemented to minimize the amount of changes necessary to initially migrate your applications.
This is provided via an alternate builder (`browser-esbuild`).
You can update the `build` target for any application target to migrate to the new build system.
-4
View File
@@ -33,10 +33,6 @@ export class Ticker {
Like the `async` pipe, `toSignal` subscribes to the Observable immediately, which may trigger side effects. The subscription created by
`toSignal` automatically unsubscribes from the given Observable upon destruction of the component in which `toSignal` is called.
### Injection context
`toSignal` by default needs to run in an [injection context](/guide/dependency-injection-context), such as during construction of a component or service. If an injection context is not available, an `Injector` can instead be explicitly specified.
### Initial values
Observables may not produce a value synchronously on subscription, but signals always require a current value. There are several ways to deal with this "initial" value of `toSignal` signals.
+2 -1
View File
@@ -10,7 +10,8 @@ covers [Angular versions under active support](guide/releases#actively-supported
| Angular | Node.js | TypeScript | RxJS |
| ------------------ | ------------------------------------ | -------------- | ------------------ |
| 17.1.0 | ^18.13.0 \|\| ^20.9.0 | >=5.2.0 <5.4.0 | ^6.5.3 \|\| ^7.4.0 |
| 17.3.x | ^18.13.0 \|\| ^20.9.0 | >=5.2.0 <5.5.0 | ^6.5.3 \|\| ^7.4.0 |
| 17.1.x \|\| 17.2.x | ^18.13.0 \|\| ^20.9.0 | >=5.2.0 <5.4.0 | ^6.5.3 \|\| ^7.4.0 |
| 17.0.x | ^18.13.0 \|\| ^20.9.0 | >=5.2.0 <5.3.0 | ^6.5.3 \|\| ^7.4.0 |
| 16.1.x \|\| 16.2.x | ^16.14.0 \|\| ^18.10.0 | >=4.9.3 <5.2.0 | ^6.5.3 \|\| ^7.4.0 |
| 16.0.x | ^16.14.0 \|\| ^18.10.0 | >=4.9.3 <5.1.0 | ^6.5.3 \|\| ^7.4.0 |
+1 -1
View File
@@ -6,7 +6,7 @@ A few lines of TypeScript are all it takes to create your first Angular app. As
The code editor contains a complete Angular app.
<iframe src="https://stackblitz.com/github/angular/angular/tree/main/aio/content/demos/first-app?embed=1&file=src/main.ts&hideExplorer=1&hideNavigation=1" height="550" width="100%" style="border: solid 1px 777"></iframe>
<iframe src="https://stackblitz.com/github/angular/angular/tree/17.3.x/aio/content/demos/first-app?embed=1&file=src/main.ts&hideExplorer=1&hideNavigation=1" height="550" width="100%" style="border: solid 1px 777"></iframe>
The Angular app in the code editor shows the TypeScript that makes a simple, but complete, Angular component.
It imports resources from existing libraries and defines the properties of the new component.
+2
View File
@@ -51,6 +51,8 @@
// `/generated/docs/api/forms/f_ormb_uilder.json`.
//////////////////////////////////////////////////////////////////////////////////////////////
"redirects": [
{"type": 301, "source": "/", "destination": "https://angular.dev/"},
// A random bad indexed page that used `api/api`
{"type": 301, "source": "/api/api/:rest*", "destination": "/api/:rest*"},
+9 -9
View File
@@ -6,7 +6,7 @@
"author": "Angular",
"license": "MIT",
"scripts": {
"postinstall": "node tools/cli-patches/patch.js && patch-package --patch-dir ../tools/npm-patches/",
"postinstall": "node tools/cli-patches/patch.js && patch-package --patch-dir ../tools/npm-patches-aio/",
"prebuild": "yarn setup",
"build": "bazel build //aio:build",
"build-prod": "yarn build --config=release",
@@ -81,9 +81,9 @@
"devDependencies": {
"@angular-devkit/architect-cli": "0.1702.0-rc.0",
"@angular-devkit/build-angular": "17.2.0-rc.0",
"@angular-eslint/builder": "17.3.0",
"@angular-eslint/eslint-plugin": "17.3.0",
"@angular-eslint/eslint-plugin-template": "17.3.0",
"@angular-eslint/builder": "17.2.1",
"@angular-eslint/eslint-plugin": "17.2.1",
"@angular-eslint/eslint-plugin-template": "17.2.1",
"@angular-eslint/template-parser": "^17.0.0",
"@angular/build-tooling": "https://github.com/angular/dev-infra-private-build-tooling-builds.git#7c4cf003cb4ac849986beaa243d7e85a893612f2",
"@angular/cli": "17.2.0-rc.0",
@@ -98,8 +98,8 @@
"@types/lunr": "^2.3.3",
"@types/node": "^12.7.9",
"@types/trusted-types": "^2.0.2",
"@typescript-eslint/eslint-plugin": "7.3.1",
"@typescript-eslint/parser": "7.3.1",
"@typescript-eslint/eslint-plugin": "7.2.0",
"@typescript-eslint/parser": "7.2.0",
"archiver": "^7.0.0",
"assert": "^2.0.0",
"canonical-path": "1.0.0",
@@ -113,7 +113,7 @@
"eslint": "8.57.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jasmine": "4.1.3",
"eslint-plugin-jsdoc": "48.2.1",
"eslint-plugin-jsdoc": "48.2.0",
"eslint-plugin-prefer-arrow": "1.2.3",
"find-free-port": "^2.0.0",
"firebase-tools": "^13.0.0",
@@ -138,14 +138,14 @@
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"light-server": "^2.9.1",
"lighthouse": "^11.0.0",
"lighthouse": "~9.0.0",
"lighthouse-logger": "^2.0.0",
"lodash": "^4.17.21",
"lunr": "^2.3.9",
"npm-run-all": "^4.1.5",
"patch-package": "^7.0.0",
"protractor": "~7.0.0",
"puppeteer-core": "22.5.0",
"puppeteer-core": "~21.3.8",
"rehype-slug": "^4.0.1",
"remark": "^12.0.0",
"remark-html": "^13.0.0",

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