Compare commits

...

288 Commits

Author SHA1 Message Date
Jessica Janiuk 18091e72cb release: cut the v19.0.1 release 2024-11-26 09:40:12 -08:00
Angular Robot 4c1abc4fc1 build: update cross-repo angular dependencies (#58900)
See associated pull request for more information.

PR Close #58900
2024-11-26 15:28:21 +00:00
Jelle Bruisten 0c86d3e1f3 refactor(router): remove unused default error handler function (#58819)
with v19 the `defaultErrorHandler` has become unused, so could be removed

PR Close #58819
2024-11-26 14:49:37 +00:00
Angular Robot bea852fa15 build: update all non-major dependencies (#58888)
See associated pull request for more information.

PR Close #58888
2024-11-26 14:48:15 +00:00
Hakeem 914f540a43 fix(docs-infra): fix cards not shown if we hit the API page without active API tab (#58883)
since we are only updating the members margin at the constructing phase,
we should not disable this operation if user hit the page with tabs different than API active,
otherwise if user switched to the API page he won't see the cards since members margin equals zero and docs viewer won't be shown

Resolves #58882

PR Close #58883
2024-11-26 14:47:35 +00:00
Matthieu Riegler fbf0c8226e docs: fix @let roadmap tile. (#58886)
Prior to this change, we generated an invalid HTML with nested anchor elements. Those are not valid and are recovered by the browser by closing one early which messed the layout.

fixes #58884

PR Close #58886
2024-11-26 14:45:50 +00:00
Julian Gong f0ecbe62de docs: update link for language service config for neovim (#58479)
PR Close #58479
2024-11-25 21:22:48 +00:00
arielbackenroth 118803035f fix(core): Ensure _tick is always run within the TracingSnapshot. (#58881)
Fix a bug where calls to _tick are called without running through the snapshot.
This helps ensure that all snapshots that are requested are resumed.

PR Close #58881
2024-11-25 21:19:52 +00:00
Angular Robot bae473d718 build: update cross-repo angular dependencies (#58877)
See associated pull request for more information.

PR Close #58877
2024-11-25 18:00:48 +00:00
Angular Robot 83d2a09922 build: pin google-github-actions/auth action to 6fc4af4 (#58879)
See associated pull request for more information.

PR Close #58879
2024-11-25 17:12:50 +00:00
Andrew Kushnir 03a14b5034 refactor(core): invoke setActiveConsumer in ɵɵdeferHydrateWhen at the right time (#58864)
This commit updates the code of the `ɵɵdeferHydrateWhen` function to invoke the `setActiveConsumer` function at the right time (currently, we invoke it in the `finally` block, which is too late).

PR Close #58864
2024-11-25 16:12:37 +00:00
Andrew Kushnir 21106bf3cd refactor(core): remove unused field in ApplicationRef class (#58864)
This commit removes an unused field in the `ApplicationRef` class. Most likely the usage of the field was removed earlier.

PR Close #58864
2024-11-25 16:12:37 +00:00
Matthieu Riegler 08b9452f01 fix(core): Ensure resource sets an error (#58855)
Before this commit, a resource with a previous value wouldn't set the error state correctly.
This commit fixes this. A resource will set its status to error even when there was a previous valid value.

PR Close #58855
2024-11-25 15:28:18 +00:00
Matthieu Riegler beec8969ee docs: add standalone example for ErrorHandler (#58859)
fixes #55579

PR Close #58859
2024-11-25 15:26:50 +00:00
Kristiyan Kostadinov b386b1aa6f refactor(migrations): skip TS version check in tsurge (#58866)
Skips the TS version check in tsurge since it's blocking some internal changes and generally isn't necessary since the app will be checked when it's built anyways.

PR Close #58866
2024-11-25 15:26:18 +00:00
Kristiyan Kostadinov fb1fa8b0fc fix(compiler-cli): more accurate diagnostics for host binding parser errors (#58870)
Currently host bindings are in a bit of a weird state, because their source spans all point to the root object literal, rather than the individual expression. This is tricky to handle at the moment, because the object is being passed around as a `Record<string, string>` since the compiler needs to support both JIT and non-JIT environments, and because the AOT compiler evaluates the entire literal rather than doing it expression-by-expression. As a result, when we report errors in one of the host bindings, we end up highlighting the entire expression which can be very noisy in an IDE.

These changes aim to report a more accurate error for the most common case where the `host` object is initialized to a `string -> string` object literal by matching the failing expression to one of the property initializers. Note that this isn't 100% reliable, because we can't map cases like `host: SOME_CONST`, but it's still better than the current setup.

PR Close #58870
2024-11-25 15:25:48 +00:00
Andrew Kushnir ea0bf74e31 refactor(core): use ApplicationRef.whenStable instead of a custom util function (#58834)
This commit removes a custom `whenStable` util in favor of standard `ApplicationRef.whenStable` API.

There is also an important different between the custom `whenStable` function and `ApplicationRef.whenStable` implementation: the `whenStable` was caching the "stable" promise on per-ApplicationRef basis, which resulted in unexpected behavior with zoneless, when some code ended up getting a stale resolved promise, when an application was not stable yet, this causing order of operations issues. This commit also has an extra test that covers that case.

PR Close #58834
2024-11-25 15:25:10 +00:00
kirjs 70547ebce0 refactor(core): make lView[Injector] non-nullable (#58805)
There actually no cases, where it can be null. Also update all usages.

PR Close #58805
2024-11-25 15:24:40 +00:00
Pawel Kozlowski b8a450bbed refactor(docs-infra): use input bindings in docs component (#58826)
Use reactive inputs instead of manually getting data from the
currently activated route.

PR Close #58826
2024-11-25 15:23:54 +00:00
Sheik Althaf 9a9d1bfcdc refactor(docs-infra): remove deprecated modules from testing and use alternatives (#58847)
Removed the deprecated modules used in testing files and instead used the alternative one

PR Close #58847
2024-11-25 15:23:10 +00:00
Matthieu Riegler b21f96dc0e docs(docs-infra): display navigation items as HTML. (#58093)
fixes #57872

PR Close #58093
2024-11-25 15:22:33 +00:00
Kristiyan Kostadinov cb5ea19cde build: update g3 sync config (#58837)
Updates the sync config to exclude the entire `bazel` package. Previously only some subdirectories were excluded, but in the internal config the entire package is ignored.

PR Close #58837
2024-11-25 15:21:33 +00:00
Angular Robot fa84477f26 build: lock file maintenance (#58867)
See associated pull request for more information.

PR Close #58867
2024-11-25 15:21:03 +00:00
Joey Perrott 48b48c1eea ci: update perf workflow to the latest version (#58876)
Update the perf workflow to the latest version to allow for uploading results to database

PR Close #58876
2024-11-25 15:20:25 +00:00
vladboisa a41ac8329a docs(docs-infra): changed default type to object (#58289)
By API returned type is object, not any, rephrase docs and TIP

Fixes #58273

docs: change type from object to Object

Change the typo from object to Object

Co-authored-by: Matthieu Riegler <kyro38@gmail.com>

PR Close #58289
2024-11-22 20:30:44 +00:00
vladboisa 307ed7dba9 docs: add tools/extensions of started tutorial (#58416)
PR Close #58416
2024-11-22 20:30:07 +00:00
Andrew Kushnir 84f45ea3ff fix(core): make component id generation more stable between client and server builds (#58813)
For components with i18n in templates, the `consts` array is generated by the compiler as a function. If client and server bundles were produced with different minification configurations, the serializable contents of the function body would be different on the client and on the server. This might result in different ids generated. To avoid this issue, this commit updates the logic to not take the `consts` contents into account if it's a function.

Resolves #58713.

PR Close #58813
2024-11-22 19:36:50 +00:00
NothingEverHappens de0d5c768b docs: update prettier link to the correct one (#58757)
PR Close #58757
2024-11-22 19:33:08 +00:00
sp90 bafcf2c292 docs: add missing ng update material command to v19 update guide (#58770)
PR Close #58770
2024-11-22 19:32:29 +00:00
Ricardo 671fdce9c1 docs: fix RxJS interop typo (#58823)
PR Close #58823
2024-11-22 16:14:29 +00:00
Angular Robot 6bee546c4d build: update bazel setup (#58102)
See associated pull request for more information.

PR Close #58102
2024-11-22 15:37:10 +00:00
Angular Robot ea5d74bb34 build: update dependency typescript to v5.6.3 (#58458)
See associated pull request for more information.

PR Close #58458
2024-11-22 15:32:51 +00:00
Angular Robot d69a4e1e15 build: update dependency ngx-progressbar to v13 (#58822)
See associated pull request for more information.

Closes #58696 as a pr takeover

PR Close #58822
2024-11-22 15:32:10 +00:00
Alan Agius 78cf51b12a build: remove unused patch (#58821)
This commit removes an unused patch

PR Close #58821
2024-11-22 14:56:24 +00:00
Alan Agius 600bab4356 build: correct ignore nested node_modules (#58821)
The commit updates both Git and Bazel ignore config to ingore nested node_modules

PR Close #58821
2024-11-22 14:56:24 +00:00
Alan Agius d7dfd47232 build: fix path of @angular/ssr package (#58821)
The path was incorrect

PR Close #58821
2024-11-22 14:56:24 +00:00
Angular Robot 9fdec75c08 build: lock file maintenance (#58711)
See associated pull request for more information.

PR Close #58711
2024-11-22 14:46:21 +00:00
Melroy van den Berg a20689dc88 docs: Fix automatically typo (#58808)
PR Close #58808
2024-11-22 14:45:49 +00:00
Melroy van den Berg 46d173d60f docs: Fix more typos. (#58809)
PR Close #58809
2024-11-22 14:44:44 +00:00
ahmadhakeem18 26d75b0315 docs(docs-infra): remove the usage of the deprecated core mixin as it's no-op (#58812)
PR Close #58812
2024-11-22 14:44:11 +00:00
ahmadhakeem18 97625d22c0 docs(docs-infra): fix visually-hidden elements style (#58812)
import visually-hidden styles from CDK as the new version of Angular material no more do that inside the deprecated core mixin

PR Close #58812
2024-11-22 14:44:11 +00:00
Dany Marques ffbe7635d1 docs: signal has to be called (#58816)
PR Close #58816
2024-11-22 14:43:39 +00:00
Melroy van den Berg c30ae2d069 docs: Fix typo in standalone section of Anatomy of a component (#58807)
PR Close #58807
2024-11-22 14:43:02 +00:00
Jesús Real Serrano a0ca7d1513 docs: update resource.md (#58795)
PR Close #58795
2024-11-22 14:42:30 +00:00
mgechev b2eccad3d6 docs: update front page banner to link to the blog (#58803)
The blog post now has the release event embedded.
Link to the blog for a more comprehensive overview

PR Close #58803
2024-11-22 14:41:53 +00:00
Jessica Janiuk d3491c7cee fix(core): Prevents race condition of cleanup for incremental hydration (#58722)
When hydrating a tree of blocks, this prevents cleanup from firing more than once per tree. It also ensures the cleanup happens after hydration has finished.

fixes: #58690

PR Close #58722
2024-11-21 21:39:37 +00:00
Younes Jaaidi 5ce10264a4 fix(migrations): fix provide-initializer migration when using useFactory (#58518)
Priori to this commit, initializer functions with dependencies were not migrated correctly.
With this commit, the function is executed in a injection context to allow the usage of `inject`.

PR Close #58518
2024-11-21 20:59:35 +00:00
Ryan Russell a6d2d2dc10 fix(migrations): Mark hoisted properties as removed in inject migration (#58804)
Before, in a situation like shown in the test, all of the initializers
would be dropped, as the code would try to insert it at the hoisted
property which is going to be deleted.

PR Close #58804
2024-11-21 20:58:26 +00:00
ahmadhakeem18 ab701f4a24 docs(docs-infra): fix the hovering animation of banner text and make the action on the parent (#58775)
PR Close #58775
2024-11-21 20:55:46 +00:00
ahmadhakeem18 9796067515 docs(docs-infra): show the top-level banner on top of all the elements (#58775)
Starting from Tablet-landscape siz display the banner on top of all the
elements, and for smaller sizes display it under the nav to make it
accessible to users

PR Close #58775
2024-11-21 20:55:46 +00:00
ahmadhakeem18 836ed79c89 docs(docs-infra): fix top-level banner styles and make it responsive (#58775)
PR Close #58775
2024-11-21 20:55:46 +00:00
Paweł Maniecki fe1a771c9a docs: fix 404 link in roadmap (#58791)
https://angular.dev/guide/components/output-fn does not exist, change to https://angular.dev/guide/components/outputs

PR Close #58791
2024-11-21 16:44:10 +00:00
JoostK 99715104a1 fix(core): correctly perform lazy routes migration for components with additional decorators (#58796)
This fixes an issue where the lazy-routes migration would crash for component classes a
decorator without arguments in front of the `@Component` decorator (in particular, it needed
to be the first decorator).

Fixes #58793

PR Close #58796
2024-11-21 16:43:30 +00:00
Kristiyan Kostadinov 6b057bcfdb refactor(forms): work around another TypeScript 5.7 issue (#58782)
Reworks the changes from #58731, because they didn't cover all use cases.

PR Close #58782
2024-11-21 16:36:15 +00:00
Sheik Althaf 52912f064b refactor(devtools): migrate devtools to prettier formatting (#58766)
Added html and scss to ng-dev formatter. This will reduce the formatting changes coming in PRs.

PR Close #58766
2024-11-21 16:35:38 +00:00
Kristiyan Kostadinov 9a01c42214 refactor(core): adjust tracing service (#58771)
Adjusts the tracing service based on internal requirements.

PR Close #58771
2024-11-21 16:34:54 +00:00
Alex Rickabaugh 818659c6ec refactor(core): introduce TracingService for snapshot-based tracing (#58771)
This commit introduces a private API, the `TracingService` DI token. By
providing this token, Angular can be configured to capture tracing snapshots
for certain operations such as change detection notifications, and to run
downstream operations within the context of those snapshots.
`TracingService` abstracts this context propagation and makes it pluggable.

PR Close #58771
2024-11-21 16:34:53 +00:00
Angular Robot 8694f919ad build: update cross-repo angular dependencies (#58778)
See associated pull request for more information.

PR Close #58778
2024-11-21 16:33:44 +00:00
Alan Agius ab4f81044c docs: minor updates to hybrid rendering docs (#58797)
Fix typos and some minor things

PR Close #58797
2024-11-21 16:31:40 +00:00
Joey Perrott ec674c6a68 ci: update to latest actions from angular/dev-infra (#58799)
Update to latest commit

PR Close #58799
2024-11-21 15:01:40 +00:00
voi99 a3be5b0f25 docs(compiler): add strictStandalone option to angular compiler options (#58785)
PR Close #58785
2024-11-20 22:07:36 +00:00
Angular Robot 28254ca134 build: update io_bazel_rules_sass digest to 35b1c32 (#58674)
See associated pull request for more information.

PR Close #58674
2024-11-20 21:19:31 +00:00
Joey Perrott 4b7f295e8d ci: set up perf tracking CI job (#58779)
Set up perf tracking CI job to run on each commit to main branch

PR Close #58779
2024-11-20 21:16:23 +00:00
Angular Robot b767b660b6 build: update github/codeql-action action to v3.27.5 (#58730)
See associated pull request for more information.

PR Close #58730
2024-11-20 21:15:31 +00:00
Angular Robot 273ee7a290 build: update all non-major dependencies (#58729)
See associated pull request for more information.

PR Close #58729
2024-11-20 21:11:33 +00:00
Joey Perrott 7c9f42540b ci: update to latest actions from angular/dev-infra (#58781)
Update to latest commit

PR Close #58781
2024-11-20 11:58:14 -08:00
Angular Robot 678f333956 build: update dependency @types/diff to v6 (#58426)
See associated pull request for more information.

PR Close #58426
2024-11-20 08:54:49 -08:00
Mark Axisa ac52ce8ae7 docs(core): add descriptive usage line for projectableNodes param in createComponent docs (#58727)
PR Close #58727
2024-11-20 08:12:32 -08:00
Charles Lyding d87f4830bb refactor(language-service): reuse code fixes map for has fix check (#58759)
The error codes that have fixes are present in a Map instance and
can be directly leveraged to determine if an error code can be fixed.
This avoids multiple levels of iteration that would otherwise be needed.

PR Close #58759
2024-11-20 08:10:16 -08:00
Kristiyan Kostadinov d4f5c85f60 fix(migrations): handle parameters with initializers in inject migration (#58769)
Adds some logic to the `inject()` migration that allows is to handle parameter declarations with initializers. This was omitted initially, because we don't officially support such cases, but it came up internally.

PR Close #58769
2024-11-20 08:07:39 -08:00
aboudard baedea7b3f docs: add missing ng update command to v19 update guide (#58762)
This change adds the command to run when updating angular project from v18 to v19

PR Close #58762
2024-11-19 17:36:26 -08:00
Matthieu Riegler 472dd58537 docs(docs-infra): have a redirect for guide/components/anatomy-of-components (#58750)
fixes #58746

PR Close #58750
2024-11-19 16:52:28 -08:00
Angular Robot 69c29639fa build: update cross-repo angular dependencies (#58666)
See associated pull request for more information.

PR Close #58666
2024-11-19 16:51:40 -08:00
Jeremy Elbourn f4e2777994 docs: add details on how @defer loads deps (#58763)
PR Close #58763
2024-11-19 16:34:37 -08:00
Jeremy Elbourn 4970ebab57 docs: update titles for resource and linkedSignal (#58761)
This change updates the navigation titles for linkedSignal and resource
to follow the pattern of "<accomplish X> with <feature Y>". Also makes a
few minor updates to the body of the resource topic.

PR Close #58761
2024-11-19 16:33:53 -08:00
Charles Lyding ca032a2289 docs: add note about dev-server startup and styles (#58751)
A note has been added to the application builder documentation regarding
the Vite-based development server and style processing that could
potentially result in initial FOUC due to server processing overhead on startup.

PR Close #58751
2024-11-19 16:33:19 -08:00
Kristiyan Kostadinov a983865bff fix(language-service): add fix for individual unused imports (#58719)
Fixes that `getCodeActions` wasn't implemented for the unused imports fixer which meant that it wouldn't show up in the most common cases.

PR Close #58719
2024-11-19 12:19:15 -08:00
Kristiyan Kostadinov e6e7a4e22b fix(language-service): allow fixes to run without template info (#58719)
Currently the code fixes won't run if the template information can't be resolved on the diagnostic node. This is incorrect for diagnostics that are reported within `.ts` files. These changes make the `templateInfo` nullable and leave the early exit up to the individual fixes.

PR Close #58719
2024-11-19 12:19:14 -08:00
Charles Lyding 502ee0e722 fix(core): correctly clear template HMR internal renderer cache (#58724)
The internal renderer cache within the renderer factory was not being
correctly cleared due to a type-casting error. This prevented template
HMR from correctly updating the component. A more explicity cast has
now been used to mitigate this problem.
Component template HMR is currently considered experimental.

PR Close #58724
2024-11-19 12:18:40 -08:00
Kristiyan Kostadinov 4dfe5b6cef fix(forms): work around TypeScript 5.7 issue (#58731)
Adjusts the return type of `FormBuilder.group` to work around https://github.com/Microsoft/TypeScript/issues/60506.

PR Close #58731
2024-11-19 12:18:01 -08:00
Kristiyan Kostadinov e4dc7f1361 docs: update standalone migration guide (#58703)
Updates the guide for the standalone migration to account for standalone being the default.

PR Close #58703
2024-11-19 09:54:54 -08:00
Matthieu Riegler 154e6052d3 docs(docs-infra): fix ngmodule guide navigation. (#58740)
PR Close #58740
2024-11-19 09:53:27 -08:00
Jens Kuehlers bf8ee41877 docs: fix v19 support dates (#58732)
PR Close #58732
2024-11-19 09:52:45 -08:00
Paul Gschwendtner 5838f43774 docs: add link to v19 blog post (#58745)
Adds a link to the v19 blog post

PR Close #58745
2024-11-19 17:38:48 +00:00
Paul Gschwendtner c4357ebcc1 docs: update tutorials and playground to v19.0.0 (#58742)
Updates boilerplate for tutorial and playground to use v19

PR Close #58742
2024-11-19 17:26:48 +00:00
Paul Gschwendtner 7bd56fd296 build: publish angular-in-memory-web-api@0.19.0 for v19 compatibility (#58741)
We re-publish this package with new peer dependencies for v19
compatibility.

PR Close #58741
2024-11-19 16:55:59 +00:00
Paul Gschwendtner e7566c3c47 release: cut the v19.0.0 release 2024-11-19 15:21:41 +01:00
mgechev b2802e573a docs: update links in the roadmap (#58728)
PR Close #58728
2024-11-18 18:25:36 -08:00
mgechev 02b258a2ed docs: update the angular roadmap for v19 (#58549)
PR Close #58549
2024-11-18 16:03:00 -08:00
Matthieu Riegler f696ecb424 docs(docs-infra): redirect to the root of the app. (#58700)
Prior to this commits the redirected path was relative.

fixes #58699

PR Close #58700
2024-11-18 13:35:58 -08:00
ahmadhakeem18 c79dd4e722 docs(docs-infra): Fix overflow styles in cards code examples (#58704)
PR Close #58704
2024-11-18 13:35:15 -08:00
ahmadhakeem18 88c253ff61 docs(docs-infra): Fix the borders of Cards header to match its parent (#58704)
PR Close #58704
2024-11-18 13:35:15 -08:00
Matthieu Riegler 2c04430a3e docs: update version compatibility. (#58720)
TS 5.4 support was dropped by #57577
TS 5.6 support was added by #57749

PR Close #58720
2024-11-18 13:34:35 -08:00
marktechson 2c05f4ce9c docs: add v19 developer event banner (#58721)
PR Close #58721
2024-11-18 12:48:47 -08:00
Jeremy Elbourn 805d8f1ca1 docs: reorganize NgModule and Animations guides (#58694)
* Move the NgModules and Animations guide under "Extended Ecosystem"
* Remove all NgModule topics except for the (newly written) overview.
  All of the content in these topics was inherently written on the idea
  that your application was organized around NgModules. I went through
  all of it, moved the important parts to the overview, and deemed the
  rest obsolete (though it will always remain in archived versions).

PR Close #58694
2024-11-15 14:36:39 -08:00
hawkgs 392b9920a0 docs(docs-infra): remove Featured section from the API reference list page (#58659)
Remove the Featured/Most Common section from the reference list and stylize and position the filter appropriately.

PR Close #58659
2024-11-15 10:32:22 -08:00
Andrew Kushnir 51df77583c docs: update location of REQUEST-related tokens in docs content (#58693)
Since https://github.com/angular/angular/commit/a55341b1ab8d2bc4285a4cce59df7fc0b23c0125 commit, the `REQUEST`, `RESPONSE_INIT` and `REQUEST_CONTEXT` tokens became a part of the `@angular/core` pcakage. This commit updates the docs to mention `@angular/core` as a primary location of those tokens.

PR Close #58693
2024-11-15 10:30:12 -08:00
Jessica Janiuk 497fe97ada docs: add incremental hydration guide (#58671)
This adds a guide for incremental hydration. It also updates the navigation and adds links to it from the hydration guide.

PR Close #58671
2024-11-15 09:50:13 -08:00
Jeremy Elbourn 1192c89671 docs: initial resource docs (#58687)
Adding an initial pass of docs for `resource` under the Signals heading.

PR Close #58687
2024-11-15 09:48:10 -08:00
Andrew Kushnir 36a5712b67 release: cut the v19.0.0-rc.3 release 2024-11-15 09:37:58 -08:00
Pawel Kozlowski df210a463b refactor(core): mark linkedSignal as developer preview (#58684)
This commit bumps up the stability status of the linkedSignal
to developer preview - clearly expressing our highier confidence
in this API.

PR Close #58684
2024-11-15 14:15:20 +01:00
cexbrayat e6514b9f3d fix(migrations): do not migrate next calls in template if not an EventEmitter (#58631)
Fixes #58630

```html
<button (click)="someSubject.next()">Click</button>
```

was migrated to an `.emit` call, even if `someSubject` was not an `EventEmitter`.

The issue was the same in host listeners.

PR Close #58631
2024-11-15 14:13:52 +01:00
Kristiyan Kostadinov e33b19592f fix(bazel): allow strictStandalone to be passed through tsconfig (#58683)
Allows users to pass the `strictStandalone` compiler option through the tsconfig.

PR Close #58683
2024-11-15 12:53:10 +01:00
Georgy Serga 806a61b5a6 fix(compiler): fix multiline selectors (#58681)
multiline selectors where not correctly recognized by the regexp, fix it to fetch newlines as well

Fixes #58399

PR Close #58681
2024-11-15 11:30:27 +01:00
Georgy Serga e5d3abb298 fix(compiler): resolve :host:host-context(.foo) (#58681)
fix results which had to parse several `-shadowcsshost-no-combinator` occurrences in a single selector

PR Close #58681
2024-11-15 11:30:27 +01:00
Georgy Serga 80f56954ce fix(compiler): transform chained pseudo-selectors (#58681)
fix transformation logic for `:where` and `:is` pseudo-selectors
when these selectors were used in a chain. results were often broken,
the last letter of the selector was incorrectly trimmed.
see tests for examples

Fixes #58226

PR Close #58681
2024-11-15 11:30:27 +01:00
Georgy Serga 2be161d015 fix(compiler): fix :host parsing in pseudo-selectors (#58681)
fix several use-cases where `:host` was used in or around pseudo-selectors
- `:host` followed by a comma inside pseudo-selectors
- `:host` outside of pseudo-selectors when another `:host` is present within
see tests for examples

PR Close #58681
2024-11-15 11:30:27 +01:00
Andrew Kushnir 91a616fca7 refactor(core): add REQUEST, RESPONSE_INIT and REQUEST_CONTEXT tokens (#58669)
This commit introduces the `REQUEST`, `RESPONSE_INIT` and `REQUEST_CONTEXT` tokens, which will replace similar ones from https://github.com/angular/angular-cli/blob/28503186230b5e22b84499641d56c9c981fdab1d/packages/angular/ssr/tokens/src/tokens.ts, so those tokens would be imported in application code via `@angular/core` package.

PR Close #58669
2024-11-14 14:21:21 -08:00
Guillaume MOREAU c53e3ac300 docs: fix typo in build system migration doc (#58668)
PR Close #58668
2024-11-14 14:18:15 -08:00
Jeremy Elbourn 21ccc2333a docs: correct SSR guide landing page (#58667)
A previous change updated the navigation from "Performance" to "Server-side & hybrid rendering", but the landing page was missed.

PR Close #58667
2024-11-14 14:17:13 -08:00
Matthieu Riegler 5b7e768226 docs: remove mention of allowSignalWrites (#57974)
PR Close #57974
2024-11-14 14:16:28 -08:00
Jeremy Elbourn ee499473ef docs: remove standalone: true across content (#58660)
This change removes `standalone: true` from documentation and examples now that it is the default.

PR Close #58660
2024-11-14 16:40:12 +00:00
Angular Robot 02555bf5ef build: update cross-repo angular dependencies (#58654)
See associated pull request for more information.

PR Close #58654
2024-11-14 16:39:37 +00:00
Jessica Janiuk e7131231fe release: cut the v19.0.0-rc.2 release 2024-11-14 08:35:17 -08:00
Jessica Janiuk fa1b021aad refactor(core): add performance feature flag for incremental hydration (#58658)
This adds a flag for incremental hydration to get usage statistics.

PR Close #58658
2024-11-14 15:07:39 +00:00
Jessica Janiuk 5fe57d4fbb fix(core): fixes issues with control flow and incremental hydration (#58644)
If a defer block is nested inside control flow while also being nested
underneath a defer block all using incremental hydration, timing issues
prevented the child nodes from being properly hydrated. This ensures
hydration happens on next render.

PR Close #58644
2024-11-14 14:59:53 +00:00
Paul Gschwendtner f503c15ea9 refactor(compiler-cli): parse angularCompilerOptions from bazel options as a fallback (#58637)
This commit is only useful to Google. It fixes that some code relies on
`readConfiguration`, but doesn't properly parse Angular compiler options
as those are part of `bazelOptions.angularCompilerOptions` if the
1P-generated tsconfig's are used.

PR Close #58637
2024-11-14 14:55:54 +00:00
cexbrayat 715caea46b refactor(migrations): typos in signal migration incompatibility reasons (#58636)
A dot was appearing in the middle of the comment for `DerivedIsIncompatible`.
While at it, a dot was missing in `ClassManuallyInstantiated`.

PR Close #58636
2024-11-14 14:55:04 +00:00
Paul Gschwendtner d892b4aa2b build: update ng-dev to fix release tool (#58651)
Includes: https://github.com/angular/dev-infra/pull/2446

PR Close #58651
2024-11-14 14:54:05 +00:00
Jens Kuehlers 29001ea586 docs: add State of JS 2024 banner (#58649)
PR Close #58649
2024-11-14 14:53:20 +00:00
Jeremy Elbourn 506413cf23 docs: add topic for linkedSignal (#58647)
Adds a topic to the Signals guide for `linkedSignal`. Also fixes a few broken links.

PR Close #58647
2024-11-14 14:52:33 +00:00
Jeremy Elbourn acca96c3e1 docs: rename "Performance" guide to "Server-side & Hybrid rendering" (#58638)
* This makes it easier for developers discover SSR docs
* Deletes the original `@defer` guide now that there's a new `@defer` topic in the template guide
* Moves the Image optimization topic to the Directives guide. This isn't my _favorite_ place for this guide and I may revisit in a follow-up PR.

PR Close #58638
2024-11-14 14:51:51 +00:00
Jeremy Elbourn 5ffec9a3af docs: update essentials guide to include signals (#58603)
This change updates the _Essentials_ topic with the following changes:
* Change the "Managing dynamic data" topic to "Reactivity with signals",
  largely replacing the existing content to focus specifically on
  signals.
* Replace the "to-do" examples with examples for building a
  `UserProfile` component. I made this change because the todo-item
  component had an accessibility problem: it was a list item component
  that rendered an `li` into its own template. This meant that the
  component's host element was in between the `ul` and the `li`, which
  is invalid. The "right" way to do this would have been to use a
  component with an attribute selector, but this isn't something that
  fits into the _Essentials_ guide.
* Reorder some of the concepts in the components topic
* Combine "Rendering dynamic templates", "Conditionals and loops", and
  "Handling user interaction" into one topic, "Dynamic interfaces with
  templates". Having these as separate topics meant that there was more
  preamble/scaffolding around these relatively straightforward ideas.
* Renamed the "Sharing logic" topic to "Modular design with dependency
  injection". Aside from this, I have made no meaningful changes to the
  DI topic; I may come back for another edit pass here, but this is not
  necesary for v19.
* Add a link to the in-depth guide for each essentials topic.
* Add a new introduction to the _Essentials_ overview that explains what
  this guide is and what it's trying to accomplish.

PR Close #58603
2024-11-14 14:51:20 +00:00
Julio Massano Santos f8248b948d docs: adds interceptor testing (#57568)
PR Close #57568
2024-11-14 14:50:43 +00:00
Angular Robot 45537eb648 build: update cross-repo angular dependencies (#58641)
See associated pull request for more information.

PR Close #58641
2024-11-13 20:45:11 +00:00
Jeremy Elbourn 23530a47de docs: update NgModule overview for standalone default (#58606)
This is the first commit towards updating the NgModule guide to reflect
the fact that v19+ is standalone by default. This PR focuses on:
* Updating the overview to give an actual overview of the most
  important/common uses of `NgModule`
* Add callouts recommending standalone APIs over `NgModule`
* Remove several stale docs that no longer make sense in v19+

This guide (directory) needs additional follow up work; I plan to
address the remaining content in follow-up changes.

PR Close #58606
2024-11-13 20:04:24 +00:00
Angular Robot e1e2e3fb67 build: update io_bazel_rules_sass digest to b442a44 (#58617)
See associated pull request for more information.

PR Close #58617
2024-11-13 18:49:21 +00:00
Angular Robot 4abb64580f build: update cross-repo angular dependencies (#58639)
See associated pull request for more information.

PR Close #58639
2024-11-13 18:37:47 +00:00
Charles Lyding 87dc5003a2 refactor(language-service): suppress inline TCB required diagnostic for syncs (#58619)
The NG8900 diagnostic is a non-actionable error code that does not affect
the build result of a component.

PR Close #58619
2024-11-13 18:36:08 +00:00
Kristiyan Kostadinov e26797b38e fix(migrations): replace removed NgModules in tests with their exports (#58627)
In #57684 the standalone migration was changed so that it replaces any leftover modules with their `exports`, in an attempt to preserve more working code. These changes expand that logic to also cover tests since it's somewhat common internally to only import a component's module without having any references to the component.

Note that tests are a bit of a special case, because we don't have access to the template type checker, so instead we copy over all of the `exports` of that module.

PR Close #58627
2024-11-13 18:04:32 +00:00
Kristiyan Kostadinov c570be385c refactor(compiler-cli): broaden type of getPotentialImportsFor (#58627)
Currently the `getPotentialImportsFor` only accepts a `ClassDeclaration` as the context for generating an import, but that's not necessary because it doesn't require any class-specific information. These changes expand it to any `Node` so that it can be used when generating imports in testing declarations.

PR Close #58627
2024-11-13 18:04:31 +00:00
cexbrayat b84ed2b628 fix(migrations): include the output migration in the defaults of the signal migration (#58635)
Running `ng g @angular/core:signals` prompts for the question on which migration to run and offers 3 options (inputs, outputs, queries).
Running with `--defaults` skips the prompts, but only runs 2 of them.
This fixes it by including the `outputs` migration in the default ones.

PR Close #58635
2024-11-13 18:03:59 +00:00
Angular Robot cfecdd50e7 build: update cross-repo angular dependencies (#58634)
See associated pull request for more information.

PR Close #58634
2024-11-13 18:03:10 +00:00
Jeremy Elbourn 29207d84a3 docs: update components guide for default standalone (#58605)
This change updates the components guide to reflect the fact that
standalone is now the default.

PR Close #58605
2024-11-13 15:40:21 +00:00
Jeremy Elbourn 7082688a14 docs: show component signal APIs as the standard approach (#58572)
This change updates the docs to show the signal-based APIs for inputs
and queries as the primary way to do things (and also the `output`
function).

Specifically, this means:
* Component guide
   * Show `input` and `model` as the main approach, moving `@Input` lower on the same page
   * Show signal-based queries as the main approach, moving the
     decorator-based queries lower on the same page
   * Show `output` as the main approach, moving `@Output` lower on the
     same page
   * Delete the separate topic for the `output` function
* Signals guide
   * Delete the topics for input, model, and queries, as they are not in
     the components guide.
   * Move all rxjs-interop content to a new guide under "Extended
     ecosystem"

I plan to further update the "Essentials" guide and the "Signals" guide
in follow-up PRs.

PR Close #58572
2024-11-13 15:39:50 +00:00
Jessica Janiuk a5e7a02f9b refactor(core): moves incremental hydration codebase to better locations (#58616)
This eliminates the extra incremental.ts codepath and moves its functions to appropriate locations.

PR Close #58616
2024-11-12 22:25:27 +00:00
Joey Perrott 26602fcaae ci: remove circleci as we no longer rely on it (#58615)
Remove CircleCI artifacts and configuration

PR Close #58615
2024-11-12 18:39:25 +00:00
Kristiyan Kostadinov 560282aa9b fix(compiler): control flow nodes with root at the end projected incorrectly (#58607)
Fixes an edge case where a control flow node that has non-projectable nodes followed by an element node at the end would cause the entire control flow node to be project. For example if we have a projection target of `Main: <ng-content/> Slot: <ng-content select="[foo]"/>`, inserting a node of `@if (true) {Hello <span foo>world</span>}` would project the entire `Hello world` into the `[foo]` slot.

In the process of working on the issue, I also found that `@let` declarations at the root of the control flow node would prevent content projection as well.

PR Close #58607
2024-11-12 18:05:00 +00:00
Jessica Janiuk 51933ef5a6 fix(core): prevent errors on contract cleanup (#58614)
If contract cleanup is called more than once, the assertion that the container manager will be present results in exceptions.

PR Close #58614
2024-11-12 17:25:50 +00:00
arturovt 71ee81af2c fix(core): clean up event contract once hydration is done (#58174)
In this commit, we clean up the event contract once hydration is complete, which removes event
listeners registered through the container manager. If we do not clean up the contract, the listeners
will remain on the `document.body`. When incremental hydration is enabled, we cannot clean up the event
contract immediately; instead, we schedule its cleanup when the app is destroyed. This is because the
event contract is required for deferred blocks, of which we are unaware, that need to be hydrated.

PR Close #58174
2024-11-12 15:05:46 +00:00
Jessica Janiuk d190f82147 test(core): add incremental hydration tests (#58601)
This adds some additional tests for incremental hydration around registry and contract cleanup.

PR Close #58601
2024-11-12 14:49:06 +00:00
ashish b59c218b2d docs(docs-infra): Fixed grammatical error (#58611)
PR Close #58611
2024-11-12 14:48:12 +00:00
Angular Robot dc5d2b7c34 build: update github/codeql-action action to v3.27.2 (#58604)
See associated pull request for more information.

PR Close #58604
2024-11-12 14:47:19 +00:00
Kristiyan Kostadinov 829aa5dade refactor(migrations): handle fake async catalyst (#58608)
Fixes that the standalone migration wasn't handling the `fake_async` path for Catalyst.

PR Close #58608
2024-11-12 14:45:40 +00:00
Matthieu Riegler a32eb1ccbe docs: fix link in 6-property-binding tutorial (#58594)
fixes #58588

PR Close #58594
2024-11-12 14:45:00 +00:00
Jessica Janiuk c77b53be11 refactor(core): reorganize defer codebase (#58598)
This moves all the helpers out of the instructions file, keeping the instructions limited to the actual instruction set. This adds files for defer block rendering functions and triggering functions, respectively.

PR Close #58598
2024-11-11 19:11:02 +00:00
Angular Robot b834d7f5ee build: update cross-repo angular dependencies (#58597)
See associated pull request for more information.

PR Close #58597
2024-11-11 19:02:08 +00:00
Joey Perrott 549c0ad2bd docs: remove "getting started" from headers on API ref page (#58595)
Remove the "Getting Started" text from the headers as it is unnecessary and confusing

PR Close #58595
2024-11-11 17:53:20 +00:00
Angular Robot d92001acd4 build: update cross-repo angular dependencies (#58593)
See associated pull request for more information.

PR Close #58593
2024-11-11 17:24:46 +00:00
Angular Robot 1996794957 build: update dependency marked to v15 (#58573)
See associated pull request for more information.

PR Close #58573
2024-11-11 17:11:27 +00:00
Matthieu Riegler 320560b254 ci: re-enable adev tests (#58574)
Previously we disabled the tests to land some breaking changes.
We can now update the dependencies and re-enable the tests.

PR Close #58574
2024-11-11 16:52:09 +00:00
Kristiyan Kostadinov 9bbb01c85e fix(compiler-cli): report individual diagnostics for unused imports (#58589)
Initially the unused imports check was implemented so that it reports one diagnostic per component with the individual unused imports being highlighted through the `relatedInformation`. This works fine when reporting errors to the command line, but vscode appears to only show `relatedInformation` when the user hovers over a diagnostic which is a sub-par experience.

These changes switch to reporting a diagnostic for each unused import instead.

PR Close #58589
2024-11-11 15:31:00 +00:00
Paul Gschwendtner 7cff2b73d2 refactor(migrations): improve temporary variable generation in signal migrations (#58581)
This commit improves the temporary variable generation in signal
migrations, whenever references are "shared" inside property
declarations.

PR Close #58581
2024-11-11 15:29:21 +00:00
Paul Gschwendtner 3df159f54a refactor(migrations): improve control flow analysis for loops in signal migration (#58581)
Currently whenever we would come across a code snippet like this, where
`maxCellsPerRow` is an input, the control flow analysis would fall apart
because the first occurence of the node points to a control flow node
that is offset-wise "after" the first occurence. This commit makes the
logic more robust.

PR Close #58581
2024-11-11 15:29:21 +00:00
Jessica Janiuk 746ea40c37 Revert "ci: re-enable adev tests (#58574)" (#58592)
This reverts commit 7263917793.

PR Close #58592
2024-11-11 15:28:37 +00:00
Matthieu Riegler 64661dd0dd ci: re-enable adev tests (#58574)
Previously we disabled the tests to land some breaking changes.
We can now update the dependencies and re-enable the tests.

PR Close #58574
2024-11-11 14:50:59 +00:00
Charles Lyding b6a998b2fd docs: add define option and prebundling info for application builder (#58569)
The application builder documentation now contains information about the
`define` option and its usage as well as development server prebundling.

PR Close #58569
2024-11-11 14:36:41 +00:00
Sheik Althaf 10540b54f9 refactor(docs-infra): use reactive APIs in shared components (#58425)
Migrated the input, output and queries to reactive APIs for better support of zoneless.

PR Close #58425
2024-11-11 14:36:05 +00:00
Jessica Janiuk a524f42635 refactor(core): clean up incremental code base (#58553)
This re-organizes the code to be a bit cleaner with no more need for the onTriggerFn function.

PR Close #58553
2024-11-11 14:35:37 +00:00
Jessica Janiuk 923cc33c6d refactor(core): Ensure registry and map are empty on view destroy (#58553)
This cleans up the memory usage of the defer block registry and jsactionmap when a view is destroyed that contains a defer block that is not yet hydrated.

PR Close #58553
2024-11-11 14:35:37 +00:00
Alan Agius 9395aae1f7 docs: update hybrid rendering docs to remove RenderMode.AppShell (#58564)
More context in https://github.com/angular/angular-cli/pull/28818

PR Close #58564
2024-11-08 18:56:36 +00:00
Angular Robot c988b91759 build: update cross-repo angular dependencies (#58571)
See associated pull request for more information.

PR Close #58571
2024-11-08 18:54:26 +00:00
Anner Visser e1c7327064 docs: Fix menu label for ng cache clean, clear -> clean (#58560)
PR Close #58560
2024-11-08 17:28:04 +00:00
Paul Gschwendtner c53ad709b1 refactor(migrations): support running existing migrations with plain TS programs (#58541)
Previously we always ran Tsurge migrations with an Angular program, even
if it's a plain `ts_library` target. This has changed now, so we also
need to properly handle the case where a `ts_library` is analyzed, but
no Angular program is available.

PR Close #58541
2024-11-08 17:22:06 +00:00
Paul Gschwendtner d6749683ba refactor(migrations): conditionally create plain TS programs for Tsurge analyzers (#58541)
Tsurge can run against the full Google3 depot, and will often also deal
with plain `ts_library` targets. Those shouldn't be constructed with the
Angular compiler as this could cause out of memory breakages etc. The
targets are simply not "proven" to be compatible with the Angular
compiler; so we shouldn't use them when not necessary.

PR Close #58541
2024-11-08 17:22:06 +00:00
Angular Robot c5511dc458 build: update cross-repo angular dependencies (#58550)
See associated pull request for more information.

PR Close #58550
2024-11-08 17:18:16 +00:00
Charles Lyding 1848d2719f docs: add initial new feature info for application builder (#58547)
Adds information about loader option, loader import
attributes, and import/export condition features.

PR Close #58547
2024-11-08 17:17:37 +00:00
Teun Willems f8322bd7cb docs: remove foreach from testing.md as it's not a JS function (#58565)
Foreach was present in the documentation even though it's not valid Javascript

PR Close #58565
2024-11-08 17:16:45 +00:00
Alan Agius 499b227e11 fix(docs-infra): retain function keyword in API definitions (#58561)
**Before:**
```ts
animate(
  timings: string | number,
  styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata | null
): AnimationAnimateMetadata;
```

**Now:**
```ts
function animate(
  timings: string | number,
  styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata | null
): AnimationAnimateMetadata;
```

PR Close #58561
2024-11-08 17:16:06 +00:00
Alan Agius 791ee323dc fix(compiler-cli): correct extraction of generics from type aliases (#58548)
**Before:**
```ts
type HttpEvent = | HttpSentEvent
  | HttpHeaderResponse
  | HttpResponse<T>
  | HttpProgressEvent
  | HttpUserEvent<T>
```

**After:**
```ts
type HttpEvent<T> = | HttpSentEvent
  | HttpHeaderResponse
  | HttpResponse<T>
  | HttpProgressEvent
  | HttpUserEvent<T>
```

PR Close #58548
2024-11-08 17:15:09 +00:00
Alan Agius 4bebc9d5e4 docs(docs-infra): update default generic values and add constraints for type parameters in functions (#58548)
Before
```typescript
createNodeRequestHandler(
  handler: T
): T;
```

```typescript
class NgIf<T> {
  @Input() set ngIf(value: T);
  @Input() set ngIfThen(value: TemplateRef<NgIfContext<T>> | null);
  @Input() set ngIfElse(value: TemplateRef<NgIfContext<T>> | null);
  static ngTemplateGuard_ngIf: "binding";
  static ngTemplateContextGuard<T>(dir: NgIf<T>, ctx: any): boolean;
}
```

Now
```typescript
createNodeRequestHandler<T extends NodeRequestHandlerFunction>(
  handler: T
): T;
```

```typescript
class NgIf<T = unknown> {
  @Input() set ngIf(value: T);
  @Input() set ngIfThen(value: TemplateRef<NgIfContext<T>> | null);
  @Input() set ngIfElse(value: TemplateRef<NgIfContext<T>> | null);
  static ngTemplateGuard_ngIf: "binding";
  static ngTemplateContextGuard<T>(dir: NgIf<T>, ctx: any): boolean;
}
```

PR Close #58548
2024-11-08 17:15:09 +00:00
Alan Agius a314878bb5 ci: add packages/ssr in pullappove (#58556)
This directory was not included in the pullapprove config.
PR Close #58556
2024-11-07 22:43:23 +00:00
Alan Agius 7c4e0766be build: remove redundant file (#58556)
This file is incorrect.

PR Close #58556
2024-11-07 22:43:23 +00:00
Angular Robot fda8f70e29 build: lock file maintenance (#58450)
See associated pull request for more information.

PR Close #58450
2024-11-07 21:29:53 +00:00
Alan Agius c4a84920b2 refactor(compiler-cli): Improved filterMethodOverloads to Include Members without body (#58445)
Previously, `filterMethodOverloads` excluded all members without a body, causing issues with the extraction of functions and members in TypeScript types.

PR Close #58445
2024-11-07 21:28:55 +00:00
Alan Agius 671fafac95 docs: add hybrid rendering API guide (#58445)
This commit introduces a new guide for hybrid rendering APIs, which are currently in developer preview. This documentation provides insights into the usage and features of the APIs, helping developers understand their capabilities and limitations during the preview phase.

PR Close #58445
2024-11-07 21:28:55 +00:00
Alan Agius b62c4534b2 docs: update SSR documentation to include API references (#58445)
This update removes hard-coded options and enhances the SSR documentation to incorporate API references.

PR Close #58445
2024-11-07 21:28:55 +00:00
Alan Agius 3c0b2441fd build(docs-infra): include API references for @angular/ssr entry points (#58445)
This commit utilizes the `@angular/ssr` NPM package to generate an API reference for its entry points using the `generate_api_docs` Bazel rule, which will be included in http://angular.dev/api.

PR Close #58445
2024-11-07 21:28:55 +00:00
mgechev 3aa02635db docs: add v19 instructions in the update guide (#58268)
The first draft is mostly Gemini with some
rephrasing from me. Please have a look and suggest
edits :)

PR Close #58268
2024-11-07 19:00:04 +00:00
Alan Agius ab701ad1a6 ci: add myself to the renovate-changes PullApprove group (#58537)
I frequently need to ping others to approve Renovate PRs, so this should streamline the process.

PR Close #58537
2024-11-07 18:51:48 +00:00
Alan Agius 65a0a1d416 docs(docs-infra): add support for @remarks (#58523)
In TSDoc, we currently handle the `@usageNotes` annotation, but this is not a standard TSDoc tag. Instead, the `@remarks` annotation is the correct standard, which is used in the Angular CLI repo and on the SSR package.

This change ensures that `@remarks` is treated the same as `@usageNotes` during the transform process.

PR Close #58523
2024-11-07 15:49:15 +00:00
Charles Lyding 0ec9533a6f refactor(core): always create new renderer when applying HMR metadata update (#58527)
The DOM renderer classes perform initialization that captures state from
the component definition during construction. To ensure that the state is
kept synchronized with any newly applied metadata from an HMR `applyMetadata`
call, each renderer is now recreated during the apply process. This also
allows inline component styles to be updated in cases where external component
stylesheets may not be viable.

PR Close #58527
2024-11-07 14:30:31 +00:00
Alan Agius 203aa0c124 test(platform-server): fix issue with ngServerMode when focusing fit tests (#58538)
This commit addresses a problem with tests that use the `fit` function to focus on individual test cases. While these tests run successfully in the full suite, they fail when focused individually using `fit`.

The issue lies in the behavior of `withEventReply` and other hydration-related functions (i.e., `provideX`, `withX`). These functions return platform-specific providers based on the `ngServerMode` setting, causing inconsistencies between server and browser environments. As a result, provider instances cannot be reused across server and browser applications.

**Example of problematic code:**
```ts
const hydrationFeatures = [withEventReply()];
const html = await ssr(SimpleComponent, { hydrationFeatures });
// Expected behavior ...

const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
  hydrationFeatures,
});
// Expected behavior ...
```

**Solution:**
To address this, we define `hydrationFeatures` as a function instead of a static array. This ensures that a new instance of `withEventReply` is created separately for each environment, eliminating platform-specific mismatches between server and browser contexts:

```typescript
const hydrationFeatures = () => [withEventReply()];  // Define as a function
const html = await ssr(SimpleComponent, { hydrationFeatures: hydrationFeatures() });
// Expected behavior ...

const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
  hydrationFeatures: hydrationFeatures(),
});
// Expected behavior ...
```

PR Close #58538
2024-11-07 14:29:59 +00:00
Joey Perrott 4a0d9eb01e fix(docs-infra): update search provider link (#58542)
Update the link used to reference algolia as the search provider on our documentation site. Adds a few URL parameters
for algolia to map back to our usage.

PR Close #58542
2024-11-07 14:27:12 +00:00
Angular Robot 1ead8ba765 build: update cross-repo angular dependencies (#58544)
See associated pull request for more information.

PR Close #58544
2024-11-07 14:26:27 +00:00
Charles Lyding 10e6a25643 docs: add component HMR information to application build system (#58528)
Add background and usage information for the new component HMR features
available in v19.

PR Close #58528
2024-11-07 13:26:55 +01:00
Angular Robot 5eb3db8686 build: update cross-repo angular dependencies (#58457)
See associated pull request for more information.

PR Close #58457
2024-11-07 13:24:00 +01:00
Jessica Janiuk f994539f6b release: cut the v19.0.0-rc.1 release 2024-11-06 10:18:42 -08:00
Paul Gschwendtner 728bfbbb31 refactor(migrations): speed up code refactoring action for queries (#58525)
We were not properly passing around the TCB full program optimization,
so TCB generation was done per individual file. This significantly
slowed down reference resolution.

PR Close #58525
2024-11-06 16:30:18 +01:00
Paul Gschwendtner 4a0dc3c712 refactor(migrations): enable debug printing of compiler diagnostics (#58515)
This is useful for some migrations and eases debugging, so we are
building an environment-guarded debug print.

PR Close #58515
2024-11-06 13:04:22 +01:00
Paul Gschwendtner d4d76ead80 fix(compiler-cli): do not fail fatal when references to non-existent module are discovered (#58515)
Currently when application source code references e.g. an NgModule that
points to references that aren't available, the compiler will break at
runtime without any actionable/reasonable error.

This could happen for example when a library is referenced in code, but
the library is simply not available in the `node_modules`. Clearly,
TypeScript would issue import diagnostics here, but the Angular compiler
shouldn't break fatally. This is useful for migrations which may run
against projects which aren't fully compilable. The compiler handles
this fine in all cases, except when processing `.d.ts` currently... and
the runtime exception invalides all other information of the program
etc.

This commit fixes this by degrading such unexpected cases for `.d.ts`
metadata reading to be handled gracefully. This matches existing logic
where the `.d.ts` doesn't necessarily match the "expecation"/"expected
format".

The worst case is that the Angular compiler will not have type
information for some directives of e.g. a library that just isn't
installed in local `node_modules`; compared to magical errors and
unexpected runtime behavior.

PR Close #58515
2024-11-06 13:04:22 +01:00
Paul Gschwendtner e85ac5c7cb fix(migrations): properly bundle shared compiler code into migrations (#58515)
The use of relative imports vs. module imports and the existing mismatch
can cause symbols to be duplicated in migrations. This is problematic as
it breaks migration logic or compiler logic in the worst case.

Long-term we will solve this by having a better Bazel toolchain where
both relative and module imports can point to the same files; but in
practice this is not the case right now.

This commit fixes the fallback template logic in the signal
input/queries migration; in case no type check block information is
available.

PR Close #58515
2024-11-06 13:04:22 +01:00
Kristiyan Kostadinov 8ae84be3df fix(core): avoid slow stringification when checking for duplicates in dev mode (#58521)
When we check for duplicates in dev mode, we end up stringifying an `LView` even if we don't report an error. This can be expensive in large views.

These changes work around the issue by only generating the string when we have an error to throw.

Fixes #58509.

PR Close #58521
2024-11-06 13:02:37 +01:00
Kristiyan Kostadinov b0711d74c4 refactor(core): clean up standalone flag (#58478)
The `NG_STANDALONE_DEFAULT_VALUE` is no longer being patched internally and can be removed.

PR Close #58478
2024-11-06 07:01:25 +01:00
Madhu Ranjan 5c9e2e41e1 docs: fix example for pipe operator precedence by removing extra parenthesis (#58488)
PR Close #58488
2024-11-06 07:00:42 +01:00
Angular Robot 3db099c8e6 build: update babel dependencies (#58499)
See associated pull request for more information.

PR Close #58499
2024-11-06 06:59:44 +01:00
Angular Robot 85fa27d92a build: update dependency angular-split to v18 (#58510)
See associated pull request for more information.

PR Close #58510
2024-11-05 16:38:13 +01:00
Alan Agius 5b5828e856 ci: exclude packages/ssr/BUILD.bazel from requiring a G3 sync (#58514)
This file is only used to generate adev docs

PR Close #58514
2024-11-05 16:36:19 +01:00
Angular Robot e7ac965b29 docs: update Angular CLI help [19.0.x] (#58511)
Updated Angular CLI help contents.

PR Close #58511
2024-11-05 14:10:20 +01:00
Charles Lyding c36a1c023b fix(platform-browser): correctly add external stylesheets to ShadowDOM components (#58482)
Angular components that use ShadowDOM view encapsulation have an alternate
execution path for adding component styles to the DOM that does not use the
SharedStylesHost that all other view encapsulation modes leverage. To ensure
that ShadowDOM components receive all defined styles, additional logic has been
added to the ShadowDOM specific renderer to also cover external styles.

PR Close #58482
2024-11-05 11:33:17 +01:00
Angular Robot 90509f88fe build: update all non-major dependencies (#58506)
See associated pull request for more information.

PR Close #58506
2024-11-05 08:14:53 +01:00
Angular Robot a32e897c5a build: migrate config renovate.json (#58503)
PR Close #58503
2024-11-05 07:51:40 +01:00
Sheik Althaf ba84a02a6b refactor(devtools): convert to bootstrap application for shell and demo apps (#58319)
Migrated the demo apps and shell-browser apps to use bootstrap application, simplifed routing and standalone components.

PR Close #58319
2024-11-05 07:35:43 +01:00
cexbrayat 11f86a0a08 refactor(migrations): use import manager in provide-initializer (#58456)
The manual replacement logic had a flaw and was inserting the imports several times.

For example:

```ts
import { APP_INITIALIZER, ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { InitService } from './init.service';

export const appConfig: ApplicationConfig = {
  providers: [provideZoneChangeDetection({ eventCoalescing: true }),
    {
      provide: APP_INITIALIZER,
      useFactory: (initService: InitService) => initService.init(),
      deps: [InitService],
      multi: true
    },
    {
      provide: APP_INITIALIZER,
      useFactory: (initService: InitService) => initService.init(),
      deps: [InitService],
      multi: true
    }
  ]
};
```

produced:

```ts
import { ApplicationConfig, provideZoneChangeDetection, inject, provideAppInitializer }{ ApplicationConfig, provideZoneChangeDetection, inject, provideAppInitializer } from '@angular/core';
import { InitService } from './init.service';

export const appConfig: ApplicationConfig = {
  providers: [provideZoneChangeDetection({ eventCoalescing: true }),
    provideAppInitializer(() => { return ((initService: InitService) => initService.init())(inject(InitService)); }),
    provideAppInitializer(() => { return ((initService: InitService) => initService.init())(inject(InitService)); })
  ]
};
```

It now produces proper imports:

```ts
import { ApplicationConfig, provideZoneChangeDetection, inject, provideAppInitializer } from '@angular/core';
```

PR Close #58456
2024-11-04 18:15:00 +01:00
Miles Malerba 996593809c build: Update prettierrc to always use trailing commas (#58266)
This updates the prettierrc to reflect how the code seems to already be
formatted. I noticed that without this my IDE seemed to be introducing
formatting changes on save.

PR Close #58266
2024-11-04 18:14:05 +01:00
Koyejo e6b05c72ea docs: fix grammatical error in template binding documentation (#58491)
This update corrects a grammatical error in the "CSS style properties" section of the template binding documentation. The sentence "You must create a new object instance when you modify these values in order to Angular to apply any updates" was updated to read correctly as "You must create a new object instance when you modify these values in order for Angular to apply any updates." This clarification helps improve readability and ensures the documentation communicates instructions accurately for readers.
PR Close #58491
2024-11-04 17:15:39 +01:00
Kristiyan Kostadinov 6e0af6dbbb fix(core): resolve forward-referenced host directives during directive matching (#58492)
When the compiler generates the `HostDirectivesFeature`, it generates either an eager call (`ɵɵHostDirectivesFeature([])`) or a lazy call (`ɵɵHostDirectivesFeature(() => [])`. The lazy call is necessary when there are forward references within the `hostDirectives` array. Currently we resolve the lazy variant when the component definition is created which has been enough for most cases, however if the host is injected by one of its host directives, we can run into a reference error because DI is synchronous and the host's class hasn't been defined yet.

These changes resolve the issue by pushing the lazy resolution later during directive matching when all classes are guanrateed to exist.

Fixes #58485.

PR Close #58492
2024-11-04 16:17:23 +01:00
cexbrayat 36f4457b69 refactor(migrations): useFactory in provide-initializer migration (#58493)
The following provider:

```ts
{
  provide: APP_INITIALIZER,
  useFactory: (initService: InitService) => {
    return () => initService.init()
  },
  deps: [InitService],
  multi: true
}
```

was migrated into:

```ts
provideAppInitializer(() => { return ((initService: InitService) => {
  return () => initService.init()
})(inject(InitService)); })
```

This doesn't compile because there is an extra function:

```
✘ [ERROR] TS2345: Argument of type '() => () => void' is not assignable to parameter of type '() => void | Observable<unknown> | Promise<unknown>'.
  Type '() => void' is not assignable to type 'void | Observable<unknown> | Promise<unknown>'. [plugin angular-compiler]

    src/app/app.config.ts:7:26:
      7 │ ...ovideAppInitializer(() => { return ((initService: InitService) => {
```

It now migrates the provider into:

```ts
provideAppInitializer(((initService: InitService) => {
  return () => initService.init()
})(inject(InitService)))
```

PR Close #58493
2024-11-04 15:45:50 +01:00
Angular Robot 61565eafee build: update io_bazel_rules_sass digest to c375923 (#58477)
See associated pull request for more information.

PR Close #58477
2024-11-04 15:37:38 +01:00
Alan Agius 23b1316822 ci: restore the local Yarn copy before executing renovate-update-generated-files (#58497)
There is an unidentified issue causing the Yarn binary to be altered, resulting in packages not installing correctly and leading to failures in the process.

PR Close #58497
2024-11-04 15:35:06 +01:00
Enea Jahollari c5e676bb87 fix(migrations): flip the default standalone flag in route-lazy-loading migration (#58474)
Before v19, the default value of the standalone flag was false, this code change flips the logic in the migration to make it true by default.

PR Close #58474
2024-11-03 19:07:09 +01:00
Kristiyan Kostadinov 86d8f6bda8 refactor(compiler): trigger hmr load on initialization (#58465)
Adjusts the HMR initialization to avoid the edge case where a developer makes change to a non-rendered component that exists in a lazy loaded chunk that has not been loaded yet. The changes include:
* Moving the `import` statement out into a separate function.
* Adding a null check for `d.default` before calling `replaceMEtadata`.
* Triggering the `import` callback eagerly on initialization.

Example of the new generated code:

```js
(() => {
  function Cmp_HmrLoad(t) {
    import(
      /* @vite-ignore */ "/@ng/component?c=test.ts%40Cmp&t=" + encodeURIComponent(t)
    ).then((m) => m.default && i0.ɵɵreplaceMetadata(Cmp, m.default, [/* Dependencies go here */]));
  }
  (typeof ngDevMode === "undefined" || ngDevMode) && Cmp_HmrLoad(Date.now());
  (typeof ngDevMode === "undefined" || ngDevMode) &&
    import.meta.hot &&
    import.meta.hot.on("angular:component-update", (d) => {
      if (d.id === "test.ts%40Cmp") {
        Cmp_HmrLoad(d.timestamp);
      }
    });
})();
```

PR Close #58465
2024-11-01 19:14:16 +00:00
Alan Agius 3f82c3f0eb ci: run Renovate post tasks sequentially (#58472)
Due to a bug in Renovate (see: https://github.com/sarunint/renovate/blob/276a01fdd743d270fd2662cabb3b0e1e465aec83/lib/util/exec/common.ts#L50-L53), post tasks are incorrectly running in parallel. This causes 'yarn install' to overlap with 'yarn ng-dev misc update-generated-files', resulting in incomplete installs before file updates start.

PR Close #58472
2024-11-01 19:10:28 +00:00
Alan Agius 5278f194e5 ci: update renovate postUpgradeTasks executionMode to branch (#58470)
This change modifies the execution level of `postUpgradeTasks` in Renovate. By setting `executionMode` to `branch`, the task will run once per branch, rather than for each dependency update. This helps streamline tasks across dependencies by consolidating them at the branch level.

PR Close #58470
2024-11-01 16:50:50 +00:00
Costin Sin efa7baa976 refactor(zone.js): Change the type of _taskCounts to an IndexSignature that can have keys (#51739)
named as the values of the `TaskType` type.

The Closure Compiler used at Google has a property renaming optimization
that can change the property names when minifying code. Having the
correct type helps the TSJS team that develops a tool to identfy
property renaming issues directly in TypeScript.

Signed-off-by: Costin Sin <sin.costinrobert@gmail.com>

PR Close #51739
2024-11-01 15:44:09 +00:00
Alan Agius f87a773278 ci: restrict file updates to a specified file location for post-task saves (#58460)
This is aiming to resolve issues with Renovate when executing `yarn ng-dev misc update-generated-files`

PR Close #58460
2024-11-01 15:43:23 +00:00
Angular Robot da1cd6fc59 build: update io_bazel_rules_sass digest to e3b2785 (#58420)
See associated pull request for more information.

PR Close #58420
2024-11-01 14:42:59 +00:00
Jordan Hall 257d5b9979 build: Update publish-build-artifacts to honor ORG (#58408)
Currently you pass in the ORG and it still tries to publish to Angular rather than your ow ORG repo that gets created

PR Close #58408
2024-11-01 14:41:58 +00:00
Shannon V.C. 8a38b68561 docs: fix external link in NG0100 error page (#58462)
Fixes external link for 'Everything you need to know about the "ExpressionChangedAfterItHasBeenCheckedError" error' on the NG0100 error page.
Domain has changed from indepth.dev to angularindepth.com

PR Close #58462
2024-11-01 14:34:31 +00:00
Kristiyan Kostadinov 3b130087e9 refactor(language-service): update code fix for unused imports (#58468)
Since the unused imports diagnostic setup has changed, we need to update the code fix to account for it.

PR Close #58468
2024-11-01 14:33:56 +00:00
Kristiyan Kostadinov 22cd6869ef fix(compiler-cli): make the unused imports diagnostic easier to read (#58468)
The unused imports diagnostic reports once on the entire initializer and then again once per unused imports. This ends up being a bit hard to follow, because in a lot of cases the code snippet looks identical.

These changes switch to highlighting the `imports:` part of the property declaration and only highlighting the unused imports without a message.

PR Close #58468
2024-11-01 14:33:56 +00:00
Kristiyan Kostadinov abd0da7265 refactor(compiler): remove unused field from output AST (#58444)
The `ExternalReference.runtime` field wasn't being used anywhere.

PR Close #58444
2024-11-01 14:32:57 +00:00
Kristiyan Kostadinov b25121ee4a fix(compiler): avoid having to duplicate core environment (#58444)
Switches to referencing the core environment directly in the generated code, instead of having to duplicate it.

PR Close #58444
2024-11-01 14:32:57 +00:00
Jeevan Mahesha d7a7c80066 docs: update ng-template guide to include NgTemplateOutlet import and correct syntax (#58443)
PR Close #58443
2024-10-31 19:59:19 +01:00
Pawel Kozlowski f1aab73189 refactor(docs-infra): migrate to output (#58447)
This change contains result of the automated migration
of the decorator based @Output to the function equivalent.

PR Close #58447
2024-10-31 19:58:37 +01:00
Alan Agius 1a919034a1 build: update yarn to 1.22.22 (#58448)
Trying to get around a problem is causing renovate to keep trying updating this file.

PR Close #58448
2024-10-31 19:06:20 +01:00
Alan Agius 44a7257303 build: update cross-repo angular dependencies (#58446)
See associated pull request for more information.

Closes #57880 as a pr takeover

PR Close #58446
2024-10-31 19:05:01 +01:00
Andrew Kushnir 600ef5eff2 refactor(core): tree-shake defer block registry (#58424)
This commit updates the code of the incremental hydration feature to make the `DeferBlockRegistry` class tree-shakable. The class is only needed for hydration cases and it should not be included into client bundles for client-only apps.

PR Close #58424
2024-10-31 18:12:03 +01:00
Jessica Janiuk 0ca14e2c72 refactor(core): More cleanup of incremental hydration code (#58430)
This cleans up much of incremental.ts and adds documentation.

PR Close #58430
2024-10-31 11:26:58 +01:00
Jessica Janiuk 8d00d0fe85 refactor(core): Eliminate recursion in incremental hydration (#58419)
This implements a queue rather than a recursive call, which enables
proper cleanup timing for defer block registry.

PR Close #58419
2024-10-31 11:22:58 +01:00
Kristiyan Kostadinov ea9bfff739 refactor(migrations): attempt to correct initialization order in internal inject migration (#58427)
Updates the internal part of the `inject` migration to attempt to correct some cases where the declaration order of properties doesn't match the initialization order.

PR Close #58427
2024-10-31 09:17:51 +01:00
Kristiyan Kostadinov bb6e0aab1b refactor(migrations): make it easier to delete nodes including comments (#58427)
We were repeating the logic that deletes a node together with all its comments in a few different places. These changes consolidate the logic under `ChangeTracker.removeNode`.

PR Close #58427
2024-10-31 09:17:51 +01:00
Kristiyan Kostadinov b5b0b4af29 refactor(migrations): internal inject migration applying some changes to abstract classes (#58427)
We were filtering out abstract classes pretty late in the migration which led to the internal part of it to make some changes that aren't finalized later. These changes fix the issue by filtering out abstract classes during analysis.

PR Close #58427
2024-10-31 09:17:51 +01:00
Alan Agius ea086905c3 fix(docs-infra): reduce margin-block-start from doc anchor headers (#58431)
This change reduces the spacing between headers, which is currently excessive.

PR Close #58431
2024-10-31 09:15:36 +01:00
Alex Rickabaugh ee1d06c8fa release: cut the v19.0.0-rc.0 release 2024-10-30 13:20:44 -07:00
Matthieu Riegler dcd16b43f3 refactor(migrations): Make the explicit standalone migration idempotent (#58418)
With this commit the  explicit standalone migration uses the presents of imports to make sure that we can safely remove the standalone prop
and not adding it again when re-run.

PR Close #58418
2024-10-30 11:55:11 -07:00
Alan Agius 3230d78c54 refactor(core): introduce ngServerMode as global (#58386)
This commit adds the `ngServerMode` as global, which allows for the tree-shaking of server-only code from the bundles. When this flag is unset at runtime, server-specific code will be excluded by Closure, optimizing bundle size.

**Internal Angular Flag:** This is an internal Angular flag (not a public API), avoid relying on it in application code.

PR Close #58386
2024-10-30 10:13:28 -07:00
Pawel Kozlowski 616b411a6d fix(migrations): properly migrate output aliases (#58411)
Before this fix the output migration was incorrectly assuming
that the @Output decorator takes its params as an object.
What happens in reality is that the @Output decorator is taking
alias as the only argument, without any object literal wrapper.

PR Close #58411
2024-10-30 10:01:28 -07:00
Pawel Kozlowski d504452e2f fix(migrations): properly replace imports across files (#58414)
This change fixes a bug where the output migration was interacting
with the InputManager utility in the way that was resulting in
incorrect import replacements.

The fix consists of making sure that a new ImportManager instance
is created for each and every file containing @Output declarations.

PR Close #58414
2024-10-30 09:24:06 -07:00
Paul Gschwendtner ddef41e897 refactor(migrations): gracefully handle metadata parsing errors in signal migration (#58413)
In 1P, we saw that a type of a target wasn't resolvable, referenced in a
`hostBindings#directive` field. This breaks the entire pipeline; so we
should handle gracefully but report an error.

Worst case scenario here is that we would miss some references to the
given directive/component. This is acceptable and we can continue
investigation why that given target was broken; especially since the
file was part of the target inputs- but seemingly not in the `tsconfig`.

PR Close #58413
2024-10-30 09:23:39 -07:00
Paul Gschwendtner 8709359a1f refactor(migrations): improve temporary variable insertion in signal migrations (#58413)
Fixes that the migrations weren't properly determing the highest block
of multiple shared references. The logic was flawed by checking the
`start` indices; because we also need to respect that the blocks
should enclose all references; and the block practically is a common
ancestor. This is not guaranteed without this commit.

Note: The logic assumes that all references are part of the same control
flow container; this is verified.

PR Close #58413
2024-10-30 09:23:39 -07:00
Kristiyan Kostadinov dbe612f2cd fix(compiler-cli): disable standalone by default on older versions of Angular (#58405)
Disables the standalone by default behavior in the compiler when running against and older version of Angular. This is necessary, because the language service may be using the latest version of the compiler against and older version of core in a particular workspace.

PR Close #58405
2024-10-30 09:23:12 -07:00
Pawel Kozlowski 3e50842593 refactor(docs-infra): use reactive APIs in adev components (#58357)
This is a relativelly small refactoring to a couple of
adev components. The goal here is to use new reactive
APIs in the idiomatic way.

PR Close #58357
2024-10-30 09:21:25 -07:00
Angular Robot 3d918de05f build: update scorecard action dependencies (#58400)
See associated pull request for more information.

PR Close #58400
2024-10-29 05:10:31 -07:00
Alan Agius a899623b51 refactor(core): move static AfterRenderImpl.PHASES to a top-level variable (#58402)
Improves code minification.

PR Close #58402
2024-10-29 05:08:13 -07:00
Jessica Janiuk 7cb6adcb50 refactor(core): prevent unnecessary hydration work in csr cases (#58366)
This adds a shouldHydrate check that prevents any additional work in cases when hydration is not necessary.

PR Close #58366
2024-10-29 05:07:37 -07:00
Jessica Janiuk fd7716440b fix(core): Prevents trying to trigger incremental hydration on CSR (#58366)
hydrate triggers were firing in CSR cases and attempting to find parent defer blocks. This prevents that from happening. In these cases, the defer block id will be empty.

fixes: #58359

PR Close #58366
2024-10-29 05:07:37 -07:00
Angular Robot 98f54cb134 docs: update Angular CLI help [19.0.x] (#58395)
Updated Angular CLI help contents.

PR Close #58395
2024-10-28 12:50:53 -07:00
george looshch 23531f249e docs: remove an unnecessary whitespace (#58388)
Remove an unnecessary whitespace between an opening parenthesis and a
word in the documentation on lifecycle.

Closes #58380

PR Close #58388

PR Close #58388
2024-10-28 12:49:38 -07:00
george looshch c6a21cc7f9 docs: fix backtick escaping in a Markdown file (#58387)
Fix backtick escaping for the template string example in the
documentation on expression syntax.

Closes #58382

PR Close #58387

PR Close #58387
2024-10-28 12:49:01 -07:00
Jeevan Mahesha df14cb6f8e docs: update ProfileEditorComponent to use inject() for FormBuilder (#58378)
PR Close #58378
2024-10-28 12:48:29 -07:00
Jessica Janiuk f815d7b8c8 refactor(core): Additional cleanup for incremental hydration (#58394)
This adds comments, removes some duplicate logic, and eliminates some unnecessary complexity of the incremental hydration core logic.

PR Close #58394
2024-10-28 12:40:27 -07:00
Kristiyan Kostadinov 90c7ec39a0 fix(migrations): inject migration always inserting generated variables before super call (#58393)
Fixes that if a class has a `super` call, the `inject` migration would always insert the generated variable before it, even if there's other code before the `super` call.

PR Close #58393
2024-10-28 12:39:04 -07:00
Kristiyan Kostadinov eafe9040a2 refactor(migrations): inject migration internal mode incorrectly migration properties initialized to identifiers (#58393)
Fixes that when the `inject` migration in internal mode was starting to visit the nodes one level down from the root when considering whether an expression contains local references. This lead it to skip over top-level identifiers and migrate some code incorrectly.

PR Close #58393
2024-10-28 12:39:04 -07:00
Kristiyan Kostadinov 7a65cdd911 fix(migrations): inject migration not inserting generated code after super call in some cases (#58393)
Fixes an issue where the `inject` migration was generating and attempting to insert code after a `super` call, but the string buffering implementation was dropping it if the statement right after the `super` call was deleted as a result of the migration.

PR Close #58393
2024-10-28 12:39:03 -07:00
Kristiyan Kostadinov 1806fcce82 refactor(migrations): hoist uninitialized members to top of class if they are not combined in the internal migration (#58393)
When the internal mode for the `inject` migration is enabled, we find properties without initializers, we add their initializers and we prepend the `inject` calls before them. The remaining properties that couldn't be combined are left in place. This appears to break some internal cases.

These changes work around the issue by hoisting all the non-combined members above the `inject()` calls. This should be safe, because they don't have initializers and as such can't have dependencies.

PR Close #58393
2024-10-28 12:39:03 -07:00
Kristiyan Kostadinov 598c397c85 refactor(core): account for anonymous classes in internal utility (#58392)
Fixes that the `getClosestComponentName` utility was reporting an empty string if it encounters an anonymous class.

PR Close #58392
2024-10-28 12:38:03 -07:00
Brandon Roberts 98804fd4be fix(compiler): add more specific matcher for hydrate never block (#58360)
Fixes an issue where additional characters were allowed afte the "hydrate never" block.

Closes #58358

PR Close #58360
2024-10-28 12:35:11 -07:00
Kristiyan Kostadinov ad3fbe6d97 refactor(core): remove globalApi tag (#58375)
`@globalApi` was an AIO implementation detail that isn't relevant anymore.

PR Close #58375
2024-10-28 12:33:54 -07:00
Angular Robot 2de5314400 build: update actions/checkout digest to 11bd719 (#58329)
See associated pull request for more information.

PR Close #58329
2024-10-28 12:31:14 -07:00
David LJ c0d606195c docs: fix errata in provideEnvironmentInitializer API docs (#58355)
PR Close #58355
2024-10-28 12:29:53 -07:00
Alan Agius 1efc4bb9e6 test: update defer symbol test golden file (#58297)
Update the golden file of the defer symbol test

PR Close #58297
2024-10-28 12:26:06 -07:00
Alan Agius 2d3a689660 refactor(core): eliminate top-level property access in ɵɵNgOnChangesFeature (#58297)
Top-level property access was causing dead code elimination (DCE) and tree-shaking issues. This commit modifies `ɵɵNgOnChangesFeature` to prevent these bailouts.

PR Close #58297
2024-10-28 12:26:06 -07:00
Alan Agius cf7f8c7c03 refactor(core): make AfterRenderImpl tree-shakable by moving PHASES (#58297)
Marked the PHASES constant within AfterRenderImpl as @__PURE__ to enable better tree-shaking during bundling. This optimization ensures that unused code is more effectively eliminated, improving overall bundle size and performance.

Closes #58296

PR Close #58297
2024-10-28 12:26:06 -07:00
Alan Agius 7dfb127c03 refactor: add @__PURE__ next to @pureOrBreakMyCode for improved bundler compatibility (#58297)
Added the `@__PURE__` annotation alongside `@pureOrBreakMyCode` to improve compatibility with third-party bundlers. This refactor follows optimization best practices, ensuring broader support across different tools, as `@pureOrBreakMyCode` was only supported by Closure Compiler.

PR Close #58297
2024-10-28 12:26:06 -07:00
Alan Agius 93c3f7a931 build: remove usages of useDefineForClassFields: false (#58297)
When setting `"useDefineForClassFields": false`, static fields are compiled within a block that relies on the `this` context. This output makes it more difficult for bundlers to treeshake and eliminate unused code.

PR Close #58297
2024-10-28 12:26:06 -07:00
Jessica Janiuk 395cb34599 refactor(core): cleanup incremental hydration code (#58363)
This cleans up some minor issues with the incremental hydration implementation and should make maintaining it a little easier.

PR Close #58363
2024-10-28 09:26:45 -07:00
Paul Gschwendtner 00b79f8157 test: support parallel tsurge unit combining in batch test infra (#58280)
This allows the batch test for the signal input migration to pass.

PR Close #58280
2024-10-25 18:47:41 +00:00
Paul Gschwendtner 50e99b66e5 refactor(migrations): update migrations to combine analysis data in parallel (#58280)
This is necessary given the previous Tsurge refactorings. It should
speed up migrations in the merge phase signficiantly and reduce memory
pressure. In 1P, we already have workers from analyze phase anyway— so
those can be re-used for parallel metadata merging.

PR Close #58280
2024-10-25 18:47:41 +00:00
Paul Gschwendtner 0b2f18ff25 refactor(migrations): support parallel tsurge metadata merging (#58280)
This is helpful and important for large scale migrations where a single
call for merging _all_ unit data's can be subject to memory / disk
resource constraints. Consider a compilation unit data for every target
in Google3, and those being merged in a single program.

PR Close #58280
2024-10-25 18:47:41 +00:00
Matthieu Riegler 77fa588025 ci: disable adev tests (#58367)
The changes in #58288 are responsible for breaking the tests (see #54858). We'll re-enable them on the next release.

PR Close #58367
2024-10-25 18:45:21 +00:00
Yong Su d7283bf740 refactor(core): allow passing passive option to addEvent (#58316)
For scroll-blocking events like 'touchstart', 'touchmove', 'wheel' and 'mousewheel',
if passive option is not specified when adding the event listener, browser may give
a violation warning.

This PR allows us to set the passive option when calling event lib's addEvent().

PR Close #58316
2024-10-24 17:49:26 -07:00
Yong Su f34268161b refactor(core): allow passing passive option to addEvent (#58316)
For scroll-blocking events like 'touchstart', 'touchmove', 'wheel' and 'mousewheel',
if passive option is not specified when adding the event listener, browser may give
a violation warning.

This PR allows us to set the passive option when calling event lib's addEvent().

PR Close #58316
2024-10-24 17:49:26 -07:00
Matthieu Riegler 9c4bcb16ca docs(docs-infra): re-enable adev tests (#58276)
PR Close #58276
2024-10-24 16:42:18 -07:00
Daniel Payet 0730d9d748 fix(localize): Adding arb format to the list of valid formats in the localization extractor cli (#58287)
Although the ARB format is supported, it's missing from the command's list of options.

Fix #58286

PR Close #58287
2024-10-24 16:41:49 -07:00
Joey Perrott a49c35ec76 fix(router): remove setter for injector on OutletContext (#58343)
This is a cleanup/completion of the work in #56798

PR Close #58343
2024-10-24 16:41:04 -07:00
Brandon Roberts 917e99db42 docs(platform-browser): update usage notes for incremental hydration (#58339)
PR Close #58339
2024-10-24 16:39:27 -07:00
Alex Rickabaugh da9c0c5044 refactor: cleanup initializers that use ctor params (#58349)
Fix initializer of instance members that reference identifiers declared in
the constructor.

When public class fields are enabled, such cases throw TS2729: property used
before its initialization.

PR Close #58349
2024-10-24 16:38:50 -07:00
Angular Robot d5998daa3d build: update io_bazel_rules_sass digest to c677123 (#58338)
See associated pull request for more information.

PR Close #58338
2024-10-24 16:36:37 -07:00
Gourav102 486c5a9d7e Update queries.md (#58330)
Fixed a formatting error and a grammar error
PR Close #58330
2024-10-24 16:25:11 -07:00
Jessica Janiuk 28516fd852 refactor(core): prevent annotating in hydrate never blocks (#58328)
This fixes an issue with hydrate never where jsaction annotations would still hydrate even when they should not.'

PR Close #58328
2024-10-24 16:20:53 -07:00
Matthieu Riegler c79b62ced2 refactor(core): remove the standalone feature (#58288)
By removing the standalone feature, we reduce the amount of code generated for components but at the cost of including the `StandaloneService` in the main bundle even if no standalone components are included in it.

PR Close #58288
2024-10-24 16:19:02 -07:00
Kristiyan Kostadinov c095679f92 fix(core): avoid breaking change with apps using rxjs 6.x (#58341)
The `rxResource` was using `firstValueFrom` which isn't supported in rxjs 6.x. `@angular/core` currently supports rxjs 6 so we need this to be backwards compatible. This came up when trying to deploy the Material docs site which is still on rxjs 6 ([see](https://github.com/angular/components/actions/runs/11487971079/job/31973721563)).

PR Close #58341
2024-10-24 16:17:48 -07:00
Matthieu Riegler aadcfda224 refactor(language-service): support standalone by default (#58238)
`isStandaloneDecorator()` returns `false` only when the component is explicitly not standalone

PR Close #58238
2024-10-24 12:44:13 -07:00
Matthieu Riegler d9ac59c88f refactor(compiler): update compliance tests. (#58238)
`standalone: true` is now the default at runtime.

PR Close #58238
2024-10-24 12:44:13 -07:00
Matthieu Riegler 61a732d71e refactor(core): Don't generate standalone: true for definitions (#58238)
The runtime default is now `standalone: true`.
`ɵɵdefineComponent`, `ɵɵdefineDirective` and `ɵɵdefinePipe` now set `standalone` as `true` by default in the definitions.

PR Close #58238
2024-10-24 12:44:13 -07:00
Néstor Sabater a36b54d63e docs(router): document segment consumption during route evaluation (#58069)
PR Close #58069
2024-10-24 12:41:40 -07:00
Andrew Kushnir f418b49547 release: cut the v19.0.0-next.11 release 2024-10-23 13:19:55 -07:00
1144 changed files with 40012 additions and 30991 deletions
+7 -7
View File
@@ -8,32 +8,32 @@ dist
# All integration test node_modules folders
integration/animations/node_modules
integration/animations-async/node_modules
integration/cli-elements-universal/node_modules
integration/cli-hello-world/node_modules
integration/cli-hello-world-ivy-i18n/node_modules
integration/cli-hello-world-lazy/node_modules
integration/cli-hello-world-mocha/node_modules
integration/cli-signal-inputs/node_modules
integration/platform-server-hydration/node_modules
integration/defer/node_modules
integration/dynamic-compiler/node_modules
integration/forms/node_modules
integration/injectable-def/node_modules
integration/ivy-i18n/node_modules
integration/ng-add-localize/node_modules
integration/ng_elements/node_modules
integration/ng_update/node_modules
integration/ng_update_migrations/node_modules
integration/ng-add-localize/node_modules
integration/nodenext_resolution/node_modules
integration/npm_package_archives.bzl/node_modules
integration/platform-server/node_modules
integration/platform-server-hydration/node_modules
integration/service-worker-schema/node_modules
integration/side-effects/node_modules
integration/standalone-bootstrap/node_modules
integration/terser/node_modules
integration/trusted-types/node_modules
integration/typings_test_rxjs7/node_modules
integration/typings_test_ts49/node_modules
integration/typings_test_ts50/node_modules
integration/typings_test_ts51/node_modules
integration/typings_test_ts52/node_modules
integration/typings_test_ts55/node_modules
integration/typings_test_ts56/node_modules
integration/typings_test_ts57/node_modules
modules/ssr-benchmarks/node_modules
-6
View File
@@ -78,12 +78,6 @@ query --output=label_kind
# By default, failing tests don't print any output, it goes to the log file
test --test_output=errors
################################
# Settings for CircleCI #
################################
# Bazel flags for CircleCI are in /.circleci/bazel.linux.rc and /.circleci/bazel.windows.rc
##################################
# Remote Build Execution support #
# Turn on these settings with #
-19
View File
@@ -1,19 +0,0 @@
# Encryption
Based on https://github.com/circleci/encrypted-files
In the CircleCI web UI, we have a secret variable called `KEY`
https://circleci.com/gh/angular/angular/edit#env-vars
which is only exposed to non-fork builds
(see "Pass secrets to builds from forked pull requests" under
https://circleci.com/gh/angular/angular/edit#advanced-settings)
We use this as a symmetric AES encryption key to encrypt tokens like
a GitHub token that enables publishing snapshots.
To create the github_token file, we take this approach:
- Find the angular-builds:token in the internal pw database
- Go inside the CircleCI default docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it circleci/node:10.12`
- echo "https://[token]:@github.com" > credentials
- openssl aes-256-cbc -e -in credentials -out .circleci/github_token -k $KEY
- If needed, base64-encode the result so you can copy-paste it out of docker: `base64 github_token`
-16
View File
@@ -1,16 +0,0 @@
# Settings in this file should be OS agnostic. Use the bazel.<OS>.rc files for OS specific settings.
# Print all the options that apply to the build.
# This helps us diagnose which options override others
# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc)
build --announce_rc
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
# By default this is set in the project `.bazelrc` to `1`.
test --flaky_test_attempts=3
# More details on failures
build --verbose_failures=true
# CI supports colors but Bazel does not detect it.
common --color=yes
-23
View File
@@ -1,23 +0,0 @@
# These options are enabled when running on CI
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
# See documentation in /docs/BAZEL.md
# Import config items common to both Linux and Windows setups.
# https://docs.bazel.build/versions/master/guide.html#bazelrc-syntax-and-semantics
try-import %workspace%/.circleci/bazel.common.rc
# Save downloaded repositories in a location that can be cached by CircleCI. This helps us
# speeding up the analysis time significantly with Bazel managed node dependencies on the CI.
build --repository_cache=/home/circleci/bazel_repository_cache
# Workaround https://github.com/bazelbuild/bazel/issues/3645
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
# Limit Bazel to consuming resources that fit in CircleCI "2xlarge+" class
# https://circleci.com/docs/2.0/configuration-reference/#resource_class
build --local_cpu_resources=20
build --local_ram_resources=40960
# All build executed remotely should be done using our RBE configuration.
build:remote --google_default_credentials
build --config=remote
-17
View File
@@ -1,17 +0,0 @@
# These options are enabled when running on CI
# We do this by copying this file to $env:ProgramData\bazel.bazelrc at the start of the build.
# See documentation in /docs/BAZEL.md
# Import config items common to both Linux and Windows setups.
# https://docs.bazel.build/versions/master/guide.html#bazelrc-syntax-and-semantics
try-import %workspace%/.circleci/bazel.common.rc
# Manually set the local resources used in windows CI runs
build --local_ram_resources=120000
build --local_cpu_resources=32
# All windows jobs run on master and should use http caching
build --remote_http_cache=https://storage.googleapis.com/angular-team-cache
build --remote_accept_cached=true
build --remote_upload_local_results=true
build --google_default_credentials
-16
View File
@@ -1,16 +0,0 @@
# This config is remaining in place to prevent pull requests failing because of CircleCI config missing.
version: 2.1
jobs:
pass:
docker:
- image: cimg/base:2022.05
steps:
- run: echo "This too shall pass (always)"
workflows:
version: 2
default_workflow:
jobs:
- pass
-76
View File
@@ -1,76 +0,0 @@
####################################################################################################
# Helpers for defining environment variables for CircleCI.
#
# In CircleCI, each step runs in a new shell. The way to share ENV variables across steps is to
# export them from `$BASH_ENV`, which is automatically sourced at the beginning of every step (for
# the default `bash` shell).
#
# See also https://circleci.com/docs/2.0/env-vars/#using-bash_env-to-set-environment-variables.
####################################################################################################
# Set and print an environment variable.
#
# Use this function for setting environment variables that are public, i.e. it is OK for them to be
# visible to anyone through the CI logs.
#
# Usage: `setPublicVar <name> <value>`
function setPublicVar() {
setSecretVar $1 "$2";
echo "$1=$2";
}
# Set (without printing) an environment variable.
#
# Use this function for setting environment variables that are secret, i.e. should not be visible to
# everyone through the CI logs.
#
# Usage: `setSecretVar <name> <value>`
function setSecretVar() {
# WARNING: Secrets (e.g. passwords, access tokens) should NOT be printed.
# (Keep original shell options to restore at the end.)
local -r originalShellOptions=$(set +o);
set +x -eu -o pipefail;
local assignmentStatement="export $1=\"${2:-}\";"
echo "${assignmentStatement}" >> $BASH_ENV;
eval "${assignmentStatement}"
# Restore original shell options.
eval "$originalShellOptions";
}
# Create a function to set an environment variable, when called.
#
# Use this function for creating setter for public environment variables that require expensive or
# time-consuming computations and may not be needed. When needed, you can call this function to set
# the environment variable (which will be available through `$BASH_ENV` from that point onwards).
#
# Arguments:
# - `<name>`: The name of the environment variable. The generated setter function will be
# `setPublicVar_<name>`.
# - `<code>`: The code to run to compute the value for the variable. Since this code should be
# executed lazily, it must be properly escaped. For example:
# ```sh
# # DO NOT do this:
# createPublicVarSetter MY_VAR "$(whoami)"; # `whoami` will be evaluated eagerly
#
# # DO this isntead:
# createPublicVarSetter MY_VAR "\$(whoami)"; # `whoami` will NOT be evaluated eagerly
# ```
#
# Usage: `createPublicVarSetter <name> <code>`
#
# Example:
# ```sh
# createPublicVarSetter MY_VAR 'echo "FOO"';
# echo $MY_VAR; # Not defined
#
# setPublicVar_MY_VAR;
# source $BASH_ENV;
# echo $MY_VAR; # FOO
# ```
function createPublicVarSetter() {
echo "setPublicVar_$1() { setPublicVar $1 \"$2\"; }" >> $BASH_ENV;
}
-4
View File
@@ -1,4 +0,0 @@
####################################################################################################
# Set bazel configuration for CircleCI runs.
####################################################################################################
cp "${PROJECT_ROOT}/.circleci/bazel.linux.rc" ".bazelrc.user";
-88
View File
@@ -1,88 +0,0 @@
#!/usr/bin/env bash
# Variables
readonly projectDir=$(realpath "$(dirname ${BASH_SOURCE[0]})/..")
readonly envHelpersPath="$projectDir/.circleci/env-helpers.inc.sh";
# Load helpers and make them available everywhere (through `$BASH_ENV`).
source $envHelpersPath;
echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
# Define PUBLIC environment variables for CircleCI.
####################################################################################################
# See https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables for more info.
####################################################################################################
setPublicVar CI "$CI"
setPublicVar PROJECT_ROOT "$projectDir";
# This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL";
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
# `CI_COMMIT_RANGE` is only used on push builds (a.k.a. non-PR, non-scheduled builds and rerun
# workflows of such builds).
setPublicVar CI_GIT_BASE_REVISION "${CIRCLE_GIT_BASE_REVISION}";
setPublicVar CI_GIT_REVISION "${CIRCLE_GIT_REVISION}";
setPublicVar CI_COMMIT_RANGE "$CIRCLE_GIT_BASE_REVISION..$CIRCLE_GIT_REVISION";
setPublicVar CI_PULL_REQUEST "${CIRCLE_PR_NUMBER:-false}";
setPublicVar CI_REPO_NAME "$CIRCLE_PROJECT_REPONAME";
setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
setPublicVar CI_PR_REPONAME "$CIRCLE_PR_REPONAME";
setPublicVar CI_PR_USERNAME "$CIRCLE_PR_USERNAME";
####################################################################################################
# Define "lazy" PUBLIC environment variables for CircleCI.
# (I.e. functions to set an environment variable when called.)
####################################################################################################
createPublicVarSetter CI_STABLE_BRANCH "\$(npm info @angular/core dist-tags.latest | sed -r 's/^\\s*([0-9]+\\.[0-9]+)\\.[0-9]+.*$/\\1.x/')";
####################################################################################################
# Define SECRET environment variables for CircleCI.
####################################################################################################
setSecretVar CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN "$AIO_DEPLOY_TOKEN";
setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
####################################################################################################
# Define SauceLabs environment variables for CircleCI.
####################################################################################################
setPublicVar SAUCE_USERNAME "angular-framework";
setSecretVar SAUCE_ACCESS_KEY "f4bf7c639c5a-c6bb-d6a4-a4b5-800aa111";
# TODO(josephperrott): Remove environment variables once all saucelabs tests are via bazel method.
setPublicVar SAUCE_LOG_FILE /tmp/angular/sauce-connect.log
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-framework-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX}"
# Amount of seconds we wait for sauceconnect to establish a tunnel instance. In order to not
# acquire CircleCI instances for too long if sauceconnect failed, we need a connect timeout.
setPublicVar SAUCE_READY_FILE_TIMEOUT 120
####################################################################################################
# Create shell script in /tmp for Bazel actions to access CI envs without
# busting the cache. Used by payload-size.sh script in integration tests.
####################################################################################################
readonly bazelVarEnv="/tmp/bazel-ci-env.sh"
echo "# Setup by /.circle/env.sh" > $bazelVarEnv
echo "export PROJECT_ROOT=\"${PROJECT_ROOT}\";" >> $bazelVarEnv
echo "export CI_BRANCH=\"${CI_BRANCH}\";" >> $bazelVarEnv
echo "export CI_BUILD_URL=\"${CI_BUILD_URL}\";" >> $bazelVarEnv
echo "export CI_COMMIT=\"${CI_COMMIT}\";" >> $bazelVarEnv
echo "export CI_PULL_REQUEST=\"${CI_PULL_REQUEST}\";" >> $bazelVarEnv
echo "export CI_REPO_NAME=\"${CI_REPO_NAME}\";" >> $bazelVarEnv
echo "export CI_REPO_OWNER=\"${CI_REPO_OWNER}\";" >> $bazelVarEnv
echo "export CI_SECRET_PAYLOAD_FIREBASE_TOKEN=\"${CI_SECRET_PAYLOAD_FIREBASE_TOKEN}\";" >> $bazelVarEnv
####################################################################################################
# Platform-specific environment setup (which can leverage the base variables from here)
####################################################################################################
# Conditionally, load additional environment settings based on the current VM
# operating system running. We detect Windows by checking for `%AppData%`.
if [[ -n "${APPDATA}" ]]; then
source ${projectDir}/.circleci/env.windows.sh
else
source ${projectDir}/.circleci/env.linux.sh
fi
-13
View File
@@ -1,13 +0,0 @@
####################################################################################################
# Set bazel configuration for CircleCI runs.
####################################################################################################
cp "${PROJECT_ROOT}/.circleci/bazel.windows.rc" ".bazelrc.user";
# Override the `PATH` environment variable so that the windows-nvm NodeJS version
# always has precedence over potential existing NodeJS versions from the image.
setPublicVar PATH "/c/Program Files/nodejs/:$PATH"
# Expose the Bazelisk version. We need to run Bazelisk globally since Windows has problems launching
# Bazel from a node modules directoy that might be modified by the Bazel Yarn install then.
setPublicVar BAZELISK_VERSION \
"$(cd ${PROJECT_ROOT}; node -p 'require("./package.json").devDependencies["@bazel/bazelisk"]')"
-11
View File
@@ -1,11 +0,0 @@
#!/bin/sh
# Install bazel remote cache proxy
# This is temporary until the feature is no longer experimental on CircleCI.
# See remote cache documentation in /docs/BAZEL.md
set -u -e
readonly DOWNLOAD_URL="https://5-116431813-gh.circle-artifacts.com/0/pkg/bazel-remote-proxy-$(uname -s)_$(uname -m)"
curl --fail -o ~/bazel-remote-proxy "$DOWNLOAD_URL"
chmod +x ~/bazel-remote-proxy
+1 -2
View File
@@ -1,6 +1,5 @@
# Image metadata and config.
# Ideally, the Node.js version should match what we use on CI.
# See `executors > default-executor` in `.circleci/config.yml`.
FROM cimg/node:18.13.0@sha256:45d0ee279f522c4562a464df71108104cc9b2187205333ffd0707d4f05589731
@@ -12,7 +11,7 @@ LABEL name="Angular dev environment" \
EXPOSE 4000 4200 4433 5000 8080 9876
# Switch to `root` (CircleCI images use `circleci` as the user).
# Switch to `root`.
USER root
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -5,9 +5,9 @@ runs:
using: 'composite'
steps:
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/saucelabs@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Starting Saucelabs tunnel service
shell: bash
run: ./tools/saucelabs/sauce-service.sh run &
+4 -4
View File
@@ -21,16 +21,16 @@ jobs:
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'adev: preview'))
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel build //adev:build --full_build_adev --config=release
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
workflow-artifact-name: 'adev-preview'
pull-number: '${{github.event.pull_request.number}}'
+2 -2
View File
@@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
token: '${{secrets.GITHUB_TOKEN}}'
@@ -40,7 +40,7 @@ jobs:
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs ${{env.PREVIEW_SITE}}
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
github-token: '${{secrets.GITHUB_TOKEN}}'
workflow-artifact-name: 'adev-preview'
@@ -13,9 +13,9 @@ jobs:
assistant_to_the_branch_manager:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: angular/dev-infra/github-actions/branch-manager@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
- uses: angular/dev-infra/github-actions/branch-manager@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+2 -2
View File
@@ -28,7 +28,7 @@ jobs:
- uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1
id: comment-branch
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# Specify repository as the PR branch might be from a fork.
repository: ${{steps.comment-branch.outputs.head_owner}}/${{steps.comment-branch.outputs.head_repo}}
@@ -38,7 +38,7 @@ jobs:
- uses: ./.github/actions/yarn-install
- uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
- uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
bazelrc: ./.bazelrc.user
+22 -24
View File
@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Install node modules
@@ -41,13 +41,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
@@ -59,13 +59,13 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
@@ -76,32 +76,30 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev in fast mode to ensure it continues to work
run: yarn bazel build //adev:build --config=release
# TODO: re-enable tests once the next release is shipped
# Tests are broken because of https://github.com/angular/angular/issues/54858
# - name: Run tests
# run: yarn bazel test //adev/...
- name: Run tests
run: yarn bazel test //adev/...
publish-snapshots:
runs-on:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
@@ -113,7 +111,7 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
node-module-directories: |
@@ -121,9 +119,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@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
@@ -160,7 +158,7 @@ jobs:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Install node modules
@@ -173,11 +171,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
+4 -4
View File
@@ -12,14 +12,14 @@ jobs:
labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- uses: angular/dev-infra/github-actions/commit-message-based-labels@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: angular/dev-infra/github-actions/commit-message-based-labels@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
post_approval_changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- uses: angular/dev-infra/github-actions/post-approval-changes@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: angular/dev-infra/github-actions/post-approval-changes@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+2 -2
View File
@@ -13,8 +13,8 @@ jobs:
statuses: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- uses: angular/dev-infra/github-actions/google-internal-tests@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: angular/dev-infra/github-actions/google-internal-tests@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
run-tests-guide-url: http://go/angular-g3sync-start
github-token: ${{ secrets.GITHUB_TOKEN }}
+4 -4
View File
@@ -13,17 +13,17 @@ jobs:
JOBS: 2
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
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@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/saucelabs@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Set up Sauce Tunnel Daemon
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
env:
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
status:
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/unified-status-check@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
- uses: angular/dev-infra/github-actions/unified-status-check@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+53
View File
@@ -0,0 +1,53 @@
name: Performance Tracking
on:
push:
branches:
- main
permissions:
contents: 'read'
id-token: 'write'
defaults:
run:
shell: bash
jobs:
list:
timeout-minutes: 3
runs-on: ubuntu-latest
outputs:
workflows: ${{ steps.workflows.outputs.workflows }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn -s install --frozen-lockfile
- id: workflows
run: echo "workflows=$(yarn -s ng-dev perf workflows --list)" >> "$GITHUB_OUTPUT"
workflow:
timeout-minutes: 30
runs-on: ubuntu-latest
needs: list
strategy:
matrix:
workflow: ${{ fromJSON(needs.list.outputs.workflows) }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn -s install --frozen-lockfile
# We utilize the google-github-actions/auth action to allow us to get an active credential using workflow
# identity federation. This allows us to request short lived credentials on demand, rather than storing
# credentials in secrets long term. More information can be found at:
# https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-google-cloud-platform
- uses: 'google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f' # v2
with:
project_id: 'internal-200822'
workload_identity_provider: 'projects/823469418460/locations/global/workloadIdentityPools/measurables-tracking/providers/angular'
service_account: 'measures-uploader@internal-200822.iam.gserviceaccount.com'
- run: yarn ng-dev perf workflows --name ${{ matrix.workflow }} --commit-sha ${{github.sha}}
+21 -23
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Install node modules
@@ -39,7 +39,7 @@ jobs:
- name: Check code format
run: yarn ng-dev format changed --check ${{ github.event.pull_request.base.sha }}
- name: Check Package Licenses
uses: angular/dev-infra/github-actions/linting/licenses@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/linting/licenses@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
allow-dependencies-licenses: 'pkg:npm/google-protobuf@'
@@ -47,13 +47,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
@@ -65,13 +65,13 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
@@ -83,19 +83,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
run: yarn tsx ./scripts/build/build-packages-dist.mts
- name: Archive build artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: pr-artifacts-${{ github.event.number }}
path: dist/packages-dist/
@@ -105,26 +105,24 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev in fast mode to ensure it continues to work
run: yarn bazel build //adev:build --config=release
# TODO: re-enable tests once the next release is shipped
# Tests are broken because of https://github.com/angular/angular/issues/54858
# - name: Run tests
# run: yarn bazel test //adev/...
- name: Run tests
run: yarn bazel test //adev/...
zone-js:
runs-on:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
node-module-directories: |
@@ -132,9 +130,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@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/setup@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/bazel/configure-remote@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
@@ -171,7 +169,7 @@ jobs:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
cache-node-modules: true
- name: Install node modules
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
steps:
- name: 'Checkout code'
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
@@ -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@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
with:
sarif_file: results.sarif
+2 -2
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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
@@ -32,7 +32,7 @@ jobs:
env:
ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN }}
- name: Create a PR (if necessary)
uses: angular/dev-infra/github-actions/create-pr-for-changes@8d3cb7b9e1b3edd1dc168376689d27407d2dfa7a
uses: angular/dev-infra/github-actions/create-pr-for-changes@9bf81f9c029a09347afb376b9e1ae12b33f1a1fa
with:
branch-prefix: update-cli-help
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
+2 -10
View File
@@ -4,11 +4,8 @@
/bazel-out
/integration/bazel/bazel-*
*.log
/node_modules/
# CircleCI temporary file for cache key computation.
# See `save_month_to_file` in `.circleci/config.yml`.
month.txt
node_modules/
modules/ssr-benchmarks/node_modules/
# Include when developing application packages.
pubspec.lock
@@ -57,10 +54,5 @@ baseline.json
# Husky
.husky/_
# Ignore cache created with the Angular CLI.
.angular/
# Ignore AIO files, useful when changing branches
aio/node_modules
aio/out-tsc
+7
View File
@@ -0,0 +1,7 @@
workflows:
build-adev:
name: Build adev
prepare:
- bazel clean
workflow:
- bazel build //adev:build
+1
View File
@@ -8,6 +8,7 @@ export const format: FormatConfig = {
'matchers': [
'**/*.{yaml,yml}',
'**/*.{js,ts}',
'devtools/**/*.{js,ts,html,scss}',
// Do not format d.ts files as they are generated
'!**/*.d.ts',
+2 -9
View File
@@ -3,15 +3,7 @@
"separateFilePatterns": ["packages/core/primitives/**"],
"alwaysExternalFilePatterns": [
"packages/*",
"packages/bazel/*",
"packages/bazel/src/*",
"packages/bazel/src/api-extractor/**",
"packages/bazel/src/builders/**",
"packages/bazel/src/ng_module/**",
"packages/bazel/src/ng_package/**",
"packages/bazel/src/protractor/**",
"packages/bazel/src/schematics/**",
"packages/bazel/src/types_bundle/**",
"packages/bazel/**",
"packages/compiler-cli/linker/**",
"packages/compiler-cli/src/ngtsc/sourcemaps/**",
"packages/compiler-cli/src/ngtsc/testing/**",
@@ -27,6 +19,7 @@
"packages/localize/**",
"packages/private/**",
"packages/service-worker/**",
"packages/ssr/BUILD.bazel",
"packages/common/locales/generate-locales-tool/**",
"packages/common/locales/index.bzl",
"packages/http/**",
+2 -1
View File
@@ -6,5 +6,6 @@
"singleQuote": true,
"semi": true,
"quoteProps": "preserve",
"bracketSpacing": false
"bracketSpacing": false,
"trailingComma": "all"
}
+3 -1
View File
@@ -300,6 +300,7 @@ groups:
- >
contains_any_globs(files, [
'packages/platform-server/**/{*,.*}',
'packages/ssr/**/{*,.*}',
])
reviewers:
users:
@@ -633,7 +634,6 @@ groups:
- >
contains_any_globs(files.exclude('.pullapprove.yml'), [
'{*,.*}',
'.circleci/**/{*,.*}',
'.devcontainer/**/{*,.*}',
'.github/**/{*,.*}',
'.husky/**/{*,.*}',
@@ -684,6 +684,8 @@ groups:
conditions:
- author in ["angular-robot"]
reviewers:
users:
- ~alan-agius4
teams:
- framework-team
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2,4 +2,4 @@
# yarn lockfile v1
yarn-path ".yarn/releases/yarn-1.22.19.cjs"
yarn-path ".yarn/releases/yarn-1.22.22.cjs"
+2 -2
View File
@@ -64,8 +64,8 @@ config_setting(
nodejs_binary(
name = "yarn_vendored",
data = [".yarn/releases/yarn-1.22.19.cjs"],
entry_point = ".yarn/releases/yarn-1.22.19.cjs",
data = [".yarn/releases/yarn-1.22.22.cjs"],
entry_point = ".yarn/releases/yarn-1.22.22.cjs",
visibility = [
"//integration:__subpackages__",
"//modules/ssr-benchmarks:__subpackages__",
+208 -339
View File
@@ -1,76 +1,221 @@
<a name="18.2.9"></a>
# 18.2.9 (2024-10-23)
<a name="19.0.1"></a>
# 19.0.1 (2024-11-26)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [b0ab653965](https://github.com/angular/angular/commit/b0ab653965cf88fcfde23fc6a6cc78ce3121a30f) | fix | report when NgModule imports or exports itself ([#58231](https://github.com/angular/angular/pull/58231)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.10"></a>
# 19.0.0-next.10 (2024-10-16)
## Breaking Changes
### core
- Angular directives, components and pipes are now standalone by default. Specify `standalone: false` for declarations that are currently declared in `@NgModule`s. `ng update` for v19 will take care of this automatically.
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [0c9d721ac1](https://github.com/angular/angular/commit/0c9d721ac157662b2602cf0278ba4b79325f6882) | feat | add support for the `typeof` keyword in template expressions. ([#58183](https://github.com/angular/angular/pull/58183)) |
| [a3cb530d84](https://github.com/angular/angular/commit/a3cb530d846bf4d15802b9f42b6dee5c9a3a08ee) | fix | handle typeof expressions in serializer ([#58217](https://github.com/angular/angular/pull/58217)) |
| [ba4340875a](https://github.com/angular/angular/commit/ba4340875ac8e338ff1390fc7897eecc704ef7c5) | fix | ignore placeholder-only i18n messages ([#58154](https://github.com/angular/angular/pull/58154)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [231e6ff6ca](https://github.com/angular/angular/commit/231e6ff6ca0dae0289a03615bcaed29455c2d4b8) | feat | generate the HMR replacement module ([#58205](https://github.com/angular/angular/pull/58205)) |
| [fb44323c51](https://github.com/angular/angular/commit/fb44323c51da5a86853aafd8a70ce0c25d6c0d7f) | fix | incorrectly generating relative file paths on case-insensitive platforms ([#58150](https://github.com/angular/angular/pull/58150)) |
| [fb1fa8b0fc](https://github.com/angular/angular/commit/fb1fa8b0fc04c9cfac6551ca27bee89dcd7c72ac) | fix | more accurate diagnostics for host binding parser errors ([#58870](https://github.com/angular/angular/pull/58870)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [6b8c494d05](https://github.com/angular/angular/commit/6b8c494d05e545830fffb9626153480af6339ddc) | feat | flipping the default value for `standalone` to `true` ([#58169](https://github.com/angular/angular/pull/58169)) |
| [3f1e7ab6ae](https://github.com/angular/angular/commit/3f1e7ab6ae984149004c449c04301b434ea64d2a) | feat | promote `outputFromObservable` & `outputToObservable` to stable. ([#58214](https://github.com/angular/angular/pull/58214)) |
| [97c44a1d6c](https://github.com/angular/angular/commit/97c44a1d6c41be250d585fba5af2bc2af4d98ae2) | feat | Promote `takeUntilDestroyed` to stable. ([#58200](https://github.com/angular/angular/pull/58200)) |
| [819ff034ce](https://github.com/angular/angular/commit/819ff034ce7cf014cedef60510b83af9340efa71) | feat | treat directives, pipes, components as by default ([#58229](https://github.com/angular/angular/pull/58229)) |
| [502ee0e722](https://github.com/angular/angular/commit/502ee0e7221a9e7cfa0fa3bd92298d3b650a7713) | fix | correctly clear template HMR internal renderer cache ([#58724](https://github.com/angular/angular/pull/58724)) |
| [99715104a1](https://github.com/angular/angular/commit/99715104a1a787c3899dfbfac6b44f28c7d24356) | fix | correctly perform lazy routes migration for components with additional decorators ([#58796](https://github.com/angular/angular/pull/58796)) |
| [118803035f](https://github.com/angular/angular/commit/118803035f366acdffc577ec857b888f764bb338) | fix | Ensure _tick is always run within the TracingSnapshot. ([#58881](https://github.com/angular/angular/pull/58881)) |
| [08b9452f01](https://github.com/angular/angular/commit/08b9452f012b2ef660f767c2f0a4bf86bb15bb61) | fix | Ensure resource sets an error ([#58855](https://github.com/angular/angular/pull/58855)) |
| [84f45ea3ff](https://github.com/angular/angular/commit/84f45ea3ffe02003350c6c19fdafdc6f4d521ccb) | fix | make component id generation more stable between client and server builds ([#58813](https://github.com/angular/angular/pull/58813)) |
| [d3491c7cee](https://github.com/angular/angular/commit/d3491c7cee3d110da1adb51f8047b4e1976ece71) | fix | Prevents race condition of cleanup for incremental hydration ([#58722](https://github.com/angular/angular/pull/58722)) |
### forms
| Commit | Type | Description |
| -- | -- | -- |
| [4dfe5b6cef](https://github.com/angular/angular/commit/4dfe5b6cefd7901a466b37b660f8b3a051a06cb3) | fix | work around TypeScript 5.7 issue ([#58731](https://github.com/angular/angular/pull/58731)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [a983865bff](https://github.com/angular/angular/commit/a983865bffa828a982ef7e56204924d9c2989ead) | fix | add fix for individual unused imports ([#58719](https://github.com/angular/angular/pull/58719)) |
| [e6e7a4e22b](https://github.com/angular/angular/commit/e6e7a4e22b0a654808e5eb88a30cd6effa383332) | fix | allow fixes to run without template info ([#58719](https://github.com/angular/angular/pull/58719)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [5ce10264a4](https://github.com/angular/angular/commit/5ce10264a434ffc8e31cdc68208d2c3c7f8378ed) | fix | fix provide-initializer migration when using useFactory ([#58518](https://github.com/angular/angular/pull/58518)) |
| [d4f5c85f60](https://github.com/angular/angular/commit/d4f5c85f60133550303d59b3f9e3e34f14ca63ce) | fix | handle parameters with initializers in inject migration ([#58769](https://github.com/angular/angular/pull/58769)) |
| [a6d2d2dc10](https://github.com/angular/angular/commit/a6d2d2dc104608f14c3850b21bc23ba75ca04e4d) | fix | Mark hoisted properties as removed in inject migration ([#58804](https://github.com/angular/angular/pull/58804)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.9"></a>
# 19.0.0-next.9 (2024-10-10)
<a name="19.0.0"></a>
# 19.0.0 (2024-11-19)
Blog post: https://blog.angular.dev/meet-angular-v19-7b29dfd05b84
## Breaking Changes
### compiler
- `this.foo` property reads no longer refer to template context variables. If you intended to read the template variable, do not use `this.`.
### core
- Angular directives, components and pipes are now standalone by default.
* Specify `standalone: false` for declarations that are currently declared in modules.
* `ng update` for v19 will take care of this automatically.
- TypeScript versions less than 5.5 are no longer supported.
- Timing changes for `effect` API (in developer preview):
* effects which are triggered outside of change detection run as part of
the change detection process instead of as a microtask. Depending on the
specifics of application/test setup, this can result in them executing
earlier or later (or requiring additional test steps to trigger; see below
examples).
* effects which are triggered during change detection (e.g. by input
signals) run _earlier_, before the component's template.
- `ExperimentalPendingTasks` has been renamed to `PendingTasks`.
- The `autoDetect` feature of `ComponentFixture` will now
attach the fixture to the `ApplicationRef`. As a result, errors during
automatic change detection of the fixture be reported to the `ErrorHandler`.
This change may cause custom error handlers to observe new failures that were previously unreported.
- `createComponent` will now render default fallback with empty `projectableNodes`.
* When passing an empty array to `projectableNodes` in the `createComponent` API, the default fallback content
of the `ng-content` will be rendered if present. To prevent rendering the default content, pass `document.createTextNode('')` as a `projectableNode`.
```ts
// The first ng-content will render the default fallback content if present
createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
// To prevent projecting the default fallback content:
createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });
```
- Errors that are thrown during `ApplicationRef.tick`
will now be rethrown when using `TestBed`. These errors should be
resolved by ensuring the test environment is set up correctly to
complete change detection successfully. There are two alternatives to
catch the errors:
* Instead of waiting for automatic change detection to happen, trigger
it synchronously and expect the error. For example, a jasmine test
could write `expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()`
* `TestBed` will reject any outstanding `ComponentFixture.whenStable` promises. A jasmine test,
for example, could write `expectAsync(fixture.whenStable()).toBeRejected()`.
As a last resort, you can configure errors to _not_ be rethrown by
setting `rethrowApplicationErrors` to `false` in `TestBed.configureTestingModule`.
- The timers that are used for zone coalescing and hybrid
mode scheduling (which schedules an application state synchronization
when changes happen outside the Angular zone) will now run in the zone
above Angular rather than the root zone. This will mostly affect tests
which use `fakeAsync`: these timers will now be visible to `fakeAsync`
and can be affected by `tick` or `flush`.
- The deprecated `factories` property in `KeyValueDiffers` has been removed.
### elements
- as part of switching away from custom CD behavior to the
hybrid scheduler, timing of change detection around custom elements has
changed subtly. These changes make elements more efficient, but can cause
tests which encoded assumptions about how or when elements would be checked
to require updating.
### localize
- The `name` option in the `ng add @localize` schematic has been removed in favor of the `project` option.
- The `name` option in the `ng add `@localize`` schematic has been removed in favor of the `project` option.
### platform-browser
- The deprecated `BrowserModule.withServerTransition` method has been removed. Please use the `APP_ID` DI token to set the application id instead.
### router
- The `Router.errorHandler` property has been removed.
Adding an error handler should be configured in either
`withNavigationErrorHandler` with `provideRouter` or the `errorHandler`
property in the extra options of `RouterModule.forRoot`. In addition,
the error handler cannot be used to change the return value of the
router navigation promise or prevent it from rejecting. Instead, if you
want to prevent the promise from rejecting, use `resolveNavigationPromiseOnError`.
- The return type of the `Resolve` interface now includes
`RedirectCommand`.
### common
| Commit | Type | Description |
| -- | -- | -- |
| [24c6373820](https://github.com/angular/angular/commit/24c6373820231faf9d012a2e4d7ea945d3e8513b) | feat | add optional rounded transform support in cloudinary image loader ([#55364](https://github.com/angular/angular/pull/55364)) |
| [50f08e6c4b](https://github.com/angular/angular/commit/50f08e6c4bf1caeeb08d3505ce7fabd466b9c76b) | feat | automatically use sizes auto in NgOptimizedImage ([#57479](https://github.com/angular/angular/pull/57479)) |
| [13c13067bc](https://github.com/angular/angular/commit/13c13067bc3ed50cb80b0a86e62655448adb3051) | feat | disable keyvalue sorting using null compareFn ([#57487](https://github.com/angular/angular/pull/57487)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [a2e4ee0cb3](https://github.com/angular/angular/commit/a2e4ee0cb3d40cadc05e28d58b06853973944456) | feat | add diagnostic for unused standalone imports ([#57605](https://github.com/angular/angular/pull/57605)) |
| [0c9d721ac1](https://github.com/angular/angular/commit/0c9d721ac157662b2602cf0278ba4b79325f6882) | feat | add support for the `typeof` keyword in template expressions. ([#58183](https://github.com/angular/angular/pull/58183)) |
| [09f589f000](https://github.com/angular/angular/commit/09f589f0006f4b428b675b83c12c0dc8ebb7e45f) | fix | `this.a` should always refer to class property `a` ([#55183](https://github.com/angular/angular/pull/55183)) |
| [e8d1944999](https://github.com/angular/angular/commit/e8d1944999e1fdfbd67630d475334c0d7f41a0eb) | fix | add multiple :host and nested selectors support ([#57796](https://github.com/angular/angular/pull/57796)) |
| [82144b6d63](https://github.com/angular/angular/commit/82144b6d63d072d112d1a7f4dcc018a1d64bb994) | fix | allow combinators inside pseudo selectors ([#57796](https://github.com/angular/angular/pull/57796)) |
| [292ea4714f](https://github.com/angular/angular/commit/292ea4714fb7e76cf1748d2f9059991e05c42574) | fix | fix comment typo ([#57796](https://github.com/angular/angular/pull/57796)) |
| [69529d8873](https://github.com/angular/angular/commit/69529d8873fbd7888ab68fddc6e7c654c5065764) | fix | fix parsing of the :host-context with pseudo selectors ([#57796](https://github.com/angular/angular/pull/57796)) |
| [2374b87b64](https://github.com/angular/angular/commit/2374b87b643e0373f85cf126d4b01b2fff785f64) | fix | preserve attributes attached to :host selector ([#57796](https://github.com/angular/angular/pull/57796)) |
| [46a6324c82](https://github.com/angular/angular/commit/46a6324c82a41b69c16a4c8c9f3fc52d1ecf6917) | fix | scope :host-context inside pseudo selectors, do not decrease specificity ([#57796](https://github.com/angular/angular/pull/57796)) |
| [bc5f1175e9](https://github.com/angular/angular/commit/bc5f1175e9f39dfa2699c4de19ee9af4ce4b50d1) | fix | transform pseudo selectors correctly for the encapsulated view ([#57796](https://github.com/angular/angular/pull/57796)) |
| [98804fd4be](https://github.com/angular/angular/commit/98804fd4beb6292f5a50ce728424fdb33c47f654) | fix | add more specific matcher for hydrate never block ([#58360](https://github.com/angular/angular/pull/58360)) |
| [b25121ee4a](https://github.com/angular/angular/commit/b25121ee4aba427954fef074a967b9332654be84) | fix | avoid having to duplicate core environment ([#58444](https://github.com/angular/angular/pull/58444)) |
| [560282aa9b](https://github.com/angular/angular/commit/560282aa9b3204ad8311017905beed63072c7303) | fix | control flow nodes with root at the end projected incorrectly ([#58607](https://github.com/angular/angular/pull/58607)) |
| [2be161d015](https://github.com/angular/angular/commit/2be161d015ce6bab0142b6e6c34a8ede6341f627) | fix | fix `:host` parsing in pseudo-selectors ([#58681](https://github.com/angular/angular/pull/58681)) |
| [806a61b5a6](https://github.com/angular/angular/commit/806a61b5a619d98c0226ba6a566b1562f6e16e5a) | fix | fix multiline selectors ([#58681](https://github.com/angular/angular/pull/58681)) |
| [a3cb530d84](https://github.com/angular/angular/commit/a3cb530d846bf4d15802b9f42b6dee5c9a3a08ee) | fix | handle typeof expressions in serializer ([#58217](https://github.com/angular/angular/pull/58217)) |
| [ba4340875a](https://github.com/angular/angular/commit/ba4340875ac8e338ff1390fc7897eecc704ef7c5) | fix | ignore placeholder-only i18n messages ([#58154](https://github.com/angular/angular/pull/58154)) |
| [e5d3abb298](https://github.com/angular/angular/commit/e5d3abb29842412f82a67562aceff245d493ec53) | fix | resolve `:host:host-context(.foo)` ([#58681](https://github.com/angular/angular/pull/58681)) |
| [80f56954ce](https://github.com/angular/angular/commit/80f56954cecf763e36bdcfbbd592a82d693eeef7) | fix | transform chained pseudo-selectors ([#58681](https://github.com/angular/angular/pull/58681)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [8d8c03abc4](https://github.com/angular/angular/commit/8d8c03abc40099da268d7301f029954f3e3f1c90) | fix | defer symbols only used in types ([#58104](https://github.com/angular/angular/pull/58104)) |
| [d9687f43dd](https://github.com/angular/angular/commit/d9687f43dd2ccfcf7dd3ee4f9066ce727f3224c6) | feat | 'strictStandalone' flag enforces standalone ([#57935](https://github.com/angular/angular/pull/57935)) |
| [9e87593055](https://github.com/angular/angular/commit/9e87593055a5314a67090bd15d5552c23b538050) | feat | ensure template style elements are preprocessed as inline styles ([#57429](https://github.com/angular/angular/pull/57429)) |
| [231e6ff6ca](https://github.com/angular/angular/commit/231e6ff6ca0dae0289a03615bcaed29455c2d4b8) | feat | generate the HMR replacement module ([#58205](https://github.com/angular/angular/pull/58205)) |
| [dbe612f2cd](https://github.com/angular/angular/commit/dbe612f2cd59adecdab3abb270b014c4b26e472c) | fix | disable standalone by default on older versions of Angular ([#58405](https://github.com/angular/angular/pull/58405)) |
| [d4d76ead80](https://github.com/angular/angular/commit/d4d76ead802837bc6cc7908bc9ebfefa73eb9969) | fix | do not fail fatal when references to non-existent module are discovered ([#58515](https://github.com/angular/angular/pull/58515)) |
| [33fe252c58](https://github.com/angular/angular/commit/33fe252c588ee94d6ef99e8070d35c483ec24fda) | fix | do not report unused declarations coming from an imported array ([#57940](https://github.com/angular/angular/pull/57940)) |
| [fb44323c51](https://github.com/angular/angular/commit/fb44323c51da5a86853aafd8a70ce0c25d6c0d7f) | fix | incorrectly generating relative file paths on case-insensitive platforms ([#58150](https://github.com/angular/angular/pull/58150)) |
| [22cd6869ef](https://github.com/angular/angular/commit/22cd6869ef453c342b206f84e857ef6c34922fa5) | fix | make the unused imports diagnostic easier to read ([#58468](https://github.com/angular/angular/pull/58468)) |
| [9bbb01c85e](https://github.com/angular/angular/commit/9bbb01c85e763b0457456a2393a834db15008671) | fix | report individual diagnostics for unused imports ([#58589](https://github.com/angular/angular/pull/58589)) |
| [4716c3b966](https://github.com/angular/angular/commit/4716c3b9660b01f4ef3642fb774270b7f4a13d1a) | perf | reduce duplicate component style resolution ([#57502](https://github.com/angular/angular/pull/57502)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [6ea8e1e9aa](https://github.com/angular/angular/commit/6ea8e1e9aae028572873cf97aa1949c8153f458f) | feat | Add a schematics to migrate to `standalone: false`. ([#57643](https://github.com/angular/angular/pull/57643)) |
| [3ebe6b4ad4](https://github.com/angular/angular/commit/3ebe6b4ad401337e18619edc34477ae98226fa3e) | feat | Add async `run` method on `ExperimentalPendingTasks` ([#56546](https://github.com/angular/angular/pull/56546)) |
| [69fc5ae922](https://github.com/angular/angular/commit/69fc5ae9229b872a9ad70eb920087af2a378fead) | feat | Add incremental hydration public api ([#58249](https://github.com/angular/angular/pull/58249)) |
| [8ebbae88ca](https://github.com/angular/angular/commit/8ebbae88ca48b8aa78cd85deedbed19d44b8227e) | feat | Add rxjs operator prevent app stability until an event ([#56533](https://github.com/angular/angular/pull/56533)) |
| [19edf2c057](https://github.com/angular/angular/commit/19edf2c057f7587bc16812685d31a556521ad414) | feat | add syntactic sugar for initializers ([#53152](https://github.com/angular/angular/pull/53152)) |
| [c93b510f9b](https://github.com/angular/angular/commit/c93b510f9b2e23aa7a3848a04c05249fde14a9b1) | feat | allow passing `undefined` without needing to include it in the type argument of `input` ([#57621](https://github.com/angular/angular/pull/57621)) |
| [ab25a192ba](https://github.com/angular/angular/commit/ab25a192ba664863ad68d224b9b2df78da22769a) | feat | allow running output migration on a subset of paths ([#58299](https://github.com/angular/angular/pull/58299)) |
| [fc59e2a7b7](https://github.com/angular/angular/commit/fc59e2a7b7afa491a5ea740284a742574805eb36) | feat | change effect() execution timing & no-op `allowSignalWrites` ([#57874](https://github.com/angular/angular/pull/57874)) |
| [8bcc663a53](https://github.com/angular/angular/commit/8bcc663a53888717cdf4ce0c23404caa00abb1b2) | feat | drop support for TypeScript 5.4 ([#57577](https://github.com/angular/angular/pull/57577)) |
| [18d8d44b1f](https://github.com/angular/angular/commit/18d8d44b1f3d56a4eda68f2cafded7529e08d0f1) | feat | experimental `resource()` API for async dependencies ([#58255](https://github.com/angular/angular/pull/58255)) |
| [9762b24b5e](https://github.com/angular/angular/commit/9762b24b5e8d7ab3ed2321959492a77b01d8ae57) | feat | experimental impl of `rxResource()` ([#58255](https://github.com/angular/angular/pull/58255)) |
| [6b8c494d05](https://github.com/angular/angular/commit/6b8c494d05e545830fffb9626153480af6339ddc) | feat | flipping the default value for `standalone` to `true` ([#58169](https://github.com/angular/angular/pull/58169)) |
| [e6e5d29e83](https://github.com/angular/angular/commit/e6e5d29e830a0a74d7677d5f2345f29391064853) | feat | initial version of the output migration ([#57604](https://github.com/angular/angular/pull/57604)) |
| [be2e49639b](https://github.com/angular/angular/commit/be2e49639bda831831ad62d49253db942a83fd46) | feat | introduce `afterRenderEffect` ([#57549](https://github.com/angular/angular/pull/57549)) |
| [ec386e7f12](https://github.com/angular/angular/commit/ec386e7f1216e0047392e75ab686b310b073eb42) | feat | introduce debugName optional arg to framework signal functions ([#57073](https://github.com/angular/angular/pull/57073)) |
| [8311f00faa](https://github.com/angular/angular/commit/8311f00faaf282d1a5b1ddca29247a2fba94a692) | feat | introduce the reactive linkedSignal ([#58189](https://github.com/angular/angular/pull/58189)) |
| [1b1519224d](https://github.com/angular/angular/commit/1b1519224d10c1cd25d05d7b958772b9adee1e1a) | feat | mark input, output and model APIs as stable ([#57804](https://github.com/angular/angular/pull/57804)) |
| [a7eff3ffaa](https://github.com/angular/angular/commit/a7eff3ffaaecbcb3034130d475ff7b4e41a1e1cc) | feat | mark signal-based query APIs as stable ([#57921](https://github.com/angular/angular/pull/57921)) |
| [a1f229850a](https://github.com/angular/angular/commit/a1f229850ad36da009f772faa831da173a60268c) | feat | migrate ExperimentalPendingTasks to PendingTasks ([#57533](https://github.com/angular/angular/pull/57533)) |
| [3f1e7ab6ae](https://github.com/angular/angular/commit/3f1e7ab6ae984149004c449c04301b434ea64d2a) | feat | promote `outputFromObservable` & `outputToObservable` to stable. ([#58214](https://github.com/angular/angular/pull/58214)) |
| [97c44a1d6c](https://github.com/angular/angular/commit/97c44a1d6c41be250d585fba5af2bc2af4d98ae2) | feat | Promote `takeUntilDestroyed` to stable. ([#58200](https://github.com/angular/angular/pull/58200)) |
| [e5adf92965](https://github.com/angular/angular/commit/e5adf9296595644e415d5c147df08890be01ba77) | feat | stabilize `@let` syntax ([#57813](https://github.com/angular/angular/pull/57813)) |
| [b063468027](https://github.com/angular/angular/commit/b0634680272569501146bb7a9cdfe53033e25971) | feat | support TypeScript 5.6 ([#57424](https://github.com/angular/angular/pull/57424)) |
| [819ff034ce](https://github.com/angular/angular/commit/819ff034ce7cf014cedef60510b83af9340efa71) | feat | treat directives, pipes, components as by default ([#58229](https://github.com/angular/angular/pull/58229)) |
| [ee426c62f0](https://github.com/angular/angular/commit/ee426c62f07579ec7dc89ce9582972cc1e3471d4) | fix | allow signal write error ([#57973](https://github.com/angular/angular/pull/57973)) |
| [67db4305c2](https://github.com/angular/angular/commit/67db4305c2261625fd54d284c29e94e26cb19488) | fix | clean up afterRender after it is executed ([#58119](https://github.com/angular/angular/pull/58119)) |
| [c095679f92](https://github.com/angular/angular/commit/c095679f927ad67fec6c18cb140ea550ae02639e) | fix | avoid breaking change with apps using rxjs 6.x ([#58341](https://github.com/angular/angular/pull/58341)) |
| [71ee81af2c](https://github.com/angular/angular/commit/71ee81af2c4c5854a54cf94a48d5829da41878a7) | fix | clean up event contract once hydration is done ([#58174](https://github.com/angular/angular/pull/58174)) |
| [f03d274e87](https://github.com/angular/angular/commit/f03d274e87c919514a70d02c0699523957de7386) | fix | ComponentFixture autoDetect feature works like production ([#55228](https://github.com/angular/angular/pull/55228)) |
| [950a5540f1](https://github.com/angular/angular/commit/950a5540f15118e7360506ad82ec9dab5a11f789) | fix | Ensure the `ViewContext` is retained after closure minification ([#57903](https://github.com/angular/angular/pull/57903)) |
| [7b1e5be20b](https://github.com/angular/angular/commit/7b1e5be20b99c88246c6be78a4dcd64eb55cee1a) | fix | fallback to default ng-content with empty projectable nodes. ([#57480](https://github.com/angular/angular/pull/57480)) |
| [0300dd2e18](https://github.com/angular/angular/commit/0300dd2e18f064f2f57f7371e0dc5c01218b5019) | fix | Fix fixture.detectChanges with autoDetect disabled and zoneless ([#57416](https://github.com/angular/angular/pull/57416)) |
| [5fe57d4fbb](https://github.com/angular/angular/commit/5fe57d4fbb578c35a8e8ef037ae8c19c8a0e901c) | fix | fixes issues with control flow and incremental hydration ([#58644](https://github.com/angular/angular/pull/58644)) |
| [51933ef5a6](https://github.com/angular/angular/commit/51933ef5a6ce62df37945fa22e87e3868288e318) | fix | prevent errors on contract cleanup ([#58614](https://github.com/angular/angular/pull/58614)) |
| [fd7716440b](https://github.com/angular/angular/commit/fd7716440bec8f7ed042d79bafacf3048d45cd47) | fix | Prevents trying to trigger incremental hydration on CSR ([#58366](https://github.com/angular/angular/pull/58366)) |
| [656b5d3e78](https://github.com/angular/angular/commit/656b5d3e78004229a76488e0de1eb1d3508d8f6d) | fix | Re-assign error codes to be within core bounds (<1000) ([#53455](https://github.com/angular/angular/pull/53455)) |
| [6e0af6dbbb](https://github.com/angular/angular/commit/6e0af6dbbbe5e9a9e2e5809ada0b7b5a7e456402) | fix | resolve forward-referenced host directives during directive matching ([#58492](https://github.com/angular/angular/pull/58492)) |
| [468d3fb9b1](https://github.com/angular/angular/commit/468d3fb9b1c3dd6dff86afcb6d8f89cc4c29b24b) | fix | rethrow errors during ApplicationRef.tick in TestBed ([#57200](https://github.com/angular/angular/pull/57200)) |
| [226a67dabb](https://github.com/angular/angular/commit/226a67dabba90a488ad09ce7bb026b8883c90d4a) | fix | Schedulers run in zone above Angular rather than root ([#57553](https://github.com/angular/angular/pull/57553)) |
| [97fb86d331](https://github.com/angular/angular/commit/97fb86d3310ae891ba4d894a8d3479eda08bd4c2) | perf | set encapsulation to `None` for empty component styles ([#57130](https://github.com/angular/angular/pull/57130)) |
| [c15ec36bd1](https://github.com/angular/angular/commit/c15ec36bd1dcff4c7c387337a5bcfd928994db2f) | refactor | remove deprecated `factories` Property in `KeyValueDiffers` ([#58064](https://github.com/angular/angular/pull/58064)) |
### elements
| Commit | Type | Description |
| -- | -- | -- |
| [fe5c4e086a](https://github.com/angular/angular/commit/fe5c4e086add655bf53315d71b0736ff758c7199) | fix | support `output()`-shaped outputs ([#57535](https://github.com/angular/angular/pull/57535)) |
| [0cebfd7462](https://github.com/angular/angular/commit/0cebfd7462c6a7c6c3b0d66720c436a4b0eea19d) | fix | switch to `ComponentRef.setInput` & remove custom scheduler ([#56728](https://github.com/angular/angular/pull/56728)) |
### forms
| Commit | Type | Description |
| -- | -- | -- |
| [3e7d724037](https://github.com/angular/angular/commit/3e7d724037cca4d256b1442eda20d6c6ad91d279) | feat | add ability to clear a FormRecord ([#50750](https://github.com/angular/angular/pull/50750)) |
| [18b6f3339f](https://github.com/angular/angular/commit/18b6f3339f46b37ee67fce2fa8a900cc73b2f23c) | fix | fix FormRecord type inference ([#50750](https://github.com/angular/angular/pull/50750)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [4b9accdf16](https://github.com/angular/angular/commit/4b9accdf166f3990b3706de83ada15937fe786e2) | feat | promote `withRequestsMadeViaParent` to stable. ([#58221](https://github.com/angular/angular/pull/58221)) |
| [057cf7fb6b](https://github.com/angular/angular/commit/057cf7fb6bd2ac37a7a30d3a143e6737e386247f) | fix | preserve all headers from Headers object ([#57802](https://github.com/angular/angular/pull/57802)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [8da9fb49b5](https://github.com/angular/angular/commit/8da9fb49b54e50de2d028691f73fb773def62ecd) | feat | add code fix for unused standalone imports ([#57605](https://github.com/angular/angular/pull/57605)) |
| [1f067f4507](https://github.com/angular/angular/commit/1f067f4507b6e908fe991d5de0dc4d3a627ab2f9) | feat | add code reactoring action to migrate `@Input` to signal-input ([#57214](https://github.com/angular/angular/pull/57214)) |
| [56ee47f2ec](https://github.com/angular/angular/commit/56ee47f2ec6e983e2ffdf59476ab29a92590811e) | feat | allow code refactorings to compute edits asynchronously ([#57214](https://github.com/angular/angular/pull/57214)) |
| [bc83fc1e2e](https://github.com/angular/angular/commit/bc83fc1e2ebac1a99b6e8ed63cea48f48dd7c863) | feat | support converting to signal queries in VSCode extension ([#58106](https://github.com/angular/angular/pull/58106)) |
| [5c4305f024](https://github.com/angular/angular/commit/5c4305f0248ac3cc1adc76aebd3ef8af041039dc) | feat | support migrating full classes to signal inputs in VSCode ([#57975](https://github.com/angular/angular/pull/57975)) |
| [6342befff8](https://github.com/angular/angular/commit/6342befff8ee491f37e8912cccb0099bbbf01042) | feat | support migrating full classes to signal queries ([#58263](https://github.com/angular/angular/pull/58263)) |
| [7ecfd89592](https://github.com/angular/angular/commit/7ecfd8959219b6e2ec19e1244a6694711daf1782) | fix | The suppress diagnostics option should work for external templates ([#57873](https://github.com/angular/angular/pull/57873)) |
### localize
| Commit | Type | Description |
| -- | -- | -- |
@@ -78,22 +223,47 @@
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [dff4de0f75](https://github.com/angular/angular/commit/dff4de0f75741bc629462bb8da833b876c754453) | feat | add a combined migration for all signals APIs ([#58259](https://github.com/angular/angular/pull/58259)) |
| [b6bc93803c](https://github.com/angular/angular/commit/b6bc93803c246d47aac0d2d8619271d42b249a4a) | feat | add schematic to migrate to signal queries ([#58032](https://github.com/angular/angular/pull/58032)) |
| [2bfc64daf1](https://github.com/angular/angular/commit/2bfc64daf1cad9be8099759e8de7a361555ad5d1) | feat | expose output as function migration ([#58299](https://github.com/angular/angular/pull/58299)) |
| [59fe9bc772](https://github.com/angular/angular/commit/59fe9bc77236f1374427a851e55b0fa5216d9cf9) | feat | introduce signal input migration as `ng generate` schematic ([#57805](https://github.com/angular/angular/pull/57805)) |
| [90c7ec39a0](https://github.com/angular/angular/commit/90c7ec39a06e5c14711e0a42e2d6a478cde2b9cc) | fix | inject migration always inserting generated variables before super call ([#58393](https://github.com/angular/angular/pull/58393)) |
| [7a65cdd911](https://github.com/angular/angular/commit/7a65cdd911cbbf22445c916fc754d3a3304bc5fe) | fix | inject migration not inserting generated code after super call in some cases ([#58393](https://github.com/angular/angular/pull/58393)) |
| [c1aa411cf1](https://github.com/angular/angular/commit/c1aa411cf13259d991c8f224a2bafc3e9763fe8d) | fix | properly resolve tsconfig paths on windows ([#58137](https://github.com/angular/angular/pull/58137)) |
| [e26797b38e](https://github.com/angular/angular/commit/e26797b38efe0ac813601c10581f34b7591954c1) | fix | replace removed NgModules in tests with their exports ([#58627](https://github.com/angular/angular/pull/58627)) |
### platform-browser
| Commit | Type | Description |
| -- | -- | -- |
| [c36a1c023b](https://github.com/angular/angular/commit/c36a1c023b34f9b2056e1bef6364787e8495bfad) | fix | correctly add external stylesheets to ShadowDOM components ([#58482](https://github.com/angular/angular/pull/58482)) |
| [5c61f46409](https://github.com/angular/angular/commit/5c61f46409855bb8fe66d71a9c16c00753032987) | refactor | remove deprecated `BrowserModule.withServerTransition` method ([#58062](https://github.com/angular/angular/pull/58062)) |
### platform-server
| Commit | Type | Description |
| -- | -- | -- |
| [9e82559de4](https://github.com/angular/angular/commit/9e82559de4e99a1aedf645a05b01fc08d3f4b1b1) | fix | destroy `PlatformRef` when error happens during the `bootstrap()` phase ([#58112](https://github.com/angular/angular/pull/58112)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [f271021e19](https://github.com/angular/angular/commit/f271021e190ede70bfd181d46f0a468a8e7fa144) | feat | Add `routerOutletData` input to `RouterOutlet` directive ([#57051](https://github.com/angular/angular/pull/57051)) |
| [b2790813a6](https://github.com/angular/angular/commit/b2790813a62e4dfdd77e27d1bb82201788476d06) | fix | Align RouterModule.forRoot errorHandler with provider error handler ([#57050](https://github.com/angular/angular/pull/57050)) |
| [a49c35ec76](https://github.com/angular/angular/commit/a49c35ec769461b9eb490719f0aa3e5aea8e243f) | fix | remove setter for `injector` on `OutletContext` ([#58343](https://github.com/angular/angular/pull/58343)) |
| [7436d3180e](https://github.com/angular/angular/commit/7436d3180ea5ad2c0b58d920bd45f8641a14cc8d) | fix | Update Resolve interface to include RedirectCommand like ResolveFn ([#57309](https://github.com/angular/angular/pull/57309)) |
### service-worker
| Commit | Type | Description |
| -- | -- | -- |
| [8ddce80a0b](https://github.com/angular/angular/commit/8ddce80a0bab4ebbd0f7db1c85ee27e4f0249db9) | feat | allow specifying maxAge for entire application ([#49601](https://github.com/angular/angular/pull/49601)) |
| [1479af978c](https://github.com/angular/angular/commit/1479af978cd2bbe4ee9f1ca9682684b8e5135fa7) | feat | finish implementation of refreshAhead feature ([#53356](https://github.com/angular/angular/pull/53356)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.9"></a>
# 18.2.9 (2024-10-23)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [b0ab653965](https://github.com/angular/angular/commit/b0ab653965cf88fcfde23fc6a6cc78ce3121a30f) | fix | report when NgModule imports or exports itself ([#58231](https://github.com/angular/angular/pull/58231)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.8"></a>
# 18.2.8 (2024-10-10)
### compiler
@@ -121,45 +291,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.8"></a>
# 19.0.0-next.8 (2024-10-02)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [c3115b882e](https://github.com/angular/angular/commit/c3115b882ebbe4f971e1f06bb1ce2cdf43327bb0) | fix | execute checks and remove placeholder when image is already loaded ([#55444](https://github.com/angular/angular/pull/55444)) |
| [b7bd429951](https://github.com/angular/angular/commit/b7bd42995130f80ea74ed5b905446f09a98a9480) | fix | prevent warning about oversize image twice ([#58021](https://github.com/angular/angular/pull/58021)) |
| [e8b2d5fad8](https://github.com/angular/angular/commit/e8b2d5fad8aece3b2e3f4a7ed1356642f68ee275) | fix | skip checking whether SVGs are oversized ([#57966](https://github.com/angular/angular/pull/57966)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [d9687f43dd](https://github.com/angular/angular/commit/d9687f43dd2ccfcf7dd3ee4f9066ce727f3224c6) | feat | 'strictStandalone' flag enforces standalone ([#57935](https://github.com/angular/angular/pull/57935)) |
| [39ccaf4cc4](https://github.com/angular/angular/commit/39ccaf4cc457894a3cf0455349e1c016a858751a) | fix | correctly get the type of nested function call expressions ([#57010](https://github.com/angular/angular/pull/57010)) |
| [33fe252c58](https://github.com/angular/angular/commit/33fe252c588ee94d6ef99e8070d35c483ec24fda) | fix | do not report unused declarations coming from an imported array ([#57940](https://github.com/angular/angular/pull/57940)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [3240598158](https://github.com/angular/angular/commit/32405981582030d7eb5d307f44b9c00fb384c480) | fix | provide flag to opt into manual cleanup for after render hooks ([#57917](https://github.com/angular/angular/pull/57917)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [22dafa658b](https://github.com/angular/angular/commit/22dafa658bdf5536c3002e7f312efe0dfbc7236d) | fix | cleanup JSONP script listeners once loading completed ([#57877](https://github.com/angular/angular/pull/57877)) |
| [057cf7fb6b](https://github.com/angular/angular/commit/057cf7fb6bd2ac37a7a30d3a143e6737e386247f) | fix | preserve all headers from Headers object ([#57802](https://github.com/angular/angular/pull/57802)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [5c4305f024](https://github.com/angular/angular/commit/5c4305f0248ac3cc1adc76aebd3ef8af041039dc) | feat | support migrating full classes to signal inputs in VSCode ([#57975](https://github.com/angular/angular/pull/57975)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [b6bc93803c](https://github.com/angular/angular/commit/b6bc93803c246d47aac0d2d8619271d42b249a4a) | feat | add schematic to migrate to signal queries ([#58032](https://github.com/angular/angular/pull/58032)) |
| [ef577b2d2b](https://github.com/angular/angular/commit/ef577b2d2b62ba0a48a120b9631296812e9049d3) | fix | delete constructor if it only has super call ([#58013](https://github.com/angular/angular/pull/58013)) |
### upgrade
| Commit | Type | Description |
| -- | -- | -- |
| [5f56a65837](https://github.com/angular/angular/commit/5f56a6583753f5aaff8a43e1e5f9a376433d0c0c) | fix | support input signal bindings ([#57020](https://github.com/angular/angular/pull/57020)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.7"></a>
# 18.2.7 (2024-10-02)
### common
@@ -191,80 +322,11 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.7"></a>
# 19.0.0-next.7 (2024-09-25)
## Breaking Changes
### core
- Changes to effect timing which generally has two implications:
* effects which are triggered outside of change detection run as part of
the change detection process instead of as a microtask. Depending on the
specifics of application/test setup, this can result in them executing
earlier or later (or requiring additional test steps to trigger; see below
examples).
* effects which are triggered during change detection (e.g. by input
signals) run _earlier_, before the component's template.
We've seen a few common failure cases:
* Tests which used to rely on the `Promise` timing of effects now need to
`await whenStable()` or call `.detectChanges()` in order for effects to
run.
* Tests which use faked clocks may need to fast-forward/flush the clock to
cause effects to run.
* `effect()`s triggered during CD could rely on the application being fully
rendered (for example, they could easily read computed styles, etc). With
the change, they run before the component's updates and can get incorrect
answers. The recent `afterRenderEffect()` API is a natural replacement for
this style of effect.
* `effect()`s which synchronize with the forms system are particularly
timing-sensitive and might need to adjust their initialization timing.
- `ExperimentalPendingTasks` has been renamed to
`PendingTasks`.
### core
| Commit | Type | Description |
| -- | -- | -- |
| [fc59e2a7b7](https://github.com/angular/angular/commit/fc59e2a7b7afa491a5ea740284a742574805eb36) | feat | change effect() execution timing & no-op `allowSignalWrites` ([#57874](https://github.com/angular/angular/pull/57874)) |
| [a7eff3ffaa](https://github.com/angular/angular/commit/a7eff3ffaaecbcb3034130d475ff7b4e41a1e1cc) | feat | mark signal-based query APIs as stable ([#57921](https://github.com/angular/angular/pull/57921)) |
| [a1f229850a](https://github.com/angular/angular/commit/a1f229850ad36da009f772faa831da173a60268c) | feat | migrate ExperimentalPendingTasks to PendingTasks ([#57533](https://github.com/angular/angular/pull/57533)) |
| [950a5540f1](https://github.com/angular/angular/commit/950a5540f15118e7360506ad82ec9dab5a11f789) | fix | Ensure the `ViewContext` is retained after closure minification ([#57903](https://github.com/angular/angular/pull/57903)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [7ecfd89592](https://github.com/angular/angular/commit/7ecfd8959219b6e2ec19e1244a6694711daf1782) | fix | The suppress diagnostics option should work for external templates ([#57873](https://github.com/angular/angular/pull/57873)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.6"></a>
# 18.2.6 (2024-09-25)
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.6"></a>
# 19.0.0-next.6 (2024-09-18)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [f611faadfe](https://github.com/angular/angular/commit/f611faadfedd8dc2c3291da98e2c2c60fe3984bd) | fix | extended diagnostics not validating ICUs ([#57845](https://github.com/angular/angular/pull/57845)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [3ebe6b4ad4](https://github.com/angular/angular/commit/3ebe6b4ad401337e18619edc34477ae98226fa3e) | feat | Add async `run` method on `ExperimentalPendingTasks` ([#56546](https://github.com/angular/angular/pull/56546)) |
| [1b1519224d](https://github.com/angular/angular/commit/1b1519224d10c1cd25d05d7b958772b9adee1e1a) | feat | mark input, output and model APIs as stable ([#57804](https://github.com/angular/angular/pull/57804)) |
| [e5adf92965](https://github.com/angular/angular/commit/e5adf9296595644e415d5c147df08890be01ba77) | feat | stabilize `@let` syntax ([#57813](https://github.com/angular/angular/pull/57813)) |
| [4231e8f28f](https://github.com/angular/angular/commit/4231e8f28ffe8f55dddc2af0647b5b04fa8445d7) | fix | Handle `@let` declaration with array when `preparingForHydration` ([#57816](https://github.com/angular/angular/pull/57816)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [59fe9bc772](https://github.com/angular/angular/commit/59fe9bc77236f1374427a851e55b0fa5216d9cf9) | feat | introduce signal input migration as `ng generate` schematic ([#57805](https://github.com/angular/angular/pull/57805)) |
| [6144612940](https://github.com/angular/angular/commit/614461294041d7a2331bf7528907f37353205115) | fix | account for explicit standalone: false in migration ([#57803](https://github.com/angular/angular/pull/57803)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.5"></a>
# 18.2.5 (2024-09-18)
### compiler-cli
@@ -282,15 +344,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.5"></a>
# 19.0.0-next.5 (2024-09-11)
### core
| Commit | Type | Description |
| -- | -- | -- |
| [c93b510f9b](https://github.com/angular/angular/commit/c93b510f9b2e23aa7a3848a04c05249fde14a9b1) | feat | allow passing `undefined` without needing to include it in the type argument of `input` ([#57621](https://github.com/angular/angular/pull/57621)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.4"></a>
# 18.2.4 (2024-09-11)
### compiler
@@ -304,60 +357,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.4"></a>
# 19.0.0-next.4 (2024-09-09)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [40ff18f87a](https://github.com/angular/angular/commit/40ff18f87a04fd1c00dea9fee1568bfe52acf25c) | fix | produce less noisy errors when parsing control flow ([#57711](https://github.com/angular/angular/pull/57711)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [6ea8e1e9aa](https://github.com/angular/angular/commit/6ea8e1e9aae028572873cf97aa1949c8153f458f) | feat | Add a schematics to migrate to `standalone: false`. ([#57643](https://github.com/angular/angular/pull/57643)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [cbec46a51d](https://github.com/angular/angular/commit/cbec46a51d22a1238cc8bf1ebdf343d031b8f0ba) | feat | migrate .pipe calls in outputs used in tests ([#57691](https://github.com/angular/angular/pull/57691)) |
| [68e5370a66](https://github.com/angular/angular/commit/68e5370a66633f4b069d6adffa95c2ea94291820) | feat | remove complete calls for migrated outputs ([#57671](https://github.com/angular/angular/pull/57671)) |
| [9da21f798d](https://github.com/angular/angular/commit/9da21f798de2033af9d39a8a9b255ef2fe74f948) | feat | replace .next usage on outputs ([#57654](https://github.com/angular/angular/pull/57654)) |
| [71f5ef2aa5](https://github.com/angular/angular/commit/71f5ef2aa53a74bab7d0543f98870d81c44c4978) | fix | change imports to be G3 compatible ([#57654](https://github.com/angular/angular/pull/57654)) |
| [3a264db866](https://github.com/angular/angular/commit/3a264db86611cba9b69780d7f01ee25787278320) | fix | properly handle comments in output migration ([#57691](https://github.com/angular/angular/pull/57691)) |
| [fc95a9adff](https://github.com/angular/angular/commit/fc95a9adff42da53dfeee5df8c42be25e8559708) | fix | replace leftover modules with their exports during pruning ([#57684](https://github.com/angular/angular/pull/57684)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.3"></a>
# 19.0.0-next.3 (2024-09-04)
## Breaking Changes
### core
- * TypeScript versions less than 5.5 are no longer supported.
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [a2e4ee0cb3](https://github.com/angular/angular/commit/a2e4ee0cb3d40cadc05e28d58b06853973944456) | feat | add diagnostic for unused standalone imports ([#57605](https://github.com/angular/angular/pull/57605)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [8bcc663a53](https://github.com/angular/angular/commit/8bcc663a53888717cdf4ce0c23404caa00abb1b2) | feat | drop support for TypeScript 5.4 ([#57577](https://github.com/angular/angular/pull/57577)) |
| [e6e5d29e83](https://github.com/angular/angular/commit/e6e5d29e830a0a74d7677d5f2345f29391064853) | feat | initial version of the output migration ([#57604](https://github.com/angular/angular/pull/57604)) |
| [be2e49639b](https://github.com/angular/angular/commit/be2e49639bda831831ad62d49253db942a83fd46) | feat | introduce `afterRenderEffect` ([#57549](https://github.com/angular/angular/pull/57549)) |
### elements
| Commit | Type | Description |
| -- | -- | -- |
| [fe5c4e086a](https://github.com/angular/angular/commit/fe5c4e086add655bf53315d71b0736ff758c7199) | fix | support `output()`-shaped outputs ([#57535](https://github.com/angular/angular/pull/57535)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [c2892fee58](https://github.com/angular/angular/commit/c2892fee58d28ffec0dfeaad6a5d6822c040cf03) | fix | Dynamicaly call the global fetch implementation ([#57531](https://github.com/angular/angular/pull/57531)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [8da9fb49b5](https://github.com/angular/angular/commit/8da9fb49b54e50de2d028691f73fb773def62ecd) | feat | add code fix for unused standalone imports ([#57605](https://github.com/angular/angular/pull/57605)) |
| [1f067f4507](https://github.com/angular/angular/commit/1f067f4507b6e908fe991d5de0dc4d3a627ab2f9) | feat | add code refactoring action to migrate `@Input` to signal-input ([#57214](https://github.com/angular/angular/pull/57214)) |
| [56ee47f2ec](https://github.com/angular/angular/commit/56ee47f2ec6e983e2ffdf59476ab29a92590811e) | feat | allow code refactorings to compute edits asynchronously ([#57214](https://github.com/angular/angular/pull/57214)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.3"></a>
# 18.2.3 (2024-09-04)
### http
@@ -367,67 +366,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.2"></a>
# 19.0.0-next.2 (2024-08-28)
## Breaking Changes
### core
- Render default fallback with empty `projectableNodes`.
When passing an empty array to `projectableNodes` in the `createComponent` API, the default fallback content of the `ng-content` will be rendered if present. To prevent rendering the default content, pass `document.createTextNode('')` as a `projectableNode`.
For example:
```ts
// The first ng-content will render the default fallback content if present
createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
// To prevent projecting the default fallback content:
createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });
```
- The timers that are used for zone coalescing and hybrid
mode scheduling (which schedules an application state synchronization
when changes happen outside the Angular zone) will now run in the zone
above Angular rather than the root zone. This will mostly affect tests
which use `fakeAsync`: these timers will now be visible to `fakeAsync`
and can be affected by `tick` or `flush`.
### elements
- as part of switching away from custom CD behavior to the
hybrid scheduler, timing of change detection around custom elements has
changed subtly. These changes make elements more efficient, but can cause
tests which encoded assumptions about how or when elements would be checked
to require updating.
### common
| Commit | Type | Description |
| -- | -- | -- |
| [50f08e6c4bf](https://github.com/angular/angular/commit/50f08e6c4bf1caeeb08d3505ce7fabd466b9c76b) | feat | automatically use sizes auto in NgOptimizedImage ([#57479](https://github.com/angular/angular/pull/57479)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [4716c3b9660](https://github.com/angular/angular/commit/4716c3b9660b01f4ef3642fb774270b7f4a13d1a) | perf | reduce duplicate component style resolution ([#57502](https://github.com/angular/angular/pull/57502)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [a3cdbfe87f5](https://github.com/angular/angular/commit/a3cdbfe87f5a8daef11a154ef3edb5a3a5c12f77) | fix | avoid leaking memory if component throws during creation ([#57546](https://github.com/angular/angular/pull/57546)) |
| [7a99815146e](https://github.com/angular/angular/commit/7a99815146eb78074aa3ed6db73c6e87042df692) | fix | Do not bubble capture events. ([#57476](https://github.com/angular/angular/pull/57476)) |
| [7b1e5be20b9](https://github.com/angular/angular/commit/7b1e5be20b99c88246c6be78a4dcd64eb55cee1a) | fix | fallback to default ng-content with empty projectable nodes. ([#57480](https://github.com/angular/angular/pull/57480)) |
| [0300dd2e18f](https://github.com/angular/angular/commit/0300dd2e18f064f2f57f7371e0dc5c01218b5019) | fix | Fix fixture.detectChanges with autoDetect disabled and zoneless ([#57416](https://github.com/angular/angular/pull/57416)) |
| [226a67dabba](https://github.com/angular/angular/commit/226a67dabba90a488ad09ce7bb026b8883c90d4a) | fix | Schedulers run in zone above Angular rather than root ([#57553](https://github.com/angular/angular/pull/57553)) |
### elements
| Commit | Type | Description |
| -- | -- | -- |
| [0cebfd7462c](https://github.com/angular/angular/commit/0cebfd7462c6a7c6c3b0d66720c436a4b0eea19d) | fix | switch to `ComponentRef.setInput` & remove custom scheduler ([#56728](https://github.com/angular/angular/pull/56728)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [8f6308457f0](https://github.com/angular/angular/commit/8f6308457f0f03e9bbd09f4bc10d1c61fd41d22c) | fix | Do not unnecessarily run matcher twice on route matching ([#57530](https://github.com/angular/angular/pull/57530)) |
### upgrade
| Commit | Type | Description |
| -- | -- | -- |
| [c9d90786d0a](https://github.com/angular/angular/commit/c9d90786d0a6421bbb21b9d1649d031b34e3fa5d) | fix | Address Trusted Types violations in @angular/upgrade ([#57454](https://github.com/angular/angular/pull/57454)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.2"></a>
# 18.2.2 (2024-08-28)
### core
@@ -466,75 +404,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.1"></a>
# 19.0.0-next.1 (2024-08-22)
## Breaking Changes
### core
- The `autoDetect` feature of `ComponentFixture` will now
attach the fixture to the `ApplicationRef`. As a result, errors during
automatic change detection of the fixture be reported to the `ErrorHandler`.
This change may cause custom error handlers to observe new failures that were previously unreported.
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [9e87593055](https://github.com/angular/angular/commit/9e87593055a5314a67090bd15d5552c23b538050) | feat | ensure template style elements are preprocessed as inline styles ([#57429](https://github.com/angular/angular/pull/57429)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [b063468027](https://github.com/angular/angular/commit/b0634680272569501146bb7a9cdfe53033e25971) | feat | support TypeScript 5.6 ([#57424](https://github.com/angular/angular/pull/57424)) |
| [3b0dca75d6](https://github.com/angular/angular/commit/3b0dca75d6dab6039253edd00c436715775bd0dd) | fix | Allow zoneless scheduler to run inside `fakeAsync` ([#56932](https://github.com/angular/angular/pull/56932)) |
| [f03d274e87](https://github.com/angular/angular/commit/f03d274e87c919514a70d02c0699523957de7386) | fix | ComponentFixture autoDetect feature works like production ([#55228](https://github.com/angular/angular/pull/55228)) |
| [d4449fce21](https://github.com/angular/angular/commit/d4449fce21bebbb18f9e1341f1675cdbec7e83ac) | fix | handle hydration of components that project content conditionally ([#57383](https://github.com/angular/angular/pull/57383)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [4ae66f25d0](https://github.com/angular/angular/commit/4ae66f25d01ffd603872b3df3faf5c5c555b6446) | fix | account for members with doc strings and no modifiers ([#57389](https://github.com/angular/angular/pull/57389)) |
| [ac93839d69](https://github.com/angular/angular/commit/ac93839d694929fdf16c610994a369d4efb2823a) | fix | avoid migrating route component in tests ([#57317](https://github.com/angular/angular/pull/57317)) |
| [58a79b6e43](https://github.com/angular/angular/commit/58a79b6e435f2a46a7ab17ff5538083e05340b6f) | fix | preserve type when using inject decorator ([#57389](https://github.com/angular/angular/pull/57389)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.0-next.0"></a>
# 19.0.0-next.0 (2024-08-14)
## Breaking Changes
### core
- Errors that are thrown during `ApplicationRef.tick`
will now be rethrown when using `TestBed`. These errors should be
resolved by ensuring the test environment is set up correctly to
complete change detection successfully. There are two alternatives to
catch the errors:
* Instead of waiting for automatic change detection to happen, trigger
it synchronously and expect the error. For example, a jasmine test
could write `expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()`
* `TestBed` will reject any outstanding `ComponentFixture.whenStable` promises. A jasmine test,
for example, could write `expectAsync(fixture.whenStable()).toBeRejected()`.
As a last resort, you can configure errors to _not_ be rethrown by
setting `rethrowApplicationErrors` to `false` in `TestBed.configureTestingModule`.
### router
- The `Router.errorHandler` property has been removed.
Adding an error handler should be configured in either
`withNavigationErrorHandler` with `provideRouter` or the `errorHandler`
property in the extra options of `RouterModule.forRoot`. In addition,
the error handler cannot be used to change the return value of the
router navigation promise or prevent it from rejecting. Instead, if you
want to prevent the promise from rejecting, use `resolveNavigationPromiseOnError`.
- The return type of the `Resolve` interface now includes
`RedirectCommand`.
### core
| Commit | Type | Description |
| -- | -- | -- |
| [468d3fb9b1](https://github.com/angular/angular/commit/468d3fb9b1c3dd6dff86afcb6d8f89cc4c29b24b) | fix | rethrow errors during ApplicationRef.tick in TestBed ([#57200](https://github.com/angular/angular/pull/57200)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [f271021e19](https://github.com/angular/angular/commit/f271021e190ede70bfd181d46f0a468a8e7fa144) | feat | Add `routerOutletData` input to `RouterOutlet` directive ([#57051](https://github.com/angular/angular/pull/57051)) |
| [b2790813a6](https://github.com/angular/angular/commit/b2790813a62e4dfdd77e27d1bb82201788476d06) | fix | Align RouterModule.forRoot errorHandler with provider error handler ([#57050](https://github.com/angular/angular/pull/57050)) |
| [7436d3180e](https://github.com/angular/angular/commit/7436d3180ea5ad2c0b58d920bd45f8641a14cc8d) | fix | Update Resolve interface to include RedirectCommand like ResolveFn ([#57309](https://github.com/angular/angular/pull/57309)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.2.0"></a>
# 18.2.0 (2024-08-14)
### compiler
+1 -1
View File
@@ -260,7 +260,7 @@ The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is opti
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (examples: CircleCi, SauceLabs)
* **ci**: Changes to our CI configuration files and scripts (examples: Github Actions, SauceLabs)
* **docs**: Documentation only changes
* **feat**: A new feature
* **fix**: A bug fix
-9
View File
@@ -24,9 +24,6 @@
</p>
<p align="center">
<a href="https://circleci.com/gh/angular/workflows/angular/tree/main">
<img src="https://img.shields.io/circleci/build/github/angular/angular/main.svg?logo=circleci&logoColor=fff&label=CircleCI" alt="CI status" />
</a>&nbsp;
<a href="https://www.npmjs.com/@angular/core">
<img src="https://img.shields.io/npm/v/@angular/core.svg?logo=npm&logoColor=fff&label=NPM+package&color=limegreen" alt="Angular on npm" />
</a>&nbsp;
@@ -35,12 +32,6 @@
</a>
</p>
<p align="center">
<a href="https://app.circleci.com/insights/github/angular/angular/workflows/default_workflow?branch=main">
<img src="https://dl.circleci.com/insights-snapshot/gh/angular/angular/main/default_workflow/badge.svg" alt="InsightsSnapshot" />
</a>
</p>
<hr>
## Documentation
+3 -3
View File
@@ -143,10 +143,10 @@ cldr_xml_data_repository(
# sass rules
http_archive(
name = "io_bazel_rules_sass",
sha256 = "b00f13a280fc60ef2a1d142b31c629075bac841c980a0c3462190f338e5d584a",
strip_prefix = "rules_sass-6e23fb1351f392f7fe7a07038cd537770fe97742",
sha256 = "0c97c6d8f7a8697e53d91832117c91b71a23e6900acf530a22bf3de2e05179fc",
strip_prefix = "rules_sass-35b1c3236a2b2a23c9d1eaeb82c5f7d030a892d1",
urls = [
"https://github.com/bazelbuild/rules_sass/archive/6e23fb1351f392f7fe7a07038cd537770fe97742.zip",
"https://github.com/bazelbuild/rules_sass/archive/35b1c3236a2b2a23c9d1eaeb82c5f7d030a892d1.zip",
],
)
@@ -1 +1 @@
<ng-content></ng-content>
<ng-content />
@@ -1,76 +1,78 @@
<ng-template #navigationList let-navigationItems>
<ul
class="docs-navigation-list docs-faceted-list"
[class.docs-navigation-list-dropdown]="isDropdownView"
[class.docs-navigation-list-dropdown]="isDropdownView()"
>
@for (item of navigationItems; track $index) {
<li
class="docs-faceted-list-item"
[class.docs-navigation-link-hidden]="displayItemsToLevel && item.level > displayItemsToLevel"
>
@if (item.path) { @if (item.isExternal) {
<a [href]="item.path" target="_blank">
<span [class.docs-external-link]="item.isExternal">{{ item.label }}</span>
@if (item.children && item.level! > 1 && !item.isExpanded) {
<docs-icon>chevron_right</docs-icon>
}
</a>
} @else {
<a
[routerLink]="'/' + item.path"
[routerLinkActiveOptions]="{
queryParams: 'ignored',
fragment: 'ignored',
matrixParams: 'exact',
paths: 'exact',
exact: false
}"
routerLinkActive="docs-faceted-list-item-active"
(click)="emitClickOnLink()"
<li
class="docs-faceted-list-item"
[class.docs-navigation-link-hidden]="displayItemsToLevel() && item.level > displayItemsToLevel()"
>
<span>{{ item.label }}</span>
@if (item.children && !item.isExpanded) {
<docs-icon>chevron_right</docs-icon>
}
</a>
} } @else {
<!-- Nav Section Header -->
@if (item.level !== collapsableLevel && item.level !== expandableLevel) {
<div class="docs-secondary-nav-header">
<span>{{ item.label }}</span>
</div>
}
@if (item.path) {
@if (item.isExternal) {
<a [href]="item.path" target="_blank">
<span [class.docs-external-link]="item.isExternal">{{ item.label }}</span>
@if (item.children && item.level! > 1 && !item.isExpanded) {
<docs-icon>chevron_right</docs-icon>
}
</a>
} @else {
<a
[routerLink]="'/' + item.path"
[routerLinkActiveOptions]="{
queryParams: 'ignored',
fragment: 'ignored',
matrixParams: 'exact',
paths: 'exact',
exact: false
}"
routerLinkActive="docs-faceted-list-item-active"
(click)="emitClickOnLink()"
>
<span [innerHtml]="item.label"></span>
@if (item.children && !item.isExpanded) {
<docs-icon>chevron_right</docs-icon>
}
</a>
}
} @else {
<!-- Nav Section Header -->
@if (item.level !== collapsableLevel() && item.level !== expandableLevel()) {
<div class="docs-secondary-nav-header">
<span [innerHtml]="item.label"></span>
</div>
}
<!-- Nav Button Expand/Collapse -->
@if ((item.children && item.level === expandableLevel) || item.level === collapsableLevel) {
<button
type="button"
(click)="toggle(item)"
attr.aria-label="{{ item.isExpanded ? 'Collapse' : 'Expand' }} {{ item.label }}"
[attr.aria-expanded]="item.isExpanded"
class="docs-secondary-nav-button"
[class.docs-faceted-list-item-active]="item | isActiveNavigationItem: activeItem()"
[class.docs-expanded-button]="item.children && item.level == collapsableLevel"
[class.docs-not-expanded-button]="item.children && item.level === expandableLevel"
[class.docs-nav-item-has-icon]="
item.children && item.level === expandableLevel && !item.isExpanded
"
>
@if (item.children && item.level === collapsableLevel) {
<docs-icon>arrow_back</docs-icon>
<!-- Nav Button Expand/Collapse -->
@if (
(item.children && item.level === expandableLevel()) || item.level === collapsableLevel()
) {
<button
type="button"
(click)="toggle(item)"
attr.aria-label="{{ item.isExpanded ? 'Collapse' : 'Expand' }} {{ item.label }}"
[attr.aria-expanded]="item.isExpanded"
class="docs-secondary-nav-button"
[class.docs-faceted-list-item-active]="item | isActiveNavigationItem: activeItem()"
[class.docs-expanded-button]="item.children && item.level == collapsableLevel()"
[class.docs-not-expanded-button]="item.children && item.level === expandableLevel()"
[class.docs-nav-item-has-icon]="
item.children && item.level === expandableLevel() && !item.isExpanded
"
>
@if (item.children && item.level === collapsableLevel()) {
<docs-icon>arrow_back</docs-icon>
}
<span>{{ item.label }}</span>
</button>
}
}
<span>{{ item.label }}</span>
</button>
} } @if (item.children?.length > 0) {
<ng-container
*ngTemplateOutlet="navigationList; context: {$implicit: item.children}"
></ng-container>
}
</li>
@if (item.children?.length > 0) {
<ng-container *ngTemplateOutlet="navigationList; context: {$implicit: item.children}" />
}
</li>
}
</ul>
</ng-template>
<ng-container
*ngTemplateOutlet="navigationList; context: {$implicit: navigationItems}"
></ng-container>
<ng-container *ngTemplateOutlet="navigationList; context: {$implicit: navigationItems()}" />
@@ -44,11 +44,13 @@ describe('NavigationList', () => {
],
}).compileComponents();
fixture = TestBed.createComponent(NavigationList);
fixture.componentRef.setInput('navigationItems', []);
component = fixture.componentInstance;
});
it('should display provided navigation structure', () => {
component.navigationItems = [...navigationItems];
fixture.componentRef.setInput('navigationItems', [...navigationItems]);
fixture.detectChanges();
const links = fixture.debugElement.queryAll(By.css('a'));
@@ -59,7 +61,7 @@ describe('NavigationList', () => {
});
it('should append `docs-navigation-list-dropdown` when isDropdownView is true', () => {
component.isDropdownView = true;
fixture.componentRef.setInput('isDropdownView', true);
fixture.detectChanges();
const ulElement = fixture.debugElement.query(By.css('ul.docs-navigation-list-dropdown'));
@@ -68,7 +70,7 @@ describe('NavigationList', () => {
});
it('should not append `docs-navigation-list-dropdown` when isDropdownView is false', () => {
component.isDropdownView = false;
fixture.componentRef.setInput('isDropdownView', false);
fixture.detectChanges();
const ulElement = fixture.debugElement.query(By.css('ul.docs-navigation-list-dropdown'));
@@ -78,7 +80,7 @@ describe('NavigationList', () => {
it('should emit linkClicked when user clicked on link', () => {
const emitClickOnLinkSpy = spyOn(component, 'emitClickOnLink');
component.navigationItems = [...navigationItems];
fixture.componentRef.setInput('navigationItems', [...navigationItems]);
fixture.detectChanges(true);
const guideLink = fixture.debugElement.query(By.css('a[href="/guide"]'));
@@ -102,7 +104,7 @@ describe('NavigationList', () => {
const toggleItemSpy = spyOn(navigationState, 'toggleItem');
const itemToToggle = navigationItems[1];
component.expandableLevel = 1;
fixture.componentRef.setInput('expandableLevel', 1);
component.toggle(itemToToggle);
expect(toggleItemSpy).toHaveBeenCalledOnceWith(itemToToggle);
@@ -113,15 +115,15 @@ describe('NavigationList', () => {
const toggleItemSpy = spyOn(navigationState, 'toggleItem');
const itemToToggle = navigationItems[1].children![1];
component.collapsableLevel = 2;
fixture.componentRef.setInput('collapsableLevel', 2);
component.toggle(itemToToggle);
expect(toggleItemSpy).toHaveBeenCalledOnceWith(itemToToggle);
});
it('should display items to provided level', () => {
component.navigationItems = [...navigationItems];
component.displayItemsToLevel = 1;
fixture.componentRef.setInput('navigationItems', [...navigationItems]);
fixture.componentRef.setInput('displayItemsToLevel', 1);
fixture.detectChanges(true);
const visibleItems = fixture.debugElement.queryAll(
@@ -6,14 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Input,
Output,
inject,
} from '@angular/core';
import {ChangeDetectionStrategy, Component, inject, input, output} from '@angular/core';
import {NavigationItem} from '../../interfaces/index';
import {NavigationState} from '../../services/index';
import {RouterLink, RouterLinkActive} from '@angular/router';
@@ -30,24 +23,23 @@ import {IsActiveNavigationItem} from '../../pipes/is-active-navigation-item.pipe
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NavigationList {
@Input({required: true}) navigationItems: NavigationItem[] = [];
@Input() displayItemsToLevel: number = 2;
@Input() collapsableLevel: number | undefined = undefined;
@Input() expandableLevel: number = 2;
@Input() isDropdownView = false;
readonly navigationItems = input.required<NavigationItem[]>();
readonly displayItemsToLevel = input<number>(2);
readonly collapsableLevel = input<number | undefined>();
readonly expandableLevel = input<number>(2);
readonly isDropdownView = input<boolean>(false);
@Output() linkClicked = new EventEmitter<void>();
readonly linkClicked = output<void>();
private readonly navigationState = inject(NavigationState);
expandedItems = this.navigationState.expandedItems;
activeItem = this.navigationState.activeNavigationItem;
readonly activeItem = this.navigationState.activeNavigationItem;
toggle(item: NavigationItem): void {
if (
item.level === 1 &&
item.level !== this.expandableLevel &&
item.level !== this.collapsableLevel
item.level !== this.expandableLevel() &&
item.level !== this.collapsableLevel()
) {
return;
}
@@ -7,7 +7,7 @@
(ngModelChange)="updateSearchQuery($event)"
class="docs-search-input"
placeholder="Search docs"
></docs-text-field>
/>
@if (searchResults() && searchResults()!.length > 0) {
<ul class="docs-search-results docs-mini-scroll-track">
@@ -31,7 +31,7 @@
<ng-container
[ngTemplateOutlet]="highlightSnippet"
[ngTemplateOutletContext]="{snippet}"
></ng-container>
/>
</span>
</div>
@@ -43,7 +43,7 @@
<ng-container
[ngTemplateOutlet]="highlightSnippet"
[ngTemplateOutletContext]="{snippet}"
></ng-container>
/>
</span>
}
</div>
@@ -70,7 +70,8 @@
<div class="docs-algolia">
<span>Search by</span>
<a href="https://www.algolia.com/developers/" target="_blank" rel="noopener">
<a target="_blank" rel="noopener"
href="https://www.algolia.com/developers/?utm_source=angular.dev&utm_medium=referral&utm_content=powered_by&utm_campaign=docsearch">
<docs-algolia-icon />
</a>
</div>
@@ -1,5 +1,10 @@
<select [attr.id]="id" [attr.name]="name" [ngModel]="selectedOption()" (ngModelChange)="setOption($event)">
@for (item of options; track item) {
<select
[attr.id]="id()"
[attr.name]="name()"
[ngModel]="selectedOption()"
(ngModelChange)="setOption($event)"
>
@for (item of options(); track item) {
<option [value]="item.value">{{ item.label }}</option>
}
</select>
@@ -22,6 +22,12 @@ describe('Select', () => {
});
fixture = TestBed.createComponent(Select);
component = fixture.componentInstance;
// Sets the required inputs
fixture.componentRef.setInput('selectId', 'id');
fixture.componentRef.setInput('name', 'name');
fixture.componentRef.setInput('options', []);
fixture.detectChanges();
});
@@ -7,7 +7,7 @@
*/
import {ControlValueAccessor, NG_VALUE_ACCESSOR, FormsModule} from '@angular/forms';
import {ChangeDetectionStrategy, Component, Input, forwardRef, signal} from '@angular/core';
import {ChangeDetectionStrategy, Component, model, forwardRef, input, signal} from '@angular/core';
import {CommonModule} from '@angular/common';
type SelectOptionValue = string | number | boolean;
@@ -36,10 +36,10 @@ export interface SelectOption {
},
})
export class Select implements ControlValueAccessor {
@Input({required: true, alias: 'selectId'}) id!: string;
@Input({required: true}) name!: string;
@Input({required: true}) options!: SelectOption[];
@Input() disabled = false;
readonly id = input.required<string>({alias: 'selectId'});
readonly name = input.required<string>();
readonly options = input.required<SelectOption[]>();
readonly disabled = model<boolean>(false);
// Implemented as part of ControlValueAccessor.
private onChange: (value: SelectOptionValue) => void = (_: SelectOptionValue) => {};
@@ -64,11 +64,11 @@ export class Select implements ControlValueAccessor {
// Implemented as part of ControlValueAccessor.
setDisabledState?(isDisabled: boolean): void {
this.disabled = isDisabled;
this.disabled.set(isDisabled);
}
setOption($event: SelectOptionValue): void {
if (this.disabled) {
if (this.disabled()) {
return;
}
@@ -1,9 +1,9 @@
<label [attr.for]="buttonId">
<span class="docs-label">{{ label }}</span>
<label [attr.for]="buttonId()">
<span class="docs-label">{{ label() }}</span>
<div class="docs-toggle">
<input
type="checkbox"
[id]="buttonId"
[id]="buttonId()"
role="switch"
(click)="toggle()"
[class.docs-toggle-active]="checked()"
@@ -21,6 +21,8 @@ describe('SlideToggle', () => {
providers: [provideExperimentalZonelessChangeDetection()],
});
fixture = TestBed.createComponent(SlideToggle);
fixture.componentRef.setInput('buttonId', 'id');
fixture.componentRef.setInput('label', 'foo');
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {ChangeDetectionStrategy, Component, Input, forwardRef, signal} from '@angular/core';
import {ChangeDetectionStrategy, Component, forwardRef, model, input, signal} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
@@ -26,9 +26,9 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
],
})
export class SlideToggle implements ControlValueAccessor {
@Input({required: true}) buttonId!: string;
@Input({required: true}) label!: string;
@Input() disabled = false;
readonly buttonId = input.required<string>();
readonly label = input.required<string>();
readonly disabled = model<boolean>(false);
// Implemented as part of ControlValueAccessor.
private onChange: (value: boolean) => void = (_: boolean) => {};
@@ -53,12 +53,12 @@ export class SlideToggle implements ControlValueAccessor {
// Implemented as part of ControlValueAccessor.
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
this.disabled.set(isDisabled);
}
// Toggles the checked state of the slide-toggle.
toggle(): void {
if (this.disabled) {
if (this.disabled()) {
return;
}
@@ -71,6 +71,8 @@ describe('TableOfContents', () => {
spyOn(tableOfContentsLoaderSpy, 'buildTableOfContent').and.returnValue();
tableOfContentsLoaderSpy.tableOfContentItems.set(items);
fixture = TestBed.createComponent(TableOfContents);
fixture.componentRef.setInput('contentSourceElement', document.createElement('div'));
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -10,7 +10,7 @@ import {
ChangeDetectionStrategy,
Component,
DestroyRef,
Input,
input,
computed,
inject,
} from '@angular/core';
@@ -30,7 +30,7 @@ import {IconComponent} from '../icon/icon.component';
})
export class TableOfContents {
// Element that contains the content from which the Table of Contents is built
@Input({required: true}) contentSourceElement!: HTMLElement;
readonly contentSourceElement = input.required<HTMLElement>();
private readonly scrollSpy = inject(TableOfContentsScrollSpy);
private readonly tableOfContentsLoader = inject(TableOfContentsLoader);
@@ -43,8 +43,8 @@ export class TableOfContents {
TableOfContentsLevel = TableOfContentsLevel;
ngAfterViewInit() {
this.tableOfContentsLoader.buildTableOfContent(this.contentSourceElement);
this.scrollSpy.startListeningToScroll(this.contentSourceElement, this.destroyRef);
this.tableOfContentsLoader.buildTableOfContent(this.contentSourceElement());
this.scrollSpy.startListeningToScroll(this.contentSourceElement(), this.destroyRef);
}
scrollToTop(): void {
@@ -1,11 +1,11 @@
@if (!hideIcon) {
<docs-icon class="docs-icon_high-contrast">search</docs-icon>
@if (!hideIcon()) {
<docs-icon class="docs-icon_high-contrast">search</docs-icon>
}
<input
#inputRef
type="text"
[attr.placeholder]="placeholder"
[attr.name]="name"
[attr.placeholder]="placeholder()"
[attr.name]="name()"
[ngModel]="value()"
(ngModelChange)="setValue($event)"
class="docs-text-field"
@@ -10,11 +10,12 @@ import {
ChangeDetectionStrategy,
Component,
ElementRef,
Input,
ViewChild,
input,
afterNextRender,
forwardRef,
signal,
model,
viewChild,
} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR} from '@angular/forms';
@@ -39,13 +40,13 @@ import {IconComponent} from '../icon/icon.component';
},
})
export class TextField implements ControlValueAccessor {
@ViewChild('inputRef') private input?: ElementRef<HTMLInputElement>;
readonly input = viewChild.required<ElementRef<HTMLInputElement>>('inputRef');
@Input() name: string | null = null;
@Input() placeholder: string | null = null;
@Input() disabled = false;
@Input() hideIcon = false;
@Input() autofocus = false;
readonly name = input<string | null>(null);
readonly placeholder = input<string | null>(null);
readonly disabled = model<boolean>(false);
readonly hideIcon = input<boolean>(false);
readonly autofocus = input<boolean>(false);
// Implemented as part of ControlValueAccessor.
private onChange: (value: string) => void = (_: string) => {};
@@ -55,8 +56,8 @@ export class TextField implements ControlValueAccessor {
constructor() {
afterNextRender(() => {
if (this.autofocus) {
this.input?.nativeElement.focus();
if (this.autofocus()) {
this.input().nativeElement.focus();
}
});
}
@@ -78,11 +79,11 @@ export class TextField implements ControlValueAccessor {
// Implemented as part of ControlValueAccessor.
setDisabledState?(isDisabled: boolean): void {
this.disabled = isDisabled;
this.disabled.set(isDisabled);
}
setValue(value: string): void {
if (this.disabled) {
if (this.disabled()) {
return;
}
@@ -1,17 +1,19 @@
@if (!hasClosed()) {
@if (link()) {
<a [href]="link()" class="docs-top-level-banner">
<h1 tabindex="-1" class="docs-top-level-banner-cta background">{{ text() }}</h1>
<h1 tabindex="0" class="docs-top-level-banner-cta shimmer">{{ text() }}</h1>
</a>
} @else {
<div class="docs-top-level-banner">
<h1 tabindex="-1" class="docs-top-level-banner-cta background">{{ text() }}</h1>
<h1 tabindex="0" class="docs-top-level-banner-cta shimmer">{{ text() }}</h1>
</div>
}
<button class="docs-top-level-banner-close" type="button" (click)="close()">
<docs-icon class="docs-icon_high-contrast">close</docs-icon>
</button>
@if (link()) {
<a [href]="link()" class="docs-top-level-banner">
<h1 tabindex="-1" class="docs-top-level-banner-cta shimmer">{{ text() }}</h1>
<h1 tabindex="0" class="docs-top-level-banner-cta background"><span class="docs-top-level-banner-cta__text">{{ text()
}}</span></h1>
</a>
} @else {
<div class="docs-top-level-banner">
<h1 tabindex="-1" class="docs-top-level-banner-cta shimmer">{{ text() }}</h1>
<h1 tabindex="0" class="docs-top-level-banner-cta background"><span class="docs-top-level-banner-cta__text">{{ text()
}}</span></h1>
</div>
}
<button class="docs-top-level-banner-close" type="button" (click)="close()">
<docs-icon class="docs-icon_high-contrast">close</docs-icon>
</button>
}
@@ -1,9 +1,13 @@
:host {
&:not(:empty) {
z-index: 50;
z-index: var(--z-index-top-level-banner);
position: fixed;
height: 2rem;
display: flex;
align-items: center;
justify-content: center;
height: auto;
width: 100vw;
padding: .5rem;
border-bottom: 1px solid var(--septenary-contrast);
text-align: center;
align-content: center;
@@ -12,16 +16,22 @@
}
a.docs-top-level-banner {
width: 100%;
display: inherit;
display: grid;
width: auto;
margin: 0rem 2.5rem;
&:hover{
h1.docs-top-level-banner-cta.background{
span.docs-top-level-banner-cta__text::after{
transform: scaleX(1);
transform-origin: bottom left;
}}
}
}
h1.docs-top-level-banner-cta {
display: inline;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
grid-row-start: 1;
grid-column-start: 1;
font-size: 0.875rem;
margin: 0;
width: fit-content;
@@ -29,45 +39,46 @@
&.background {
color: var(--tertiary-contrast);
& .docs-top-level-banner-cta__text{
position:relative;
&::after {
content: '';
position: absolute;
width: calc(100% + 2rem);
height: 1px;
bottom: -2px;
left: -1rem;
background: var(--tertiary-contrast);
transform: scaleX(0);
transform-origin: bottom right;
@media (prefers-reduced-motion: no-preference) {
transition: transform 0.3s ease;
}
}
}
}
&:not(.background) {
color: transparent;
&::after {
content: '';
position: absolute;
width: 100%;
height: 1px;
bottom: -2px;
left: 0;
background: var(--tertiary-contrast);
transform: scaleX(0);
transform-origin: bottom right;
@media (prefers-reduced-motion: no-preference) {
transition: transform 0.3s ease;
}
}
&:hover {
&::after {
transform: scaleX(1);
transform-origin: bottom left;
}
}
}
}
.docs-top-level-banner-close {
position: absolute;
top: 0.25rem;
right: 0.5rem;
right: 1.4rem;
color: var(--tertiary-contrast);
padding-left: 0rem;
}
}
.shimmer {
background: var(--red-to-pink-to-purple-horizontal-gradient);
z-index: 1;
@media (prefers-reduced-motion: no-preference) {
background-repeat: no-repeat;
@@ -36,7 +36,7 @@
h5,
h6 {
.docs-anchor {
margin-block-start: 2.5rem;
margin-block-start: 0.75rem;
display: inline-block;
color: inherit;
@@ -8,8 +8,8 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {RouterTestingModule} from '@angular/router/testing';
import {provideNoopAnimations} from '@angular/platform-browser/animations';
import {provideRouter} from '@angular/router';
import {ExampleViewerContentLoader} from '../../../interfaces';
import {EXAMPLE_VIEWER_CONTENT_LOADER} from '../../../providers';
import {CodeExampleViewMode, ExampleViewer} from '../example-viewer/example-viewer.component';
@@ -80,8 +80,10 @@ describe('DocViewer', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [DocViewer, NoopAnimationsModule, RouterTestingModule],
imports: [DocViewer],
providers: [
provideNoopAnimations(),
provideRouter([]),
provideExperimentalZonelessChangeDetection(),
{provide: EXAMPLE_VIEWER_CONTENT_LOADER, useValue: exampleContentSpy},
{provide: NavigationState, useValue: navigationStateSpy},
@@ -26,8 +26,7 @@ import {
ViewContainerRef,
ViewEncapsulation,
ɵPendingTasks as PendingTasks,
EventEmitter,
Output,
output,
} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {TOC_SKIP_CONTENT_MARKER, NavigationState} from '../../../services/index';
@@ -68,7 +67,7 @@ export const GITHUB_CONTENT_URL =
export class DocViewer implements OnChanges {
@Input() docContent?: string;
@Input() hasToc = false;
@Output() contentLoaded = new EventEmitter<void>();
readonly contentLoaded = output<void>();
private readonly destroyRef = inject(DestroyRef);
private readonly document = inject(DOCUMENT);
@@ -134,7 +133,7 @@ export class DocViewer implements OnChanges {
// Render ToC
this.renderTableOfContents(contentContainer);
this.contentLoaded.next();
this.contentLoaded.emit();
}
/**
@@ -11,7 +11,7 @@ import {ExampleViewer} from './example-viewer.component';
import {DocsContentLoader, ExampleMetadata, ExampleViewerContentLoader} from '../../../interfaces';
import {DOCS_CONTENT_LOADER, EXAMPLE_VIEWER_CONTENT_LOADER} from '../../../providers';
import {Component, provideExperimentalZonelessChangeDetection} from '@angular/core';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {provideNoopAnimations} from '@angular/platform-browser/animations';
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {Clipboard} from '@angular/cdk/clipboard';
@@ -35,8 +35,9 @@ describe('ExampleViewer', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ExampleViewer, NoopAnimationsModule],
imports: [ExampleViewer],
providers: [
provideNoopAnimations(),
provideExperimentalZonelessChangeDetection(),
{provide: EXAMPLE_VIEWER_CONTENT_LOADER, useValue: exampleContentSpy},
{provide: DOCS_CONTENT_LOADER, useValue: contentServiceSpy},
@@ -7,7 +7,7 @@
*/
import {DOCUMENT} from '@angular/common';
import {Directive, ElementRef, EventEmitter, Input, Output, inject} from '@angular/core';
import {Directive, ElementRef, Input, inject, output} from '@angular/core';
@Directive({
selector: '[docsClickOutside]',
@@ -18,7 +18,7 @@ import {Directive, ElementRef, EventEmitter, Input, Output, inject} from '@angul
})
export class ClickOutside {
@Input('docsClickOutsideIgnore') public ignoredElementsIds: string[] = [];
@Output('docsClickOutside') public clickOutside = new EventEmitter<void>();
public readonly clickOutside = output<void>({alias: 'docsClickOutside'});
private readonly document = inject(DOCUMENT);
private readonly elementRef = inject(ElementRef<HTMLElement>);
+9 -9
View File
@@ -2,14 +2,14 @@
"name": "@angular/docs",
"version": "0.0.0-PLACEHOLDER",
"peerDependencies": {
"@angular/cdk": "^19.0.0-next",
"@angular/common": "^19.0.0-next",
"@angular/core": "^19.0.0-next",
"@angular/forms": "^19.0.0-next",
"@angular/material": "^19.0.0-next",
"@angular/platform-browser": "^19.0.0-next",
"@angular/router": "^19.0.0-next",
"@angular/ssr": "^19.0.0-next",
"@angular/cdk": "^19.0.0",
"@angular/common": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/forms": "^19.0.0",
"@angular/material": "^19.0.0",
"@angular/platform-browser": "^19.0.0",
"@angular/router": "^19.0.0",
"@angular/ssr": "^19.0.0",
"algoliasearch": "^5.0.0",
"rxjs": "^7.8.1"
},
@@ -21,7 +21,7 @@
"fflate": "^0.8.2",
"html-entities": "~2.5.2",
"jsdom": "~25.0.0",
"marked": "~14.1.0",
"marked": "~15.0.0",
"mermaid": "^11.0.0",
"shiki": "^1.10.3"
},
@@ -52,6 +52,8 @@ function main() {
rootDir: '.',
skipLibCheck: true,
target: ts.ScriptTarget.ES2022,
// This is necessary because otherwise types that include `| null` are not included in the documentation.
strictNullChecks: true,
moduleResolution: ts.ModuleResolutionKind.NodeNext,
experimentalDecorators: true,
};
@@ -94,7 +94,9 @@ export interface ConstantEntry extends DocEntry {
}
/** Documentation entity for a type alias. */
export type TypeAliasEntry = ConstantEntry;
export interface TypeAliasEntry extends ConstantEntry {
generics: GenericEntry[];
}
/** Documentation entity for a TypeScript class. */
export interface ClassEntry extends DocEntry {
@@ -21,11 +21,7 @@ export async function initHighlighter() {
});
}
export function codeToHtml(
code: string,
language: string | undefined,
options?: {removeFunctionKeyword?: boolean},
): string {
export function codeToHtml(code: string, language: string | undefined): string {
const html = highlighter.codeToHtml(code, {
lang: language ?? 'text',
themes: {
@@ -36,9 +32,6 @@ export function codeToHtml(
defaultColor: false,
});
if (options?.removeFunctionKeyword) {
return replaceKeywordFromShikiHtml('function', html);
}
return html;
}
@@ -43,7 +43,6 @@ export const signatureCard = (
// Always omit types in signature headers, to keep them short.
true,
)}
removeFunctionKeyword={true}
/>
</code>
) : (
@@ -11,10 +11,8 @@ import {RawHtml} from './raw-html';
import {codeToHtml} from '../shiki/shiki';
/** Component to render a header of the CLI page. */
export function HighlightTypeScript(props: {code: string; removeFunctionKeyword?: boolean}) {
const result = codeToHtml(props.code, 'typescript', {
removeFunctionKeyword: props.removeFunctionKeyword,
});
export function HighlightTypeScript(props: {code: string; }) {
const result = codeToHtml(props.code, 'typescript');
return <RawHtml value={result} />;
}
@@ -0,0 +1,59 @@
import {makeGenericsText} from '../../transforms/code-transforms';
describe('makeGenericsText', () => {
it('should return an empty string if no generics are provided', () => {
expect(makeGenericsText(undefined)).toBe('');
expect(makeGenericsText([])).toBe('');
});
it('should return a single generic type without constraints or default', () => {
const generics = [{name: 'T', constraint: undefined, default: undefined}];
expect(makeGenericsText(generics)).toBe('<T>');
});
it('should handle a single generic type with a constraint', () => {
const generics = [{name: 'T', constraint: 'string', default: undefined}];
expect(makeGenericsText(generics)).toBe('<T extends string>');
});
it('should handle a single generic type with a default value', () => {
const generics = [{name: 'T', default: 'number', constraint: undefined}];
expect(makeGenericsText(generics)).toBe('<T = number>');
});
it('should handle a single generic type with both constraint and default value', () => {
const generics = [{name: 'T', constraint: 'string', default: 'number'}];
expect(makeGenericsText(generics)).toBe('<T extends string = number>');
});
it('should handle multiple generic types without constraints or defaults', () => {
const generics = [
{name: 'T', constraint: undefined, default: undefined},
{name: 'U', constraint: undefined, default: undefined},
];
expect(makeGenericsText(generics)).toBe('<T, U>');
});
it('should handle multiple generic types with constraints and defaults', () => {
const generics = [
{name: 'T', constraint: 'string', default: 'number'},
{name: 'U', constraint: 'boolean', default: undefined},
{name: 'V', default: 'any', constraint: undefined},
];
expect(makeGenericsText(generics)).toBe(
'<T extends string = number, U extends boolean, V = any>',
);
});
it('should handle complex generics with mixed constraints and defaults', () => {
const generics = [
{name: 'A', constraint: 'string', default: undefined},
{name: 'B', constraint: undefined, default: undefined},
{name: 'C', default: 'number', constraint: undefined},
{name: 'D', constraint: 'boolean', default: 'true'},
];
expect(makeGenericsText(generics)).toBe(
'<A extends string, B, C = number, D extends boolean = true>',
);
});
});
@@ -9,6 +9,7 @@
import {
DocEntry,
FunctionSignatureMetadata,
GenericEntry,
MemberEntry,
MemberTags,
ParameterEntry,
@@ -66,9 +67,7 @@ export function addRenderableCodeToc<T extends DocEntry & HasModuleName>(
const metadata = mapDocEntryToCode(entry);
appendPrefixAndSuffix(entry, metadata);
let codeWithSyntaxHighlighting = codeToHtml(metadata.contents, 'typescript', {
removeFunctionKeyword: true,
});
let codeWithSyntaxHighlighting = codeToHtml(metadata.contents, 'typescript');
if (isDecoratorEntry(entry)) {
// Shiki requires a keyword for correct formating of Decorators
@@ -242,7 +241,8 @@ export function mapDocEntryToCode(entry: DocEntry): CodeTableOfContentsData {
}
if (isTypeAliasEntry(entry)) {
const contents = `type ${entry.name} = ${entry.type}`;
const generics = makeGenericsText(entry.generics);
const contents = `type ${entry.name}${generics} = ${entry.type}`;
if (isDeprecated) {
const numberOfLinesOfCode = getNumberOfLinesOfCode(contents);
@@ -332,8 +332,10 @@ function getMethodCodeLine(
displayParamsInNewLines: boolean = false,
isFunction: boolean = false,
): string {
const generics = makeGenericsText(member.generics);
displayParamsInNewLines &&= member.params.length > 0;
return `${isFunction ? 'function' : ''}${memberTags.join(' ')} ${member.name}(${displayParamsInNewLines ? '\n ' : ''}${member.params
return `${isFunction ? 'function' : ''}${memberTags.join(' ')} ${member.name}${generics}(${displayParamsInNewLines ? '\n ' : ''}${member.params
.map((param) => mapParamEntry(param))
.join(`,${displayParamsInNewLines ? '\n ' : ' '}`)}${
displayParamsInNewLines ? '\n' : ''
@@ -442,13 +444,7 @@ function appendPrefixAndSuffix(entry: DocEntry, codeTocData: CodeTableOfContents
};
if (isClassEntry(entry) || isInterfaceEntry(entry)) {
const generics =
entry.generics?.length > 0
? `<${entry.generics
.map((g) => (g.constraint ? `${g.name} extends ${g.constraint}` : g.name))
.join(', ')}>`
: '';
const generics = makeGenericsText(entry.generics);
const extendsStr = entry.extends ? ` extends ${entry.extends}` : '';
// TODO: remove the ? when we distinguish Class & Decorator entries
const implementsStr =
@@ -501,3 +497,45 @@ export function addApiLinksToHtml(htmlString: string): string {
return result;
}
/**
* Constructs a TypeScript generics string based on an array of generic type entries.
*
* This function takes an array of generic type entries and returns a formatted string
* representing TypeScript generics syntax, including any constraints and default values
* specified in each entry.
*
* @param generics - An array of `GenericEntry` objects representing the generics to be formatted,
* or `undefined` if there are no generics.
*
* @returns A formatted string representing TypeScript generics syntax, or an empty string if no generics are provided.
*/
export function makeGenericsText(generics: GenericEntry[] | undefined): string {
if (!generics?.length) {
return '';
}
const parts: string[] = ['<'];
for (let index = 0; index < generics.length; index++) {
const {constraint, default: defaultVal, name} = generics[index];
parts.push(name);
if (constraint) {
parts.push(' extends ', constraint);
}
if (defaultVal !== undefined) {
parts.push(' = ', defaultVal);
}
if (index < generics.length - 1) {
parts.push(', ');
}
}
parts.push('>');
return parts.join('');
}
@@ -33,6 +33,7 @@ import {getLinkToModule} from './url-transforms';
import {addApiLinksToHtml} from './code-transforms';
import {getCurrentSymbol, getModuleName, logUnknownSymbol} from '../symbol-context';
export const JS_DOC_REMARKS_TAG = 'remarks';
export const JS_DOC_USAGE_NOTES_TAG = 'usageNotes';
export const JS_DOC_SEE_TAG = 'see';
export const JS_DOC_DESCRIPTION_TAG = 'description';
@@ -96,7 +97,9 @@ export function addHtmlAdditionalLinks<T extends HasJsDocTags & HasModuleName>(
}
export function addHtmlUsageNotes<T extends HasJsDocTags>(entry: T): T & HasHtmlUsageNotes {
const usageNotesTag = entry.jsdocTags.find((tag) => tag.name === JS_DOC_USAGE_NOTES_TAG);
const usageNotesTag = entry.jsdocTags.find(
({name}) => name === JS_DOC_USAGE_NOTES_TAG || name === JS_DOC_REMARKS_TAG,
);
const htmlUsageNotes = usageNotesTag
? (marked.parse(
convertJsDocExampleToHtmlExample(wrapExampleHtmlElementsWithCode(usageNotesTag.comment)),
@@ -10,22 +10,22 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^16.1.1",
"@angular/common": "^16.1.1",
"@angular/compiler": "^16.1.1",
"@angular/core": "^16.1.1",
"@angular/forms": "^16.1.1",
"@angular/platform-browser": "^16.1.1",
"@angular/platform-browser-dynamic": "^16.1.1",
"@angular/router": "^16.1.1",
"@angular/animations": "^19.0.0",
"@angular/common": "^19.0.0",
"@angular/compiler": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/forms": "^19.0.0",
"@angular/platform-browser": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0",
"@angular/router": "^19.0.0",
"rxjs": "~7.4.0",
"tslib": "^2.3.0",
"zone.js": "~0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^16.1.0",
"@angular/cli": "^16.1.0",
"@angular/compiler-cli": "^16.1.1",
"@angular-devkit/build-angular": "^19.0.0",
"@angular/cli": "^19.0.0",
"@angular/compiler-cli": "^19.0.0",
"@types/jasmine": "~3.10.0",
"@types/node": "^12.11.1",
"jasmine-core": "~3.10.0",
@@ -34,6 +34,6 @@
"karma-coverage": "~2.0.3",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.0.3"
"typescript": "~5.6.3"
}
}
@@ -9,18 +9,18 @@
},
"private": true,
"dependencies": {
"@angular/common": "^17.0.0-rc.1",
"@angular/compiler": "^17.0.0-rc.1",
"@angular/core": "^17.0.0-rc.1",
"@angular/platform-browser": "^17.0.0-rc.1",
"@angular/common": "^19.0.0",
"@angular/compiler": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/platform-browser": "^19.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.0.0-rc.2",
"@angular/cli": "^17.0.0-rc.2",
"@angular/compiler-cli": "^17.0.0-rc.1",
"typescript": "~5.2.0"
"@angular-devkit/build-angular": "^19.0.0",
"@angular/cli": "^19.0.0",
"@angular/compiler-cli": "^19.0.0",
"typescript": "~5.6.3"
}
}
+1
View File
@@ -1,5 +1,6 @@
:root {
--z-index-mini-menu: 200;
--z-index-top-level-banner: 150;
--z-index-nav: 100;
--z-index-cookie-consent: 60;
--z-index-content: 50;
+6
View File
@@ -276,6 +276,12 @@
overflow-x: auto;
display: flex;
flex-direction: column;
align-items: start;
}
pre > * {
min-width: 100%;
width: auto;
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
// TODO: Continue organizing and refactoring this file
@use '@angular/material' as mat;
@use '@angular/cdk';
// Using disable-next-line to avoid stylelint errors - these imports are necessary
// TODO: Is there another way to prevent these linting errors?
@@ -61,7 +62,7 @@ $theme: mat.m2-define-light-theme(
);
// Include material core styles.
@include mat.core();
@include cdk.a11y-visually-hidden();
@include mat.tabs-theme($theme);
@include mat.button-toggle-theme($theme);
@include mat.tooltip-theme($theme);
@@ -16,6 +16,7 @@ import {
FileSystemTree,
IFSWatcher,
PortListener,
PreviewMessageListener,
ServerReadyListener,
Unsubscribe,
WebContainer,
@@ -98,6 +99,7 @@ export class FakeWebContainer extends WebContainer {
override on(event: 'port', listener: PortListener): Unsubscribe;
override on(event: 'server-ready', listener: ServerReadyListener): Unsubscribe;
override on(event: 'error', listener: ErrorListener): Unsubscribe;
override on(event: 'preview-message', listener: PreviewMessageListener): Unsubscribe;
override on(event: unknown, listener: unknown): Unsubscribe {
return () => {};
}
+1 -1
View File
@@ -1,6 +1,6 @@
@defer (when isBrowser) {
<adev-progress-bar />
<docs-top-level-banner expiry="2024-09-27" id="ng-survey-2024" link="https://goo.gle/angular-survey-2024" text="Take the 2024 Angular Developer Survey today!" />
<docs-top-level-banner expiry="2024-12-06" id="state-of-js-2024" link="https://survey.devographics.com/en-US/survey/state-of-js/2024?source=angular_homepage" text="Share your experience with Angular in The State of JavaScript 2024 survey" />
}
<button (click)="focusFirstHeading()" class="adev-skip">Skip to main content</button>
+5
View File
@@ -19,6 +19,11 @@
transform: translateY(0);
transition: transform 0.3s ease-out 0.6s;
}
// show it under the navbar.
@include mq.for-tablet-landscape-down{
z-index: calc(var(--z-index-nav) - 1);
}
}
// Case: If secondary navigation exists, display banner below secondary navigation for tablets.
@@ -26,7 +26,8 @@ describe('ProgressBarComponent', () => {
});
it('should call progressBar.complete() on route change', async () => {
const progressBarCompleteSpy = spyOn(component.progressBar, 'complete');
const progressBar = component.progressBar();
const progressBarCompleteSpy = spyOn(progressBar, 'complete');
const harness = await RouterTestingHarness.create();
await harness.navigateByUrl('/');
@@ -12,10 +12,11 @@ import {
inject,
OnInit,
PLATFORM_ID,
ViewChild,
Signal,
viewChild,
} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
import {NgProgressbar} from 'ngx-progressbar';
import {NgProgressbar, NgProgressRef} from 'ngx-progressbar';
import {
NavigationCancel,
NavigationEnd,
@@ -41,7 +42,7 @@ export const PROGRESS_BAR_DELAY = 30;
export class ProgressBarComponent implements OnInit {
private readonly router = inject(Router);
@ViewChild(NgProgressbar, {static: true}) progressBar!: NgProgressbar;
progressBar = viewChild.required(NgProgressRef);
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
@@ -62,7 +63,7 @@ export class ProgressBarComponent implements OnInit {
map(() => {
// Only apply set the property if the navigation is not "immediate"
return setTimeout(() => {
this.progressBar.start();
this.progressBar().start();
}, PROGRESS_BAR_DELAY);
}),
switchMap((timeoutId) => {
@@ -83,7 +84,7 @@ export class ProgressBarComponent implements OnInit {
.subscribe((timeoutId) => {
// When the navigation finishes, prevent the navigating class from being applied in the timeout.
clearTimeout(timeoutId);
this.progressBar.complete();
this.progressBar().complete();
});
}
}
@@ -12,7 +12,7 @@ import {ChangeDetectorRef, signal} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MatTabGroupHarness} from '@angular/material/tabs/testing';
import {By} from '@angular/platform-browser';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {provideNoopAnimations} from '@angular/platform-browser/animations';
import {BehaviorSubject} from 'rxjs';
import {EmbeddedTutorialManager} from '../embedded-tutorial-manager.service';
@@ -21,7 +21,6 @@ import {CodeEditor, REQUIRED_FILES} from './code-editor.component';
import {CodeMirrorEditor} from './code-mirror-editor.service';
import {FakeChangeDetectorRef} from '@angular/docs';
import {TutorialType} from '@angular/docs';
import {MatTooltip} from '@angular/material/tooltip';
import {MatTooltipHarness} from '@angular/material/tooltip/testing';
const files = [
@@ -53,8 +52,9 @@ describe('CodeEditor', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [CodeEditor, NoopAnimationsModule, MatTooltip],
imports: [CodeEditor],
providers: [
provideNoopAnimations(),
{
provide: CodeMirrorEditor,
useValue: codeMirrorEditorService,
@@ -21,7 +21,7 @@
<as-split class="docs-right-side" direction="vertical" restrictMove="true" gutterSize="5">
<!-- Preview Section: for larger screens -->
@if (!displayPreviewInMatTabGroup()) {
<as-split-area [size]="50" [order]="1">
<as-split-area [size]="50">
<!-- Preview Section: for larger screens -->
<div class="adev-preview-section">
<div class="adev-preview-header">
@@ -34,7 +34,7 @@
</as-split-area>
}
<as-split-area class="docs-editor-tabs-and-refresh" [size]="50" [order]="2">
<as-split-area class="docs-editor-tabs-and-refresh" [size]="50">
<!-- Container to hide preview, console and footer when only the interactive terminal is used -->
<mat-tab-group class="docs-editor-tabs" animationDuration="0ms" mat-stretch-tabs="false">
@if (displayPreviewInMatTabGroup()) {
@@ -1,7 +1,8 @@
@if (documentContent()) {
@let docContent = this.docContent();
@if (docContent) {
<docs-viewer
class="docs-viewer"
[docContent]="documentContent()!.contents"
[docContent]="docContent.contents"
[hasToc]="true"
/>
}
+2 -10
View File
@@ -7,10 +7,7 @@
*/
import {DocContent, DocViewer} from '@angular/docs';
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import {toSignal} from '@angular/core/rxjs-interop';
import {ActivatedRoute} from '@angular/router';
import {map} from 'rxjs/operators';
import {ChangeDetectionStrategy, Component, input} from '@angular/core';
@Component({
selector: 'docs-docs',
@@ -21,14 +18,9 @@ import {map} from 'rxjs/operators';
templateUrl: './docs.component.html',
})
export default class DocsComponent {
private readonly activatedRoute = inject(ActivatedRoute);
// Based on current route, proper static content for doc page is fetched.
// In case when exists example-viewer placeholders, then ExampleViewer
// components are going to be rendered.
private readonly documentContent$ = this.activatedRoute.data.pipe(
map((data) => data['docContent'] as DocContent),
);
documentContent = toSignal(this.documentContent$);
docContent = input<DocContent>();
}
@@ -2,9 +2,9 @@
<div class="adev-top">
<div class="adev-top-content">
<!-- Banner(s) can be edited here! -->
<a href="https://goo.gle/angular-v18" class="adev-banner" target="_blank">
<h1 tabindex="-1">Angular v18 is now available!</h1>
<p class="adev-banner-cta">Read about our newest release</p>
<a href="https://blog.angular.dev/meet-angular-v19-7b29dfd05b84" class="adev-banner" target="_blank">
<h1 tabindex="-1">Angular v19 is here!</h1>
<p class="adev-banner-cta">Read about our newest release.</p>
</a>
</div>
</div>
@@ -1,3 +1 @@
@if (apiItemType()) {
{{ apiItemType()! | adevApiLabel: labelMode() }}
}
{{ type() | adevApiLabel: mode() }}
@@ -21,11 +21,11 @@ describe('ApiItemLabel', () => {
});
fixture = TestBed.createComponent(ApiItemLabel);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should by default display short label for Class', () => {
component.type = ApiItemType.CLASS;
fixture.componentRef.setInput('type', ApiItemType.CLASS);
fixture.componentRef.setInput('mode', 'short');
fixture.detectChanges();
const label = fixture.nativeElement.innerText;
@@ -34,8 +34,8 @@ describe('ApiItemLabel', () => {
});
it('should display full label for Class when labelMode equals full', () => {
component.type = ApiItemType.CLASS;
component.mode = 'full';
fixture.componentRef.setInput('type', ApiItemType.CLASS);
fixture.componentRef.setInput('mode', 'full');
fixture.detectChanges();
const label = fixture.nativeElement.innerText;
@@ -44,8 +44,8 @@ describe('ApiItemLabel', () => {
});
it('should display short label for Class when labelMode equals short', () => {
component.type = ApiItemType.CLASS;
component.mode = 'short';
fixture.componentRef.setInput('type', ApiItemType.CLASS);
fixture.componentRef.setInput('mode', 'short');
fixture.detectChanges();
const label = fixture.nativeElement.innerText;
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {ChangeDetectionStrategy, Component, Input, signal} from '@angular/core';
import {ChangeDetectionStrategy, Component, input} from '@angular/core';
import {ApiItemType} from '../interfaces/api-item-type';
import {ApiLabel} from '../pipes/api-label.pipe';
@@ -16,19 +16,12 @@ import {ApiLabel} from '../pipes/api-label.pipe';
templateUrl: './api-item-label.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
'[attr.data-type]': 'apiItemType()',
'[attr.data-mode]': 'labelMode()',
'[attr.data-type]': 'type()',
'[attr.data-mode]': 'mode()',
},
imports: [ApiLabel],
})
export default class ApiItemLabel {
@Input({required: true}) set type(value: ApiItemType) {
this.apiItemType.set(value);
}
@Input({required: true}) set mode(value: 'short' | 'full') {
this.labelMode.set(value);
}
protected apiItemType = signal<ApiItemType | undefined>(undefined);
protected labelMode = signal<'short' | 'full'>('short');
readonly type = input.required<ApiItemType>();
readonly mode = input.required<'short' | 'full'>();
}
@@ -1,22 +1,19 @@
<header class="adev-api-items-section-header">
<h3 [attr.id]="group.id">
@if (group.isFeatured) {
<docs-icon aria-hidden>star</docs-icon>
}
<h3 [id]="group().id">
<!-- we use innerHtml because the title can be an html string-->
<a
routerLink="/api"
[fragment]="group.id"
[fragment]="group().id"
queryParamsHandling="preserve"
class="adev-api-anchor"
tabindex="-1"
[innerHtml]="group.title"
[innerHtml]="group().title"
></a>
</h3>
</header>
<ul class="adev-api-items-section-grid">
@for (apiItem of group.items; track apiItem.url) {
@for (apiItem of group().items; track apiItem.url) {
<li [class.adev-api-items-section-item-deprecated]="apiItem.isDeprecated">
<a
[routerLink]="'/' + apiItem.url"
@@ -34,15 +31,6 @@
@if (apiItem.isDeprecated) {
<span class="docs-deprecated"> &lt;!&gt; </span>
}
@if (apiItem.isFeatured) {
<docs-icon
class="adev-api-items-section-item-featured"
[class.adev-api-item-in-featured-section]="group.isFeatured"
[class.adev-api-items-section-item-featured-active]="apiItem.isFeatured"
>
star
</docs-icon>
}
</li>
}
</ul>
@@ -57,39 +57,16 @@
margin-block-start: 3px;
}
// star icon
.adev-api-items-section-item-featured {
opacity: 0;
border: none;
background-color: transparent;
color: var(--quinary-contrast);
cursor: pointer;
margin-top: -2px;
transition: color 0.3s ease;
&-active {
opacity: 1;
color: var(--quinary-contrast);
}
}
&:hover {
border-inline-start: 1px solid var(--quaternary-contrast);
background-color: var(--septenary-contrast);
a {
color: var(--primary-contrast);
}
.adev-api-items-section-item-featured-active {
color: var(--tertiary-contrast);
}
}
}
}
.adev-api-item-in-featured-section {
display: none;
}
.adev-api-items-section-item {
display: flex;
flex: 1;
@@ -106,9 +83,8 @@
margin-inline-start: 0.5rem;
}
.adev-api-anchor {
color: inherit;
@include anchor.docs-anchor();
}
}
@@ -12,7 +12,7 @@ import ApiItemsSection from './api-items-section.component';
import {ApiItemsGroup} from '../interfaces/api-items-group';
import {ApiReferenceManager} from '../api-reference-list/api-reference-manager.service';
import {ApiItemType} from '../interfaces/api-item-type';
import {RouterTestingModule} from '@angular/router/testing';
import {provideRouter} from '@angular/router';
import {By} from '@angular/platform-browser';
describe('ApiItemsSection', () => {
@@ -20,80 +20,47 @@ describe('ApiItemsSection', () => {
let fixture: ComponentFixture<ApiItemsSection>;
let apiReferenceManagerSpy: jasmine.SpyObj<ApiReferenceManager>;
const fakeFeaturedGroup: ApiItemsGroup = {
title: 'Featured',
id: 'featured',
isFeatured: true,
const fakeGroup: ApiItemsGroup = {
title: 'Group',
id: 'group',
items: [
{
title: 'Fake Featured Title',
itemType: ApiItemType.CLASS,
url: 'api/fakeFeaturedTitle',
isFeatured: true,
},
{
title: 'Fake Deprecated Title',
itemType: ApiItemType.CONST,
url: 'api/fakeDeprecatedTitle',
isFeatured: false,
isDeprecated: true,
},
{
title: 'Fake Standard Title',
itemType: ApiItemType.DIRECTIVE,
url: 'api/fakeTitle',
isFeatured: false,
},
],
};
const fakeGroup: ApiItemsGroup = {
title: 'Example group',
id: 'example',
isFeatured: false,
items: [
{title: 'Fake Title', itemType: ApiItemType.CONST, url: 'api/fakeTitle', isFeatured: false},
],
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ApiItemsSection, RouterTestingModule],
providers: [{provide: ApiReferenceManager, useValue: apiReferenceManagerSpy}],
imports: [ApiItemsSection],
providers: [
provideRouter([]),
{provide: ApiReferenceManager, useValue: apiReferenceManagerSpy},
],
});
fixture = TestBed.createComponent(ApiItemsSection);
component = fixture.componentInstance;
});
it('should render star icon for featured group', () => {
component.group = fakeFeaturedGroup;
fixture.detectChanges();
const starIcon = fixture.debugElement.query(By.css('.adev-api-items-section-header docs-icon'));
expect(starIcon).toBeTruthy();
});
it('should not render star icon for standard group', () => {
component.group = fakeGroup;
fixture.detectChanges();
const starIcon = fixture.debugElement.query(By.css('.adev-api-items-section-header docs-icon'));
expect(starIcon).toBeFalsy();
});
it('should render list of all APIs of provided group', () => {
component.group = fakeFeaturedGroup;
fixture.componentRef.setInput('group', fakeGroup);
fixture.detectChanges();
const apis = fixture.debugElement.queryAll(By.css('.adev-api-items-section-grid li'));
expect(apis.length).toBe(3);
expect(apis.length).toBe(2);
});
it('should display deprecated icon for deprecated API', () => {
component.group = fakeFeaturedGroup;
fixture.componentRef.setInput('group', fakeGroup);
fixture.detectChanges();
const deprecatedApiIcons = fixture.debugElement.queryAll(
@@ -101,22 +68,11 @@ describe('ApiItemsSection', () => {
);
const deprecatedApiTitle = deprecatedApiIcons[0].parent?.query(By.css('.adev-item-title'));
console.log('DEPRECATED API ICONS', deprecatedApiIcons);
console.log('DEPRECATED API TITLE', deprecatedApiTitle);
expect(deprecatedApiIcons.length).toBe(1);
expect(deprecatedApiIcons[0]).toBeTruthy();
expect(deprecatedApiTitle?.nativeElement.innerText).toBe('Fake Deprecated Title');
});
it('should display star icon for featured API', () => {
component.group = fakeFeaturedGroup;
fixture.detectChanges();
const featuredApiIcons = fixture.debugElement.queryAll(
By.css('.adev-api-items-section-grid li .adev-api-items-section-item-featured'),
);
const featuredApiTitle = featuredApiIcons[0].parent?.query(By.css('.adev-item-title'));
expect(featuredApiIcons.length).toBe(1);
expect(featuredApiIcons[0]).toBeTruthy();
expect(featuredApiTitle?.nativeElement.innerText).toBe('Fake Featured Title');
});
});
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
import {ChangeDetectionStrategy, Component, input} from '@angular/core';
import {RouterLink} from '@angular/router';
import {ApiItemsGroup} from '../interfaces/api-items-group';
import ApiItemLabel from '../api-item-label/api-item-label.component';
@@ -21,5 +21,5 @@ import {IconComponent} from '@angular/docs';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class ApiItemsSection {
@Input({required: true}) group!: ApiItemsGroup;
group = input.required<ApiItemsGroup>();
}
@@ -1,8 +1,8 @@
<div class="adev-header-and-tabs docs-scroll-track-transparent">
<docs-viewer [docContent]="headerInnerHtml()" class="docs-reference-header"></docs-viewer>
<docs-viewer [docContent]="parsedDocContent().header" class="docs-reference-header"></docs-viewer>
<mat-tab-group class="docs-reference-tabs" animationDuration="0ms" mat-stretch-tabs="false" [selectedIndex]="selectedTabIndex()">
@for (tab of tabs(); track tab) {
<mat-tab-group class="docs-reference-tabs" animationDuration="0ms" mat-stretch-tabs="false" [selectedIndex]="selectedTabIndex()" (selectedIndexChange)="tabChange($event)">
@for (tab of tabs(); track tab.url) {
<mat-tab [label]="tab.title">
<div class="adev-reference-tab-body">
<docs-viewer [docContent]="tab.content"></docs-viewer>
@@ -12,10 +12,10 @@
</mat-tab-group>
</div>
@if (canDisplayCards() && membersMarginTopInPx() > 0) {
@if (isApiTabActive() && membersMarginTopInPx() > 0) {
<docs-viewer
class="docs-reference-members-container"
[docContent]="membersInnerHtml()"
[docContent]="parsedDocContent().members"
[style.marginTop.px]="membersMarginTopInPx()"
(contentLoaded)="membersCardsLoaded()">
</docs-viewer>
@@ -272,7 +272,7 @@
header {
display: flex;
flex-direction: column;
border-radius: 0.25rem;
border-radius: 0.25rem 0.25rem 0 0;
background-color: var(--octonary-contrast);
position: relative;
z-index: 10;
@@ -10,11 +10,11 @@ import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {TestBed} from '@angular/core/testing';
import {MatTabGroupHarness} from '@angular/material/tabs/testing';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {provideNoopAnimations} from '@angular/platform-browser/animations';
import {ReferenceScrollHandler} from '../services/reference-scroll-handler.service';
import {signal} from '@angular/core';
import {provideRouter} from '@angular/router';
import {RouterTestingHarness, RouterTestingModule} from '@angular/router/testing';
import {provideRouter, withComponentInputBinding} from '@angular/router';
import {RouterTestingHarness} from '@angular/router/testing';
import ApiReferenceDetailsPage from './api-reference-details-page.component';
import {By} from '@angular/platform-browser';
@@ -40,20 +40,24 @@ describe('ApiReferenceDetailsPage', () => {
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [ApiReferenceDetailsPage, RouterTestingModule, NoopAnimationsModule],
imports: [ApiReferenceDetailsPage],
providers: [
provideRouter([
{
path: '**',
component: ApiReferenceDetailsPage,
data: {
'docContent': {
id: 'id',
contents: SAMPLE_CONTENT_WITH_TABS,
provideNoopAnimations(),
provideRouter(
[
{
path: '**',
component: ApiReferenceDetailsPage,
data: {
'docContent': {
id: 'id',
contents: SAMPLE_CONTENT_WITH_TABS,
},
},
},
},
]),
],
withComponentInputBinding(),
),
],
});
TestBed.overrideProvider(ReferenceScrollHandler, {useValue: fakeApiReferenceScrollHandler});
@@ -7,21 +7,15 @@
*/
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
DestroyRef,
Injector,
OnInit,
ViewChild,
afterNextRender,
inject,
signal,
input,
computed,
} from '@angular/core';
import {DOCUMENT} from '@angular/common';
import {MatTabGroup, MatTabsModule} from '@angular/material/tabs';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {distinctUntilChanged, map} from 'rxjs/operators';
import {MatTabsModule} from '@angular/material/tabs';
import {DocContent, DocViewer} from '@angular/docs';
import {ActivatedRoute, Router} from '@angular/router';
import {ApiItemType} from './../interfaces/api-item-type';
@@ -30,7 +24,6 @@ import {
API_REFERENCE_DETAILS_PAGE_HEADER_CLASS_NAME,
API_REFERENCE_DETAILS_PAGE_MEMBERS_CLASS_NAME,
API_REFERENCE_TAB_ATTRIBUTE,
API_REFERENCE_TAB_QUERY_PARAM,
API_REFERENCE_TAB_API_LABEL,
API_TAB_CLASS_NAME,
API_REFERENCE_TAB_BODY_CLASS_NAME,
@@ -47,116 +40,94 @@ import {AppScroller} from '../../../app-scroller';
providers: [ReferenceScrollHandler],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
@ViewChild(MatTabGroup, {static: true}) matTabGroup!: MatTabGroup;
export default class ApiReferenceDetailsPage {
private readonly activatedRoute = inject(ActivatedRoute);
private readonly destroyRef = inject(DestroyRef);
private readonly document = inject(DOCUMENT);
private readonly router = inject(Router);
private readonly scrollHandler = inject(ReferenceScrollHandler);
private readonly appScroller = inject(AppScroller);
private readonly injector = inject(Injector);
docContent = input<DocContent | undefined>();
tab = input<string | undefined>();
// aliases
ApiItemType = ApiItemType;
canDisplayCards = signal<boolean>(false);
tabs = signal<{url: string; title: string; content: string}[]>([]);
headerInnerHtml = signal<string | undefined>(undefined);
membersInnerHtml = signal<string | undefined>(undefined);
membersMarginTopInPx = this.scrollHandler.membersMarginTopInPx;
selectedTabIndex = signal(0);
// computed state
parsedDocContent = computed(() => {
// TODO: pull this logic outside of a computed where it can be tested etc.
const docContent = this.docContent();
if (docContent === undefined) {
return {
header: undefined,
members: undefined,
tabs: [],
};
}
const element = this.document.createElement('div');
element.innerHTML = docContent.contents;
// Get the innerHTML of the header element from received document.
const header = element.querySelector(API_REFERENCE_DETAILS_PAGE_HEADER_CLASS_NAME);
// Get the innerHTML of the card elements from received document.
const members = element.querySelector(API_REFERENCE_DETAILS_PAGE_MEMBERS_CLASS_NAME);
// Get the tab elements from received document.
// We're expecting that tab element will contain `tab` attribute.
const tabs = Array.from(element.querySelectorAll(`[${API_REFERENCE_TAB_ATTRIBUTE}]`)).map(
(tab) => ({
url: tab.getAttribute(API_REFERENCE_TAB_URL_ATTRIBUTE)!,
title: tab.getAttribute(API_REFERENCE_TAB_ATTRIBUTE)!,
content: tab.innerHTML,
}),
);
element.remove();
return {
header: header?.innerHTML,
members: members?.innerHTML,
tabs,
};
});
tabs = () => this.parsedDocContent().tabs;
selectedTabIndex = computed(() => {
const existingTabIdx = this.tabs().findIndex((tab) => tab.url === this.tab());
return Math.max(existingTabIdx, 0);
});
isApiTabActive = computed(() => {
const activeTabTitle = this.tabs()[this.selectedTabIndex()]?.title;
return activeTabTitle === API_REFERENCE_TAB_API_LABEL || activeTabTitle === 'CLI';
});
constructor() {
this.appScroller.disableScrolling = true;
}
ngOnInit(): void {
this.setPageContent();
afterNextRender({
write: () => {
this.scrollHandler.updateMembersMarginTop(API_REFERENCE_TAB_BODY_CLASS_NAME);
},
});
}
ngOnDestroy() {
this.appScroller.disableScrolling = false;
}
ngAfterViewInit(): void {
this.setActiveTab();
this.listenToTabChange();
}
membersCardsLoaded(): void {
this.scrollHandler.setupListeners(API_TAB_CLASS_NAME);
}
// Fetch the content for API Reference page based on the active route.
private setPageContent(): void {
this.activatedRoute.data
.pipe(
map((data) => data['docContent']),
takeUntilDestroyed(this.destroyRef),
)
.subscribe((doc: DocContent | undefined) => {
this.setContentForPageSections(doc);
afterNextRender(() => this.setActiveTab(), {injector: this.injector});
});
}
private listenToTabChange(): void {
this.matTabGroup.selectedIndexChange
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((index) => {
this.router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: {tab: this.tabs()[index].url},
queryParamsHandling: 'merge',
});
});
}
private setContentForPageSections(doc: DocContent | undefined): void {
const element = this.document.createElement('div');
element.innerHTML = doc?.contents!;
// Get the innerHTML of the header element from received document.
const header = element.querySelector(API_REFERENCE_DETAILS_PAGE_HEADER_CLASS_NAME);
if (header) {
this.headerInnerHtml.set(header.innerHTML);
}
// Get the innerHTML of the card elements from received document.
const members = element.querySelector(API_REFERENCE_DETAILS_PAGE_MEMBERS_CLASS_NAME);
if (members) {
this.membersInnerHtml.set(members.innerHTML);
}
// Get the tab elements from received document.
// We're expecting that tab element will contain `tab` attribute.
const tabs = Array.from(element.querySelectorAll(`[${API_REFERENCE_TAB_ATTRIBUTE}]`));
this.tabs.set(
tabs.map((tab) => ({
url: tab.getAttribute(API_REFERENCE_TAB_URL_ATTRIBUTE)!,
title: tab.getAttribute(API_REFERENCE_TAB_ATTRIBUTE)!,
content: tab.innerHTML,
})),
);
element.remove();
}
private setActiveTab(): void {
this.activatedRoute.queryParamMap
.pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
.subscribe((paramsMap) => {
const selectedTabUrl = paramsMap.get(API_REFERENCE_TAB_QUERY_PARAM);
const tabIndexToSelect = this.tabs().findIndex((tab) => tab.url === selectedTabUrl);
this.selectedTabIndex.set(tabIndexToSelect < 0 ? 0 : tabIndexToSelect);
this.scrollHandler.updateMembersMarginTop(API_REFERENCE_TAB_BODY_CLASS_NAME);
const isApiTabActive =
this.tabs()[this.selectedTabIndex()]?.title === API_REFERENCE_TAB_API_LABEL ||
this.tabs()[this.selectedTabIndex()]?.title === 'CLI';
this.canDisplayCards.set(isApiTabActive);
});
tabChange(tabIndex: number) {
this.router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: {tab: this.tabs()[tabIndex].url},
queryParamsHandling: 'merge',
});
}
}
@@ -1,43 +1,38 @@
<div class="adev-reference-list-page">
<header>
<h6>Getting Started</h6>
<h1>API Reference</h1>
</header>
@if (featuredGroup().items.length) {
<adev-api-items-section [group]="featuredGroup()" class="adev-featured-list" />
}
<form class="adev-reference-list-form">
<ul class="adev-reference-list-legend">
@for (itemType of itemTypes; track itemType) {
<li
class="adev-reference-list-legend-item"
[class.adev-reference-list-legend-item-active]="type() === itemType"
(click)="filterByItemType(itemType)"
>
<docs-api-item-label [type]="itemType" mode="short" class="docs-api-item-label" />
<span class="docs-api-item-label-full">{{ itemType | adevApiLabel : 'full' }}</span>
</li>
}
</ul>
<header>
<h1>API Reference</h1>
</header>
<div class="adev-reference-list-filter">
<div class="adev-reference-list-query-filter">
<docs-text-field name="query" placeholder="Filter" [(ngModel)]="query" />
<div class="adev-reference-list-form-part-two">
<docs-slide-toggle
buttonId="includeDeprecated"
label="Show @deprecated"
name="includeDeprecated"
[(ngModel)]="includeDeprecated"
/>
</div>
<docs-slide-toggle
buttonId="includeDeprecated"
label="Show @deprecated"
name="includeDeprecated"
[(ngModel)]="includeDeprecated"
/>
</div>
@for (group of filteredGroups(); track group.id) {
<adev-api-items-section [group]="group" />
} @empty {
<div class="adev-reference-list-empty">
<p>No API items found.</p>
</div>
<p class="adev-reference-list-type-filter-label">Filter by Identifier type</p>
<ul class="adev-reference-list-type-filter">
@for (itemType of itemTypes; track itemType) {
<li
class="adev-reference-list-type-filter-item"
[class.adev-reference-list-type-filter-item-active]="type() === itemType"
(click)="filterByItemType(itemType)"
>
<docs-api-item-label [type]="itemType" mode="short" class="docs-api-item-label" />
<span class="docs-api-item-label-full">{{ itemType | adevApiLabel : 'full' }}</span>
</li>
}
</form>
</ul>
</div>
@for (group of filteredGroups(); track group.id) {
<adev-api-items-section [group]="group" />
} @empty {
<div class="adev-reference-list-empty">
<p>No API items found.</p>
</div>
}
@@ -1,6 +1,7 @@
.adev-reference-list-page {
:host {
padding: var(--layout-padding);
max-width: var(--page-width);
display: block;
container: api-ref-page / inline-size;
@@ -20,91 +21,86 @@
color: var(--secondary-contrast);
}
}
}
.adev-reference-list-legend {
display: grid;
grid-template-columns: repeat(6, 1fr);
margin-block-start: 0;
padding-inline: 0;
cursor: pointer;
width: 100%;
.adev-reference-list-filter {
border-block-end: 1px solid var(--senary-contrast);
padding-block-end: 2rem;
margin-block-end: 1rem;
@container api-ref-page (max-width: 775px) {
grid-template-columns: repeat(5, 1fr);
}
@container api-ref-page (max-width: 600px) {
grid-template-columns: repeat(4, 1fr);
}
@container api-ref-page (max-width: 500px) {
grid-template-columns: repeat(3, 1fr);
}
@container api-ref-page (max-width: 350px) {
grid-template-columns: repeat(2, 1fr);
}
li {
display: flex;
gap: 0.5rem;
align-items: center;
padding: 0.3rem;
font-size: 0.875rem;
color: var(--quaternary-contrast);
font-weight: 500;
text-transform: capitalize;
border: 1px solid transparent;
border-radius: 0.25rem;
margin-inline-end: 0.5rem;
margin-block-end: 0.5rem;
transition:
color 0.3s ease,
background 0.3s ease,
border 0.3s ease;
&:hover {
color: var(--primary-contrast);
border: 1px solid var(--senary-contrast);
.adev-reference-list-type-filter-label {
margin-block: 2.5rem 1rem;
}
&.adev-reference-list-legend-item-active {
background: var(--septenary-contrast);
border: 1px solid var(--quinary-contrast);
color: var(--primary-contrast);
.adev-reference-list-type-filter {
display: grid;
grid-template-columns: repeat(6, 1fr);
margin-block: 0;
padding-inline: 0;
cursor: pointer;
width: 100%;
gap: 0.5rem;
@container api-ref-page (max-width: 775px) {
grid-template-columns: repeat(5, 1fr);
}
@container api-ref-page (max-width: 600px) {
grid-template-columns: repeat(4, 1fr);
}
@container api-ref-page (max-width: 500px) {
grid-template-columns: repeat(3, 1fr);
}
@container api-ref-page (max-width: 350px) {
grid-template-columns: repeat(2, 1fr);
}
li {
display: flex;
gap: 0.5rem;
align-items: center;
padding: 0.3rem;
font-size: 0.875rem;
color: var(--quaternary-contrast);
font-weight: 500;
text-transform: capitalize;
border: 1px solid transparent;
border-radius: 0.25rem;
transition:
color 0.3s ease,
background 0.3s ease,
border 0.3s ease;
&:hover {
color: var(--primary-contrast);
border: 1px solid var(--senary-contrast);
}
&.adev-reference-list-type-filter-item-active {
background: var(--septenary-contrast);
border: 1px solid var(--quinary-contrast);
color: var(--primary-contrast);
}
}
}
.adev-reference-list-query-filter {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
}
}
.adev-reference-list-form {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 1.5rem;
padding-block-start: 1.5rem;
padding-block-end: 2rem;
border-block: 1px solid var(--senary-contrast);
}
.adev-reference-list-empty {
text-align: center;
margin-block-start: 2rem;
.adev-reference-list-form-part-two {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
}
p {
font-size: 1rem;
}
}
.adev-reference-list-empty {
text-align: center;
p {
font-size: 1rem;
.docs-api-item-label-full {
white-space: nowrap;
}
}
.adev-featured-list {
display: block;
padding-block-end: 1rem;
margin-block: 1rem;
border-top: 0;
margin-top: -1.5rem;
}
.docs-api-item-label-full {
white-space: nowrap;
}

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