Compare commits

...

400 Commits

Author SHA1 Message Date
Pawel Kozlowski 07a0b87a4c release: cut the v18.1.0 release 2024-07-10 15:00:47 +02:00
Harish Krishnan 551ffbf9f2 docs: Update components-scenarios.md (#56921)
Fix grammatical issues

PR Close #56921
2024-07-10 11:29:17 +02:00
cexbrayat 4d87b9e899 fix(core): rename the equality function option in toSignal (#56769) (#56922)
The option introduced in 5df3e78c99 has been named `equals` whereas the existing option in `signal` is named `equal`.
This commit renames the new option to `equal` as well to keep the naming coherent across these APIs.

PR Close #56769

PR Close #56922
2024-07-10 11:09:07 +02:00
Matthieu Riegler 0da9eae24c docs: update version table for 18.1 (#56920)
PR Close #56920
2024-07-10 09:34:48 +02:00
Andrew Scott 15d2e8d54c docs: Update component testing scenarios (#56388)
This update goes through half of the component-scenarios guide and makes
relevant updates to examples.

Updates include:

* Use signals in examples
* Advise and use `await fixture.whenStable` more frequently than
  `detectChanges`
* Use and advise mocks and spies more sparingly
* Remove `waitForAsync` and jasmine `done` guidance - The ecosystem has evolved
  and these aren't needed
* Remove marble testing for rxjs - this belongs in rxjs documentation,
  not in Angular
* Remove class-only component testing. This approach is not advisable
  for components.

related to #48510

PR Close #56388
2024-07-10 09:11:21 +02:00
Marcos Paulo dos Santos 3a453d6040 docs: update compat table with 13.4.x (#56915)
PR Close #56915
2024-07-10 09:10:29 +02:00
Andrew Scott 8bd4c074af fix(core): toSignal equal option should be passed to inner computed (#56903)
The user-defined equality function needs to be passed to the inner
computed it will still use `Object.is` and prevent notifications.

PR Close #56903
2024-07-09 19:52:18 +02:00
Jessica Janiuk 5f97d6aec2 fix(migrations): Fix cf migration let condition semicolon order (#56913)
In rare cases people may put let statements before else statements and omit semicolons, causing migration issues.

PR Close #56913
2024-07-09 18:17:52 +02:00
Matthieu Riegler 2f8bf933f4 refactor(compiler-cli): escape missing decorators. (#56794)
Escaping decorators is required as else they are considered as new JSDocs tags.

fixes #56569

PR Close #56794
2024-07-09 13:13:53 +02:00
Ofer Segev ae9505b702 docs: update dependency-injection-context.md (#56736)
HeroService is not part of this example, and is only introduced in the next example. Use type Service1 for this.service1, as its type
PR Close #56736
2024-07-09 13:05:57 +02:00
Matthieu Riegler 0f4219cf0c refactor(platform-server): Add private profiler. (#56274)
The commit adds a private profiler to investigate SSR performance.

PR Close #56274
2024-07-09 12:47:46 +02:00
Kristiyan Kostadinov f689214178 docs: fix wrong link in template overview (#56911)
One of the links added in #56886 was incomplete.

PR Close #56911
2024-07-09 12:13:12 +02:00
Daniel Puckowski aef166f763 fix(compiler): fix CSS animation rule scope (#56800)
It is valid CSS to list keyframe names in an animation declaration only
separating the names with a comma and no whitespace. This is typical of
production builds. Updated a couple of regexes and added a couple of
tests to account for this scenario.

Fixes #53038

PR Close #56800
2024-07-09 09:44:56 +02:00
Kristiyan Kostadinov 02f5e73a8d docs: add documentation page for let declarations (#56886)
Adds a docs page for the new `@let` syntax in Angular 18.1.

PR Close #56886
2024-07-09 09:38:23 +02:00
Matthieu Riegler 20f5e1291e docs: add a FAQ on how to find the LCP image (#56779)
PR Close #56779
2024-07-09 09:37:20 +02:00
Andrew Kushnir 8adc6b9425 test(core): simplify @defer-based test to make CI more stable (#56904)
This commit updates one of the `@defer`-based test to use the `on immediate` trigger to make a test mor
e stable without the need to add mocks for the `on idle` (default) condition.

PR Close #56904
2024-07-09 09:36:12 +02:00
vladboisa 35fa9b0f77 docs(docs-infra): add missing context with link (#56896)
Added missing link documenting ng global features.

Fixes #56488

PR Close #56896
2024-07-08 18:04:00 +02:00
Paul Gschwendtner 56ec97d2e1 refactor(compiler-cli): do not truncate/reduce types in API docs (#56572)
Fixes that e.g. signal input APIs docs were removing `undefined` from
the shorthand `input<T>()` documentation.

PR Close #56572
2024-07-08 16:26:40 +02:00
Matthieu Riegler ba325c59c0 docs: remove private symbol from docs (#56851)
fixes #56850

PR Close #56851
2024-07-08 09:54:14 +02:00
Charles Lyding 447a36ef95 refactor(localize): reduce deep imports in ng add schematic (#56839)
The `@angular/schematic` package has a `utility` export path which can be
used to access common utility rules and helpers. The previous deep imports
into the `@angular/schematic` package have been switched to the actual
export path where possible. This lowers the potential for breakage from
internal package changes.

PR Close #56839
2024-07-08 09:51:53 +02:00
Sasidharan SD 8326e62313 docs: fix previous configuration link (#56880)
PR Close #56880
2024-07-08 09:48:02 +02:00
cexbrayat 9b35726e42 fix(common): typo in warning for NgOptimizedDirective (#56817)
The warning message for the `PLACEHOLDER_DIMENSION_LIMIT_EXCEEDED` check has a repetition of `of`.

PR Close #56817
2024-07-05 13:03:56 +02:00
Kristiyan Kostadinov cdebf751e4 fix(compiler-cli): used before declared diagnostic not firing for control flow blocks (#56843)
When we process `@if` and `@for` blocks, we create a scope around their expressions in order to encapsulate the aliases to them. The problem is that this doesn't represent the actual structure since the expression is part of the outer scope. This surfaces by not raising the "used before declared" diagnostic for `@let` declarations.

These changes resolve the issue by processing the expression as a part of the parent scope.

Fixes #56842.

PR Close #56843
2024-07-05 13:02:58 +02:00
Kristiyan Kostadinov 66e582551e fix(compiler-cli): avoid duplicate diagnostics for let declarations read before definition (#56843)
Fixes that in some cases `@let` declarations that are read before they're defined were producing multiple diagnostics.

PR Close #56843
2024-07-05 13:02:58 +02:00
Dan Nisenson 1efe907881 docs: fix broken link (#56848)
fix link @ /guide/forms/reactive-forms#reactive-forms-api-summary
prev: /api/forms
current: /api#forms

PR Close #56848
2024-07-05 12:27:35 +02:00
Corbin Crutchley 1074134d4b docs: add window title to reference pages (#56840)
PR Close #56840
2024-07-04 14:29:29 +02:00
Alan Agius ecc56447b9 perf(http): execute fetch outside of Angular zone (#56820)
In this update, the fetch backend now executes fetch operations outside of the Angular zone. This adjustment primarily aims to decrease Continuous Delivery (CD) cycles on Node.js. The decision was influenced by Undici, the Node.js fetch implementation, which relies on `setTimeouts` to manage response timeouts.

PR Close #56820
2024-07-04 12:10:35 +02:00
Michael van der Luit 85da4b3b2a docs: update app-shell docs to reflect v17 (#56836)
Fixes the build commands as previously mentioned here: https://github.com/angular/angular/pull/52294

PR Close #56836
2024-07-04 11:32:14 +02:00
Harish Krishnan 3fa21cbbc5 docs: Update image-optimization.md (#56819)
Fix the mistyped attribute rel
PR Close #56819
2024-07-04 09:56:18 +02:00
Matthieu Riegler 1ee64a5c45 refactor(common): Fire priority check on stable. (#56776)
To support routing on app init, the directive will now fire the priority check when the apps become stable.

fixes #56757

PR Close #56776
2024-07-03 14:40:48 +00:00
Andrew Kushnir 3235d6d6dd fix(core): establish proper defer injector hierarchy for components attached to ApplicationRef (#56763)
This commit updates the logic that create an injector for defer blocks (when it's needed) to account for a situation when a component is instantiated without a connection to the current component tree. This can happen if a component is created using its factory function or via `createComponent()` call.

Resolves #56372.

PR Close #56763
2024-07-03 14:08:44 +00:00
Krishna Sahu 6ad2fe6ab0 docs: add toSignal import inside the demo example (#56804)
PR Close #56804
2024-07-03 14:07:51 +00:00
komura-c 0e0fb7bb61 docs: fix missing image and baseUrl in tutorials/first-app (#56766)
PR Close #56766
2024-07-02 20:21:41 +00:00
Andrew Kushnir 8a0a00e212 docs: add Event Replay section to the Hydration guide (#56770)
PR Close #56770
2024-07-02 20:19:53 +00:00
Matthieu Riegler 092bfe95cc fix(core): support injection of object with null constructor. (#56553)
This is debug only code, it shouldn't have any consequences on prod build.

fixes #56552

PR Close #56553
2024-07-02 17:33:32 +00:00
Andrew Scott c4384bf269 fix(router): routes should not get stale providers (#56798)
This fixes a bug with RouterOutlet and its context where it would reuse
providers from a previously activated route.

fixes #56774

PR Close #56798
2024-07-02 17:10:52 +00:00
Angular Robot 52852abb56 build: update github/codeql-action action to v3.25.11 (#56803)
See associated pull request for more information.

PR Close #56803
2024-07-02 13:04:27 -04:00
Ben Hong 0f612dcaf8 docs: update playground app to use hello world for easier onboarding (#56813)
PR Close #56813
2024-07-02 12:57:31 -04:00
Ben Elliott 9acccb11ff docs: Update interceptors.md to replace public class with export class in DI section (#56807)
PR Close #56807
2024-07-02 16:44:12 +00:00
Ben Hong e914767efb docs: add documentation aroun build error for docs (#56814)
PR Close #56814
2024-07-02 16:43:07 +00:00
Angular Robot 58be8e6bf8 build: update all non-major dependencies (#56801)
See associated pull request for more information.

PR Close #56801
2024-07-02 15:26:28 +00:00
Pawel Kozlowski 9cc4dbeadd refactor(common): remove remaining code for NgSwitch equality patch (#56806)
This change is the final cleanup after removing NgSwitch's equality patch
that was used in G3 to allow == matching for a certain period of time. This
code is no longer needed as both the external ecosystem and G3 are using
=== equality for matching NgSwitch cases.

PR Close #56806
2024-07-02 14:16:24 +00:00
Jessica Janiuk 7f5d70a74a release: cut the v18.1.0-rc.0 release 2024-07-01 14:01:57 -07:00
Thomas Nguyen 3d1bc5a51e refactor(core): Add an ngOnDestroy to GlobalEventDelegation. (#56762)
It seems that this makes test libs that contain > 1 test file pass.

PR Close #56762
2024-07-01 20:33:17 +00:00
Enea Jahollari fd6cd0422d feat(compiler): Add extended diagnostic to warn when there are uncalled functions in event bindings (#56295)
The diagnostic will catch issues like:

```html
<button (click)="increment"></button>
<button (click)="increment; decrement"></button>
<button (click)="true ? increment : decrement"></button>
<button (click)="nested.nested1.nested2.increment"></button>
```

PR Close #56295
2024-07-01 20:31:19 +00:00
Andrew Kushnir a0fbd0e5e1 docs: update 18.1.0 release date (#56789)
PR Close #56789
2024-07-01 19:37:33 +00:00
Joey Perrott b4cc8d4a8e ci: upload build artifacts on each pr run (#56787)
Upload the snapshot build artifacts to each pr run to use for testing.

PR Close #56787
2024-07-01 18:48:57 +00:00
Matthieu Riegler f407e3ce6f refactor(common): allow string urls in NgOptimizedImage input (#54901)
With this commit it is now possible to pass an url as placeholder for the image directive.

PR Close #54901
2024-07-01 18:13:24 +00:00
Kristiyan Kostadinov 341a116d61 fix(compiler): allow more characters in let declaration name (#56764)
Fixes that `@let` didn't allow $ in its name, even though JS identifiers allow it.

PR Close #56764
2024-07-01 18:12:53 +00:00
Thomas Nguyen 551027e04e refactor(core): Set the jsaction cache directly instead of using jsaction attribute. (#56747)
This should make things somewhat faster, since setAttribute can be slower than addEventListener. Jsaction attribute is still needed for SSR though.

PR Close #56747
2024-07-01 17:31:24 +00:00
Alex Rickabaugh 46b0292261 refactor(core): export additional methods from primitives/signals (#56759)
Export `producerIncrementEpoch` which was missing before, as well as a new
`runPostSignalSetFn` helper. These changes make it easier to write `signal`-
like utilities which don't use the `createSignal` abstraction.

PR Close #56759
2024-07-01 14:39:44 +00:00
Kristiyan Kostadinov 2a1291e942 fix(compiler): give precedence to local let declarations over parent ones (#56752)
Currently the logic that maps a name to a variable looks at the variables in their definition order. This means that `@let` declarations from parent views will always come before local ones, because the local ones are declared inline whereas the parent ones are hoisted to the top of the function.

These changes resolve the issue by giving precedence to the local variables.

Fixes #56737.

PR Close #56752
2024-07-01 14:03:57 +00:00
Kristiyan Kostadinov 4d18c5bfd5 fix(compiler-cli): flag all conflicts between let declarations and local symbols (#56752)
Expands the check around conflicting `@let` declarations to also cover template variables and local references.

PR Close #56752
2024-07-01 14:03:57 +00:00
Kristiyan Kostadinov 5996502921 fix(compiler-cli): type check let declarations nested inside nodes (#56752)
Fixes that we were only capturing `@let` declarations at the top level of the scope, not any of the nested children.

PR Close #56752
2024-07-01 14:03:57 +00:00
Harish Krishnan aad3c2da6e docs: Update structural-directives.md (#56753)
PR Close #56753
2024-07-01 14:03:24 +00:00
Harish Krishnan 4017f72e8c docs: Update rxjs-interop.md (#56771)
Fix grammatical error
PR Close #56771
2024-07-01 14:02:46 +00:00
Kristiyan Kostadinov 5dc6deca85 build: update docs infra package (#56758)
Updates to the latest docs infra code to fix an issue with generating the `hiddenFiles` field.

PR Close #56758
2024-07-01 13:43:10 +00:00
Jessica Janiuk ecd5e6b754 ci: update pullapprove primitives list (#56761)
This removes one user from the shared primitives group to fix pullapprove requests.

PR Close #56761
2024-06-28 21:07:59 +00:00
cexbrayat f25653e231 fix(common): typo in NgOptimizedImage warning (#56756)
A space is missing in the warning message for `TOO_MANY_PRIORITY_ATTRIBUTES`.

PR Close #56756
2024-06-28 18:38:25 +00:00
Kristiyan Kostadinov ceaaa9815b build: update to latest docs tooling to resolve missing answers (#56746)
Updates to the latest version of `@angular/docs` which should include a fix for the missing answers in the tutorials.

PR Close #56746
2024-06-27 21:17:38 +00:00
Andrew Scott ed2665a74d docs: fix indentation on control flow documentation page (#56748)
This fixes the indentation on the examples in the control flow docs

fixes #56745

PR Close #56748
2024-06-27 19:55:48 +00:00
Tom Wilkinson 040d86137e refactor(core): Remove dom.ts and use native Element.prototype.contains. (#56591)
Delete the entire dom.ts file, it is no longer needed.

PR Close #56591
2024-06-27 18:28:19 +00:00
Tom Wilkinson 3773f406ac refactor(core): Remove ActionResolver code from EventContract (#56723)
Now that all `Dispatcher` implementations use `ActionResolver`, `EventContract` no longer needs to. Additionally, all a11y click support has been removed. `EventContract` will not specifically listen for `keydown` automatically, as all `EventContract` instances already have `keydown` listeners. This removes the need for the `A11Y_CLICK_SUPPORT` define, which will be removed in a future PR.

PR Close #56723
2024-06-27 18:27:44 +00:00
Tom Wilkinson 60a72af163 refactor(core): Remove attribute, char, and property values for ActionFlow. (#56590)
These values are inlined in ActionFlow internally in google3, and are no longer used.

Do some additional cleanup to only define the properties once.

PR Close #56590
2024-06-27 18:27:15 +00:00
Sasidharan SD 0cfd13c671 docs: fix cold observable and frames link (#56742)
PR Close #56742
2024-06-27 18:26:25 +00:00
Andrew Kushnir 917cd14bb4 ci: add more team members into the public-api group (#56743)
This commit adds more team members into the `public-api` group, so that they can approve public API changes, but they would not be requested for reviews by PullApprove (to avoid requests for unrelated changes).

PR Close #56743
2024-06-27 18:24:43 +00:00
Andrew Kushnir 344775344b Revert "fix(common): Don't run preconnect assertion on the server. (#56213)" (#56740)
This reverts commit 39e48ce675.

PR Close #56740
2024-06-27 17:44:42 +00:00
Paul Gschwendtner 2d8a96b684 refactor(compiler-cli): support running JIT transforms as part of tsickle emit (#56520)
When running the JIT transforms in 1P w/ tsickle, tsickle will
transform source files before our custom transforms can run. This is
also impacting the Ivy transform and hence we use `ts.getOriginalNode`
in various places to inspect the source AST for detecting Angular.

For the JIT transform we need to do a similar change so that the
transform could run in 1P.

PR Close #56520
2024-06-27 15:55:18 +00:00
Matthieu Riegler e618521a57 docs: replace @link with absolute link. (#56557)
Currently `@link` doesn't work for cross-package references.

Fixes #56556

PR Close #56557
2024-06-27 15:54:47 +00:00
Matthieu Riegler 39e48ce675 fix(common): Don't run preconnect assertion on the server. (#56213)
The `window` global is patched by domino on the server but the value of `window.location.href` isn't a valid base.

Before this change `getUrl()` would throw when running in devmode on the server.

Fixes #56207

PR Close #56213
2024-06-27 15:54:12 +00:00
Matthieu Riegler d23aa878a0 test(core): Add testing for defer error block (#56561)
In #56558 it was raised that we used an devMode function in a prod scope.
This commit adds a test when an defer error block is missing in devMode and prodMode

PR Close #56561
2024-06-27 15:53:19 +00:00
Angular Robot 34b5efcf0d build: update dependency selenium-webdriver4 to v4.22.0 (#56580)
See associated pull request for more information.

PR Close #56580
2024-06-27 15:52:47 +00:00
Pawel Kozlowski 08f56d980b refactor(common): remove ng_switch ability to use == equality check (#56426)
In Angular v17 we've alligned NgSwitch equality check with the build in control
flow to be ===. At the same time we've left the ability to use ==. This ability was
controlled by the NG_SWITCH_USE_STRICT_EQUALS const targetted by the G3 patch.

This commits removes the infrastructure to swap equality operator in preparation
for the G3 patch removal.

PR Close #56426
2024-06-27 15:07:57 +00:00
Thomas Nguyen 40fb81fd0e refactor(core): Add global event delegation provider (#56247)
This replaces all addEventListener calls with a stashing function,
and installs an event listener on the document body to retrieve
the stashed function;

PR Close #56247
2024-06-27 14:24:47 +00:00
Dylan Hunn 3bfba7ec15 docs: release notes for the v18.0.5 release 2024-06-26 17:15:22 -07:00
Dylan Hunn 5dc0de1494 release: cut the v18.1.0-next.4 release 2024-06-26 17:06:09 -07:00
Matthieu Riegler 033dfc39bc docs: Add mention of picture support in FAQ (#56692)
PR Close #56692
2024-06-26 16:58:27 -07:00
Matthieu Riegler cc4cb9608a refactor(common): Log a warning when the priority attribute of NgOptimizedImage is used too often. (#56669)
When the DOM content is loaded, Angular will log a warning message if the `priority` attribute is applied to often on `NgOptimizedImage` directive instances.

PR Close #56669
2024-06-26 12:43:00 -07:00
Matthieu Riegler ec654f72ae docs(docs-infra): fix asset path for learn angular #11 (#56587)
fixes #56568

PR Close #56587
2024-06-26 12:39:00 -07:00
Ofer Segev d3a488ad00 docs: Update signals overview.md (#56671)
change "computed" to a term using a backtick
PR Close #56671
2024-06-26 12:38:25 -07:00
Kristiyan Kostadinov 0a48d584f2 feat(core): add support for let syntax (#56715)
Enables the new `@let` syntax by default.

`@let` declarations are defined as:
1. The `@let` keyword.
2. Followed by one or more whitespaces.
3. Followed by a valid JavaScript name and zero or more whitespaces.
4. Followed by the `=` symbol and zero or more whitespaces.
5. Followed by an Angular expression which can be multi-line.
6. Terminated by the `;` symbol.

Example usage:
```
@let user = user$ | async;
@let greeting = user ? 'Hello, ' + user.name : 'Loading';
<h1>{{greeting}}</h1>
```

Fixes #15280.

PR Close #56715
2024-06-26 12:37:02 -07:00
Matthieu Riegler c19a4e7a96 docs: Move the background image migration to its own section. (#56588)
PR Close #56588
2024-06-26 08:52:17 -07:00
Tom Wilkinson 1d28fbb84c refactor(core): Use ActionResolver in Dispatcher. (#56369) (#56369)
`EventContract` usages in Angular now use `false` for
`useActionResolver`. Tests have been updated, with functionality that
depends on `ActionResolver` moving to dispatcher_test.ts.

PR Close #56369

PR Close #56369
2024-06-26 08:49:30 -07:00
Kristiyan Kostadinov 7dfe302f47 refactor(core): support let declarations during hydration (#56527)
Updates the hydration logic to account for the fact that let declarations don't create a DOM node.

PR Close #56527
2024-06-26 08:48:31 -07:00
Kristiyan Kostadinov bbe39c1738 refactor(core): integrate let instructions into the runtime (#56527)
Adds the implementation of the following new instructions:
* `declareLet` - creation-time instruction that initializes the slot for a let declaration.
* `storeLet` - update-time instruction that stores the current value of a let declaration.
* `readContextLet` - instruction that reads the stored value of a let declaration from a different view.

On top of the instructions, it also introduces a new `LetDeclaration` TNode type.
The new TNode is nececessary for DI to work correctly in pipes inside the let expression,
as well as for proper hydration support.

PR Close #56527
2024-06-26 08:48:31 -07:00
Andrew Scott 2431f206d7 refactor(forms): Update status, touched, and pristine to use private setter (#56573)
This refactor updates the touched, status, and pristine properties to
have a private setter.

PR Close #56573
2024-06-26 08:47:39 -07:00
Kristiyan Kostadinov ccc8c80cd0 build: update to TypeScript 5.5 stable (#56358)
Updates the repo to the stable release of TypeScript 5.5.

PR Close #56358
2024-06-25 09:29:16 -07:00
Shannon V.C 362e3c74a0 docs: add neovim setup section to adev (#56057)
PR Close #56057
2024-06-25 09:28:47 -07:00
Matthieu Riegler cc21989132 fix(http): Make Content-Type header case insensitive (#56541)
Prior to this change, is the `Content-Type` passed to the `FetchBackend` was lowercase it was overwritten with the default one.

fixes #56539

PR Close #56541
2024-06-25 09:28:18 -07:00
MikaelSvanasbakken f7d56790f5 docs: fix broken redirection to contributing.md (#56581)
PR Close #56581
2024-06-25 09:27:56 -07:00
Matthieu Riegler 5be16d06bd fix(core): prevent calling devMode only function on @defer error. (#56559)
`getTemplateLocationDetails()` is a devMode only function and should guarded by `ngDevMode` or calling it will throw an error.

fixes #56558

PR Close #56559
2024-06-25 09:17:33 -07:00
Sasidharan SD 85dc9123a1 docs: fix broken component fixture link (#56563)
PR Close #56563
2024-06-25 09:15:02 -07:00
Matthieu Riegler e81abdbd49 docs(docs-infra): add canonical link to each adev page (#56540)
PR Close #56540
2024-06-24 09:44:29 -07:00
Sasidharan SD 49b2e65bfb docs: fix file structure link (#56542)
PR Close #56542
2024-06-21 10:04:45 -07:00
Matthieu Riegler a9bbfdd103 build: add ignores for aio (#56538)
The files are needed/generated to run aio on the 17.3.

PR Close #56538
2024-06-21 10:03:34 -07:00
Gerald Monaco 29ca6d10cc fix(core): improve support for i18n hydration of projected content (#56192)
When collecting nodes from the DOM for hydration, we need to treat nodes with paths (e.g. content projection) as the new root for all subsequent elements, not just the next one.

Additionally, when using content projection it's possible for translated content to become disconnected, e.g. when it doesn't match a selector and there isn't a default. We need to handle such cases by manipulating the disconnected node data associated with hydration as usual.

PR Close #56192
2024-06-20 14:59:57 -07:00
Luis Fernando Scapin 3ea7794474 docs: ordered words (#56534)
Ordered correctly some words

PR Close #56534
2024-06-20 14:58:12 -07:00
Andrew Kushnir 29ecb39895 release: cut the v18.1.0-next.3 release 2024-06-20 12:07:20 -07:00
Andrew Kushnir 34c3bd3c83 docs: release notes for the v18.0.4 release 2024-06-20 12:02:32 -07:00
Andrew Scott 0d52c6b182 fix(router): Delay the view transition to ensure renders in microtasks complete (#56494)
This commit delays makes two changes:

* Use the `read` phase for `afterNextRender` hook. We really want to
   wait for any write hooks to complete before starting the animation
* In addition, wait a macrotask before resolve (really, this makes the
   above change unnecessary but it's still conceptually the right
   thing). This ensures any follow-up rendering in the microtask queue
   is flushed before the animation starts.

Important note: This only affects the timing of the animation start,
delaying it longer to allow additional rendering/change detections to
flush. This promise already resolves in an `afterNextRender` hook and is
only used directly by the browser's view transition machinery.

PR Close #56494
2024-06-20 08:56:49 -07:00
Sasidharan SD 955ade66e1 docs: fix page not found (#56512)
PR Close #56512
2024-06-20 08:56:09 -07:00
Matthieu Riegler 55835e9bc9 docs: fix code example for http headers (#56508)
PR Close #56508
2024-06-20 08:55:31 -07:00
Matthieu Riegler dd506c1802 docs: add mention of preconnect links (#56503)
Text is copied from AIO.

fixes #56502

PR Close #56503
2024-06-20 08:54:50 -07:00
Charles Lyding c12f318f72 build: remove unused root dependencies (#56499)
With the removal of AIO, several dependencies are now unused and can be removed.

PR Close #56499
2024-06-20 08:54:11 -07:00
Andrew Kushnir e20c6df65e refactor(core): use performance API for Event Replay (#56509)
This commit adds a standard performance marker that can be viewed in Chrome dev tools and other tooling.
See more info at https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark

PR Close #56509
2024-06-20 08:53:18 -07:00
Andrew Kushnir bf6df6f186 fix(core): do not activate event replay when no events are registered (#56509)
This commit adds extra checks to handle a situation when an application has no events configured, but the Event Replay feature was enabled. This situation can happen when some routes in an application are mostly static, when other routes are more interactive.

Resolves #56423.

PR Close #56509
2024-06-20 08:53:18 -07:00
cexbrayat 86bcfd3e49 fix(core): improve docs on afterRender hooks (#56522)
This commit fixes a typo in the `AfterRenderPhase` deprecation warning and improves the documentation of the options parameter of the afterRender hooks (which are now all named `options` instead of being called `opts` in some functions and `options` in others).

PR Close #56522
2024-06-20 08:51:35 -07:00
cexbrayat 03a2acd2a3 fix(core): properly remove imports in the afterRender phase migration (#56524)
Before this commit, the migration was removing the `AfterRenderPhase` enum from the imports but not the comma, resulting in invalid code:

ts
```
import { , Directive, afterRender } from '@angular/core';
```

This commit fixes this by using `updateNamedImports` and `replaceNode` instead of `removeNode`.

After:

ts
```
import { Directive, afterRender } from '@angular/core';
```

PR Close #56524
2024-06-20 08:50:28 -07:00
arturovt 39df5fa9d2 refactor(core): missing space in zoneless warning (#56491)
There's currently a missing space in the zoneless warning, showing words together.

PR Close #56491
2024-06-20 08:49:39 -07:00
Kristiyan Kostadinov 64990a50ed refactor(compiler): integrate let declarations into the template pipeline (#56299)
These changes integrate let declarations into the template pipeline. This involves a few operations:
* Producing a `declareLet` instruction call at creation time to initialize the declaration.
* Producing a `storeLet` instruction call in the place of the let declaration, including the necessary `advance` calls beforehand.
* For let declarations used within their declaration view, moving the `const` to be placed right after the `storeLet` call to ensure the their value has been computed.
* For let declarations that are _only_ used in their declaration view, removing the `storeLet` call and inlining the expression into the constant statement.

PR Close #56299
2024-06-20 08:48:52 -07:00
Joey Perrott 0bd55a684f refactor(docs-infra): complete removal of aio directory (#56496)
Finish removal of aio directory as it is no longer used or relied upon.

PR Close #56496
2024-06-18 12:26:00 -07:00
Joey Perrott bb72c26b52 refactor(docs-infra): remove reliance on aio example macro (#56496)
Remove usage of aio example macro in adev

PR Close #56496
2024-06-18 12:25:59 -07:00
Joey Perrott 7208d05a38 refactor(docs-infra): move windows-chromium-path to adev (#56496)
Move windows-chromium-path help from aio to adev

PR Close #56496
2024-06-18 12:25:59 -07:00
Andrew Scott 00bde8b1c2 fix(forms): Make NgControlStatus host bindings OnPush compatible (#55720)
This commit makes the host bindings of `NgControlStatus[Group]`
compatible with `OnPush` components. Note that this intentionally _does not_
expose any new APIs in the forms module. The goal is only to remove
unpreventable `ExpressionChangedAfterItHasBeenCheckedError` in the forms
code that developers do not have control over.

PR Close #55720
2024-06-18 11:35:34 -07:00
Matthieu Riegler 775f451682 docs: add ng generate directive page (#56417)
fixes #56296

PR Close #56417
2024-06-18 09:31:26 -07:00
Angular Robot b592fb59c1 build: update scorecard action dependencies (#56485)
See associated pull request for more information.

PR Close #56485
2024-06-18 09:30:45 -07:00
Angular Robot 4b8d90806a build: update actions/checkout action to v4.1.7 (#56484)
See associated pull request for more information.

PR Close #56484
2024-06-18 09:28:57 -07:00
Angular Robot 18d64c5b64 build: update io_bazel_rules_sass digest to b222c61 (#56483)
See associated pull request for more information.

PR Close #56483
2024-06-18 09:28:19 -07:00
Andrew Scott f8654bd3f6 fix(docs-infra): reference page restores scroll position or goes top when no anchor (#56478)
This contains follow-up fixes to 2a2439712a.
This commit updates scrolling on references page to scroll to the top
when there is no anchor in the URL. The behavior after the above commit would
be that the position doesn't change from whatever the previous page was
(potentially scrolled to the bottom). In addition, this restores the
previous scroll position when traversing through browser history rather
than always scrolling to the fragment.

PR Close #56478
2024-06-18 09:26:56 -07:00
ivanwonder 67b2c336bc fix(language-service): import the default exported component correctly (#56432)
When importing a component exported by default, the `default` can't be
used as the component name.

For example:

This is the export declarations:

```ts
export default class TestComponent {}
```

Previously, the output generated by LS looked like this:

```ts
import { default } from "./test.component";
```

Now the output looks like this:

```ts
import TestComponent from "./test.component";
```

Fixes #48689

PR Close #56432
2024-06-17 12:48:48 -07:00
Viktor T d203c499a3 docs(docs-infra): Remove redundant API link (#56480)
As there is no longer a page for the localize API the URL pointing to this page is removed

PR Close #56480
2024-06-17 12:48:12 -07:00
Andrew Kushnir 89ec195fd2 refactor(core): handle incomplete DOCUMENT instances during cleanup in tests (#56422)
`DOCUMENT` instances retrieved from DI may not contain a necessary function to complete the cleanup. In tests that don't interact with DOM, the `DOCUMENT` might be mocked and some functions might be missing. For such tests, DOM cleanup is not required and we can skip DOM cleanup logic if there are missing functions. For tests that use DOM, TestBed would behave the same as before and rely on more complete `DOCUMENT` instances.

PR Close #56422
2024-06-17 09:05:52 -07:00
Andrew Kushnir 088e6c73bf refactor(core): avoid exposing OutletInjector in injector resolution path (#56394)
Router's `OutletInjector` required a special handling in cases when `@defer` is used, see https://github.com/angular/angular/pull/55374 for additional info. As a result, the `ChainedInjector` that represents an `OutletInjector` instance is currently exposed via `getInjectorResolutionPath` function. This creates a problem, because other debug APIs used by DevTools can not interact with `ChainedInjector`s. This commit updates the logic around `getInjectorResolutionPath` utility to avoid exposing `OutletInjector`in the resolution path.

Resolves #56331.

PR Close #56394
2024-06-17 09:05:11 -07:00
Andrew Scott f346448871 docs(router): Remove deprecation on Router guard interfaces (#56408)
Many developers find these interfaces useful for various reasons. Beyond
that, the deprecation of the interfaces has incorrectly implied that
existing class-based guard implementations need to be migrated to
functions. Class injectables are _not_ deprecated and choosing to
implement a guard's state and logic as a class that is injectable in the
functions run inside the injection context is valid.

resolves #50234

PR Close #56408
2024-06-17 09:03:01 -07:00
Paul Gschwendtner 4bc99f0bdf refactor(core): ModelSignal should extend InputSignal (#56452)
This allows for helpers like the following to work intuitively for all
types of "input fields". It also establishes the intended mental
philosophy that a model is both an input and an output.

```ts
/** Unwraps all signal input properties. */
export type UnwrapSignalInputs<T> = {
  [K in keyof T]: T[K] extends InputSignalWithTransform<any, infer WriteT>
    ? WriteT
    : T[K];
};
```

PR Close #56452
2024-06-17 08:59:58 -07:00
Alex Rickabaugh 5df3e78c99 feat(core): add equality function to rxjs-interop toSignal (#56447)
`toSignal` predates the decision to allow a more flexible equality check in
signals, and thus doesn't support a custom equality function. This commit
adds the ability to pass a custom value equality function. As a side effect,
it now adds the default equality check where it wasn't used before.

Fixes #55573

PR Close #56447
2024-06-17 08:59:21 -07:00
Daniel Kimmich 08038e8573 docs: update security guide link to adev (#56469)
PR Close #56469
2024-06-17 08:54:08 -07:00
Arek 278c4a1fcb docs: fix outdated links from docs to contributing-docs folder in markdown documents (#56462)
PR Close #56462
2024-06-17 08:53:17 -07:00
Sasidharan SD 5a45d2b6b1 docs: fix location strategy link (#56475)
PR Close #56475
2024-06-17 08:48:23 -07:00
Andrew Scott 2a2439712a fix(docs-infra): Various scroll fixes for a.dev (#56464)
* Create custom scroller to manage scroll behavior more directly. There
  are two many special and weird behaviors in the site to use the
  built-in scrolling.
* Update scrolling to wait for application stability. This waits a bit
  longer than the current `Scroll` event, which happens in
  `afterNextRender` after the `NavigationEnd`. fixes #56446
* Disable scrolling on the API references page. It just never worked
  well with all the custom scroll locations
* Update card clicks on API references page to change the fragment of
  the URL (this allows docs viewers to link directly to an item). Also update
  API reference page to listen to fragment changes and use that as the
  scroll trigger rather than the click. This takes care of the initial
  scroll when the page loads as well.

fixes #56446

PR Close #56464
2024-06-17 08:46:49 -07:00
Angular Robot 4cd5fb592b build: update actions/checkout digest to 692973e (#56438)
See associated pull request for more information.

PR Close #56438
2024-06-17 08:46:06 -07:00
Joey Perrott ee8ecfaef0 ci: begin checking licenses of upstream dependencies to ensure they are approved (#56460)
Begin checking upstream dependency licenses.

PR Close #56460
2024-06-14 13:49:23 -07:00
Charles Lyding e0ee049bc3 ci: use bazel downloaded saucelabs connect binary (#56456)
The saucelabs connect tunnel utility is now downloaded via bazel as needed.
For the directly invoked case the utility is downloaded via the local shell script.
Previously it was part of the root `package.json` and downloaded whenever
a package install was executed. The utility archive was also not an actual
package which incidentally worked with npm but does not work with newer versions
of yarn.

PR Close #56456
2024-06-14 13:48:37 -07:00
Aristeidis Bampakos d64ee6cc9d docs: fix broken link in ng-container API reference (#56445)
Closes #56444
PR Close #56445
2024-06-14 10:05:42 -07:00
Matthieu Riegler ce8853e5af docs(core): remove the doc link for NG0952 (#56441)
We don't have any docs yet for that error, so I'm removing the minus sign which indicate that there is a dedicated error doc.

Fixes #56424

PR Close #56441
2024-06-14 10:05:00 -07:00
Andrew Scott 1d3a7529b4 feat(router): Set a different browser URL from the one for route matching (#53318)
This feature adds a property to the `NavigationBehaviorOptions` that
allows developers to define a different path for the browser's address
bar than the one used to match routes. This is useful for redirects
where you want to keep the browser bar the same as the original
attempted navigation but redirect to a different page, such as a 404 or
error page.

fixes #17004

PR Close #53318
2024-06-13 13:59:45 -07:00
Andrew Kushnir fca5764564 Revert "refactor(core): Use ActionResolver in Dispatcher. (#56369)" (#56440)
This reverts commit 4ebd2853fa.

PR Close #56440
2024-06-13 12:17:35 -07:00
JoostK 0b867e83b6 fix(compiler-cli): insert constant statements after the first group of imports (#56431)
The linker inserts the constant statements that are needed to support compiled templates
after the import statements of an ESM file, but it failed to account for import statements
that are not at the top of the file. This is typically seen in FESM files where multiple
individual ESMs have been concatenated into a single ESM file, with imports in various places.
The linker would then find the very last import statement to insert the constant statements
after, but this may result in TDZ errors for component templates that have been emitted
earlier in the file.

This commit updates the Babel linker plugin to insert constant statements after the last
import of the first import group, therefore avoiding the TDZ error.

Fixes #56403

PR Close #56431
2024-06-13 10:15:00 -07:00
Paul Gschwendtner 126d33a34d refactor(compiler-cli): allow generating same import specifier in different files (#56406)
The import manager ensures generation of unique identifiers when
inserting imports. This is done by inspecting existing identifiers
within the original source file, while also checking if a similar
identifier was generated at an earlier time. This is correct behavior.

We can improve the detection so that the same identifier can be
generated in different files. This is beneficial for schematic/migration
use-cases where we wouldn't want to generate import aliases in multiple
files just because we generated an import to e.g. `input` previously.

E.g. it's fine to generate

```ts
// a.ts
import {input} from '@angular/core';

// b.ts
import {input} from `@angular/core';

// instead of `input as input_1`.

```

PR Close #56406
2024-06-13 10:14:09 -07:00
Paul Gschwendtner 5162a32de8 refactor(compiler): expose shorthand object metadata in expression AST (#56405)
Whenever we parse object property assignment shorthands in expression
ASTs, the AST will have no information about whether the property read
for the `LiteralMap` is built based on the shorthand or not.

Exposing this information in the AST is useful for migrations as those
might need to decompose the shorthand into its longer form to e.g.
invoke a signal read.

PR Close #56405
2024-06-13 10:12:52 -07:00
Paul Gschwendtner 352e0782ec feat(core): expose signal input metadata in ComponentMirror (#56402)
This commit starts exposing `isSignal` for inputs in the
`ComponentMirror`. We initially had this as a draft when rolling out
signal inputs, but there were no good use-cases, so we skipped it.

Now, inside G3, for the testing infrastructure and rolling out
advancements for signal inputs, having this information is necessary and
allows identifying signal inputs without "accessing fields" on the class
that may cause side-effects (like triggering setters).

PR Close #56402
2024-06-13 10:12:06 -07:00
Viktor T c698668a52 docs: language-service - Fix quick info URLs (#56416)
- Made the links more specific
- Removed the AIO notation

PR Close #56416
2024-06-13 09:23:44 -07:00
Jens Kuehlers d5ecd2c4cc docs: add v18.x and v19. release dates (#56429)
Add planned approximate v18 minor and v19 major
release dates.

PR Close #56429
2024-06-13 09:22:15 -07:00
Pawel Kozlowski ef2ad1b2ef refactor: add select scenario to the js-web-frameworks benchmark (#56362)
Add the row selection scenario to the existing benchmark so we can
automate perf measurements during experiments.

PR Close #56362
2024-06-13 08:59:18 -07:00
Pawel Kozlowski 485c3d929d refactor: run js-web-frameworks with noop zone (#56362)
Align setup of this benchmark with
https://github.com/krausest/js-framework-benchmark/tree/master/frameworks/keyed/angular-cf-nozone
by running without zone.js using noop zone.

PR Close #56362
2024-06-13 08:59:17 -07:00
Jessica Janiuk b2c44c76dc ci: bump github action commit message labels hash (#56435)
This updates to the latest git hash for the github action for commit messages.

PR Close #56435
2024-06-13 08:55:28 -07:00
Tom Wilkinson 4ebd2853fa refactor(core): Use ActionResolver in Dispatcher. (#56369)
`EventContract` usages in Angular now use `false` for
`useActionResolver`. Tests have been updated, with functionality that
depends on `ActionResolver` moving to dispatcher_test.ts.

PR Close #56369
2024-06-13 08:50:45 -07:00
Alex Rickabaugh a114ebad7e release: cut the v18.1.0-next.2 release 2024-06-12 16:26:51 -07:00
Alex Rickabaugh 38b84007b6 docs: release notes for the v18.0.3 release 2024-06-12 16:20:47 -07:00
Sasidharan SD f4b86bd9d5 docs: fix configure routes link (#56415)
PR Close #56415
2024-06-12 13:36:27 -07:00
Angular Robot 9e670ceea3 build: update io_bazel_rules_sass digest to 221f949 (#56393)
See associated pull request for more information.

PR Close #56393
2024-06-12 13:35:32 -07:00
Angular Robot 5cc9e8075a build: update babel dependencies to v7.24.7 (#56373)
See associated pull request for more information.

PR Close #56373
2024-06-12 13:11:12 -07:00
Andrew Kushnir 71c9609298 refactor(core): inject PendingTasks as optional in EventEmitter class (#56411)
This commit makes `PendingTasks` dependency in the `EventEmitter` class optional to make sure this code works with various test setups.

PR Close #56411
2024-06-12 13:10:40 -07:00
arturovt b8d5882127 fix(zone.js): allow enabling default beforeunload handling (#55875)
Prior to this commit, when zone.js was included, it wasn't possible to handle `beforeunload`
events correctly if event handlers returned strings to prompt the user.

With this change, we introduce a global configuration flag,
`__zone_symbol__enable_beforeunload`, to allow consumers to enable the default
`beforeunload` handling behavior.

This flag is necessary to prevent any breaking changes resulting from this modification.
The previous attempt to fix it caused a large number of failures in G3. Hence, we're
hiding that fix behind the configuration flag.

Closes #47579

PR Close #55875
2024-06-12 13:06:21 -07:00
ivanwonder b400e2e4d4 feat(language-service): autocompletion for the component not imported (#55595)
This PR allows the language service to suggest imports for all directives returned from the
compiler, and generate the TypeScript module import and the decorator import when the component
is selected by the user.

PR Close #55595
2024-06-12 13:04:32 -07:00
Alex Rickabaugh 70157aa3d0 docs(service-worker): fix formatting of directory structure example (#56412)
This example was using the `<code-example>` tag from AIO instead of the
`<docs-code>` tag from ADEV.

Fixes #56398

PR Close #56412
2024-06-12 12:01:22 -07:00
Joey Perrott 96d3ed8493 ci: use depth 100 to allow for some history in artifact repos (#56414)
Use depth 100 to allow for some history in the artifact repos, without the entire history being necessary
which caused us to run out of space on the CI runner.

PR Close #56414
2024-06-12 11:45:26 -07:00
Matthieu Riegler 160171e26a docs(docs-infra): generate valid HTML for the update guide. (#56390)
Nested block elements in a `p` element are not valid.
The p block automatically closes if another block-level element is parsed before the closing.

PR Close #56390
2024-06-11 17:17:03 -07:00
Joey Perrott 03957b1c06 fix(docs-infra): use anchors instead of button for version picker links (#56368)
Use anchors as links instead of buttons

PR Close #56368
2024-06-11 17:16:20 -07:00
Andrew Kushnir b3780b8e5f ci: update payload size for a couple integration apps (#56391)
This commit updates the payload size for a couple integration apps. Those apps were likely close to a threshold already and the most recent commit added a few extra bytes to go over the limit.

PR Close #56391
2024-06-11 16:50:19 -07:00
Andrew Scott d5c6ee432f fix(core): async EventEmitter should contribute to app stability (#56308)
async `EventEmitter` should contribute to app stability.

fixes #56290

PR Close #56308
2024-06-11 15:10:21 -07:00
Angular Robot 79299575af build: update github/codeql-action action to v3.25.8 (#56374)
See associated pull request for more information.

PR Close #56374
2024-06-11 12:39:32 -07:00
Paul Gschwendtner f0d63f17e2 build: update cross-repo angular dependencies (#56364)
This commit also performs lock file maintenance on all integration
tests, fixing some ambigous ESM/CJS dependency graph issues.

e.g.

```
Unknown error: Error [ERR_REQUIRE_ESM]: require() of ES Module /tmp/ng-integration-test-aTpQOT/test-sandbox/node_modules/string-width/index.js from /tmp/ng-integration-test-aTpQOT/test-sandbox/node_modules/cliui/build/index.cjs not supported.
Instead change the require of index.js in /tmp/ng-integration-test-aTpQOT/test-sandbox/node_modules/cliui/build/index.cjs to a dynamic import() which is available in all CommonJS modules.
------------------------------------------
```

Closes #56261.

PR Close #56364
2024-06-11 12:35:47 -07:00
Andrew Scott 4c7d5d8acd fix(core): signals should be tracked when embeddedViewRef.detectChanges is called (#55719)
This commit fixes an issue where signals in embedded views are not
tracked if they are refreshed with `EmbeddedViewRef.detectChanges`
directly. We had previously assumed that embedded views were always
refreshed along with their hosts.

PR Close #55719
2024-06-11 12:35:02 -07:00
Joey Perrott 60ed6257e0 ci: remove tmp directory after publishing artifacts (#56385)
Remove teh tmp directory after publishing artifacts to prevent runner from running out of space.

PR Close #56385
2024-06-11 17:48:26 +00:00
Matthieu Riegler 25a5373af2 docs(docs-infra): guard access to navigator for prerendering (#56333)
PR Close #56333
2024-06-11 17:08:35 +00:00
Joey Perrott 0287ae5b68 ci: use full depth repositories for artifact publishing (#56383)
Use full depth repositories for artifact publishing to prevent the commits from not being able to find the path between commits during push.

PR Close #56383
2024-06-11 16:42:14 +00:00
Andrew Scott 4efe5000c0 refactor(router): Add back changes param to RouterLink ngOnChanges (#56371)
This parameter was removed in a recent change but is being added back to
avoid breaking code in a minor version.
While the changes parameter is not used, some code relies on it, mostly
through API misuse (extending `RouterLink`, manually calling `ngOnChanges`, etc.).

PR Close #56371
2024-06-11 08:30:57 -07:00
Matthieu Riegler 3cbddd2e42 refactor(compiler): Extract return type description (#56287)
Thie commit extracts return type description from the jsDoc.

Compiler part of #56277, will also need as dev-infra update.

PR Close #56287
2024-06-11 08:29:22 -07:00
Aristeidis Bampakos 54170cd60d docs: use language-agnostic links for external docs (#56377)
PR Close #56377
2024-06-11 08:26:30 -07:00
Pawel Kozlowski 31d9fa40bd fix(benchpress): adjust supported browser names for headless chrome (#56360)
The chrome version controlled by selenium reports chrome-headless-shell in the
current setup. This fix accounts for the updated browser name.

PR Close #56360
2024-06-11 08:25:10 -07:00
Angular Robot 5109a43410 docs: update Angular CLI help [main] (#56328)
Updated Angular CLI help contents.

PR Close #56328
2024-06-11 08:23:19 -07:00
Angular Robot feb9858a53 build: update all non-major dependencies (#56118)
See associated pull request for more information.

PR Close #56118
2024-06-11 08:21:47 -07:00
Jeremy Elbourn f0fbced1c5 docs: update and reorganize contributor docs (#56141)
* Move from `docs/` to `contributing-docs/`
* Updated file names to better communicate their content
* Consolidated content into fewer docs
* Updated and/or deleted obsolete info

PR Close #56141
2024-06-11 08:20:59 -07:00
Matthieu Riegler 567c2f6d90 docs: add NG0913 error doc (#56352)
File copied from AIO.

fixes #56351

PR Close #56352
2024-06-10 15:11:45 -07:00
vladboisa 33d1aa69e8 docs(docs-infra): add missing context (#56367)
Added some missing context for statement regarding base href

Fixes#56336

PR Close #56367
2024-06-10 15:08:37 -07:00
WilliamDecker 7535aeb906 ci: correct invalid attributes in prettierrc configuration (#56279)
Corrected options for "tabs" to "useTabs" (https://prettier.io/docs/en/options#tabs) and "semicolon" to "semi" (https://prettier.io/docs/en/options#semicolons) as outlined in the Prettier documentation.

PR Close #56279
2024-06-10 14:05:17 -07:00
Risqi Romadhoni e3f7d687aa docs: update link for Vite and esbuild in Angular CLI introduction (#56346)
PR Close #56346
2024-06-10 14:04:29 -07:00
Sasidharan SD 0918643cd7 docs: fix input validation link in reactive forms (#56334)
PR Close #56334
2024-06-10 14:02:56 -07:00
Preston West 38eaf46213 docs: fix 3 typos and a format issue (#56329)
PR Close #56329
2024-06-10 14:00:03 -07:00
arturovt 4616d2904d docs: update event-binding (#56322)
This commit updates the event binding part, where all `scroll` listeners are marked
as passive using the special zone.js configuration flag. The configuration has been
moved from the `polyfills` file to `index.html`. Since new apps no longer include a
`polyfills.ts` file but instead have a `polyfills` property in the builder, setting
the flag in `index.html` ensures compatibility with both configurations.

PR Close #56322
2024-06-10 13:57:24 -07:00
Denis Bendrikov 080e971db3 refactor(devtools): use dark scrollbars in dark mode (#56225)
Opt the devtools into the user's color scheme preferences

PR Close #56225
2024-06-10 13:55:43 -07:00
Angular Robot 6ca056532a build: lock file maintenance (#56361)
See associated pull request for more information.

PR Close #56361
2024-06-10 13:54:11 -07:00
Miles Malerba ea3c802056 feat(core): Add a schematic to migrate afterRender phase flag (#55648)
Adds an `ng update` migration to move users from using the phase flag
with `afterRender` / `afterNextRender` to passing a spec object instead.

PR Close #55648
2024-06-10 13:53:39 -07:00
Miles Malerba 38effcc63e fix(core): Add back phase flag option as a deprecated API (#55648)
Adds back the ability to set the phase of an `afterRender` /
`afterNextRender` callback using the `phase` option. However, this API
is now deprecated, and the phase should instead be specified by passing
a spec object rather than a callback function.

PR Close #55648
2024-06-10 13:53:39 -07:00
Miles Malerba a655e46447 feat(core): Redesign the afterRender & afterNextRender phases API (#55648)
Previously `afterRender` and `afterNextRender` allowed the user to pass
a phase to run the callback in as part of the `AfterRenderOptions`. This
worked, but made it cumbersome to coordinate work between phases.

```ts
let size: DOMRect|null = null;

afterRender(() => {
  size = nativeEl.getBoundingClientRect();
}, {phase: AfterRenderPhase.EarlyRead});

afterRender(() => {
  otherNativeEl.style.width = size!.width + 'px';
}, {phase: AfterRenderPhase.Write});
```

This PR replaces the old phases API with a new one that allows passing a
callback per phase in a single `afterRender` / `afterNextRender` call.
The return value of each phase's callback is passed to the subsequent
callbacks that were part of that `afterRender` call.

```ts
afterRender({
  earlyRead: () => nativeEl.getBoundingClientRect(),
  write: (rect) => {
    otherNativeEl.style.width = rect.width + 'px';
  }
});
```

This API also retains the ability to pass a single callback, which will
be run in the `mixedReadWrite` phase.

```ts
afterRender(() => {
  // read some stuff ...
  // write some stuff ...
});
```

PR Close #55648
2024-06-10 13:53:39 -07:00
Angular Robot 6db94d51db docs: update Angular CLI help [main] (#56280)
Updated Angular CLI help contents.

PR Close #56280
2024-06-07 09:45:58 -07:00
Preston West 257d94211c docs: fix typo in testing/services.md (#56316)
PR Close #56316
2024-06-07 09:34:15 -07:00
Kristiyan Kostadinov 96aa5c8a2c fix(migrations): resolve error in standalone migration (#56302)
This is related to an issue that was reported internally. We were assuming that `hasNgModuleMetadataElements` will return true only for property assignments initialized to arrays, but that's not the case.

These changes update the type and our assertions to more accurately reflect the AST and to avoid the error.

PR Close #56302
2024-06-07 09:33:41 -07:00
Andrew Scott a13f5da773 feat(router): Allow UrlTree as an input to routerLink (#56265)
This commit adds `UrlTree` as a valid input to `routerLink`. It
disallows using this together with any inputs that come from
`UrlCreationOptions`, such as `queryParams` or `fragment`.

We could, in the future, decide on a different approach for these, like merging or
replacing those in `urlTree` input. We cannot, however, go the other way
(decide to prevent those inputs if we've already decided to allow it and
using a merging/replacing strategy). For this reason, an error seems the
most reasonable approach to start and we can re-evaluate if there's a
compelling reason to.

fixes #34468

PR Close #56265
2024-06-07 09:33:14 -07:00
Aristeidis Bampakos a7e4a578d8 docs: use new link for update guide (#56054)
PR Close #56054
2024-06-07 09:32:46 -07:00
arturovt 2781b20567 docs: update NG0506 (#55973)
Provide a thorough explanation of why an application may remain unstable and
why developers should consider not running asynchronous code on the server outside
of the Angular zone, as this may lead to memory leaks.

PR Close #55973
2024-06-07 09:32:18 -07:00
Matthieu Riegler 7b0777b304 docs(docs-infra): Go zoneless and enable the zoneless scheduler (#55161)
PR Close #55161
2024-06-07 09:31:15 -07:00
Alan Agius 81486c2f47 fix(localize): add @angular/localize/init as polyfill in angular.json (#56300)
This commit addresses an issue where the `@angular/localize/init` polyfill is not included when there are no polyfills specified in the `angular.json` file.

PR Close #56300
2024-06-06 13:41:11 -07:00
Jessica Janiuk 181ed2a84a release: cut the zone.js-0.14.7 release (#56306)
PR Close #56306
2024-06-06 13:40:34 -07:00
Jessica Janiuk 101edda018 release: cut the v18.1.0-next.1 release 2024-06-05 13:18:05 -07:00
Jessica Janiuk cc97f11891 docs: release notes for the v18.0.2 release 2024-06-05 12:58:08 -07:00
Dylan Hunn 117a26bac3 docs(zone.js): update release guide for zone.js (#55846)
Update the releasing guide for zone.js, because one of the release commands was outdated.
PR Close #55846
2024-06-05 19:33:27 +00:00
Kristiyan Kostadinov dd869e4d68 refactor(language-service): integrate let declarations (#56270)
Integrates let declarations in the various places within the language service (quick info, completions etc).

PR Close #56270
2024-06-05 18:45:23 +00:00
Angular Robot 1653b40d14 build: update dependency @rollup/plugin-commonjs to v26 (#56281)
See associated pull request for more information.

PR Close #56281
2024-06-05 18:36:50 +00:00
Thomas Nguyen 6e89ef1ebf refactor(core): Refactor parts of event_replay into a shared library that will be used with global event delegation. (#56172)
This also moves the code that stashes the jsaction more closely to the code that actually sets the event listener.

PR Close #56172
2024-06-05 16:35:23 +00:00
marktechson 4766233f16 docs: remove v18 developer event banner (#56278)
PR Close #56278
2024-06-05 15:56:29 +00:00
Tom Wilkinson a65c1cf109 refactor(core): Add and move tests for Dispatcher. (#56193)
Move tests from `eventcontract_test.ts` to `dispatcher_test.ts` for
functionality that lives in `Dispatcher`.

Add an extra test for `preventDefault` behavior for `CLICKMOD` that
covers a previous bug case.

PR Close #56193
2024-06-04 18:05:39 +00:00
arturovt 4a3800a6a0 fix(zone.js): store remove abort listener on the scheduled task (#56160)
Prior to this commit, a memory leak occurred when the `abort` listener was
not removed from the `AbortSignal`. We introduced a fix to remove the event
listener, but it was erroneously stored on the `taskData`, which is a shared
global object. Consequently, when something attempted to remove an event listener,
it immediately removed the last stored abort listener. As a result, events would
never be canceled.

We have now rectified this by storing the remove abort listener function directly on
the task itself. This adjustment ensures that the abort listener is tied only to the
specific task. When the `abort` function is called, it cancels the task. Therefore, it
is safe to associate the cleanup function directly with the task.

Closes: #56148

PR Close #56160
2024-06-04 17:29:05 +00:00
Kristiyan Kostadinov 9aea8a0576 refactor(compiler-cli): add diagnostic for duplicate let declarations (#56199)
Adds a template diagnostic that will flag cases where multiple `@let` declarations use the same name.

PR Close #56199
2024-06-04 17:28:03 +00:00
Kristiyan Kostadinov cb165923e0 refactor(compiler-cli): account for let declarations in two-way binding check (#56199)
Updates the check that prevent writes to template variables in two-way bindings to account for let declarations.

Also fixes some old tests that weren't properly setting up two-way bindings.

PR Close #56199
2024-06-04 17:28:03 +00:00
Kristiyan Kostadinov ea4feb2721 refactor(compiler-cli): support completions for let declarations (#56199)
Adds support for let declarations inside the `CompletionEngine`.

PR Close #56199
2024-06-04 17:28:03 +00:00
Kristiyan Kostadinov 18ea7417a0 refactor(compiler-cli): support resolving the symbol of let declaration (#56199)
Updates the symbol builder to handle resolving the symbol of a let declaration.

PR Close #56199
2024-06-04 17:28:03 +00:00
Kristiyan Kostadinov 152430fa0f refactor(compiler-cli): integrate let declaration into the indexer (#56199)
Adds support for let declarations in the template indexer.

PR Close #56199
2024-06-04 17:28:03 +00:00
Kristiyan Kostadinov 695126453e refactor(compiler-cli): integrate let declarations into the template type checker (#56199)
Integrates let declarations into the template type checker by producing corresponding constants in the TCB.

This also includes a couple of custom diagnostics to flag usages of let before they're declared and illegal writes to let declarations. We can't rely on TS for these checks, because it includes the variable name in the diagnostic.

PR Close #56199
2024-06-04 17:28:03 +00:00
Kristiyan Kostadinov b7fc7fdba9 refactor(compiler): integrate let declarations into the template binder (#56199)
Integrates the let declarations into the template binder which will be used to power the scoping behavior of the new syntax.

PR Close #56199
2024-06-04 17:28:03 +00:00
Kristiyan Kostadinov 6cef0ed3ed refactor(compiler-cli): add compiler flag for testing let declarations (#56199)
Adds a private `_enableLetSyntax` flag that allows for let declarations to be enabled in tests.

PR Close #56199
2024-06-04 17:28:02 +00:00
Paweł Kubiak c8951ab57f fix(docs-infra): remove config release from test scripts (#56062)
fix(docs-infra): remove config release from test scripts

As we discussed in one of the previous PRs we should remove `--config=release` from test scripts on CI
fix(docs-infra): use DI to inject current VERSION.major

PR Close #56062
2024-06-04 17:27:27 +00:00
Angular Robot 0e2d80d5d4 build: update io_bazel_rules_sass digest to 61dde52 (#56168)
See associated pull request for more information.

PR Close #56168
2024-06-04 16:34:20 +00:00
Angular Robot d40cc85344 build: update cross-repo angular dependencies (#56259)
See associated pull request for more information.

Closes #56184 as a pr takeover

PR Close #56259
2024-06-04 16:27:46 +00:00
Alvaro Junqueira 8a24b83155 docs: fixing typo :ng-deep to ::ng-deep (#56251)
PR Close #56251
2024-06-04 16:14:50 +00:00
Pawel Kozlowski 73d0f77c34 refactor(docs-infra): mark adev-root component as OnPush (#56254)
After inspecting and testing the adev-root component is seems like
it could be marked as OnPush.
This change gets us closer to enabling zoneless for adev.

PR Close #56254
2024-06-04 13:52:37 +00:00
Pawel Kozlowski 45c56ad3df refactor(docs-infra): mark code editors components as OnPush (#56254)
After inspecting and testing the embedded-editor and adev-code-editor
components it
seems like those could be marked as OnPush.
This change gets us closer to enabling zoneless for adev.

PR Close #56254
2024-06-04 13:52:37 +00:00
Pawel Kozlowski f0ea936630 refactor(docs-infra): mark the update component as OnPush (#56254)
After inspecting and testing the adev-update-guide component it
seems like it could be marked as OnPush. This change gets us closer
to enabling zoneless for adev.

PR Close #56254
2024-06-04 13:52:37 +00:00
Sasidharan SD b0546dad83 docs: fix docs links (#56234)
PR Close #56234
2024-06-04 13:52:04 +00:00
Matthieu Riegler 73e84e2d22 refactor(core): Use Nullish coalescing assignment for view getters. (#56242)
Micro optim, this wasn't minified by the optimizer.

PR Close #56242
2024-06-03 20:10:35 +00:00
Ben Hong 3d2f963a90 docs: fix vertical playground spacing issue (#55689)
PR Close #55689
2024-06-03 19:26:09 +00:00
Ben Hong e5928e671c docs: resolve extra padding on tutorial editor (#54828)
As of this commit, there is a visual discrepancy between the height of the content on the left compared to the separator and editors on the right. It appears that the cause of this is an additional computation of layout padding which is unnecessary for these particular elements.

PR Close #54828
2024-06-03 19:24:39 +00:00
Alan Agius 01172b84d9 build: update Node.js to match Angular CLI engines (#56187)
The current supported Node.js engines by the Angular CLI are `^18.19.1 || ^20.11.1 || >=22.0.0`

PR Close #56187
2024-06-03 18:00:46 +00:00
Tomasz Ducin 8a993de4cb refactor(devtools): update links to the new docs (angular.dev) (#56138)
This PR replaces all links available within the devtools to point
to the new docs.
The links to Input/Output (decorators) have been replaced with
their function (signal) counterparts: input, output.

PR Close #56138
2024-06-03 17:38:11 +00:00
Dylan Hunn c673a0288d ci: add dylhunn@ to language-service pullapprove (#55999)
Add dylhunn@ as an approver for language service code.

PR Close #55999
2024-06-03 16:19:49 +00:00
Payam Valadkhan 9e21582456 fix(compiler-cli): Show template syntax errors in local compilation modified (#55855)
Currently the template syntax errors are extracted in the template type check phase. But in local compilation mode we skip the type check phase. As a result template syntax errors are not displayed. With this change we show the template syntax diagnostics in local mode.

PR Close #55855
2024-05-31 13:59:02 +00:00
Paweł 9d034f629f refactor(core): remove doubled line (#56091)
remove doubled line of titlecase pipe in commonModulePipes array

PR Close #56091
2024-05-31 13:24:55 +00:00
Sasidharan SD c0ad070e49 docs: fix alternate configuration link (#56201)
PR Close #56201
2024-05-31 13:24:15 +00:00
Angular Robot c1e3165ade build: update scorecard action dependencies (#56119)
See associated pull request for more information.

PR Close #56119
2024-05-31 13:15:41 +00:00
Alan Agius d530b09e40 docs: update file-structure doc (#56202)
Replace `/assets` with `public/`, this was replaced in version 18 of the Angular CLI.

PR Close #56202
2024-05-31 13:13:55 +00:00
Matthieu Riegler 398092b207 docs: update version support (#56034)
fixes #56033

PR Close #56034
2024-05-31 13:13:01 +00:00
Tyler Tierney fa7bef5b9b docs: edit sentence grammar in style-guide (#56173)
PR Close #56173
2024-05-31 13:12:29 +00:00
Andrew Scott 80f472f9f4 refactor(core): provide zone token in prod as well (#56197)
This allows us to make decisions based on whether zone is provided for
when zoneless is the default.

PR Close #56197
2024-05-30 19:24:23 -07:00
Andrew Kushnir 31f3975e4b fix(core): handle missing withI18nSupport() call for components that use i18n blocks (#56175)
This commit updates hydration serialization logic to handle a case when the `withI18nSupport()` call is not present for an application that has a component that uses i18n blocks. Note: the issue is only reproducible for components that also inject `ViewContainerRef`, since it triggers a special serialization code path.

Resolves #56074.

PR Close #56175
2024-05-30 18:36:58 +00:00
Jessica Janiuk 67128c321b ci: update explicit required reviews for primitives (#56191)
This removes the explicit 1 review required for the primitives and primitives-shared groups so that PR creators can serve as their own approval for that group.

PR Close #56191
2024-05-30 18:34:58 +00:00
Tom Wilkinson b6fb53cdc7 fix(core): Fix shouldPreventDefaultBeforeDispatching bug (#56188)
When I copied this over in https://github.com/angular/angular/commit/caedd10597a6becfc1f1f0d98b06dc76d6b25a86
the parentheses moved around the A tag check and the CLICK type check,
instead of around the CLICK and CLICKMOD check.

PR Close #56188
2024-05-30 17:54:55 +00:00
Alex Rickabaugh 1081c8d623 fix(core): don't coerce all producers to consumers on liveness change (#56140)
When a consumer switches its liveness state, it gets added to / removed from
the consumer list of all of its producers. This operation is transitive, so
if its producer is *also* a consumer and *its* liveness state is switched,
then the change is applied recursively.

Note that this only matters *if* the producer is also a consumer. However,
the logic in `producerAddLiveConsumer` / `producerRemoveLiveConsumerAtIndex`
coerced the producer node into a producer & consumer node, which allocated
extra arrays into the node structure that are never used. This didn't affect
correctness, but increased the memory usage of plain signal nodes (which are
just producers, never consumers).

This fix changes the logic in those operations to simply check if a producer
is also a consumer instead of coercing it into one.

PR Close #56140
2024-05-30 17:44:55 +00:00
Thomas Nguyen e286d3cd3b refactor(core): Remove lambda from error message. (#56161)
This should've been in the previous PR, but a bad rebase removed it.

PR Close #56161
2024-05-30 17:30:53 +00:00
Jessica Janiuk b9b78d12bc ci: update primitives-shared membership (#56189)
This updates the shared primitives ownership list to be correct.

PR Close #56189
2024-05-30 17:28:25 +00:00
Matthieu Riegler 345832f76a ci: Update Saucelabs config to use Andoid 13 and 14 (#55710)
This will allow us to run the test against versions closer to supported targets.

PR Close #55710
2024-05-30 16:43:25 +00:00
Thomas Nguyen caeb7042b0 refactor(core): Switch a .includes to a .indexOf(), as this is currently (#56046)
breaking internal tests that assert no usage of Array ES6 methods.

PR Close #56046
2024-05-30 15:30:52 +00:00
Andrew Kushnir 0529aac5e5 refactor(core): replace AIO link with ADEV one in hydration message (#56178)
This commit updates the content of hydration-related message and replaces AIO with ADEV domain.

PR Close #56178
2024-05-30 14:57:10 +00:00
Kristiyan Kostadinov 9eef041211 refactor(compiler): implement let declarations in render3 ast (#55848)
Introduces a new `LetDeclaration` into the Render3 AST, simiarly to the HTML AST, and adds an initial integration into the various visitors.

PR Close #55848
2024-05-30 14:55:36 +00:00
Kristiyan Kostadinov 1ae06e4fc6 refactor(compiler): implement let declarations in html ast (#55848)
Adds a new `LetDeclaration` node to the AST that captures the `LetStart`, `LetValue` and `LetEnd` tokens into a single node.

PR Close #55848
2024-05-30 14:55:36 +00:00
Kristiyan Kostadinov 62c5b66b41 refactor(compiler): add support for tokenizing let declarations (#55848)
Updates the lexer to produce tokens for `let` declarations. Currently it' behind a flag while the feature is being worked on.

PR Close #55848
2024-05-30 14:55:36 +00:00
Matthieu Riegler 8d75627ddd fix(core): Do not migrate HttpClientModule imports on components. (#56067)
`provideHttpClient()` returns a `EnvironmentProvider` which is not compatible with component providers.

PR Close #56067
2024-05-30 14:55:06 +00:00
Kristiyan Kostadinov 75e811c18b fix(migrations): do not generate aliased variables with the same name (#56154)
Adds some logic to avoid generating expressions like `let $index = $index` in the control flow migration.

Fixes #56152.

PR Close #56154
2024-05-30 14:54:36 +00:00
Angular Robot 3d55073531 build: update cross-repo angular dependencies (#56041)
See associated pull request for more information.

Closes #55806 as a pr takeover

PR Close #56041
2024-05-30 14:53:32 +00:00
Matthieu Riegler 7928e11a0e docs(docs-infra): move back all xterm code to the fw repo (#55642)
Previously, the `@angular/docs` package had `xterm` as dependency but wasn't referencing it. It only had dedicated styles. This commit moves back the styles to the FW repo as it is only used here.

PR Close #55642
2024-05-30 14:52:55 +00:00
Andrew Scott d73127f48d refactor(core): privately export token that indicates if zone CD is provided (#56137)
This will allow us to internally decide how to configure things when the default is zoneless.

PR Close #56137
2024-05-30 13:48:08 +00:00
vidhi hattar e1e7266ced docs: add discord link icon to nav menu (#56149)
PR Close #56149
2024-05-29 21:44:06 +00:00
Pawel Kozlowski 8a3d010d4d release: cut the v18.1.0-next.0 release 2024-05-29 18:38:06 +02:00
Pawel Kozlowski f6d5cb0426 docs: release notes for the v18.0.1 release 2024-05-29 18:13:57 +02:00
naaajii 3b2f88cd90 fix(migrations): handle empty ngSwitchCase (#56105)
empty ngSwitchCase generate `case ()` which isn't valid syntax therefore adding quotes will help prevent us migrate empty case if no condition was provided

fix angular#56030

PR Close #56105
2024-05-29 15:38:38 +02:00
Kristiyan Kostadinov e5a6f91722 feat(core): support TypeScript 5.5 (#56096)
Updates the repo to add support for TypeScript 5.5. Includes resolving some compilation errors and broken tests.

PR Close #56096
2024-05-29 15:33:33 +02:00
Thomas Nguyen 1223122080 refactor(core): Use event_dispatcher in event_replay code. (#56036)
This makes events bubble! This change also contains changes to
dispatcher and event_dispatcher to make replay synchronous,
so that we avoid odd timing issues. This can be split out though.

Lastly, we have one cleanup change to move the mapping from
event type to functions on the element itself.

PR Close #56036
2024-05-29 12:59:23 +02:00
Neil Runcie 09a7e9d41e docs: update links in guide for migrating v14 apps to v15 at angular.dev (#56116)
Fixes an issue in the update guide found at https://angular.dev/update-guide?v=14.0-15.0&l=3 which has links that redirect to v17 documentation. This is because the links were missing the v15 reference within the a tag links.

Fixes #56101

PR Close #56116
2024-05-29 12:52:22 +02:00
TJ Kohli b5e5c90f59 docs: compress favicons (#56133)
Run favicons through a few lossless image optimization algorithms to decrease size and improve loading speed

PR Close #56133
2024-05-29 12:51:08 +02:00
Char2s 400b47ebb1 docs: correct browserslist compatibility docs (#56027)
PR Close #56027
2024-05-29 12:46:12 +02:00
Angular Robot ae11a65818 docs: update Angular CLI help [main] (#56092)
Updated Angular CLI help contents.

PR Close #56092
2024-05-29 12:44:12 +02:00
Sasidharan SD 5442a8d60f docs: fix links in aot compiler page (#56132)
PR Close #56132
2024-05-29 12:40:16 +02:00
Alan Agius 3b077e65c1 test: add back control_flow_migration tests (#56130)
These were incorrectly removed via https://github.com/angular/angular/pull/55391#issuecomment-2135352758

PR Close #56130
2024-05-28 16:48:08 +02:00
Kristiyan Kostadinov fb351300c3 build: update to latest dev infra code (#56128)
Updates the repo to the latest dev infra code which involves updating a patch and renaming all the golden files to end with `.api.md`.

PR Close #56128
2024-05-28 14:42:31 +02:00
Matthieu Riegler b2445a0953 fix(core): link errors to ADEV (#55554) (#56038)
Console error links will now point to adev.

PR Close #55554

PR Close #56038
2024-05-28 12:50:53 +02:00
Harshal e39c01a53f docs: change link from #components-overide to #override-component-providers (#56111)
PR Close #56111
2024-05-28 09:32:38 +02:00
Matthieu Riegler 53ae096c3c docs: fix some errors docs (#55706)
PR Close #55706
2024-05-27 14:52:19 +02:00
Andrew Kushnir ae83646704 fix(core): handle elements with local refs in event replay serialization logic (#56076)
Previously, the event replay serialization logic was located before we verify that a `TNode` exists. `TNode`s may not exist in `tView.data` array in several cases, including cases when there is a local ref used on an element: in this case an extra slot in `LView` contains a reference to the same element and `TNode` is not needed. This commit moves the event replay serialization logic a bit lower, after we check for TNode presence.

Resolves #56073.

PR Close #56076
2024-05-27 13:50:09 +02:00
Aristeidis Bampakos 031e40e6dd docs: update CLI reference (#56060)
PR Close #56060
2024-05-27 11:42:32 +02:00
Sasidharan SD 609179807d docs: fix schematics cli broken link (#56070)
PR Close #56070
2024-05-27 11:40:41 +02:00
Charles Lyding 9d52b8fab0 docs: update tutorials to use v18 (#56043)
All documentation tutorials will now use the recently released version 18
of Angular. Additionaly, the tutorials have been migrated to use the new
`@angular/build` package which does not contain the Webpack related dependencies.
The `first-app` tutorial was not moved to `@angular/build` due to it having
karma related dependencies present which currently requires the Webpack-based
build system during test execution.

PR Close #56043
2024-05-27 11:39:26 +02:00
Ben Halbach df267c59f9 docs: change count to this.count in example (#56080)
PR Close #56080
2024-05-27 11:37:46 +02:00
Matthieu Riegler 857f867d14 docs: add update material to v18 step (#56044)
PR Close #56044
2024-05-27 11:30:46 +02:00
Matthieu Riegler 0aa311e24c docs: add search favicon for seo (#56016)
PR Close #56016
2024-05-27 11:29:17 +02:00
Aristeidis Bampakos c1fdfb4fcc docs: use customized YouTube channel link (#56051)
PR Close #56051
2024-05-27 11:28:26 +02:00
Ben Halbach eb1426c682 docs: remove extra template string termination (#56081)
PR Close #56081
2024-05-27 11:06:24 +02:00
vladboisa 825023801b docs(core): change API link (#55688)
Fix url link for Button Change detection usage

Fixes #556687

PR Close #55688
2024-05-23 18:30:25 +02:00
Andrew Scott 3b4b05d2f7 refactor(core): Remove hybrid mode flag and move scheduler provider location (#55722)
The flag is not used anymore and, as a result, is easier to move the
scheduler provider.

PR Close #55722
2024-05-23 18:15:53 +02:00
Angular Robot 4b26342ec4 build: update io_bazel_rules_sass digest to 2907a45 (#55841)
See associated pull request for more information.

PR Close #55841
2024-05-23 18:12:25 +02:00
Thomas Nguyen 690b0fb9af refactor(core): Create event types that are able to be serialized, captured, or are mouse events. (#55799)
Use these constants across jsaction and Angular.

PR Close #55799
2024-05-23 16:10:47 +02:00
Thomas Nguyen ae9af9104f refactor(core): Make sure not to do anymore jsaction work once everything is replayed. (#55799)
Without this, I think subsequent renders will populate data structures.

PR Close #55799
2024-05-23 16:10:47 +02:00
cexbrayat 4ffa73651c fix(compiler-cli): interpolatedSignalNotInvoked diagnostic for class, style, attribute and animation bindings (#55969)
This extends the diagnostic to catch issues like:

```html
<div [class.green]="mySignal"></div>
<div [style.width]="mySignal"></div>
<div [attr.role]="mySignal"></div>
<div [@triggerName]="mySignal"></div>
```

PR Close #55969
2024-05-23 15:05:02 +02:00
Pawel Kozlowski b94adb9fc7 refactor: use built-in control flow in js-web-frameworks benchmark (#55988)
Migrate the js-web-frameworks benchmark to use the built-in control flow
instead of the ngFor loop.

PR Close #55988
2024-05-23 14:09:38 +02:00
Kristiyan Kostadinov 6aeea69d5b fix(compiler): optimize track function that only passes $index (#55872)
Currently we optimize methods that pass both `$index` and the item into a method. We can take this a step further by also optimizing calls that only pass `$index` into the first parameter.

PR Close #55872
2024-05-23 14:02:30 +02:00
Pawel Kozlowski 760207b254 Revert "fix(core): link errors to ADEV (#55554)" (#56031)
This reverts commit dd0700ff1d.
We will need G3 patch cleanup before this one can land.

PR Close #56031
2024-05-23 13:57:53 +02:00
Joey Perrott 55e33ba75a build: bump in-memory-web-api to v18 (#56018)
This commit updates the in-memory-web-api package versions from v17 -> v18.

PR Close #56018
2024-05-23 12:00:29 +02:00
Matthieu Riegler dd0700ff1d fix(core): link errors to ADEV (#55554)
Console error links will now point to adev.

PR Close #55554
2024-05-23 11:58:54 +02:00
Aristeidis Bampakos 50808733bf docs: update blog link in new Angular Docs (#56022)
PR Close #56022
2024-05-23 11:41:08 +02:00
Jens Kuehlers a67c059ead docs: change robots.txt to allow crawling (#56023)
PR Close #56023
2024-05-23 11:34:25 +02:00
Jens Kuehlers b34a302361 docs: update robots.txt to allow crawlers (#56023)
PR Close #56023
2024-05-23 11:34:25 +02:00
Daniel Schmitz 98cd91a273 docs: using @if instead ngIf (#54623)
PR Close #54623
2024-05-23 11:33:21 +02:00
mgechev 19ea26c2db docs: update the roadmap to reflect latest work (#55979)
PR Close #55979
2024-05-23 11:24:33 +02:00
arturovt 85c171920a fix(zone.js): do not mutate event listener options (may be readonly) (#55796)
Prior to this commit, event listener options were mutated directly, for example,
`options.signal = undefined` or `options.once = false`.

This issue arises in apps using third-party libraries where the responsibility lies
with the library provider. Some libraries, like WalletConnect, pass an abort controller
as `addEventListener` options. Because the abort controller has the `signal` property,
this is a valid case. Thus, mutating options would throw an error since `signal`
is a readonly property.

Even though zone.js is being deprecated as Angular moves towards zoneless change detection,
this fix is necessary for apps that still use zone.js and cannot migrate to zoneless change
detection because they rely on third-party libraries and are not responsible for the code
used in them.

Closes #54142

PR Close #55796
2024-05-22 16:20:34 -07:00
Matthieu Riegler a0690fe19f refactor(core): remove unused preventDefault on listener (#55879)
`wrapListener` was only invoked with `wrapWithPreventDefault` set to `false`.

PR Close #55879
2024-05-22 16:08:39 -07:00
Emma Twersky 76633847a2 docs: add the v18 blog post link to the changelog (#56015)
PR Close #56015
2024-05-22 16:06:51 -07:00
Tom Wilkinson fdd59c49fe refactor(core): Add a new EventDispatcher class. (#55837)
`EventDispatcher` emulates the browser's event dispatch (mostly).
It supports:
 - Bubbling and `stopPropagation`/`stopImmediatePropagation`.
 - `currentTarget` during dispatch.
 - Throwing errors for `preventDefault` if the event is being dispatched
   in replay.
 - Throwing errors for `composedPath()` if event is being dispatched in
   replay.

PR Close #55837
2024-05-22 15:24:01 -07:00
cexbrayat 6024d07559 fix(core): typo in zoneless warning (#55974)
The warning introduced in ae0baa25 mispelled `applications`.

PR Close #55974
2024-05-22 15:22:19 -07:00
Joey Perrott 1e8284c574 ci: don't add redirect from next.angular.dev to vX sites (#56012)
Don't redirect from vX.angular.dev version to the next.angular.dev instance

PR Close #56012
2024-05-22 15:11:22 -07:00
Emma Twersky 9fb6043379 docs: update robots.txt (#56010)
PR Close #56010
2024-05-22 15:09:38 -07:00
twerske 1d774d6175 docs: add angular.dev release banners (#56014)
PR Close #56014
2024-05-22 15:09:10 -07:00
Dylan Hunn 5be6df65eb docs: release notes for the v17.3.10 release 2024-05-22 11:19:33 -07:00
Dylan Hunn 90ecee892d docs: release notes for the v18.0.0 release 2024-05-22 11:01:51 -07:00
Paweł Kubiak 756b891f95 fix(docs-infra): calculate list of Angular Docs versions based on VERSION (#55977)
fix(docs-infra): calculate the list of Angular Docs versions based on VERSION, append --config=release to docs build and serve the script. Support displaying the right color of navigation for the deprecated state.
fix(docs-infra): add scrollbar to version picker
fix(docs-infra): set initial adev docs version to 18
fix(docs-infra): remove --config=release from scripts for local development, write unit tests
fix(docs-infra): update CI tests step
fix(docs-infra): remove rc from the list
fix(docs-infra): update unit test to check count of versions

PR Close #55977
2024-05-22 17:25:52 +00:00
Andrew Scott acdcec9d47 docs: Add experimental and zoneless to nav (#55834)
PR Close #55834
2024-05-22 10:18:54 -07:00
Kristiyan Kostadinov d17e6a5b17 fix(language-service): use type-only import in plugin factory (#55996)
Fixes that the plugin factory was causing TypeScript to be bundled into the language service.

PR Close #55996
2024-05-22 09:52:32 -07:00
Matthieu Riegler 632f9e7d51 docs: Add v18 to update guide (#55993)
PR Close #55993
2024-05-22 16:03:01 +00:00
Joey Perrott b7a2ad2744 fix(docs-infra): use separate templates for the from and to selectors in update guide (#55992)
Use separate template names for the from and to selector dropdowns, otherwise we are only able to change the from value.

PR Close #55992
2024-05-22 15:59:33 +00:00
Dylan Hunn 048847f374 docs: release notes for the v18.0.0-rc.3 release 2024-05-21 14:41:55 -07:00
arturovt afe45616ad fix(service-worker): remove controllerchange listener when app is destroyed (#55365)
This commit updates the `ngswAppInitializer` implementation and removes the `controllerchange`
listener upon the destruction of the `ApplicationRef`. This adjustment aims to prevent memory
leaks. In a zone.js environment, neglecting to do so could lead to the perpetual creation of
a zone task, which captures the zone and obstructs proper garbage collection.

PR Close #55365
2024-05-21 14:04:22 -07:00
twerske a5512d3c4b docs: update robot.txt to index angular.dev (#55617)
PR Close #55617
2024-05-21 13:41:06 -07:00
Tom Wilkinson bb13174bd1 refactor(core): Add a bit to EventInfo to mark resolution. (#55864)
This will prevent running `ActionResolver` logic multiple times while
migrating to use `Dispatcher` to resolve actions rather than
`EventContract`.

PR Close #55864
2024-05-21 12:20:48 -07:00
Angular Robot 0b460a7f75 build: update actions/checkout digest to a5ac7e5 (#55889)
See associated pull request for more information.

PR Close #55889
2024-05-21 12:19:19 -07:00
Sasidharan SD fd2b8892ab docs: fix broken publish library link (#55895)
PR Close #55895
2024-05-21 12:15:12 -07:00
Ben Hong 0c000ac848 docs: add missing border on embedded editor (#55926)
PR Close #55926
2024-05-21 12:14:08 -07:00
Matthieu Riegler 19d782b469 docs(docs-infra): Add update guide to adev (#55638)
PR Close #55638
2024-05-21 12:01:59 -07:00
Joey Perrott e3eb5fea47 ci: properly redirect during rc phase (#55972)
Properly redirect to next.angular.dev during rc phase

PR Close #55972
2024-05-21 11:59:45 -07:00
Kristiyan Kostadinov 08523ec650 fix(compiler): allow comments between connected blocks (#55966)
Fixes that the logic which looks for connected blocks didn't allow for comments between them.

Fixes #55954.

PR Close #55966
2024-05-21 10:37:58 -07:00
garrettld 87c5f3c521 docs(common): fix FormatWidth.Short description (#55821)
PR Close #55821
2024-05-20 23:39:06 -07:00
Andrew Kushnir 14668e47eb docs: declare provideAnimationsAsync() function stable (#55871)
This commit removes the `@developerPreview` label from the `provideAnimationsAsync()` function, effectively declaring it stable.

PR Close #55871
2024-05-20 23:38:18 -07:00
cexbrayat 237eacae61 fix(compiler-cli): dom property binding check in signal extended diagnostic (#54324)
The compiler now checks if a signal is properly called on dom property bindings.
The ideal solution would be for the compiler to check if dom property bindings in general are properly typed,
but this is currently not the case, and it is a bigger task to land this change.
In the meantime, the signal diagnostic is augmented to catch cases like the following:

```
<div [id]="mySignal"></div>
```

PR Close #54324
2024-05-20 23:37:57 -07:00
Thomas Nguyen d75adc5a25 refactor(core): Add additional cleanups to PR- Simplify event handler extraction logic. (#55752)
This should have been part of an earlier commit, but was not merged.

PR Close #55752
2024-05-20 23:37:34 -07:00
Kristiyan Kostadinov ae0baa2522 fix(core): add warning when using zoneless but zone.js is still loaded (#55769)
Users may be using zoneless, but are still loading Zone.js in which case they won't get the full benefits like reduced bundle size. These changes detect such a case and log a warning.

PR Close #55769
2024-05-20 23:37:12 -07:00
Tom Wilkinson 834e627d9e refactor(core): Remove legacy_dispatcher.ts which is no longer needed. (#55784)
Also use `dispatchDelegate` by default for `eventReplayer`.

PR Close #55784
2024-05-20 23:36:51 -07:00
Pawel Kozlowski 831a20b472 refactor(docs-infra): notify on data change inside OnPush component (#55830)
The SecondaryNavigation component was updating state outside of an event handler
without notifying about this change. Modeling state as signal should take
care of proper UI updates (note that I did just a mechanical change here, maybe
there are better ways of dealing with this animations case).

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

PR Close #55876
2024-05-20 23:30:19 -07:00
Charles Lyding 0ee0002d24 docs: update build system migration URL for CLI (#55891)
The URL for the Angular CLI has been updated to `build-system-migration`
to better reflect the content of the documentation.

PR Close #55891
2024-05-20 23:29:22 -07:00
Joey Perrott 009812bdd9 ci: split ci into privileged and unprivileged workflows (#55907)
Split the workflows to prevent unexpected overlap between environments.

PR Close #55907
2024-05-20 20:33:22 +00:00
Joey Perrott d62dc97c67 Revert "Supply chain attack demo for Google VRP" (#55896)
This reverts commit 6d95131d84.

This change was created by a security researcher and is being reverted as it is a noop.
We intend to follow up with more information in a future blog. Please refer to the pull
request description for the link to this blog.

PR Close #55896
2024-05-20 19:59:08 +00:00
ghost 6d95131d84 Supply chain attack demo for Google VRP 2024-05-20 13:56:56 +03:00
Rahat Ahmed f7894885b8 refactor(core): Cleanup dead jsnamespace code (#55795)
Support for the jsnamespace attribute was removed in #55619.

PR Close #55795
2024-05-17 12:59:41 -07:00
Hyun Don Moon b89c88c73b docs: fix broken link in signals/model (#55811)
PR Close #55811
2024-05-17 12:25:46 -07:00
Jens Kuehlers 7aadf42466 docs: Include info about experimental on adev (#55857)
Copy information about meaning of "experimental"
from angular.io to angular.dev.

PR Close #55857
2024-05-17 12:25:19 -07:00
Andrew Scott cae0d3167d fix(core): exhaustive checkNoChanges should only do a single pass (#55839)
Because exhaustive checks traverse the whole tree regardless of the
dirty state, it breaks some expectations around how change detection
should be running. When a view has transplanted views, it
unconditionally marks all ancestors for traversal, assuming this is fine
because the loop will just traverse them and find nothing dirty.
However, exhaustive checkNoChanages actually refreshes everything during
traversal.

This update ensures the exhaustive check only does a single pass and
also prevents some unnecessary marking of transplanted views for
refresh since we know they're going to be reached.

PR Close #55839
2024-05-17 12:24:36 -07:00
Alex Rickabaugh 9884875c96 fix(compiler-cli): fix type narrowing of @if with aliases (#55835)
When an `@if` expression has an alias, only the type of the alias is
currently narrowed. So for example, suppose `value` is `string|undefined`:

```
@if (value; as alias) {
  {{ value.length }} <!-- error, value may be undefined -->
  {{ alias.length }} <!-- no error, alias is narrowed -->
}
```

This is especially noticeable when the expression contains guards which are
preconditions for the aliased expression:

```
@if (a && b; as alias) {...}
```

In this case, `a` would not be narrowed within the body, even though the
`@if` condition forces it to be truthy. This is a bug.

The reason is that aliased expressions were previously type-checked as:

```
var alias = a && b;
if (alias) {
  // nothing other than alias is narrowed
  ...
}
```

One option considered was to emit `const alias` instead of `var alias`.
TypeScript _does_ trace `const` expressions and narrow their individual
components when the overall expression is guarded:

```
const alias = a && b;
if (alias) {
  // a, b are also narrowed
}
```

However, this narrowing has different semantics than if `a && b` appeared
directly in the guard expression. For example, object properties aren't
narrowed with this approach, so component properties (which are referenced
as e.g. `this.a`) would not be narrowed.

Instead, we amend the guard expression to include both the expression _and_ the
alias variable, enforcing that both are narrowed.

```
var alias = a && b;
if ((a && b) && alias) {
  // a, b, and alias all narrowed correctly.
}
```

This form ensures all conditions within the guard expression get narrowed
while also narrowing the alias variable type.

Fixes #52855

PR Close #55835
2024-05-17 10:14:57 -07:00
Matthieu Riegler eddb4051b8 refactor(forms): remove deprecated symbols (#55723)
Follow-up of #55698 to help remove the symbols from G3.

PR Close #55723
2024-05-17 10:12:01 -07:00
Thomas Nguyen 0e23ed716e docs: Add documentation for event replay (#55802)
PR Close #55802
2024-05-17 10:10:06 -07:00
Dylan Hunn 13601105ec release: cut the zone.js-0.14.6 release (#55845)
PR Close #55845
2024-05-16 17:32:14 -07:00
Paul Gschwendtner 400911e3b8 fix(compiler-cli): do not throw when retrieving TCB symbol for signal input with restricted access (#55774)
Currently when attempting to retrieve a TCB symbol for an input binding
that refers to a signal input with e.g. `protected`, while the
`honorAccessModifiersForInputBindings` flag is `false`, Angular will
throw a runtime exception because the symbol retrieval code always
expects a proper field access in the TCB.

This is not the case with `honorAccessModifiersForInputBindings =
false`, as TCB will allocate a temporary variable when ignoring the
field access. This will then trigger the runtime exception (which we
added to flag such "unexpected" cases). This commit handles it
gracefully, as it's valid TCB, but we simply cannot generate a proper
TCB symbol (yet). This is similar to `@Input` decorator inputs.

In the future we may implement logic to build up TCB symbols for
non-property access bindings, for both signal inputs or `@Input`
inputs. This commit just avoids a build exception.

Related to: #54324.

PR Close #55774
2024-05-16 09:33:02 -07:00
Charles Lyding abdf453b85 docs: Update build system migration title to reflect user action (#55782)
The Angular CLI documentation topic for migrating to the new build system
now has a navigation label of "Migrating to new build system" instead of
"esbuild". This new label better reflects the action a user may want to
take rather than one of the tools used by the new build system.

PR Close #55782
2024-05-16 09:32:29 -07:00
Bouguima, Walid 2bb12ac02f fix(compiler): prevent usage of reserved control flow symbol in custom interpolation context. (#55809)
* Fixes the issue where using a reserved control flow @ symbol in a custom interpolation context yields improper parser feedback.

PR Close #55809
2024-05-16 09:28:13 -07:00
Alan Agius 20a530acb6 fix(zone.js): correctly bundle zone-patch-rxjs (#55826)
https://github.com/angular/angular/pull/53443 caused the a local `rxjs` file to be imported from an entry-point which caused this to be excluded from being bundled due to the name matching `rxjs`.

Closes #55825

PR Close #55826
2024-05-16 09:21:17 -07:00
Alan Agius f3b0e2fbc1 refactor(zone.js): remove tslib from dependencies (#55827)
Iif needed `tslib` code is included directly in the bundled FESM2015 hence making the dependency redundant.

PR Close #55827
2024-05-16 09:15:19 -07:00
cexbrayat 3d5c3d9fff fix(core): error about provideExperimentalCheckNoChangesForDebug uses wrong name (#55824)
The error about `provideExperimentalCheckNoChangesForDebug` mentions `provideCheckNoChangesForDebug` instead.

PR Close #55824
2024-05-16 09:02:28 -07:00
Andrew Scott 23eafb4aa2 docs: release notes for the v18.0.0-rc.2 release 2024-05-15 16:04:23 -07:00
Andrew Scott 7a172f7e03 docs: release notes for the v17.3.9 release 2024-05-15 13:55:39 -07:00
Andrew Scott 84b2351d50 refactor(core): Update error for both zone and zoneless to be only for apps (#55813)
Developers may want to enable zoneless for all tests by default by
adding the zoneless provider to `initTestEnvironment` and then
temporarily disabling it for individual tests with the zone provider
until they can be made zoneless compatible.

PR Close #55813
2024-05-15 13:27:26 -07:00
Thomas Nguyen 99bd9f13f8 refactor(core): Add a test case for content projection. (#55801)
This test actually used to fail until our recent improvements :))

PR Close #55801
2024-05-15 08:57:48 -07:00
Matthieu Riegler 53b0d6adb8 fix(forms): Allow canceled async validators to emit. (#55134)
With this change, If an async validator that should have emitted was cancelled by a non-emitting validator, the status change will be reported on the `AbstractControl.events` observable.

This issue can happen when a `FormControl` is added to a `FormGroup` and a FormGroupDirective/FormControlDirective trigger a non-emitting validation (which cancels the initial validator execution).

Note: The behavior remains the same of the existing `statusChanges` observable as the change was too breaking to land in G3.

fixes: angular#41519

PR Close #55134
2024-05-15 08:56:25 -07:00
Angular Robot cd13d1b290 build: update dependency conventional-changelog to v6 (#55668)
See associated pull request for more information.

PR Close #55668
2024-05-15 08:54:19 -07:00
Angular Robot 4141d70124 build: update dependency gulp-conventional-changelog to v5 (#55669)
See associated pull request for more information.

PR Close #55669
2024-05-15 08:52:30 -07:00
Pawel Kozlowski 35238a2f21 refactor(docs-infra): mark more components as OnPush (#55775)
Use the OnPush change detection strategy in more components to
improve performance and enable zoneless in the future.

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

PR Close #55786
2024-05-15 08:48:20 -07:00
Andrew Scott 4bc05410dd refactor(core): calling autoDetectChanges without params works for zoneless (#55800)
This was mistakenly implemented automatically by the override without
filling in the default value of `true` like it is for the zone-based
fixture.

PR Close #55800
2024-05-15 08:46:30 -07:00
cexbrayat 65b7cb2826 fix(migrations): migrate HttpClientTestingModule in test modules (#55803)
The migration was breaking tests with test modules that imported `HttpClientTestingModule`,
as it removed the JS imports without migrating the module imports.

The migration now handles the case where `HttpClientTestingModule` is used in test modules,
by replacing the module import with the `provideHttpClient` and `provideHttpClientTesting` providers.

Before:
```ts
import { HttpClientTestingModule } from '@angular/common/http/testing';

@NgModule({
  declarations: [AppComponent],
  imports: [HttpClientTestingModule],
})
export class TestModule {}
```

After:
```ts
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';

@NgModule({
  declarations: [AppComponent],
  imports: [],
  providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()]
})
export class TestModule {}
```

PR Close #55803
2024-05-15 08:45:31 -07:00
Tom Wilkinson f1e3ec2601 refactor(core): Add an ActionResolver option to Dispatcher. (#55757)
This will enable internal usages to migrate from ActionResolver in
EventContrat to ActionResolver in Dispatcher.

PR Close #55757
2024-05-14 15:16:26 -07:00
Tom Wilkinson caedd10597 refactor(core): Move preventDefault to Dispatcher (#55756)
This is a simple move.

PR Close #55756
2024-05-14 14:34:59 -07:00
Joey Perrott 3fae2f1e42 ci: properly rely on adev for the adev-deploy job (#55797)
Properly rely on the adev job so that the job actually triggers

PR Close #55797
2024-05-14 12:52:26 -07:00
Sasidharan SD 56fb556f65 docs: fix production mode broken link (#55794)
PR Close #55794
2024-05-14 12:21:30 -07:00
Alex Rickabaugh f736bea8ee refactor(core): deprecate @Component.interpolation (#55778)
Angular has long had the ability to use different interpolation delimiters
(by default `{{` and `}}`). This concept was copied over from AngularJS,
where AngularJS syntax is included in HTML sent over the network to the
browser. Occasionally developers would use SSR frameworks which _also_ have
interpolation syntaxes of their own, so there was a need to change the
delimiters used by AngularJS to avoid conflicts.

Since Angular templates are always processed by our compiler and the
interpolation characters are never processed by other systems first, this
option is vestigial in Angular and only increases the complexity of our
parser.

DEPRECATED: `@Component.interpolation` is deprecated. Use Angular's
delimiters instead.

PR Close #55778
2024-05-14 11:48:12 -07:00
Angular Robot b6ca7fca96 build: update all non-major dependencies (#55785)
See associated pull request for more information.

PR Close #55785
2024-05-14 11:33:18 -07:00
Joey Perrott 1b8000dd63 ci: release angular.dev on each commit (#55792)
Release angular.dev on each commit to the appropriate version of the documentation site based on the current state of the repository.

PR Close #55792
2024-05-14 11:12:45 -07:00
cexbrayat ccde17db0c fix(migrations): preserve existing properties in HttpClientModule migration (#55777)
The `HttpClientModule` migration was dropping the existing properties other than imports and providers when updating an `@NgModule`, `@Component` or `configureTestingModule`.

PR Close #55777
2024-05-14 11:10:57 -07:00
Angular Robot af065cc005 build: update cross-repo angular dependencies (#55781)
See associated pull request for more information.

PR Close #55781
2024-05-14 10:54:17 -07:00
Andrew Kushnir 0eade1c4db docs: add a note about development status of zone.js (#55746)
PR Close #55746
2024-05-14 10:53:43 -07:00
Thomas Nguyen 3ad120dfe8 refactor(core): Simplify event handler extraction logic. (#55747)
This reuses information already recorded during hydration to
remove jsaction attributes to also stash event handlers. This avoids
a tree walk and looku.

PR Close #55747
2024-05-14 09:38:43 -07:00
Thomas Nguyen 629b255ddb refactor(core): Add four tests and fix code to make tests pass. (#55747)
The first test asserts that bubbling does not work right now.

The second asserts that stopPropagation works, which should pass when test #1 passes too.

The third test asserts properties about the events passed to the event handler.

THe fourth test asserts that mouse events do not translate to jsaction nor help emit the jsaction binary. This required a change in code to make this pass.

PR Close #55747
2024-05-14 09:38:43 -07:00
Alan Agius ef029b8d00 build: switch from rollup and terser to esbuild for creating contract bundle (#55705)
This commit implements the replacement of rollup and terser with esbuild for generating the contract_bundle binary. The transition is facilitated by optimizations aimed at reducing the bundle size.

PR Close #55705
2024-05-13 12:49:30 -07:00
Tom Wilkinson 0cb50317e1 refactor(core): Rename BaseDispatcher to Dispatcher. (#55721)
Rename `BaseDispatcher` to `Dispatcher` and `Dispatcher` to
`LegacyDispatcher`. The `GlobalHandler` type and `stopPropagation`
function needs to be left for now in dispatcher.ts as it was not
exported previously from legacy_dispatcher.ts.

PR Close #55721
2024-05-13 12:30:08 -07:00
Angular Robot 7187394ffe build: update io_bazel_rules_sass digest to fcce061 (#55755)
See associated pull request for more information.

PR Close #55755
2024-05-13 11:20:22 -07:00
Sasidharan SD 8dd5c735c6 docs: add inspecting injector section in devtools (#55764)
PR Close #55764
2024-05-13 11:17:50 -07:00
Matthieu Riegler c8472e5e9e refactor(forms): deprecate unwanted control events aliases (#55698)
This commit deprecates the aliases for the control events to ease the changes in G3
A follow-up commit will remove those deprecated entries.

PR Close #55698
2024-05-13 11:16:15 -07:00
Sasidharan SD b90c6aa2ea docs: add service worker images (#55780)
PR Close #55780
2024-05-13 11:14:50 -07:00
Angular Robot 7c9f4cbf47 build: update cross-repo angular dependencies (#55718)
See associated pull request for more information.

PR Close #55718
2024-05-13 11:12:54 -07:00
Kristiyan Kostadinov aa8df1d029 refactor(core): clean up clang comments and workarounds (#55750)
Since we aren't using clang anymore, we can remove the comments and the workarounds that were in place to prevent it from doing the wrong thing.

PR Close #55750
2024-05-13 11:10:36 -07:00
Kristiyan Kostadinov 533ec52aca refactor(compiler): move variable optimization earlier in pipeline (#55771)
Currently the variable optimization phase happens somewhat late in the process which is okay since the variables are generally static (e.g. `reference()` instruction calls). In some upcoming work we'll have variables that consume slots and require `advance` instructions. To allow for them to be optimized correctly, we need to move the variable optimization phase earlier, at least before we allocate the slots.

PR Close #55771
2024-05-13 11:09:26 -07:00
Sasidharan SD 801e5e1577 docs: fix devtools links (#55766)
PR Close #55766
2024-05-13 11:08:32 -07:00
Charles Lyding 2c0e60eceb docs: initial update of application builder migration instructions for v18 (#55699)
The application migration instructions and information page now contains
updated information related to the v18 release. This includes a reordering
of the migration section to mention the automatic migration first as well
as mention that `ng update` will now ask to perform the migration for v18.

PR Close #55699
2024-05-13 11:06:53 -07:00
Tom Wilkinson 76d0aea89b refactor(core): Remove custom event and replay behavior. (#55695)
These behaviors have been moved back to g3.

PR Close #55695
2024-05-13 09:36:03 -07:00
iteriani 3068de4369 refactor(core): Remove enums from event-dispatch. (#55421)
These cause optimization issues in external.

PR Close #55421
2024-05-13 09:12:44 -07:00
Andrew Kushnir 85ac2de744 ci: update payload size for the event-dispatch-contract script (#55748)
The payload size of the `event-dispatch-contract.min.js` script was reduced by more than 5%, which triggered CI checks. This commit updates a golden file to match the actual size.

PR Close #55748
2024-05-09 19:13:36 -07:00
iteriani 28fb385eec refactor(core): Use early event contract instead of the event contract in bootstrap. (#55587)
This also fixes an existing bug where we erase the jsaction attribute too early.

Now the event contract binary is 608 bytes :D.

PR Close #55587
2024-05-09 14:34:10 -07:00
Thomas Nguyen f5b6b7fa40 refactor(core): Export some more symbols and check for truthiness on event types before adding them. (#55587)
In some cases, we will be passing in undefined for capture events, so handle this.

PR Close #55587
2024-05-09 14:34:10 -07:00
Matthieu Riegler fedeaac8ba fix(forms): Add event for forms submitted & reset (#55667)
This commit adds 2 new events to the unified control event observable.

PR Close #55667
2024-05-09 09:21:14 -07:00
Ben Hong c1915f19c6 docs: fix visible code snippets in first-app tutorial (#55742)
PR Close #55742
2024-05-08 15:46:52 -07:00
Alan Agius c0012865eb refactor(core): a couple of minor changes to the early-event-contract (#55704)
This changes include
- Using multi line comments to write JSDoc comments which improves DX
- Use `this.container` instead of `window.document.documentElement`

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

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

PR Close #55717
2024-05-08 11:08:49 -07:00
Andrew Kushnir b9c88dc366 docs: release notes for the v18.0.0-rc.1 release 2024-05-08 09:06:38 -07:00
Andrew Kushnir 0b790891f4 docs: release notes for the v17.3.8 release 2024-05-08 08:49:45 -07:00
Matthieu Riegler 7287fefe7a docs: uwu (#55666)
PR Close #55666
2024-05-07 14:57:26 -07:00
Alan Agius 8305e50f8e build: trigger error when size-tracking is enabled but not in limit file (#55708)
Trigger an error when attempting to enable size-tracking for a project not listed in the integration-payload.json file.

Before this update, size-checks would succeed even if the project wasn't included in the file size limit.

PR Close #55708
2024-05-07 13:39:56 -07:00
Alan Agius 8630dc8149 test: add Integration tests for hydration and event reply (#55708)
This commit introduces integration tests for hydration and event reply functionalities. Additionally, it implements a payload size check for the `event-dispatch-contract.min.js`.

PR Close #55708
2024-05-07 13:39:55 -07:00
Andrew Scott ca6cdcd269 refactor(core): feature for potential zoneless-compatibility debug check (#55663)
This commit adds a feature that is useful for determining if an
application is zoneless-ready. The way this works is generally only
useful right now when zoneless is enabled. Some version of this may be useful in
the future as a general configuration option to change detection to make
`checkNoChanges` pass always exhaustive as an opt-in to address #45612.

Because this is an experimental, debug-only feature, it is okay to merge
during the RC period.

PR Close #55663
2024-05-07 13:39:13 -07:00
Andrew Scott abbaf8f639 refactor(core): Throw a runtime error if both zone and zoneless are provided (#55410)
This commit adds a dev-mode error if both the zone and zoneless
providers are used together.

PR Close #55410
2024-05-07 13:37:42 -07:00
Angular Robot 8cb838f9f6 build: update io_bazel_rules_sass digest to 9a4a4be (#55700)
See associated pull request for more information.

PR Close #55700
2024-05-07 13:36:31 -07:00
Tom Wilkinson 0fb455f72e refactor(core): Move global dispatch behavior into Dispatcher. (#55692)
This behavior is now implemented by calling `dispatch` whether or not
the `action` is populated. The `Dispatcher` then does global dispatch
and early returns if there's no action.

PR Close #55692
2024-05-07 12:00:40 -07:00
Thomas Nguyen 67bb310376 refactor(core): Fix timing of removal of jsaction attribute to be after event replay. (#55696)
This otherwise leads to bugs where, by the time replay needs the attribute, hydration
happens and it's gone.

PR Close #55696
2024-05-07 08:16:16 -07:00
arturovt a9460d08a0 fix(zone.js): remove abort listener on a signal when actual event is removed (#55339)
This commit updates the implementation of the `addEventListener` patcher.

We're currently creating an abort event listener on the signal (when it's provided)
and never remove it. The abort event listener creates a closure which captures `task`
(tasks capture zones and other stuff too) and prevent `task`, zones and signals from
being garbage collected.

We now store the function which removes the abort event listener when the actual event
listener is being removed. The function is stored on task data since task data is already
being used to store different types of information that's necessary to be shared between
`addEventListener` and `removeEventListener`.

Closes #54739

PR Close #55339
2024-05-07 08:07:33 -07:00
Paul Gschwendtner afc057ee92 docs: properly link to developer preview section (#55711)
Fixes an invalid link to the developer preview section.
PR Close #55711
2024-05-07 08:06:42 -07:00
Angular Robot 0fffe5389f build: update all non-major dependencies (#55531)
See associated pull request for more information.

PR Close #55531
2024-05-07 08:05:57 -07:00
4502 changed files with 89737 additions and 250818 deletions
+1 -3
View File
@@ -5,9 +5,6 @@
.git
node_modules
dist
aio/node_modules
aio/tools/examples/shared/node_modules
aio/tools/examples/shared/example-scaffold
# All integration test node_modules folders
integration/animations/node_modules
@@ -17,6 +14,7 @@ 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
+6 -8
View File
@@ -60,14 +60,12 @@ build:release --stamp
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
build:snapshot-build --stamp
##########################################################
# AIO architect build configuration #
# See aio/angular.json for available configurations. #
# To build with a partiular configuration: #
# bazel build //aio:build --aio_build_config=<config> #
# Default config is `stable``. #
##########################################################
build --flag_alias=aio_build_config=//aio:flag_aio_build_config
# Angular DevTools for Firefox releases *cannot* be stamped and `--config snapshot-build-firefox` is a no-op.
# This is because Mozilla requires add-on source code to be uploaded and then they manually reproduce the build.
# If we stamp the build based on Git information such as the current commit, then reproducing the build would require
# uploading the entire `.git` directory. We already must upload the entire monorepo, and uploading `.git` as well
# exceeds the max source file size. To address this, we just *don't* stamp Firefox builds of Angular DevTools.
build:snapshot-build-firefox --nostamp
###############################
# Output #
+1 -1
View File
@@ -44,7 +44,7 @@ function setSecretVar() {
# 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 computaions and may not be needed. When needed, you can call this function to set
# 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:
-1
View File
@@ -16,7 +16,6 @@ echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
setPublicVar CI "$CI"
setPublicVar PROJECT_ROOT "$projectDir";
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
# 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";
+1 -5
View File
@@ -6,10 +6,6 @@
"postCreateCommand": "yarn install",
"extensions": [
"devondcarew.bazel-code",
"gkalpak.aio-docs-utils",
"ms-vscode.vscode-typescript-tslint-plugin",
// The following extensions are useful when working on angular.io (i.e. inside the `aio/` directory).
//"angular.ng-template",
//"dbaeumer.vscode-eslint",
"ms-vscode.vscode-typescript-tslint-plugin"
],
}
@@ -0,0 +1,18 @@
load("//tools:defaults.bzl", "esbuild_checked_in")
exports_files([
"tsconfig.json",
])
esbuild_checked_in(
name = "main",
entry_point = "//.github/actions/deploy-docs-site/lib:main.ts",
external = [
"undici",
],
platform = "node",
target = "node14",
deps = [
"//.github/actions/deploy-docs-site/lib",
],
)
@@ -0,0 +1,16 @@
name: 'Deploy angular.dev site'
description: 'Automatically deploy and set up redirects for angular.dev'
author: 'Angular'
inputs:
serviceKey:
description: 'The service key used for firebase deployments.'
required: true
configPath:
description: 'The path to the firebase config file.'
required: true
distDir:
description: 'The path to the firebase dist directory.'
required: true
runs:
using: 'node20'
main: 'main.js'
@@ -0,0 +1,23 @@
load("//tools:defaults.bzl", "ts_library")
package(default_visibility = ["//.github/actions/deploy-docs-site:__subpackages__"])
exports_files([
"main.ts",
])
ts_library(
name = "lib",
srcs = glob(
["*.ts"],
),
#tsconfig = "//.github/actions/deploy-docs-site:tsconfig.json",
deps = [
"@npm//@actions/core",
"@npm//@actions/github",
"@npm//@angular/ng-dev",
"@npm//@types/node",
"@npm//@types/tmp",
"@npm//tmp",
],
)
@@ -0,0 +1,15 @@
import {fileSync} from 'tmp';
import {writeSync} from 'fs';
import {getInput, setSecret} from '@actions/core';
let credentialFilePath: undefined | string;
export function getCredentialFilePath(): string {
if (credentialFilePath === undefined) {
const tmpFile = fileSync({postfix: '.json'});
writeSync(tmpFile.fd, getInput('serviceKey', {required: true}));
setSecret(tmpFile.name);
credentialFilePath = tmpFile.name;
}
return credentialFilePath;
}
@@ -0,0 +1,116 @@
import {cp, mkdtemp, readFile, rm, writeFile} from 'fs/promises';
import {Deployment} from './deployments';
import {join} from 'path';
import {tmpdir} from 'os';
import {spawnSync} from 'child_process';
import {getCredentialFilePath} from './credential';
export async function deployToFirebase(
deployment: Deployment,
configPath: string,
distDirPath: string,
) {
if (deployment.destination == undefined) {
console.log(`No deployment necessary for docs created from: ${deployment.branch}`);
return;
}
console.log('Preparing for deployment to firebase...');
const tmpDeployDir = await mkdtemp(join(tmpdir(), 'deploy-directory'));
const deployConfigPath = join(tmpDeployDir, 'firebase.json');
const config = JSON.parse(await readFile(configPath, {encoding: 'utf-8'})) as {
hosting: {public: string};
};
config['hosting']['public'] = './dist';
await writeFile(deployConfigPath, JSON.stringify(config, null, 2));
await cp(distDirPath, join(tmpDeployDir, 'dist'), {recursive: true});
spawnSync(`chmod 777 -R ${tmpDeployDir}`, {encoding: 'utf-8', shell: true});
firebase(
`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`,
tmpDeployDir,
);
firebase(
`target:apply --config ${deployConfigPath} --project angular-dev-site hosting angular-docs ${deployment.destination}`,
tmpDeployDir,
);
firebase(
`deploy --config ${deployConfigPath} --project angular-dev-site --only hosting --non-interactive`,
tmpDeployDir,
);
firebase(
`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`,
tmpDeployDir,
);
await rm(tmpDeployDir, {recursive: true});
}
export async function setupRedirect(deployment: Deployment) {
if (deployment.redirect === undefined) {
console.log(`No redirect necessary for docs created from: ${deployment.branch}`);
return;
}
console.log('Preparing to set up redirect on firebase...');
const redirectConfig = JSON.stringify(
{
hosting: {
target: 'angular-docs',
redirects: [
{
type: 302,
regex: '^(.*)$',
destination: `${deployment.redirect.to}:1`,
},
],
},
},
null,
2,
);
const tmpRedirectDir = await mkdtemp(join(tmpdir(), 'redirect-directory'));
const redirectConfigPath = join(tmpRedirectDir, 'firebase.json');
await writeFile(redirectConfigPath, redirectConfig);
spawnSync(`chmod 777 -R ${tmpRedirectDir}`, {encoding: 'utf-8', shell: true});
firebase(
`target:clear --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs`,
tmpRedirectDir,
);
firebase(
`target:apply --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs ${deployment.redirect.from}`,
tmpRedirectDir,
);
firebase(
`deploy --config ${redirectConfigPath} --project angular-dev-site --only hosting --non-interactive`,
tmpRedirectDir,
);
firebase(
`target:clear --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs`,
tmpRedirectDir,
);
await rm(tmpRedirectDir, {recursive: true});
}
function firebase(cmd: string, cwd?: string) {
spawnSync('npx', `-y firebase-tools@latest ${cmd}`.split(' '), {
cwd,
encoding: 'utf-8',
shell: true,
stdio: 'inherit',
env: {
...process.env,
GOOGLE_APPLICATION_CREDENTIALS: getCredentialFilePath(),
},
});
}
@@ -0,0 +1,67 @@
import {fetchLongTermSupportBranchesFromNpm, ActiveReleaseTrains} from '@angular/ng-dev';
import {ReleaseConfig} from '@angular/ng-dev';
import {GitClient} from '@angular/ng-dev';
export interface Deployment {
branch: string;
redirect?: {
from: string;
to: string;
};
destination?: string;
}
export type Deployments = Map<string, Deployment>;
export async function getDeployments(): Promise<Deployments> {
const {github} = await GitClient.get();
const releaseTrains = await ActiveReleaseTrains.fetch({
api: github,
name: 'angular',
owner: 'angular',
nextBranchName: 'main',
});
const ltsBranches = await fetchLongTermSupportBranchesFromNpm({
representativeNpmPackage: '@angular/core',
} as ReleaseConfig);
const docSites = new Map<string, Deployment>();
[...ltsBranches.active, ...ltsBranches.inactive].forEach((branch) => {
docSites.set(branch.name, {
branch: branch.name,
destination: `v${branch.version.major}-angular-dev`,
});
});
docSites.set(releaseTrains.latest.branchName, {
branch: releaseTrains.latest.branchName,
redirect: {
from: `v${releaseTrains.latest.version.major}-angular-dev`,
to: 'https://angular.dev',
},
destination: 'angular-dev-site',
});
if (releaseTrains.releaseCandidate) {
docSites.set(releaseTrains.next.branchName, {
branch: releaseTrains.next.branchName,
});
docSites.set(releaseTrains.releaseCandidate.branchName, {
branch: releaseTrains.releaseCandidate.branchName,
destination: 'next-angular-dev',
redirect: {
from: `v${releaseTrains.releaseCandidate.version.major}-angular-dev`,
to: 'https://next.angular.dev',
},
});
} else {
docSites.set(releaseTrains.next.branchName, {
branch: releaseTrains.next.branchName,
destination: 'next-angular-dev',
});
}
return docSites;
}
@@ -0,0 +1,71 @@
import {getInput, setFailed} from '@actions/core';
import {context} from '@actions/github';
import {deployToFirebase, setupRedirect} from './deploy';
import {getDeployments} from './deployments';
import {GithubConfig, setConfig} from '@angular/ng-dev';
const refMatcher = /refs\/heads\/(.*)/;
async function deployDocs() {
setConfig({
github: <GithubConfig>{
mainBranchName: 'main',
name: 'angular',
owner: 'angular',
},
});
if (context.eventName !== 'push') {
throw Error();
}
const matchedRef = context.ref.match(refMatcher);
if (matchedRef === null) {
throw Error();
}
const currentBranch = matchedRef[1];
const configPath = getInput('configPath');
const distDir = getInput('distDir');
const deployment = (await getDeployments()).get(currentBranch);
if (deployment === undefined) {
console.log(`Current branch (${currentBranch}) does not deploy a documentation site.`);
console.log(`Exiting...`);
process.exit(0);
}
console.log('Doc site deployment information');
console.log('');
console.log('Current Branch:');
console.log(` ${deployment.branch}`);
console.log('');
console.log('Firebase Site:');
if (deployment.destination === undefined) {
console.log(' No deployment of a documenation site is necessary');
} else {
console.log(` Deploying to: ${deployment.destination}`);
}
console.log('');
console.log('Redirect Configuration:');
if (deployment.redirect === undefined) {
console.log(' No redirects are necessary');
} else {
console.log(` From: ${deployment.redirect.from}`);
console.log(` To: ${deployment.redirect.to}`);
}
await deployToFirebase(deployment, configPath, distDir);
await setupRedirect(deployment);
}
// Only run if the action is executed in a repository with is in the Angular org. This is in place
// to prevent the action from actually running in a fork of a repository with this action set up.
if (context.repo.owner === 'angular') {
deployDocs().catch((e: Error) => {
setFailed(e.message);
console.error(e);
});
} else {
console.warn(
'The action was skipped as this action is only meant to run in repos belonging to the Angular organization.',
);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,3 @@
{
"type": "module"
}
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"module": "Node16",
"target": "es2020",
"lib": ["es2021", "dom"],
"experimentalDecorators": true,
"strict": true,
"outDir": "../../../dist/tsc-non-bazel-out",
"skipLibCheck": true,
"noImplicitOverride": true,
// TODO(ESM): Remove this when Bazel also uses the Node resolution.
"esModuleInterop": true,
"noImplicitReturns": true,
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment"
},
"exclude": []
}
+5 -5
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@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel build //adev:build
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
run: yarn bazel build //adev:build --config=release
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@03b8a7dffd1205e061f0bee949024ebefc2a6592
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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # 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@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@03b8a7dffd1205e061f0bee949024ebefc2a6592
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@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
persist-credentials: false
- uses: angular/dev-infra/github-actions/branch-manager@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- uses: angular/dev-infra/github-actions/branch-manager@03b8a7dffd1205e061f0bee949024ebefc2a6592
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@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
bazelrc: ./.bazelrc.user
+30 -109
View File
@@ -5,9 +5,6 @@ on:
branches:
- main
- '[0-9]+.[0-9]+.x'
- 'remove-aio-stuff'
pull_request:
types: [opened, synchronize, reopened]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -24,16 +21,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
node-module-directories: |
./node_modules
./aio/node_modules
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Install node modules in aio
run: yarn install --frozen-lockfile --cwd aio
- name: Check code lint
run: yarn -s tslint
- name: Check for circular dependencies
@@ -44,28 +36,18 @@ jobs:
run: yarn -s ng-dev ngbot verify
- name: Confirm code builds with typescript as expected
run: yarn -s check-tooling-setup
- name: Check commit message
# Commit message validation is only done on pull requests as its too late to validate once
# it has been merged.
if: github.event_name == 'pull_request'
run: yarn ng-dev commit-message validate-range ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
- name: Check code format
# Code formatting checks are only done on pull requests as its too late to validate once
# it has been merged.
if: github.event_name == 'pull_request'
run: yarn ng-dev format changed --check ${{ github.event.pull_request.base.sha }}
devtools:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
@@ -77,13 +59,13 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
@@ -94,31 +76,30 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- 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 --fast_adev
run: yarn bazel build //adev:build --fast_adev --config=release
- name: Run tests
run: yarn bazel test //adev:test
publish-snapshots:
if: github.event_name == 'push'
runs-on:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
@@ -130,7 +111,7 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
node-module-directories: |
@@ -138,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@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
@@ -172,26 +153,22 @@ jobs:
- run: yarn --cwd packages/zone.js/test/typings test
bazel-saucelabs:
# TODO: Replace legacy job with Bazel saucelabs job.
if: github.event_name == 'push'
runs-on: ubuntu-latest-4core
env:
JOBS: 2
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
# Checking out the pull request commit is intended here as we need to run the changed code tests.
ref: ${{ github.event.pull_request.head.sha }}
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/saucelabs@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Set up Sauce Tunnel Daemon
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
env:
@@ -201,80 +178,24 @@ jobs:
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "fixme-saucelabs", ...)')
yarn bazel test --config=saucelabs --jobs=$JOBS ${TESTS}
saucelabs:
runs-on: ubuntu-latest-4core
env:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
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@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- name: Starting Saucelabs tunnel service
run: ./tools/saucelabs/sauce-service.sh run &
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
# test in all supported browsers on Saucelabs anyway until this job can be removed.
- name: Preparing Bazel-generated fixtures required in legacy tests
run: |
yarn bazel build //packages/core/test:downleveled_es5_fixture //packages/common/locales
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
mkdir -p dist/legacy-test-out/core/test/reflection/
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
dist/legacy-test-out/core/test/reflection/es5_downleveled_inheritance_fixture.js
# Locale files are needed for i18n tests running within Saucelabs. These are added
# directly as sources so that the TypeScript compilation of `/packages/tsconfig.json`
# can succeed. Note that the base locale and currencies files are checked-in, so
# we do not need to re-generate those through Bazel.
mkdir -p packages/common/locales/extra
cp dist/bin/packages/common/locales/*.ts packages/common/locales
cp dist/bin/packages/common/locales/extra/*.ts packages/common/locales/extra
- name: Build bundle of tests to run on Saucelabs
run: node tools/legacy-saucelabs/build-saucelabs-test-bundle.mjs
- name: Wait and confirm Saucelabs tunnel has connected
run: ./tools/saucelabs/sauce-service.sh ready-wait
timeout-minutes: 3
- name: Running tests on Saucelabs.
run: KARMA_WEB_TEST_MODE=SL_REQUIRED yarn karma start ./karma-js.conf.js --single-run
- name: Stop Saucelabs tunnel service
run: ./tools/saucelabs/sauce-service.sh stop
adev-deploy:
needs: [adev]
if: needs.adev.result == 'success' && github.event_name == 'push' && github.ref_name == 'main'
env:
DEPLOY_PROJECT: angular-dev-site
DEPLOY_SITE: angular-dev-site
if: needs.adev.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel build //adev:build
- name: Move generated project files into deployment directory
run: cp -r dist/bin/adev/build adev/build
- name: Setup firebase context
run: |
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{ env.DEPLOY_PROJECT }} hosting angular-docs
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{ env.DEPLOY_PROJECT }} hosting angular-docs ${{ env.DEPLOY_SITE }}
run: yarn bazel build //adev:build --config=release
- name: Deploy to firebase
uses: FirebaseExtended/action-hosting-deploy@120e124148ab7016bec2374e5050f15051255ba2 # v0.7.1
uses: ./.github/actions/deploy-docs-site
with:
entryPoint: './adev'
firebaseServiceAccount: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
projectId: ${{ env.DEPLOY_PROJECT }}
channelId: live
serviceKey: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
configPath: 'adev/firebase.json'
distDir: 'dist/bin/adev/build/browser'
+4 -4
View File
@@ -12,14 +12,14 @@ jobs:
labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: angular/dev-infra/github-actions/commit-message-based-labels@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: angular/dev-infra/github-actions/commit-message-based-labels@11bd341a82719997a59039363f716bea76b88459
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
post_approval_changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: angular/dev-infra/github-actions/post-approval-changes@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: angular/dev-infra/github-actions/post-approval-changes@03b8a7dffd1205e061f0bee949024ebefc2a6592
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@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: angular/dev-infra/github-actions/google-internal-tests@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: angular/dev-infra/github-actions/google-internal-tests@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
run-tests-guide-url: http://go/angular-g3sync-start
github-token: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
status:
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/unified-status-check@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- uses: angular/dev-infra/github-actions/unified-status-check@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
-55
View File
@@ -1,55 +0,0 @@
name: Monitoring
on:
schedule:
# Run at 10:00AM every day.
- cron: '0 10 * * *'
permissions: {}
defaults:
run:
shell: bash
jobs:
check_aio:
runs-on: ubuntu-latest
env:
MINIMUM_PWA_SCORE: 95
strategy:
fail-fast: false
matrix:
version: ['https://next.angular.io/', 'https://angular.io/']
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
- name: Install node modules in aio
run: yarn install --frozen-lockfile --cwd aio
- name: Run basic e2e and deployment config tests.
run: yarn --cwd aio test-production-url --test_env=TARGET_URL="${{ matrix.version }}"
- name: Run PWA-score tests.
run: yarn --cwd aio test-pwa-score "${{ matrix.version }}" "${{ env.MINIMUM_PWA_SCORE }}"
- name: Run a11y tests.
run: yarn --cwd aio test-a11y-score "${{ matrix.version }}"
check_contributor_links:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Install node modules in aio
run: yarn install --frozen-lockfile --cwd aio
- name: Check website provided in contributors.json file
run: node aio/scripts/test-external-urls.js
+208
View File
@@ -0,0 +1,208 @@
name: Pull Request
on:
pull_request:
types: [opened, synchronize, reopened]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
defaults:
run:
shell: bash
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Check code lint
run: yarn -s tslint
- name: Check for circular dependencies
run: yarn -s ts-circular-deps:check
- name: Validate pull approve configuration
run: yarn -s ng-dev pullapprove verify
- name: Validate angular robot configuration
run: yarn -s ng-dev ngbot verify
- name: Confirm code builds with typescript as expected
run: yarn -s check-tooling-setup
- name: Check commit message
run: yarn ng-dev commit-message validate-range ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
- 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@515b575bd6650a12353b6039b618cdb808280ad7
devtools:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
run: yarn devtools:test
- name: Test build
run: yarn devtools:build:chrome
test:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
run: yarn test:ci
artifacts:
needs: [test]
if: needs.test.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- 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@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: pr-artifacts-${{ github.event.number }}
path: dist/packages-dist/
adev:
runs-on:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- 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 --fast_adev --config=release
- name: Run tests
run: yarn bazel test //adev:test
zone-js:
runs-on:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
cache-node-modules: true
node-module-directories: |
./node_modules
./packages/zone.js/node_modules
./packages/zone.js/test/typings/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
yarn bazel build \
//packages/zone.js/bundles:zone.umd.js \
//packages/zone.js:npm_package \
//packages/zone.js/test/closure:closure_js \
- run: |
rm -Rf packages/zone.js/build
rm -Rf packages/zone.js/test/extra/*.umd.js
mkdir -p packages/zone.js/build/
mkdir -p packages/zone.js/build/test/
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/
cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs
# Install
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
# Run zone.js tools tests
- run: yarn --cwd packages/zone.js promisefinallytest
- run: yarn --cwd packages/zone.js jest:test
- run: yarn --cwd packages/zone.js jest:nodetest
- run: yarn --cwd packages/zone.js electrontest
- run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive
- run: yarn --cwd packages/zone.js/test/typings test
saucelabs:
runs-on: ubuntu-latest-4core
env:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@03b8a7dffd1205e061f0bee949024ebefc2a6592
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@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@03b8a7dffd1205e061f0bee949024ebefc2a6592
- name: Starting Saucelabs tunnel service
run: ./tools/saucelabs/sauce-service.sh run &
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
# test in all supported browsers on Saucelabs anyway until this job can be removed.
- name: Preparing Bazel-generated fixtures required in legacy tests
run: |
yarn bazel build //packages/core/test:downleveled_es5_fixture //packages/common/locales
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
mkdir -p dist/legacy-test-out/core/test/reflection/
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
dist/legacy-test-out/core/test/reflection/es5_downleveled_inheritance_fixture.js
# Locale files are needed for i18n tests running within Saucelabs. These are added
# directly as sources so that the TypeScript compilation of `/packages/tsconfig.json`
# can succeed. Note that the base locale and currencies files are checked-in, so
# we do not need to re-generate those through Bazel.
mkdir -p packages/common/locales/extra
cp dist/bin/packages/common/locales/*.ts packages/common/locales
cp dist/bin/packages/common/locales/extra/*.ts packages/common/locales/extra
- name: Build bundle of tests to run on Saucelabs
run: node tools/legacy-saucelabs/build-saucelabs-test-bundle.mjs
- name: Wait and confirm Saucelabs tunnel has connected
run: ./tools/saucelabs/sauce-service.sh ready-wait
timeout-minutes: 3
- name: Running tests on Saucelabs.
run: KARMA_WEB_TEST_MODE=SL_REQUIRED yarn karma start ./karma-js.conf.js --single-run
- name: Stop Saucelabs tunnel service
run: ./tools/saucelabs/sauce-service.sh stop
+3 -3
View File
@@ -25,12 +25,12 @@ jobs:
steps:
- name: 'Checkout code'
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
persist-credentials: false
- name: 'Run analysis'
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
with:
results_file: results.sarif
results_format: sarif
@@ -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@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3
uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11
with:
sarif_file: results.sarif
+3 -3
View File
@@ -1,4 +1,4 @@
name: Update AIO Angular CLI help
name: Update ADEV Angular CLI help
on:
workflow_dispatch:
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
uses: angular/dev-infra/github-actions/create-pr-for-changes@03b8a7dffd1205e061f0bee949024ebefc2a6592
with:
branch-prefix: update-cli-help
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
+5 -2
View File
@@ -56,8 +56,11 @@ baseline.json
# Husky
.husky/_
aio/content/examples/.DS_Store
# Ignore cache created with the Angular CLI.
.angular/
.angular/
# Ignore AIO files, useful when changing branches
aio/node_modules
aio/out-tsc
+3 -2
View File
@@ -22,8 +22,9 @@ export const format: FormatConfig = {
'!packages/common/src/i18n/currencies.ts',
// Test cases contain non valid code.
'!packages/compiler-cli/test/compliance/test_cases/**/*.{js,ts}',
// Ignore AIO as its pending removal.
'!aio/**/*.{js,ts}',
// Ignore generated javascript file(s)
'!.github/actions/deploy-docs-site/main.js',
],
},
'buildifier': true,
+1 -1
View File
@@ -28,7 +28,7 @@ export const release: ReleaseConfig = {
return performNpmReleaseBuild();
},
releaseNotes: {
hiddenScopes: ['aio', 'bazel', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'],
hiddenScopes: ['bazel', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'],
},
releasePrLabels: ['area: build & ci', 'action: merge', 'PullApprove: disable'],
};
+2 -2
View File
@@ -1,10 +1,10 @@
{
"printWidth": 100,
"tabWidth": 2,
"tabs": false,
"useTabs": false,
"embeddedLanguageFormatting": "off",
"singleQuote": true,
"semicolon": true,
"semi": true,
"quoteProps": "preserve",
"bracketSpacing": false
}
+7 -551
View File
@@ -121,19 +121,6 @@ groups:
contains_any_globs(files, [
'packages/animations/**/{*,.*}',
'packages/platform-browser/animations/**/{*,.*}',
'aio/content/guide/animations.md',
'aio/content/guide/add-an-animation.md',
'aio/content/guide/animate-state-style.md',
'aio/content/guide/animation-api-summary.md',
'aio/content/guide/understanding-angular-animation.md',
'aio/content/examples/animations/**/{*,.*}',
'aio/content/images/guide/animations/**/{*,.*}',
'aio/content/guide/complex-animation-sequences.md',
'aio/content/guide/reusable-animations.md',
'aio/content/guide/route-animations.md',
'aio/content/guide/transition-and-triggers.md',
'aio/content/guide/animations-attach-to-html-template.md',
'aio/content/guide/animation-transition-timing.md'
])
reviewers:
users:
@@ -152,13 +139,7 @@ groups:
contains_any_globs(files, [
'packages/compiler/**/{*,.*}',
'packages/examples/compiler/**/{*,.*}',
'aio/content/examples/angular-compiler-options/**/{*,.*}',
'packages/compiler-cli/**/{*,.*}',
'aio/content/guide/angular-compiler-options.md',
'aio/content/guide/aot-compiler.md',
'aio/content/guide/aot-metadata-errors.md',
'aio/content/guide/template-typecheck.md',
'aio/content/extended-diagnostics/*.md'
])
reviewers:
users:
@@ -200,155 +181,6 @@ groups:
'packages/examples/platform-browser/**/{*,.*}',
'packages/platform-browser-dynamic/**/{*,.*}',
'packages/docs/**/{*,.*}',
'aio/content/guide/accessibility.md',
'aio/content/examples/accessibility/**/{*,.*}',
'aio/content/guide/architecture-components.md',
'aio/content/guide/architecture-modules.md',
'aio/content/guide/architecture-next-steps.md',
'aio/content/guide/architecture-services.md',
'aio/content/guide/architecture.md',
'aio/content/examples/architecture/**/{*,.*}',
'aio/content/guide/rxjs-interop.md',
'aio/content/images/guide/architecture/**/{*,.*}',
'aio/content/guide/attribute-directives.md',
'aio/content/examples/attribute-directives/**/{*,.*}',
'aio/content/images/guide/attribute-directives/**/{*,.*}',
'aio/content/guide/bootstrapping.md',
'aio/content/examples/bootstrapping/**/{*,.*}',
'aio/content/guide/change-detection.md',
'aio/content/guide/change-detection-zone-pollution.md',
'aio/content/guide/change-detection-slow-computations.md',
'aio/content/guide/change-detection-skipping-subtrees.md',
'aio/content/images/guide/change-detection/**/{*,.*}',
'aio/content/guide/class-binding.md',
'aio/content/guide/cheatsheet.md',
'aio/content/guide/component-interaction.md',
'aio/content/examples/component-interaction/**/{*,.*}',
'aio/content/images/guide/component-interaction/**/{*,.*}',
'aio/content/guide/component-overview.md',
'aio/content/errors/*.md',
'aio/content/examples/errors/**/{*,.*}',
'aio/content/examples/component-overview/**/{*,.*}',
'aio/content/guide/component-styles.md',
'aio/content/guide/developer-guide-overview.md',
'aio/content/guide/view-encapsulation.md',
'aio/content/examples/component-styles/**/{*,.*}',
'aio/content/examples/content-projection/**/{*,.*}',
'aio/content/guide/content-projection.md',
'aio/content/guide/creating-injectable-service.md',
'aio/content/guide/dependency-injection-overview.md',
'aio/content/guide/dependency-injection.md',
'aio/content/examples/dependency-injection/**/{*,.*}',
'aio/content/images/guide/dependency-injection/**/{*,.*}',
'aio/content/guide/dependency-injection-in-action.md',
'aio/content/examples/dependency-injection-in-action/**/{*,.*}',
'aio/content/images/guide/dependency-injection-in-action/**/{*,.*}',
'aio/content/guide/dependency-injection-navtree.md',
'aio/content/guide/dependency-injection-providers.md',
'aio/content/guide/dependency-injection-context.md',
'aio/content/guide/lightweight-injection-tokens.md',
'aio/content/guide/displaying-data.md',
'aio/content/examples/displaying-data/**/{*,.*}',
'aio/content/images/guide/displaying-data/**/{*,.*}',
'aio/content/guide/dynamic-component-loader.md',
'aio/content/examples/dynamic-component-loader/**/{*,.*}',
'aio/content/images/guide/dynamic-component-loader/**/{*,.*}',
'aio/content/guide/example-apps-list.md',
'aio/content/guide/feature-modules.md',
'aio/content/examples/feature-modules/**/{*,.*}',
'aio/content/images/guide/feature-modules/**/{*,.*}',
'aio/content/guide/frequent-ngmodules.md',
'aio/content/images/guide/frequent-ngmodules/**/{*,.*}',
'aio/content/guide/hierarchical-dependency-injection.md',
'aio/content/examples/hierarchical-dependency-injection/**/{*,.*}',
'aio/content/guide/image-directive.md',
'aio/content/guide/image-directive-setup.md',
'aio/content/examples/providers-viewproviders/**/{*,.*}',
'aio/content/examples/resolution-modifiers/**/{*,.*}',
'aio/content/guide/lazy-loading-ngmodules.md',
'aio/content/examples/lazy-loading-ngmodules/**/{*,.*}',
'aio/content/images/guide/lazy-loading-ngmodules/**/{*,.*}',
'aio/content/guide/lifecycle-hooks.md',
'aio/content/examples/lifecycle-hooks/**/{*,.*}',
'aio/content/images/guide/lifecycle-hooks/**/{*,.*}',
'aio/content/examples/ngcontainer/**/{*,.*}',
'aio/content/guide/ngmodules.md',
'aio/content/examples/ngmodules/**/{*,.*}',
'aio/content/guide/ngmodule-api.md',
'aio/content/guide/ngmodule-faq.md',
'aio/content/guide/ngmodule-vs-jsmodule.md',
'aio/content/guide/module-types.md',
'aio/content/guide/template-overview.md',
'aio/content/guide/template-syntax.md',
'aio/content/guide/built-in-template-functions.md',
'aio/content/examples/built-in-template-functions/**/{*,.*}',
'aio/content/guide/event-binding.md',
'aio/content/guide/event-binding-concepts.md',
'aio/content/examples/event-binding/**/{*,.*}',
'aio/content/guide/interpolation.md',
'aio/content/examples/interpolation/**/{*,.*}',
'aio/content/examples/template-syntax/**/{*,.*}',
'aio/content/images/guide/template-syntax/**/{*,.*}',
'aio/content/guide/binding-overview.md',
'aio/content/guide/binding-syntax.md',
'aio/content/examples/binding-syntax/**/{*,.*}',
'aio/content/guide/property-binding.md',
'aio/content/examples/property-binding/**/{*,.*}',
'aio/content/guide/property-binding-best-practices.md',
'aio/content/guide/attribute-binding.md',
'aio/content/examples/attribute-binding/**/{*,.*}',
'aio/content/guide/two-way-binding.md',
'aio/content/examples/two-way-binding/**/{*,.*}',
'aio/content/guide/built-in-directives.md',
'aio/content/guide/directive-composition-api.md',
'aio/content/examples/built-in-directives/**/{*,.*}',
'aio/content/images/guide/built-in-directives/**/{*,.*}',
'aio/content/guide/template-reference-variables.md',
'aio/content/examples/template-reference-variables/**/{*,.*}',
'aio/content/guide/inputs-outputs.md',
'aio/content/examples/inputs-outputs/**/{*,.*}',
'aio/content/images/guide/inputs-outputs/**/{*,.*}',
'aio/content/guide/understanding-template-expr-overview.md',
'aio/content/guide/template-expression-operators.md',
'aio/content/examples/template-expression-operators/**/{*,.*}',
'aio/content/guide/pipes.md',
'aio/content/guide/pipes-custom-data-trans.md',
'aio/content/guide/pipes-overview.md',
'aio/content/guide/pipe-precedence.md',
'aio/content/guide/pipes-transform-data.md',
'aio/content/guide/pipe-template.md',
'aio/content/examples/pipes/**/{*,.*}',
'aio/content/images/guide/pipes/**/{*,.*}',
'aio/content/guide/providers.md',
'aio/content/examples/providers/**/{*,.*}',
'aio/content/images/guide/providers/**/{*,.*}',
'aio/content/guide/signal-queries.md',
'aio/content/guide/singleton-services.md',
'aio/content/guide/signal-inputs.md',
'aio/content/guide/sharing-ngmodules.md',
'aio/content/guide/standalone-components.md',
'aio/content/guide/standalone-migration.md',
'aio/content/guide/structural-directives.md',
'aio/content/examples/structural-directives/**/{*,.*}',
'aio/content/guide/svg-in-templates.md',
'aio/content/guide/style-precedence.md',
'aio/content/images/guide/structural-directives/**/{*,.*}',
'aio/content/guide/template-statements.md',
'aio/content/guide/understanding-angular-overview.md',
'aio/content/guide/user-input.md',
'aio/content/examples/user-input/**/{*,.*}',
'aio/content/images/guide/user-input/**/{*,.*}',
'aio/content/guide/view-encapsulation.md',
'aio/content/examples/view-encapsulation/**/{*,.*}',
'aio/content/images/guide/view-encapsulation/**/{*,.*}',
'aio/content/special-elements/**/{*,.*}',
'aio/content/blocks/**/{*,.*}',
'aio/content/guide/hydration.md',
'aio/content/guide/defer.md',
'aio/content/guide/signals.md',
'aio/content/guide/control_flow.md',
'aio/content/guide/model-inputs.md',
'aio/content/examples/injection-token/**/{*,.*}',
])
reviewers:
users:
@@ -391,23 +223,6 @@ groups:
contains_any_globs(files, [
'packages/common/http/**/{*,.*}',
'packages/examples/http/**/{*,.*}',
'aio/content/guide/understanding-communicating-with-http.md',
'aio/content/guide/http-configure-http-url-parameters.md',
'aio/content/guide/http-handle-request-errors.md',
'aio/content/guide/http-intercept-requests-and-responses.md',
'aio/content/guide/http-interceptor-use-cases.md',
'aio/content/guide/http-make-jsonp-request.md',
'aio/content/guide/http-optimize-server-interaction.md',
'aio/content/guide/http-pass-metadata-to-interceptors.md',
'aio/content/guide/http-request-data-from-server.md',
'aio/content/guide/http-security-xsrf-protection.md',
'aio/content/guide/http-send-data-to-server.md',
'aio/content/guide/http-server-communication.md',
'aio/content/guide/http-setup-server-communication.md',
'aio/content/guide/http-test-requests.md',
'aio/content/guide/http-track-show-request-progress.md',
'aio/content/examples/http/**/{*,.*}',
'aio/content/images/guide/http/**/{*,.*}'
])
reviewers:
users:
@@ -427,9 +242,6 @@ groups:
- >
contains_any_globs(files, [
'packages/elements/**/{*,.*}',
'aio/content/examples/elements/**/{*,.*}',
'aio/content/images/guide/elements/**/{*,.*}',
'aio/content/guide/elements.md'
])
reviewers:
users:
@@ -451,22 +263,6 @@ groups:
contains_any_globs(files, [
'packages/forms/**/{*,.*}',
'packages/examples/forms/**/{*,.*}',
'aio/content/guide/forms.md',
'aio/content/examples/forms/**/{*,.*}',
'aio/content/images/guide/forms/**/{*,.*}',
'aio/content/guide/forms-overview.md',
'aio/content/examples/forms-overview/**/{*,.*}',
'aio/content/images/guide/forms-overview/**/{*,.*}',
'aio/content/guide/form-validation.md',
'aio/content/guide/typed-forms.md',
'aio/content/examples/form-validation/**/{*,.*}',
'aio/content/images/guide/form-validation/**/{*,.*}',
'aio/content/guide/dynamic-form.md',
'aio/content/examples/dynamic-form/**/{*,.*}',
'aio/content/images/guide/dynamic-form/**/{*,.*}',
'aio/content/guide/reactive-forms.md',
'aio/content/examples/reactive-forms/**/{*,.*}',
'aio/content/images/guide/reactive-forms/**/{*,.*}'
])
reviewers:
users:
@@ -495,21 +291,6 @@ groups:
'packages/compiler/src/render3/view/i18n/**/{*,.*}',
'packages/compiler-cli/src/extract_i18n.ts',
'packages/localize/**/{*,.*}',
'aio/content/guide/i18n-overview.md',
'aio/content/guide/i18n-common-overview.md',
'aio/content/guide/i18n-common-add-package.md',
'aio/content/guide/i18n-common-locale-id.md',
'aio/content/guide/i18n-common-format-data-locale.md',
'aio/content/guide/i18n-common-prepare.md',
'aio/content/guide/i18n-common-translation-files.md',
'aio/content/guide/i18n-common-merge.md',
'aio/content/guide/i18n-common-deploy.md',
'aio/content/guide/i18n-example.md',
'aio/content/guide/i18n-optional-overview.md',
'aio/content/guide/i18n-optional-manual-runtime-locale.md',
'aio/content/guide/i18n-optional-import-global-variants.md',
'aio/content/guide/i18n-optional-manage-marked-text.md',
'aio/content/examples/i18n/**/{*,.*}'
])
reviewers:
users:
@@ -525,9 +306,6 @@ groups:
- >
contains_any_globs(files, [
'packages/platform-server/**/{*,.*}',
'aio/content/guide/prerendering.md',
'aio/content/guide/ssr.md',
'aio/content/examples/ssr/**/{*,.*}',
])
reviewers:
users:
@@ -549,16 +327,6 @@ groups:
contains_any_globs(files, [
'packages/router/**/{*,.*}',
'packages/examples/router/**/{*,.*}',
'aio/content/guide/router.md',
'aio/content/guide/router-tutorial.md',
'aio/content/guide/router-tutorial-toh.md',
'aio/content/guide/routing-overview.md',
'aio/content/guide/router-reference.md',
'aio/content/examples/router-tutorial/**/{*,.*}',
'aio/content/examples/router/**/{*,.*}',
'aio/content/images/guide/router/**/{*,.*}',
'aio/content/guide/routing-with-urlmatcher.md',
'aio/content/examples/routing-with-urlmatcher/**/{*,.*}'
])
reviewers:
users:
@@ -575,15 +343,6 @@ groups:
contains_any_globs(files, [
'packages/service-worker/**/{*,.*}',
'packages/examples/service-worker/**/{*,.*}',
'aio/content/guide/service-worker-getting-started.md',
'aio/content/examples/service-worker-getting-started/**/{*,.*}',
'aio/content/guide/app-shell.md',
'aio/content/guide/service-worker-communications.md',
'aio/content/guide/service-worker-config.md',
'aio/content/guide/service-worker-devops.md',
'aio/content/guide/service-worker-intro.md',
'aio/content/guide/service-worker-notifications.md',
'aio/content/images/guide/service-worker/**/{*,.*}'
])
reviewers:
users:
@@ -600,17 +359,6 @@ groups:
'packages/upgrade/**/{*,.*}',
'packages/common/upgrade/**/{*,.*}',
'packages/examples/upgrade/**/{*,.*}',
'aio/content/guide/upgrade.md',
'aio/content/examples/upgrade-lazy-load-ajs/**/{*,.*}',
'aio/content/examples/upgrade-module/**/{*,.*}',
'aio/content/images/guide/upgrade/**/{*,.*}',
'aio/content/examples/upgrade-phonecat-1-typescript/**/{*,.*}',
'aio/content/examples/upgrade-phonecat-2-hybrid/**/{*,.*}',
'aio/content/examples/upgrade-phonecat-3-final/**/{*,.*}',
'aio/content/guide/upgrade-performance.md',
'aio/content/guide/upgrade-setup.md',
'aio/content/guide/ajs-quick-reference.md',
'aio/content/examples/ajs-quick-reference/**/{*,.*}'
])
reviewers:
users:
@@ -626,17 +374,6 @@ groups:
- >
contains_any_globs(files.exclude('packages/compiler-cli/*').exclude('packages/language-service/*').exclude('packages/service-worker/*'), [
'packages/**/testing/**/{*,.*}',
'aio/content/guide/testing.md',
'aio/content/guide/test-debugging.md',
'aio/content/guide/testing-attribute-directives.md',
'aio/content/guide/testing-code-coverage.md',
'aio/content/guide/testing-components-basics.md',
'aio/content/guide/testing-components-scenarios.md',
'aio/content/guide/testing-pipes.md',
'aio/content/guide/testing-services.md',
'aio/content/guide/testing-utility-apis.md',
'aio/content/examples/testing/**/{*,.*}',
'aio/content/images/guide/testing/**/{*,.*}'
])
reviewers:
users:
@@ -700,9 +437,6 @@ groups:
'packages/tsconfig-tsec-base.json',
'packages/tsec-exemption.json',
'tools/tsec.bzl',
'aio/content/guide/security.md',
'aio/content/examples/security/**/{*,.*}',
'aio/content/images/guide/security/**/{*,.*}',
])
reviewers:
users:
@@ -739,13 +473,12 @@ groups:
- >
contains_any_globs(files, [
'packages/language-service/**/{*,.*}',
'aio/content/guide/language-service.md',
'aio/content/images/guide/language-service/**/{*,.*}'
])
reviewers:
users:
- alxhub
- atscott
- dylhunn
# =========================================================
# zone.js
@@ -756,7 +489,6 @@ groups:
- >
contains_any_globs(files, [
'packages/zone.js/**/{*,.*}',
'aio/content/guide/zone.md'
])
reviewers:
users:
@@ -815,106 +547,6 @@ groups:
- dylhunn
- thePunderWoman
- josephperrott
- pkozlowski-opensource
# =========================================================
# Docs: Contributors
# =========================================================
docs-contributors:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'aio/content/marketing/contributors.json',
'aio/content/images/bios/**/{*,.*}',
])
reviewers:
users:
- MarkTechson
- mgechev
- twerske
# =========================================================
# Docs: Gettings Started & Tutorial
# =========================================================
docs-getting-started-and-tutorial:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'aio/content/guide/setup-local.md',
'aio/content/images/guide/setup-local/**/{*,.*}',
'aio/content/tutorial/**/{*,.*}',
'aio/content/images/guide/toh/**/{*,.*}',
'aio/content/demos/first-app/**/{*,.*}',
'aio/content/examples/first-app-*/**/{*,.*}',
'aio/content/images/guide/faa/**/{*,.*}',
'aio/content/examples/toh-pt0/**/{*,.*}',
'aio/content/examples/toh-pt1/**/{*,.*}',
'aio/content/examples/toh-pt2/**/{*,.*}',
'aio/content/examples/toh-pt3/**/{*,.*}',
'aio/content/examples/toh-pt4/**/{*,.*}',
'aio/content/examples/toh-pt5/**/{*,.*}',
'aio/content/examples/toh-pt6/**/{*,.*}',
'aio/content/examples/getting-started-v0/**/{*,.*}',
'aio/content/examples/getting-started/**/{*,.*}',
'aio/content/start/**/{*,.*}',
'aio/content/guide/quick-start.md',
'aio/content/images/guide/start/**/{*,.*}',
'aio/content/examples/what-is-angular/**/{*,.*}',
'aio/content/guide/what-is-angular.md'
])
reviewers:
users:
- AndrewKushnir
- thePunderWoman
# =========================================================
# Docs: Marketing
# =========================================================
docs-marketing:
<<: *defaults
conditions:
- >
contains_any_globs(files.exclude("aio/content/marketing/contributors.json"), [
'aio/content/examples/marketing-first-app/**/{*,.*}',
'aio/content/guide/roadmap.md',
'aio/content/marketing/**/{*,.*}',
'aio/content/images/marketing/**/{*,.*}',
'aio/content/file-not-found.md',
'aio/content/license.md',
'aio/content/navigation.json'
])
reviewers:
users:
- MarkTechson
- mgechev
- twerske
# =========================================================
# Docs: Observables
# =========================================================
docs-observables:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'aio/content/guide/observables.md',
'aio/content/examples/observables/**/{*,.*}',
'aio/content/guide/comparing-observables.md',
'aio/content/examples/comparing-observables/**/{*,.*}',
'aio/content/guide/observables-in-angular.md',
'aio/content/examples/observables-in-angular/**/{*,.*}',
'aio/content/guide/practical-observable-usage.md',
'aio/content/examples/practical-observable-usage/**/{*,.*}',
'aio/content/guide/rx-library.md',
'aio/content/examples/rx-library/**/{*,.*}'
])
reviewers:
users:
- alxhub
- atscott
- dylhunn
# =========================================================
# Docs: Packaging, Tooling, Releasing
@@ -924,22 +556,7 @@ groups:
conditions:
- >
contains_any_globs(files, [
'docs/PUBLIC_API.md',
'docs/RELEASE_SCHEDULE.md',
'aio/content/guide/npm-packages.md',
'aio/content/guide/browser-support.md',
'aio/content/guide/releases.md',
'aio/content/guide/updating.md',
'aio/content/guide/deprecations.md',
'aio/content/examples/deprecation-guide/**/{*,.*}',
'aio/content/guide/migration-module-with-providers.md',
'aio/content/guide/static-query-migration.md',
'aio/content/guide/update-to-latest-version.md',
'aio/content/guide/versions.md',
'aio/content/guide/update-to-version-14.md',
'aio/content/guide/update-to-version-15.md',
'aio/content/guide/update-to-version-16.md',
'aio/content/guide/update-to-version-17.md',
'contributing-docs/public-api-surface.md',
])
reviewers:
users:
@@ -949,23 +566,6 @@ groups:
- thePunderWoman
- jelbourn
# =========================================================
# Docs: Angular DevTools
# =========================================================
docs-devtools:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'aio/content/guide/devtools.md',
'aio/content/images/guide/devtools/**/{*,.*}'
])
reviewers:
users:
- MarkTechson
- mgechev
- twerske
# =========================================================
# Tooling: Compiler API shared with Angular CLI
#
@@ -989,80 +589,6 @@ groups:
required: 2 # require at least 2 approvals
reviewed_for: required
# =========================================================
# Docs: CLI
# =========================================================
docs-cli:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'aio/content/cli/**/{*,.*}',
'aio/content/guide/typescript-configuration.md',
'aio/content/examples/setup/**/{*,.*}',
'aio/content/guide/build.md',
'aio/content/images/guide/build/**/{*,.*}',
'aio/content/images/guide/cli/**/{*,.*}',
'aio/content/guide/cli-builder.md',
'aio/content/examples/cli-builder/**/{*,.*}',
'aio/content/guide/deployment.md',
'aio/content/images/guide/deployment/**/{*,.*}',
'aio/content/guide/file-structure.md',
'aio/content/guide/ivy.md',
'aio/content/guide/strict-mode.md',
'aio/content/guide/web-worker.md',
'aio/content/guide/workspace-config.md',
'aio/content/guide/migration-solution-style-tsconfig.md',
'aio/content/guide/migration-update-libraries-tslib.md',
'aio/content/guide/esbuild.md',
])
reviewers:
users:
- alan-agius4
- clydin
- dgp1130
- mgechev
# =========================================================
# Docs: CLI Libraries
# =========================================================
docs-libraries:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'aio/content/examples/angular-linker-plugin/webpack.config.mjs',
'aio/content/guide/creating-libraries.md',
'aio/content/guide/libraries.md',
'aio/content/guide/using-libraries.md',
'aio/content/guide/angular-package-format.md'
])
reviewers:
users:
- alan-agius4
- alxhub
- mgechev
# =========================================================
# Docs: Schematics
# =========================================================
docs-schematics:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'aio/content/guide/schematics.md',
'aio/content/guide/schematics-authoring.md',
'aio/content/guide/schematics-for-libraries.md',
'aio/content/images/guide/schematics/**/{*,.*}',
'aio/content/examples/schematics-for-libraries/**/{*,.*}'
])
reviewers:
users:
- alan-agius4
- dylhunn
- mgechev
# =========================================================
# Docs: Angular Dev Site
# =========================================================
@@ -1088,65 +614,6 @@ groups:
- pkozlowski-opensource
- ~JeanMeche
# =========================================================
# Docs-infra
# =========================================================
docs-infra:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'aio/{*,.*}',
'aio/aio-builds-setup/**/{*,.*}',
'aio/content/cli-src/**/{*,.*}',
'aio/content/examples/{*,.*}',
'aio/scripts/**/{*,.*}',
'aio/src/**/{*,.*}',
'aio/tests/**/{*,.*}',
'aio/tools/**/{*,.*}',
'aio/tools/examples/shared/boilerplate/cli/.vscode/**/{*,.*}',
'aio/content/BUILD.bazel',
'aio/content/images/guide/contributors-guide/**/{*,.*}',
'aio/content/guide/contributors-guide-overview.md',
'aio/content/guide/docs-style-guide.md',
'aio/content/examples/docs-style-guide/**/{*,.*}',
'aio/content/images/guide/docs-style-guide/**/{*,.*}',
'aio/content/guide/docs-lint-errors.md',
'aio/content/images/guide/docs-lint-errors/**/{*,.*}',
'aio/content/guide/localized-documentation.md',
'aio/content/guide/localizing-angular.md',
'aio/content/guide/reviewing-content.md',
'aio/content/guide/updating-content-github-ui.md',
'aio/content/guide/updating-search-keywords.md',
'aio/content/guide/doc-build-test.md',
'aio/content/guide/doc-edit-finish.md',
'aio/content/guide/doc-editing.md',
'aio/content/guide/doc-github-tasks.md',
'aio/content/guide/doc-pr-open.md',
'aio/content/guide/doc-pr-prep.md',
'aio/content/guide/doc-pr-update.md',
'aio/content/guide/doc-prepare-to-edit.md',
'aio/content/guide/doc-select-issue.md',
'aio/content/guide/doc-tasks.md',
'aio/content/guide/doc-update-overview.md',
'aio/content/guide/doc-update-start.md',
'aio/content/guide/docs-lint-errors.md',
'aio/content/images/guide/preparing-to-edit-docs/**/{*,.*}',
'aio/content/images/guide/github-for-docs/**/{*,.*}',
'aio/content/images/guide/doc-update-start/**/{*,.*}',
'aio/content/images/guide/doc-update-overview/**/{*,.*}',
'aio/content/images/guide/doc-pr-update/**/{*,.*}',
'aio/content/images/guide/doc-pr-prep/**/{*,.*}',
'aio/content/images/guide/doc-pr-open/**/{*,.*}',
'aio/content/images/guide/doc-github-tasks/**/{*,.*}',
'aio/content/images/guide/doc-prepare-to-edit/**/{*,.*}',
])
reviewers:
users:
- AndrewKushnir
- thePunderWoman
- josephperrott
# =========================================================
# Angular DevTools
# =========================================================
@@ -1183,8 +650,8 @@ groups:
'.ng-dev/**/{*,.*}',
'.vscode/**/{*,.*}',
'.yarn/**/{*,.*}',
'docs/*.md',
'docs/images/**/{*,.*}',
'contributing-docs/*.md',
'contributing-docs/images/**/{*,.*}',
'goldens/{*,.*}',
'goldens/public-api/manage.js',
'modules/{*,.*}',
@@ -1229,12 +696,6 @@ groups:
- >
contains_any_globs(files.exclude("goldens/public-api/manage.js"), [
'goldens/public-api/**/{*,.*}',
'docs/NAMING.md',
'aio/content/guide/angular-package-format.md',
'aio/content/guide/glossary.md',
'aio/content/guide/styleguide.md',
'aio/content/examples/styleguide/**/{*,.*}',
'aio/content/images/guide/styleguide/{*,.*}'
])
reviewers:
users:
@@ -1245,6 +706,9 @@ groups:
- ~jelbourn
- thePunderWoman
- pkozlowski-opensource
- ~iteriani
- ~tbondwilkinson
- ~rahatarmanahmed
reviews:
request: 3 # Request reviews from 3 people
required: 2 # Require that 2 people approve
@@ -1342,9 +806,6 @@ groups:
- dylhunn # Dylan Hunn
- AndrewKushnir # Andrew Kushnir
- atscott # Andrew Scott
reviews:
required: 1
reviewed_for: optional
labels:
pending: 'requires: TGP'
approved: 'requires: TGP'
@@ -1369,14 +830,9 @@ groups:
- jesse-good # Jesse Costello-Good
- mturco # Matt Turco
- neonstalwart # Ben Hockey
- nicholasyu-google # Nicholas Yu
- emspishak # Eric Spishak-Thomas
- iteriani # Thomas Nguyen
- tbondwilkinson # Tom Wilkinson
- rahatarmanahmed # Rahat Ahmed
reviews:
required: 1
reviewed_for: optional
labels:
pending: 'requires: TGP'
approved: 'requires: TGP'
-2
View File
@@ -12,14 +12,12 @@
"**/node_modules/**": true,
"**/bazel-out/**": true,
"**/dist/**": true,
"**/aio/src/generated/**": true,
},
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/bazel-out": true,
"**/dist": true,
"**/aio/src/generated": true,
".history": true,
},
"git.ignoreLimitWarning": true,
-1
View File
@@ -67,7 +67,6 @@ nodejs_binary(
data = [".yarn/releases/yarn-1.22.19.cjs"],
entry_point = ".yarn/releases/yarn-1.22.19.cjs",
visibility = [
"//aio/tools/examples/shared:__pkg__",
"//integration:__subpackages__",
],
)
+464 -403
View File
@@ -1,19 +1,475 @@
<a name="18.0.0-rc.0"></a>
# 18.0.0-rc.0 (2024-05-01)
<a name="18.1.0"></a>
# 18.1.0 (2024-07-10)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [f25653e231](https://github.com/angular/angular/commit/f25653e2311152d30b14d25acb0dccb4e2b5ea56) | fix | typo in NgOptimizedImage warning ([#56756](https://github.com/angular/angular/pull/56756)) |
| [9b35726e42](https://github.com/angular/angular/commit/9b35726e42ebdeed138a25581e0a7eefff466206) | fix | typo in warning for NgOptimizedDirective ([#56817](https://github.com/angular/angular/pull/56817)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [fd6cd0422d](https://github.com/angular/angular/commit/fd6cd0422d2d761d2c6cc0cd41838fbba8a3f010) | feat | Add extended diagnostic to warn when there are uncalled functions in event bindings ([#56295](https://github.com/angular/angular/pull/56295)) |
| [341a116d61](https://github.com/angular/angular/commit/341a116d611c095ed414c82612adb529e7be310c) | fix | allow more characters in let declaration name ([#56764](https://github.com/angular/angular/pull/56764)) |
| [2a1291e942](https://github.com/angular/angular/commit/2a1291e942a3cd645ee635e72e7d83722383d39b) | fix | give precedence to local let declarations over parent ones ([#56752](https://github.com/angular/angular/pull/56752)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [66e582551e](https://github.com/angular/angular/commit/66e582551eb081e422e0df41badce1821c46dc62) | fix | avoid duplicate diagnostics for let declarations read before definition ([#56843](https://github.com/angular/angular/pull/56843)) |
| [4d18c5bfd5](https://github.com/angular/angular/commit/4d18c5bfd54c53655955c8cd90472081ade40b34) | fix | flag all conflicts between let declarations and local symbols ([#56752](https://github.com/angular/angular/pull/56752)) |
| [9e21582456](https://github.com/angular/angular/commit/9e215824565f0d30da7edb20087c4460069a6660) | fix | Show template syntax errors in local compilation modified ([#55855](https://github.com/angular/angular/pull/55855)) |
| [5996502921](https://github.com/angular/angular/commit/599650292107f8856c7cd41791bd0856f9d14eb1) | fix | type check let declarations nested inside nodes ([#56752](https://github.com/angular/angular/pull/56752)) |
| [cdebf751e4](https://github.com/angular/angular/commit/cdebf751e4949048b01acc92de2517f46fcd5d37) | fix | used before declared diagnostic not firing for control flow blocks ([#56843](https://github.com/angular/angular/pull/56843)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [44c0ed83a6](https://github.com/angular/angular/commit/44c0ed83a6499fa96f65a27bc5c926579c06b6d2) | fix | hide implementation details of ExperimentalPendingTasks ([#55516](https://github.com/angular/angular/pull/55516)) |
| [a177abef1b](https://github.com/angular/angular/commit/a177abef1b0a0edc46dcca2d8c5c67669c55ff8f) | fix | render hooks should not specifically run outside the Angular zone ([#55399](https://github.com/angular/angular/pull/55399)) |
| [a5c57c7484](https://github.com/angular/angular/commit/a5c57c7484f1dc3afab4ece4e969a4a7308cdeca) | fix | resolve error for multiple component instances that use fallback content ([#55478](https://github.com/angular/angular/pull/55478)) |
### migrations
| [ea3c802056](https://github.com/angular/angular/commit/ea3c80205653af109c688a4d4808143b34591d54) | feat | Add a schematic to migrate afterRender phase flag ([#55648](https://github.com/angular/angular/pull/55648)) |
| [5df3e78c99](https://github.com/angular/angular/commit/5df3e78c9907f522f2f96c087b10ca12d57f7028) | feat | add equality function to rxjs-interop `toSignal` ([#56447](https://github.com/angular/angular/pull/56447)) |
| [0a48d584f2](https://github.com/angular/angular/commit/0a48d584f2ffeebb9402032182d4fc13a260c5cf) | feat | add support for let syntax ([#56715](https://github.com/angular/angular/pull/56715)) |
| [352e0782ec](https://github.com/angular/angular/commit/352e0782ec37d2adcc662cfc69c83d38058a34bf) | feat | expose signal input metadata in `ComponentMirror` ([#56402](https://github.com/angular/angular/pull/56402)) |
| [a655e46447](https://github.com/angular/angular/commit/a655e46447962bf56bf0184e3104328b9f7c1531) | feat | Redesign the `afterRender` & `afterNextRender` phases API ([#55648](https://github.com/angular/angular/pull/55648)) |
| [e5a6f91722](https://github.com/angular/angular/commit/e5a6f917225aafa7c5c860f280d2aafe3615727e) | feat | support TypeScript 5.5 ([#56096](https://github.com/angular/angular/pull/56096)) |
| [38effcc63e](https://github.com/angular/angular/commit/38effcc63eea360e948dc22860add72d3aa02288) | fix | Add back phase flag option as a deprecated API ([#55648](https://github.com/angular/angular/pull/55648)) |
| [86bcfd3e49](https://github.com/angular/angular/commit/86bcfd3e498b8ec1de1a2a1ad0847fe567f7e9d4) | fix | improve docs on afterRender hooks ([#56522](https://github.com/angular/angular/pull/56522)) |
| [b2445a0953](https://github.com/angular/angular/commit/b2445a095314aa66da038d3093e6a1b18fe5768b) | fix | link errors to ADEV ([#55554](https://github.com/angular/angular/pull/55554)) ([#56038](https://github.com/angular/angular/pull/56038)) |
| [03a2acd2a3](https://github.com/angular/angular/commit/03a2acd2a3bdc87aaeb6b835a7c1016f800b31cb) | fix | properly remove imports in the afterRender phase migration ([#56524](https://github.com/angular/angular/pull/56524)) |
| [4d87b9e899](https://github.com/angular/angular/commit/4d87b9e899381894a1de90f251da58613a96eed0) | fix | rename the equality function option in toSignal ([#56769](https://github.com/angular/angular/pull/56769)) ([#56922](https://github.com/angular/angular/pull/56922)) |
| [8bd4c074af](https://github.com/angular/angular/commit/8bd4c074afe85b739dff4d3c4dcc19384c42b85e) | fix | toSignal equal option should be passed to inner computed ([#56903](https://github.com/angular/angular/pull/56903)) |
### forms
| Commit | Type | Description |
| -- | -- | -- |
| [f93e5180be](https://github.com/angular/angular/commit/f93e5180be1e20a59ff68f12853653f4f3282846) | fix | resolve multiple structural issues with HttpClient migration ([#55557](https://github.com/angular/angular/pull/55557)) |
| [00bde8b1c2](https://github.com/angular/angular/commit/00bde8b1c2d1511da40526a374d4e94d31e0d575) | fix | Make `NgControlStatus` host bindings `OnPush` compatible ([#55720](https://github.com/angular/angular/pull/55720)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [cc21989132](https://github.com/angular/angular/commit/cc21989132bc64b981df83cb6ff6e1506b42a1d0) | fix | Make `Content-Type` header case insensitive ([#56541](https://github.com/angular/angular/pull/56541)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [b400e2e4d4](https://github.com/angular/angular/commit/b400e2e4d4c27a9c8d8e91b52852ef7b64f7591a) | feat | autocompletion for the component not imported ([#55595](https://github.com/angular/angular/pull/55595)) |
| [67b2c336bc](https://github.com/angular/angular/commit/67b2c336bc0bdce3f7ae054c094990a9831f5b20) | fix | import the default exported component correctly ([#56432](https://github.com/angular/angular/pull/56432)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [aefee87074](https://github.com/angular/angular/commit/aefee87074f4a5b2531f989a1876ace6e6616da4) | fix | Scroller should scroll as soon as change detection completes ([#55105](https://github.com/angular/angular/pull/55105)) |
| [a13f5da773](https://github.com/angular/angular/commit/a13f5da77303f4ab2f1543df1de1f416216b5a9c) | feat | Allow `UrlTree` as an input to `routerLink` ([#56265](https://github.com/angular/angular/pull/56265)) |
| [1d3a7529b4](https://github.com/angular/angular/commit/1d3a7529b4fa3617a5d6a97e742cb13818253a14) | feat | Set a different browser URL from the one for route matching ([#53318](https://github.com/angular/angular/pull/53318)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.5"></a>
# 18.0.5 (2024-06-26)
### core
| Commit | Type | Description |
| -- | -- | -- |
| [2f73281dfd](https://github.com/angular/angular/commit/2f73281dfd97fd254179770cbdbda5236f5f37fd) | fix | improve docs on afterRender hooks ([#56525](https://github.com/angular/angular/pull/56525)) |
| [be9e4892f9](https://github.com/angular/angular/commit/be9e4892f9d2e3dbc772b732a130f97d67cba965) | fix | improve support for i18n hydration of projected content ([#56192](https://github.com/angular/angular/pull/56192)) |
| [5f9bd5521e](https://github.com/angular/angular/commit/5f9bd5521eaadb4106c43eb2f8e7ac25777e9ea6) | fix | prevent calling devMode only function on `@defer` error. ([#56559](https://github.com/angular/angular/pull/56559)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.4"></a>
# 18.0.4 (2024-06-20)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [ec0d1bf6f3](https://github.com/angular/angular/commit/ec0d1bf6f337fc4f2c29cacaa6ca5b915eb4e561) | fix | insert constant statements after the first group of imports ([#56431](https://github.com/angular/angular/pull/56431)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [83ffa94783](https://github.com/angular/angular/commit/83ffa9478372db3e5dd2d256d266a5612008da0a) | fix | do not activate event replay when no events are registered ([#56509](https://github.com/angular/angular/pull/56509)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [5578681da2](https://github.com/angular/angular/commit/5578681da27345b0c8260eb5d73e702d19581abd) | fix | Delay the view transition to ensure renders in microtasks complete ([#56494](https://github.com/angular/angular/pull/56494)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.3"></a>
# 18.0.3 (2024-06-12)
### benchpress
| Commit | Type | Description |
| -- | -- | -- |
| [ebf00aa0659](https://github.com/angular/angular/commit/ebf00aa06592a966b72c81ff4ca09c6ef1344a20) | fix | adjust supported browser names for headless chrome ([#56360](https://github.com/angular/angular/pull/56360)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [dbd0fa00f8c](https://github.com/angular/angular/commit/dbd0fa00f8c742a9b804ce2a96a0add552a179dd) | fix | async EventEmitter should contribute to app stability ([#56308](https://github.com/angular/angular/pull/56308)) |
| [625ca3e2b3f](https://github.com/angular/angular/commit/625ca3e2b3f04fb770ecbef03a9a4151c54e201b) | fix | signals should be tracked when embeddedViewRef.detectChanges is called ([#55719](https://github.com/angular/angular/pull/55719)) |
### localize
| Commit | Type | Description |
| -- | -- | -- |
| [d6dd3dbdb09](https://github.com/angular/angular/commit/d6dd3dbdb09da956a7c7c95187ae29347568b2e9) | fix | add `@angular/localize/init` as polyfill in `angular.json` ([#56300](https://github.com/angular/angular/pull/56300)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [c07e1b33569](https://github.com/angular/angular/commit/c07e1b335695ce8e5402e7d7ad7810ccd472b224) | fix | resolve error in standalone migration ([#56302](https://github.com/angular/angular/pull/56302)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.2"></a>
# 18.0.2 (2024-06-05)
### core
| Commit | Type | Description |
| -- | -- | -- |
| [78cf9bfc0e](https://github.com/angular/angular/commit/78cf9bfc0eb1e78c1f6d3a562e65982579698896) | fix | Do not migrate `HttpClientModule` imports on components. ([#56067](https://github.com/angular/angular/pull/56067)) |
| [616cdef474](https://github.com/angular/angular/commit/616cdef4748d5112460cf58200832585856777d6) | fix | don't coerce all producers to consumers on liveness change ([#56140](https://github.com/angular/angular/pull/56140)) |
| [2a440e1064](https://github.com/angular/angular/commit/2a440e1064bddc839df91dbe77fc27bb8bd15641) | fix | Fix shouldPreventDefaultBeforeDispatching bug ([#56188](https://github.com/angular/angular/pull/56188)) |
| [290a47d842](https://github.com/angular/angular/commit/290a47d8427f4854234cb2b4244871eaf1f82c19) | fix | handle missing `withI18nSupport()` call for components that use i18n blocks ([#56175](https://github.com/angular/angular/pull/56175)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [b70b80ba55](https://github.com/angular/angular/commit/b70b80ba55ff16a5dd10e07c7120b0d3aecd5d2d) | fix | do not generate aliased variables with the same name ([#56154](https://github.com/angular/angular/pull/56154)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.1"></a>
# 18.0.1 (2024-05-29)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [419ffa2026](https://github.com/angular/angular/commit/419ffa20265e4b9b5b1d92045ec40f59f5c4de2e) | fix | optimize track function that only passes $index ([#55872](https://github.com/angular/angular/pull/55872)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [4c7efc005a](https://github.com/angular/angular/commit/4c7efc005a8d0d343f437007740254b1d35c718b) | fix | interpolatedSignalNotInvoked diagnostic for class, style, attribute and animation bindings ([#55969](https://github.com/angular/angular/pull/55969)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [4e6ea0e19c](https://github.com/angular/angular/commit/4e6ea0e19c52c9aceb635accb379572c78a457da) | fix | handle elements with local refs in event replay serialization logic ([#56076](https://github.com/angular/angular/pull/56076)) |
| [d73a0175cb](https://github.com/angular/angular/commit/d73a0175cb2d8c74e6bb877dc30eec07fd484fff) | fix | link errors to ADEV ([#55554](https://github.com/angular/angular/pull/55554)) |
| [985a215b10](https://github.com/angular/angular/commit/985a215b102be2a58dd4d13e1c05399f58f3078e) | fix | typo in zoneless warning ([#55974](https://github.com/angular/angular/pull/55974)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [ba85d08158](https://github.com/angular/angular/commit/ba85d081583277a5b7a04bc349a3a8d528467c52) | fix | handle empty ngSwitchCase ([#56105](https://github.com/angular/angular/pull/56105)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.10"></a>
# 17.3.10 (2024-05-22)
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0"></a>
# 18.0.0 (2024-05-22)
[Blog post "Angular v18 is now available"](http://goo.gle/angular-v18).
## Breaking Changes
### animations
- Deprecated `matchesElement` method has been removed from `AnimationDriver` as it is unused.
### common
- The deprecated `isPlatformWorkerUi` and `isPlatformWorkerApp` have been removed without replacement, as they serve no purpose since the removal of the WebWorker platform.
### compiler
- Angular only supports writable expressions inside of two-way bindings.
### compiler-cli
- * Angular no longer supports TypeScript versions older than 5.4.
### core
- `OnPush` views at the root of the application need to
be marked dirty for their host bindings to refresh. Previously, the host
bindings were refreshed for all root views without respecting the
`OnPush` change detection strategy.
- `OnPush` views at the root of the application need to
be marked dirty for their host bindings to refresh. Previously, the host
bindings were refreshed for all root views without respecting the
`OnPush` change detection strategy.
- The `ComponentFixture` `autoDetect` feature will no
longer refresh the component's host view when the component is `OnPush`
and not marked dirty. This exposes existing issues in components which
claim to be `OnPush` but do not correctly call `markForCheck` when they
need to be refreshed. If this change causes test failures, the easiest
fix is to change the component to `ChangeDetectionStrategy.Default`.
- `ComponentFixture.whenStable` now matches the
`ApplicationRef.isStable` observable. Prior to this change, stability
of the fixture did not include everything that was considered in
`ApplicationRef`. `whenStable` of the fixture will now include unfinished
router navigations and unfinished `HttpClient` requests. This will cause
tests that `await` the `whenStable` promise to time out when there are
incomplete requests. To fix this, remove the `whenStable`,
instead wait for another condition, or ensure `HttpTestingController`
mocks responses for all requests. Try adding `HttpTestingController.verify()`
before your `await fixture.whenStable` to identify the open requests.
Also, make sure your tests wait for the stability promise. We found many
examples of tests that did not, meaning the expectations did not execute
within the test body.
In addition, `ComponentFixture.isStable` would synchronously switch to
true in some scenarios but will now always be asynchronous.
- Angular will ensure change detection runs, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior.
This change will be more likely to impact existing unit tests.
This should usually be seen as more correct and the test should be updated,
but in cases where it is too much effort to debug, the test can revert to the old behavior by adding
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the `TestBed` providers.
Similarly, applications which may want to update state outside the zone
and _not_ trigger change detection can add
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the providers in `bootstrapApplication` or add
`schedulingMode: NgZoneSchedulingMode.NgZoneOnly` to the
`BootstrapOptions` of `bootstrapModule`.
- When Angular runs change detection, it will continue to
refresh any views attached to `ApplicationRef` that are still marked for
check after one round completes. In rare cases, this can result in infinite
loops when certain patterns continue to mark views for check using
`ChangeDetectorRef.detectChanges`. This will be surfaced as a runtime
error with the `NG0103` code.
- `async` has been removed, use `waitForAsync` instead.
- The `ComponentFixture.autoDetect` feature now executes
change detection for the fixture within `ApplicationRef.tick`. This more
closely matches the behavior of how a component would refresh in
production. The order of component refresh in tests may be slightly
affected as a result, especially when dealing with additional components
attached to the application, such as dialogs. Tests sensitive to this
type of change (such as screenshot tests) may need to be updated.
Concretely, this change means that the component will refresh _before_
additional views attached to `ApplicationRef` (i.e. dialog components).
Prior to this change, the fixture component would refresh _after_ other
views attached to the application.
- The exact timing of change detection execution when
using event or run coalescing with `NgZone` is now the first of either
`setTimeout` or `requestAnimationFrame`. Code which relies on this
timing (usually by accident) will need to be adjusted. If a callback
needs to execute after change detection, we recommend `afterNextRender`
instead of something like `setTimeout`.
- Newly created and views marked for check and reattached
during change detection are now guaranteed to be refreshed in that same
change detection cycle. Previously, if they were attached at a location
in the view tree that was already checked, they would either throw
`ExpressionChangedAfterItHasBeenCheckedError` or not be refreshed until
some future round of change detection. In rare circumstances, this
correction can cause issues. We identified one instance that relied on
the previous behavior by reading a value on initialization which was
queued to be updated in a microtask instead of being available in the
current change detection round. The component only read this value during
initialization and did not read it again after the microtask updated it.
- Testability methods `increasePendingRequestCount`,
`decreasePendingRequestCount` and `getPendingRequestCount` have been
removed. This information is tracked with zones.
### http
- By default we now prevent caching of HTTP requests that require authorization . To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`.
Example:
```ts
withHttpTransferCache({
includeRequestsWithAuthHeaders: true,
})
```
### platform-browser
- Deprecated `StateKey`, `TransferState` and `makeStateKey` have been removed from `@angular/platform-browser`, use the same APIs from `@angular/core`.
### platform-browser-dynamic
- No longer used `RESOURCE_CACHE_PROVIDER` APIs have been removed.
### platform-server
- deprecated `platformDynamicServer` has been removed. Add an `import @angular/compiler` and replace the usage with `platformServer`
- deprecated `ServerTransferStateModule` has been removed. `TransferState` can be use without providing this module.
- deprecated `useAbsoluteUrl` and `baseUrl` been removed from `PlatformConfig`. Provide and absolute `url` instead.
- Legacy handling or Node.js URL parsing has been removed from `ServerPlatformLocation`.
The main differences are;
- `pathname` is always suffixed with a `/`.
- `port` is empty when `http:` protocol and port in url is `80`
- `port` is empty when `https:` protocol and port in url is `443`
### router
- Guards can now return `RedirectCommand` for redirects
in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree`
values in `Route` types will need to be adjusted.
- This change allows `Route.redirectTo` to be a function
in addition to the previous string. Code which expects `redirectTo` to
only be a string on `Route` objects will need to be adjusted.
- When a a guard returns a `UrlTree` as a redirect, the
redirecting navigation will now use `replaceUrl` if the initial
navigation was also using the `replaceUrl` option. If this is not
desirable, the redirect can configure new `NavigationBehaviorOptions` by
returning a `RedirectCommand` with the desired options instead of `UrlTree`.
- Providers available to the routed components always
come from the injector heirarchy of the routes and never inherit from
the `RouterOutlet`. This means that providers available only to the
component that defines the `RouterOutlet` will no longer be available to
route components in any circumstances. This was already the case
whenever routes defined providers, either through lazy loading an
`NgModule` or through explicit `providers` on the route config.
- Providers available to the routed components always
come from the injector heirarchy of the routes and never inherit from
the `RouterOutlet`. This means that providers available only to the
component that defines the `RouterOutlet` will no longer be available to
route components in any circumstances. This was already the case
whenever routes defined providers, either through lazy loading an
`NgModule` or through explicit `providers` on the route config.
## Deprecations
### common
- `getCurrencySymbol`, `getLocaleCurrencyCode`, `getLocaleCurrencyName`, `getLocaleCurrencySymbol`, `getLocaleDateFormat`, `getLocaleDateTimeFormat`, `getLocaleDayNames`, `getLocaleDayPeriods`, `getLocaleDirection`, `getLocaleEraNames`, `getLocaleExtraDayPeriodRules`, `getLocaleExtraDayPeriods`, `getLocaleFirstDayOfWeek`, `getLocaleId`, `getLocaleMonthNames`, `getLocaleNumberFormat`, `getLocaleNumberSymbol`, `getLocalePluralCase`, `getLocaleTimeFormat`, `getLocaleWeekEndRange`, `getNumberOfCurrencyDigits`
### core
- `@Component.interpolation` is deprecated. Use Angular's
delimiters instead.
### http
- `HttpClientModule`, `HttpClientXsrfModule` and `HttpClientJsonpModule`
As mentionned, those modules can be replaced by provider function only.
### animations
| Commit | Type | Description |
| -- | -- | -- |
| [bcce85af72](https://github.com/angular/angular/commit/bcce85af72a82634f60b31d66a5ef42ecd844ce8) | refactor | remove deprecated `matchesElement` from `AnimationDriver` ([#55479](https://github.com/angular/angular/pull/55479)) |
### common
| Commit | Type | Description |
| -- | -- | -- |
| [d34c033902](https://github.com/angular/angular/commit/d34c033902b4e7543796de6c57d0cfd09093eb43) | refactor | Deprecate Local Data API functions ([#54483](https://github.com/angular/angular/pull/54483)) |
| [3b0de30b37](https://github.com/angular/angular/commit/3b0de30b37f558d4815ca9a61db1010aaf3df068) | refactor | remove deprecated `isPlatformWorkerApp` and `isPlatformWorkerUi` API ([#55302](https://github.com/angular/angular/pull/55302)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [91b007e58f](https://github.com/angular/angular/commit/91b007e58ffb91f7c396cbc0333a91d18f02bd27) | fix | add math elements to schema ([#55631](https://github.com/angular/angular/pull/55631)) |
| [33d0102304](https://github.com/angular/angular/commit/33d0102304e2213ee0af0bc86028a4f564c81ed4) | fix | allow comments between connected blocks ([#55966](https://github.com/angular/angular/pull/55966)) |
| [7fc7f3f05f](https://github.com/angular/angular/commit/7fc7f3f05f0139dd773032fd5ad308f8d2a9fcf5) | fix | capture all control flow branches for content projection in if blocks ([#54921](https://github.com/angular/angular/pull/54921)) |
| [a369f43fbd](https://github.com/angular/angular/commit/a369f43fbdf45456bbae1caf71ef7becd15d1e90) | fix | capture switch block cases for content projection ([#54921](https://github.com/angular/angular/pull/54921)) |
| [eb625d3783](https://github.com/angular/angular/commit/eb625d37839c3b9f20a2ffb3af06426f9910c8ac) | fix | declare for loop aliases in addition to new name ([#54942](https://github.com/angular/angular/pull/54942)) |
| [f824911510](https://github.com/angular/angular/commit/f8249115102204dbb957a0d292ed5342ea5108e9) | fix | For `FatalDiagnosticError`, hide the `message` field without affecting the emit ([#55160](https://github.com/angular/angular/pull/55160)) |
| [a040fb720a](https://github.com/angular/angular/commit/a040fb720af7db08b328a9f78511c9881f50482d) | fix | maintain multiline CSS selectors during CSS scoping ([#55509](https://github.com/angular/angular/pull/55509)) |
| [39624c6b12](https://github.com/angular/angular/commit/39624c6b129252af352c22c6d6f12ef153477bfc) | fix | output input flags as a literal ([#55215](https://github.com/angular/angular/pull/55215)) |
| [eba92cfa55](https://github.com/angular/angular/commit/eba92cfa55500f3558c02edd0aa348ae118794e0) | fix | prevent usage of reserved control flow symbol in custom interpolation context. ([#55809](https://github.com/angular/angular/pull/55809)) |
| [7d5bc1c628](https://github.com/angular/angular/commit/7d5bc1c62870d9c68e06eddec229a9b8988e92ee) | fix | remove container index from conditional instruction ([#55190](https://github.com/angular/angular/pull/55190)) |
| [4eb0165750](https://github.com/angular/angular/commit/4eb0165750d8c65812502343a70ef4cc35c725b9) | fix | remove support for unassignable expressions in two-way bindings ([#55342](https://github.com/angular/angular/pull/55342)) |
| [e1650e3b13](https://github.com/angular/angular/commit/e1650e3b13556ab09c919cfdf97913fa0291622c) | fix | throw error if item name and context variables conflict ([#55045](https://github.com/angular/angular/pull/55045)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [5bd188a394](https://github.com/angular/angular/commit/5bd188a394d30053099e2c83fe79136d590e5399) | feat | add partial compilation support for deferred blocks ([#54908](https://github.com/angular/angular/pull/54908)) |
| [b02b31a915](https://github.com/angular/angular/commit/b02b31a915333e680cf96de5d0f965a6e2639028) | feat | drop support for TypeScript older than 5.4 ([#54961](https://github.com/angular/angular/pull/54961)) |
| [78188e877a](https://github.com/angular/angular/commit/78188e877a4db8655bdd3dc5012b70b12a7234de) | fix | add diagnostic if initializer API is used outside of an initializer ([#54993](https://github.com/angular/angular/pull/54993)) |
| [69a83993b3](https://github.com/angular/angular/commit/69a83993b3772dd98cc10d3e12b0ca6c66293cf2) | fix | do not throw when retrieving TCB symbol for signal input with restricted access ([#55774](https://github.com/angular/angular/pull/55774)) |
| [4f4f41016e](https://github.com/angular/angular/commit/4f4f41016e897c3fab77ffc23fcfeddadaa782c1) | fix | dom property binding check in signal extended diagnostic ([#54324](https://github.com/angular/angular/pull/54324)) |
| [7a16d7e969](https://github.com/angular/angular/commit/7a16d7e969eaf5a9475ffdd21a4bf637ce523856) | fix | don't type check the bodies of control flow nodes in basic mode ([#55360](https://github.com/angular/angular/pull/55360)) |
| [8d93597a82](https://github.com/angular/angular/commit/8d93597a82860112a5398828745653a7e27dcef0) | fix | fix type narrowing of `@if` with aliases ([#55835](https://github.com/angular/angular/pull/55835)) |
| [9b424d7224](https://github.com/angular/angular/commit/9b424d7224db46edb16c81979c7e231d5e3db5e9) | fix | preserve original reference to non-deferrable dependency ([#54759](https://github.com/angular/angular/pull/54759)) |
| [694ba79cbf](https://github.com/angular/angular/commit/694ba79cbf7aaed1079b1fabf53ea446162fc933) | fix | report cases where initializer APIs are used in a non-directive class ([#54993](https://github.com/angular/angular/pull/54993)) |
| [6219341d26](https://github.com/angular/angular/commit/6219341d267ae7689299835b90f0afa0fe61e213) | fix | report errors when initializer APIs are used on private fields ([#54981](https://github.com/angular/angular/pull/54981)) |
| [c04ffb1fa6](https://github.com/angular/angular/commit/c04ffb1fa61f5164ee5eb7c05b7d76292042ff0b) | fix | use switch statements to narrow Angular switch blocks ([#55168](https://github.com/angular/angular/pull/55168)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [a730f09ae9](https://github.com/angular/angular/commit/a730f09ae9e729da79a3e0951e15e0139ef67713) | feat | Add a public API to establish events to be replayed and an attribute to mark an element with an event handler. ([#55356](https://github.com/angular/angular/pull/55356)) |
| [fdd560ea14](https://github.com/angular/angular/commit/fdd560ea14f2f35608e26102c7fac0471a634b3e) | feat | Add ability to configure zone change detection to use zoneless scheduler ([#55252](https://github.com/angular/angular/pull/55252)) |
| [bce5e2344f](https://github.com/angular/angular/commit/bce5e2344f312dc3a8a30d54e412958bd07180c1) | feat | Add build target for jsaction contract binary. ([#55319](https://github.com/angular/angular/pull/55319)) |
| [666d646575](https://github.com/angular/angular/commit/666d646575800e9326eebd513776f8e92b0357e9) | feat | Add event delegation library to queue up events and replay them when the application is ready ([#55121](https://github.com/angular/angular/pull/55121)) |
| [5f06ca8f55](https://github.com/angular/angular/commit/5f06ca8f5539ed208bae0b110887b5538ac4041f) | feat | add HOST_TAG_NAME token ([#54751](https://github.com/angular/angular/pull/54751)) |
| [a600a39d0c](https://github.com/angular/angular/commit/a600a39d0cf9bb8fc2b6786e6f31acb78b7acc6e) | feat | add support for fallback content in ng-content ([#54854](https://github.com/angular/angular/pull/54854)) |
| [146306a141](https://github.com/angular/angular/commit/146306a1417c378920d80a6d91fd847f22e407ab) | feat | add support for i18n hydration ([#54823](https://github.com/angular/angular/pull/54823)) |
| [f09c5a7bc4](https://github.com/angular/angular/commit/f09c5a7bc455a59aea133264cbf9fd9ef7509a7f) | feat | Add zoneless change detection provider as experimental ([#55329](https://github.com/angular/angular/pull/55329)) |
| [d28614b90e](https://github.com/angular/angular/commit/d28614b90eff835639747e8961fe61e874c44666) | feat | Modify EventType from an enum to an object. ([#55323](https://github.com/angular/angular/pull/55323)) |
| [ac863ded48](https://github.com/angular/angular/commit/ac863ded4818af3426ef5888c706a2bd8c79c0be) | feat | provide ExperimentalPendingTasks API ([#55487](https://github.com/angular/angular/pull/55487)) |
| [1ee9f32621](https://github.com/angular/angular/commit/1ee9f32621f6d72e8038a08f5ad4a0cfe8bd6a13) | feat | Synchronize changes from internal JSAction codebase. ([#55182](https://github.com/angular/angular/pull/55182)) |
| [d888da4606](https://github.com/angular/angular/commit/d888da460696ee74bb4c10a19ac49e3fa1948399) | fix | `ApplicationRef.tick` should respect OnPush for host bindings ([#53718](https://github.com/angular/angular/pull/53718)) |
| [64f870c12b](https://github.com/angular/angular/commit/64f870c12bae1ad66509f0d65f8d3e051aae6eaa) | fix | `ApplicationRef.tick` should respect OnPush for host bindings ([#53718](https://github.com/angular/angular/pull/53718)) ([#53718](https://github.com/angular/angular/pull/53718)) |
| [8cad4e8cbe](https://github.com/angular/angular/commit/8cad4e8cbe2baf20dae7b7ef1f4253a4940cbba0) | fix | `ComponentFixture` `autoDetect` respects `OnPush` flag of host view ([#54824](https://github.com/angular/angular/pull/54824)) |
| [658cf8c384](https://github.com/angular/angular/commit/658cf8c3840b637284a5bb6c9751226d24ccbf9f) | fix | `ComponentFixture` stability should match `ApplicationRef` ([#54949](https://github.com/angular/angular/pull/54949)) |
| [2fc11eae9e](https://github.com/angular/angular/commit/2fc11eae9ea65160866bf7ba46c10520ae9a141f) | fix | account for re-projected ng-content elements with fallback content ([#54854](https://github.com/angular/angular/pull/54854)) |
| [0cbd73c6e9](https://github.com/angular/angular/commit/0cbd73c6e9931dc4938054fc6f7831bdee2606a4) | fix | add warning when using zoneless but zone.js is still loaded ([#55769](https://github.com/angular/angular/pull/55769)) |
| [d5edfde6ee](https://github.com/angular/angular/commit/d5edfde6ee3d65bf7f938ecfeac9f30633f8731b) | fix | afterRender hooks registered outside change detection can mark views dirty ([#55623](https://github.com/angular/angular/pull/55623)) |
| [de7447d15e](https://github.com/angular/angular/commit/de7447d15ed964ae26f0dace4cb3b08f5cccb1c1) | fix | Angular should not ignore changes that happen outside the zone ([#55102](https://github.com/angular/angular/pull/55102)) |
| [ba8e465974](https://github.com/angular/angular/commit/ba8e46597435a827670f10b971b2c58f7033b180) | fix | Change Detection will continue to refresh views while marked for check ([#54734](https://github.com/angular/angular/pull/54734)) |
| [5a10f405d3](https://github.com/angular/angular/commit/5a10f405d315a28b9a000c669e9b1cb3fa24a7f1) | fix | complete the removal of deprecation `async` function ([#55491](https://github.com/angular/angular/pull/55491)) |
| [24bc0ed4f2](https://github.com/angular/angular/commit/24bc0ed4f2de47bd998338d73cba394fb45dd497) | fix | ComponentFixture autodetect should detect changes within ApplicationRef.tick ([#54733](https://github.com/angular/angular/pull/54733)) |
| [1c0ec56c46](https://github.com/angular/angular/commit/1c0ec56c462cf18fb38aae29858165a08b5a2a82) | fix | correctly project single-root content inside control flow ([#54921](https://github.com/angular/angular/pull/54921)) |
| [840c375255](https://github.com/angular/angular/commit/840c375255dc381674bb27746d9ababd14567c33) | fix | do not save point-in-time `setTimeout` and `rAF` references ([#55124](https://github.com/angular/angular/pull/55124)) |
| [10c5cdb49c](https://github.com/angular/angular/commit/10c5cdb49c51c95086febd37f4d88a9b944d7e1c) | fix | ensure change detection runs in a reasonable timeframe with zone coalescing ([#54578](https://github.com/angular/angular/pull/54578)) |
| [ad045efd4b](https://github.com/angular/angular/commit/ad045efd4b1565e01c14399998143538ebfbfd99) | fix | Ensure views marked for check are refreshed during change detection ([#54735](https://github.com/angular/angular/pull/54735)) |
| [69085ea26e](https://github.com/angular/angular/commit/69085ea26e11f372578999337b2d8f099600b630) | fix | error about provideExperimentalCheckNoChangesForDebug uses wrong name ([#55824](https://github.com/angular/angular/pull/55824)) |
| [0147e0b85a](https://github.com/angular/angular/commit/0147e0b85a4f1201b1ae5edaa0d2bc708a13673e) | fix | exhaustive checkNoChanges should only do a single pass ([#55839](https://github.com/angular/angular/pull/55839)) |
| [e02bcf89cf](https://github.com/angular/angular/commit/e02bcf89cf77c3118c649a7db68e66a78f16155c) | fix | Fix clearing of pending task in zoneless cleanup implementation ([#55074](https://github.com/angular/angular/pull/55074)) |
| [0cec9e4f9a](https://github.com/angular/angular/commit/0cec9e4f9a90ec59f0e9838dcbd82705b1709fc0) | fix | Fix null dereference error `addEvent` ([#55353](https://github.com/angular/angular/pull/55353)) |
| [44c0ed83a6](https://github.com/angular/angular/commit/44c0ed83a6499fa96f65a27bc5c926579c06b6d2) | fix | hide implementation details of ExperimentalPendingTasks ([#55516](https://github.com/angular/angular/pull/55516)) |
| [314112de99](https://github.com/angular/angular/commit/314112de99bb97475a0d8bdbddf84a3b3ce4a8fb) | fix | Prevent `markForCheck` during change detection from causing infinite loops ([#54900](https://github.com/angular/angular/pull/54900)) |
| [a5fa279b6e](https://github.com/angular/angular/commit/a5fa279b6e9f5ab4005d6d33107f0e1bb48d05de) | fix | prevent i18n hydration from cleaning projected nodes ([#54823](https://github.com/angular/angular/pull/54823)) |
| [6534c035c0](https://github.com/angular/angular/commit/6534c035c099b30987d6fd1346aea454b79cc79d) | fix | Remove deprecated Testability methods ([#53768](https://github.com/angular/angular/pull/53768)) |
| [a5c57c7484](https://github.com/angular/angular/commit/a5c57c7484f1dc3afab4ece4e969a4a7308cdeca) | fix | resolve error for multiple component instances that use fallback content ([#55478](https://github.com/angular/angular/pull/55478)) |
| [f44a5e4604](https://github.com/angular/angular/commit/f44a5e460491a29e5c0cad5577bade8347d52e11) | fix | support content projection and VCRs in i18n ([#54823](https://github.com/angular/angular/pull/54823)) |
| [0510930a25](https://github.com/angular/angular/commit/0510930a257e610460c875dbbc5566fd06547814) | fix | TestBed should not override NgZone from initTestEnvironment ([#55226](https://github.com/angular/angular/pull/55226)) |
| [e9a0c86766](https://github.com/angular/angular/commit/e9a0c86766ab15c896e026120f0c63c2fb1f9e04) | fix | TestBed should not override NgZone from initTestEnvironment ([#55226](https://github.com/angular/angular/pull/55226)) |
| [700c0520bb](https://github.com/angular/angular/commit/700c0520bb638952ba41a8d8260cf12afb078c0e) | fix | Update ApplicationRef.tick loop to only throw in dev mode ([#54848](https://github.com/angular/angular/pull/54848)) |
| [a99cb7ce5b](https://github.com/angular/angular/commit/a99cb7ce5b77a125ab660da8ebef23ecb158e2e3) | fix | zoneless scheduler should check if Zone is defined before accessing it ([#55118](https://github.com/angular/angular/pull/55118)) |
| [1fd63e9cff](https://github.com/angular/angular/commit/1fd63e9cff9159a8c10c35a0af43bc986e4e8e26) | refactor | deprecate `@Component.interpolation` ([#55778](https://github.com/angular/angular/pull/55778)) |
### forms
| Commit | Type | Description |
| -- | -- | -- |
| [1c736dc3b2](https://github.com/angular/angular/commit/1c736dc3b258a502360cda40b3a00c07102ccbf5) | feat | Unified Control State Change Events ([#54579](https://github.com/angular/angular/pull/54579)) |
| [61007dced0](https://github.com/angular/angular/commit/61007dced0f3396c40efcd2617c130633fb9837a) | fix | Add event for forms submitted & reset ([#55667](https://github.com/angular/angular/pull/55667)) |
| [2e27ca9ddf](https://github.com/angular/angular/commit/2e27ca9ddfc1f3f0387cd720071e85ff46f19db6) | fix | Allow canceled async validators to emit. ([#55134](https://github.com/angular/angular/pull/55134)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [6f88d80758](https://github.com/angular/angular/commit/6f88d8075895bd80592b1b7e0fba8202a58a5417) | feat | allow caching requests with different origins between server and client ([#55274](https://github.com/angular/angular/pull/55274)) |
| [8eacb6e4b9](https://github.com/angular/angular/commit/8eacb6e4b982a5aa23cfbf9078dc4e19d9466d73) | feat | exclude caching for authenticated HTTP requests ([#55034](https://github.com/angular/angular/pull/55034)) |
| [d9b339fdbc](https://github.com/angular/angular/commit/d9b339fdbc0f8d1e9bb7b1e4190e7d80e68542f9) | fix | resolve `withRequestsMadeViaParent` behavior with `withFetch` ([#55652](https://github.com/angular/angular/pull/55652)) |
| [ef665a40a5](https://github.com/angular/angular/commit/ef665a40a580ff4df79617084ac83738f28ae924) | refactor | Deprecate `HttpClientModule` & related modules ([#54020](https://github.com/angular/angular/pull/54020)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [6d1b82df32](https://github.com/angular/angular/commit/6d1b82df32049cfaba2f6a50b9639b6e3b722170) | fix | allow external projects to use provided compiler options ([#55035](https://github.com/angular/angular/pull/55035)) |
| [a48afe0d94](https://github.com/angular/angular/commit/a48afe0d9478aca314e68552f4af77f4123563cd) | fix | avoid generating TS syntactic diagnostics for templates ([#55091](https://github.com/angular/angular/pull/55091)) |
| [bd236cc150](https://github.com/angular/angular/commit/bd236cc150e1b21932612ecf91678be77a503d18) | fix | implement getDefinitionAtPosition for Angular templates ([#55269](https://github.com/angular/angular/pull/55269)) |
| [4166dfc1b6](https://github.com/angular/angular/commit/4166dfc1b62a83b60203bfe45a6d4aa7148a0b23) | fix | prevent underlying TS Service from handling template files ([#55003](https://github.com/angular/angular/pull/55003)) |
| [b7f2fd4739](https://github.com/angular/angular/commit/b7f2fd473988a561bfd032386d8955e90c8d91ed) | fix | use type-only import in plugin factory ([#55996](https://github.com/angular/angular/pull/55996)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [f914f6a362](https://github.com/angular/angular/commit/f914f6a3628847c06cbdde9c90cd417fb2f4c61f) | feat | Migration schematics for `HttpClientModule` ([#54020](https://github.com/angular/angular/pull/54020)) |
| [8459ee46cb](https://github.com/angular/angular/commit/8459ee46cba7f63966c41a2fb7199ec295a91cbb) | fix | handle more cases in HttpClientModule migration ([#55640](https://github.com/angular/angular/pull/55640)) |
| [c4b2f18709](https://github.com/angular/angular/commit/c4b2f18709076f8c400bd26226be37ae07e5e83d) | fix | migrate HttpClientTestingModule in test modules ([#55803](https://github.com/angular/angular/pull/55803)) |
| [bb4a4016a9](https://github.com/angular/angular/commit/bb4a4016a9a29a9c56342ee01d866b0c8a3fb419) | fix | preserve existing properties in HttpClientModule migration ([#55777](https://github.com/angular/angular/pull/55777)) |
| [f93e5180be](https://github.com/angular/angular/commit/f93e5180be1e20a59ff68f12853653f4f3282846) | fix | resolve multiple structural issues with HttpClient migration ([#55557](https://github.com/angular/angular/pull/55557)) |
### platform-browser
| Commit | Type | Description |
| -- | -- | -- |
| [45ae7a6b60](https://github.com/angular/angular/commit/45ae7a6b60019bd49b8a58122a0d5bcbda7e245b) | feat | add withI18nSupport() in developer preview ([#55130](https://github.com/angular/angular/pull/55130)) |
| [23f914f101](https://github.com/angular/angular/commit/23f914f1012545330f6a5aeed4e862bf0e66117b) | fix | Use the right namespace for mathML. ([#55622](https://github.com/angular/angular/pull/55622)) |
| [cba336d4f1](https://github.com/angular/angular/commit/cba336d4f1badd601b24a58fc51bde995f45682d) | refactor | remove deprecated transfer state APIs ([#55474](https://github.com/angular/angular/pull/55474)) |
### platform-browser-dynamic
| Commit | Type | Description |
| -- | -- | -- |
| [eb20c1a8b1](https://github.com/angular/angular/commit/eb20c1a8b18e2e080c856e3e1bf7bcd02f3bfd28) | refactor | unused `RESOURCE_CACHE_PROVIDER` API has been removed ([#54875](https://github.com/angular/angular/pull/54875)) |
### platform-server
| Commit | Type | Description |
| -- | -- | -- |
| [5674c644ab](https://github.com/angular/angular/commit/5674c644abf51ae8764befd3011742ff1febdf29) | fix | add `nonce` attribute to event record script ([#55495](https://github.com/angular/angular/pull/55495)) |
| [e71e869112](https://github.com/angular/angular/commit/e71e869112af1c0ee7a9dd64a963ad7af14a40e2) | fix | remove event dispatch script from HTML when hydration is disabled ([#55681](https://github.com/angular/angular/pull/55681)) |
| [07ac017731](https://github.com/angular/angular/commit/07ac017731f0e08ea3736f1f212093a28648a304) | refactor | remove deprecated `platformDynamicServer` API ([#54874](https://github.com/angular/angular/pull/54874)) |
| [e8b588d8b7](https://github.com/angular/angular/commit/e8b588d8b7fc014aaef99d4b0c1e4567b4aa195d) | refactor | remove deprecated `ServerTransferStateModule` API ([#54874](https://github.com/angular/angular/pull/54874)) |
| [3b1967ca64](https://github.com/angular/angular/commit/3b1967ca64479df9137b3ad7a0d04dbaff6496f4) | refactor | remove deprecated `useAbsoluteUrl` and `baseUrl` from `PlatformConfig` ([#54874](https://github.com/angular/angular/pull/54874)) |
| [2357d3566c](https://github.com/angular/angular/commit/2357d3566c4d18dc40cbda6644ed459ef7703893) | refactor | remove legacy URL handling logic ([#54874](https://github.com/angular/angular/pull/54874)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [4a42961393](https://github.com/angular/angular/commit/4a42961393b3abf40f34374df059d3959dadecc0) | feat | `withNavigationErrorHandler` can convert errors to redirects ([#55370](https://github.com/angular/angular/pull/55370)) |
| [8735af08b9](https://github.com/angular/angular/commit/8735af08b976b30cf236a83f9e8b64b5ff62e9f3) | feat | Add ability to return `UrlTree` with `NavigationBehaviorOptions` from guards ([#45023](https://github.com/angular/angular/pull/45023)) |
| [87f3f27f90](https://github.com/angular/angular/commit/87f3f27f9087d757e18e8e2a0f2fca6f2a2c7edf) | feat | Allow resolvers to return `RedirectCommand` ([#54556](https://github.com/angular/angular/pull/54556)) |
| [2b802587f2](https://github.com/angular/angular/commit/2b802587f27186baa493c1dd01f42d568b652f38) | feat | Allow Route.redirectTo to be a function which returns a string or UrlTree ([#52606](https://github.com/angular/angular/pull/52606)) |
| [60f1d681e0](https://github.com/angular/angular/commit/60f1d681e0ba66d3d94b0819f2c612f095c2d3d3) | fix | preserve replaceUrl when returning a urlTree from CanActivate ([#54042](https://github.com/angular/angular/pull/54042)) |
| [3839cfbb18](https://github.com/angular/angular/commit/3839cfbb18fcc70cae5a6ba4ba7676b1c4acf7a0) | fix | Routed components never inherit `RouterOutlet` `EnvironmentInjector` ([#54265](https://github.com/angular/angular/pull/54265)) |
| [da906fdafc](https://github.com/angular/angular/commit/da906fdafcbb302fa280a162d1c1f04369be2efa) | fix | Routed components never inherit `RouterOutlet` `EnvironmentInjector` ([#54265](https://github.com/angular/angular/pull/54265)) |
### service-worker
| Commit | Type | Description |
| -- | -- | -- |
| [3bc63eaaf3](https://github.com/angular/angular/commit/3bc63eaaf344712ac6de1c9618d4558d9443c848) | fix | avoid running CDs on `controllerchange` ([#54222](https://github.com/angular/angular/pull/54222)) |
| [e598634c10](https://github.com/angular/angular/commit/e598634c10a60936ec4199b221eca4e901220763) | fix | remove `controllerchange` listener when app is destroyed ([#55365](https://github.com/angular/angular/pull/55365)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.9"></a>
# 17.3.9 (2024-05-15)
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.8"></a>
# 17.3.8 (2024-05-08)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [c21b459ba6](https://github.com/angular/angular/commit/c21b459ba6520fd5835e23800338ac9c997fee91) | fix | add math elements to schema ([#55631](https://github.com/angular/angular/pull/55631)) ([#55645](https://github.com/angular/angular/pull/55645)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [3818436ebc](https://github.com/angular/angular/commit/3818436ebc649267bb39b976b6b567b7f2b06a64) | fix | don't schedule timer triggers on the server ([#55605](https://github.com/angular/angular/pull/55605)) |
<!-- CHANGELOG SPLIT MARKER -->
@@ -34,78 +490,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.6"></a>
# 18.0.0-next.6 (2024-04-25)
## Breaking Changes
### animations
- Deprecated `matchesElement` method has been removed from `AnimationDriver` as it is unused.
### core
- `async` has been removed, use `waitForAsync` instead.
### http
- By default we now prevent caching of HTTP requests that require authorization . To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`.
Example:
```ts
withHttpTransferCache({
includeRequestsWithAuthHeaders: true,
})
```
### platform-browser
- Deprecated `StateKey`, `TransferState` and `makeStateKey` have been removed from `@angular/platform-browser`, use the same APIs from `@angular/core`.
## Deprecations
### common
- `getCurrencySymbol`, `getLocaleCurrencyCode`, `getLocaleCurrencyName`, `getLocaleCurrencySymbol`, `getLocaleDateFormat`, `getLocaleDateTimeFormat`, `getLocaleDayNames`, `getLocaleDayPeriods`, `getLocaleDirection`, `getLocaleEraNames`, `getLocaleExtraDayPeriodRules`, `getLocaleExtraDayPeriods`, `getLocaleFirstDayOfWeek`, `getLocaleId`, `getLocaleMonthNames`, `getLocaleNumberFormat`, `getLocaleNumberSymbol`, `getLocalePluralCase`, `getLocaleTimeFormat`, `getLocaleWeekEndRange`, `getNumberOfCurrencyDigits`
### http
- `HttpClientModule`, `HttpClientXsrfModule` and `HttpClientJsonpModule`
As mentionned, those modules can be replaced by provider function only.
### animations
| Commit | Type | Description |
| -- | -- | -- |
| [bcce85af72](https://github.com/angular/angular/commit/bcce85af72a82634f60b31d66a5ef42ecd844ce8) | refactor | remove deprecated `matchesElement` from `AnimationDriver` ([#55479](https://github.com/angular/angular/pull/55479)) |
### common
| Commit | Type | Description |
| -- | -- | -- |
| [d34c033902](https://github.com/angular/angular/commit/d34c033902b4e7543796de6c57d0cfd09093eb43) | refactor | Deprecate Local Data API functions ([#54483](https://github.com/angular/angular/pull/54483)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [7a16d7e969](https://github.com/angular/angular/commit/7a16d7e969eaf5a9475ffdd21a4bf637ce523856) | fix | don't type check the bodies of control flow nodes in basic mode ([#55360](https://github.com/angular/angular/pull/55360)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [a730f09ae9](https://github.com/angular/angular/commit/a730f09ae9e729da79a3e0951e15e0139ef67713) | feat | Add a public API to establish events to be replayed and an attribute to mark an element with an event handler. ([#55356](https://github.com/angular/angular/pull/55356)) |
| [5f06ca8f55](https://github.com/angular/angular/commit/5f06ca8f5539ed208bae0b110887b5538ac4041f) | feat | add HOST_TAG_NAME token ([#54751](https://github.com/angular/angular/pull/54751)) |
| [ac863ded48](https://github.com/angular/angular/commit/ac863ded4818af3426ef5888c706a2bd8c79c0be) | feat | provide ExperimentalPendingTasks API ([#55487](https://github.com/angular/angular/pull/55487)) |
| [5a10f405d3](https://github.com/angular/angular/commit/5a10f405d315a28b9a000c669e9b1cb3fa24a7f1) | fix | complete the removal of deprecation `async` function ([#55491](https://github.com/angular/angular/pull/55491)) |
| [c175bca364](https://github.com/angular/angular/commit/c175bca36432b26851adb4ea9d850c2d07fba864) | fix | DeferBlockFixture.render should not wait for stability ([#55271](https://github.com/angular/angular/pull/55271)) |
| [9894278e71](https://github.com/angular/angular/commit/9894278e712a50079af87898a63e1d19a462d015) | fix | make `ActivatedRoute` inject correct instance inside `@defer` blocks ([#55374](https://github.com/angular/angular/pull/55374)) |
| [5948193e13](https://github.com/angular/angular/commit/5948193e1368eec86647b4c1c0b337a387b27087) | fix | skip defer timers on the server ([#55480](https://github.com/angular/angular/pull/55480)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [6f88d80758](https://github.com/angular/angular/commit/6f88d8075895bd80592b1b7e0fba8202a58a5417) | feat | allow caching requests with different origins between server and client ([#55274](https://github.com/angular/angular/pull/55274)) |
| [8eacb6e4b9](https://github.com/angular/angular/commit/8eacb6e4b982a5aa23cfbf9078dc4e19d9466d73) | feat | exclude caching for authenticated HTTP requests ([#55034](https://github.com/angular/angular/pull/55034)) |
| [ef665a40a5](https://github.com/angular/angular/commit/ef665a40a580ff4df79617084ac83738f28ae924) | refactor | Deprecate `HttpClientModule` & related modules ([#54020](https://github.com/angular/angular/pull/54020)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [f914f6a362](https://github.com/angular/angular/commit/f914f6a3628847c06cbdde9c90cd417fb2f4c61f) | feat | Migration schematics for `HttpClientModule` ([#54020](https://github.com/angular/angular/pull/54020)) |
### platform-browser
| Commit | Type | Description |
| -- | -- | -- |
| [cba336d4f1](https://github.com/angular/angular/commit/cba336d4f1badd601b24a58fc51bde995f45682d) | refactor | remove deprecated transfer state APIs ([#55474](https://github.com/angular/angular/pull/55474)) |
### platform-server
| Commit | Type | Description |
| -- | -- | -- |
| [5674c644ab](https://github.com/angular/angular/commit/5674c644abf51ae8764befd3011742ff1febdf29) | fix | add `nonce` attribute to event record script ([#55495](https://github.com/angular/angular/pull/55495)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [4a42961393](https://github.com/angular/angular/commit/4a42961393b3abf40f34374df059d3959dadecc0) | feat | `withNavigationErrorHandler` can convert errors to redirects ([#55370](https://github.com/angular/angular/pull/55370)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.6"></a>
# 17.3.6 (2024-04-25)
### core
@@ -117,83 +501,11 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.5"></a>
# 18.0.0-next.5 (2024-04-17)
## Breaking Changes
### common
- The deprecated `isPlatformWorkerUi` and `isPlatformWorkerApp` have been removed without replacement, as they serve no purpose since the removal of the WebWorker platform.
### compiler
- Angular only supports writable expressions inside of two-way bindings.
### core
- Angular will ensure change detection runs, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior.
This change will be more likely to impact existing unit tests.
This should usually be seen as more correct and the test should be updated,
but in cases where it is too much effort to debug, the test can revert to the old behavior by adding
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the `TestBed` providers.
Similarly, applications which may want to update state outside the zone
and _not_ trigger change detection can add
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the providers in `bootstrapApplication` or add
`schedulingMode: NgZoneSchedulingMode.NgZoneOnly` to the
`BootstrapOptions` of `bootstrapModule`.
- Testability methods `increasePendingRequestCount`,
`decreasePendingRequestCount` and `getPendingRequestCount` have been
removed. This information is tracked with zones.
### common
| Commit | Type | Description |
| -- | -- | -- |
| [3b0de30b37](https://github.com/angular/angular/commit/3b0de30b37f558d4815ca9a61db1010aaf3df068) | refactor | remove deprecated `isPlatformWorkerApp` and `isPlatformWorkerUi` API ([#55302](https://github.com/angular/angular/pull/55302)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [7d5bc1c628](https://github.com/angular/angular/commit/7d5bc1c62870d9c68e06eddec229a9b8988e92ee) | fix | remove container index from conditional instruction ([#55190](https://github.com/angular/angular/pull/55190)) |
| [4eb0165750](https://github.com/angular/angular/commit/4eb0165750d8c65812502343a70ef4cc35c725b9) | fix | remove support for unassignable expressions in two-way bindings ([#55342](https://github.com/angular/angular/pull/55342)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [fdd560ea14](https://github.com/angular/angular/commit/fdd560ea14f2f35608e26102c7fac0471a634b3e) | feat | Add ability to configure zone change detection to use zoneless scheduler ([#55252](https://github.com/angular/angular/pull/55252)) |
| [bce5e2344f](https://github.com/angular/angular/commit/bce5e2344f312dc3a8a30d54e412958bd07180c1) | feat | Add build target for jsaction contract binary. ([#55319](https://github.com/angular/angular/pull/55319)) |
| [f09c5a7bc4](https://github.com/angular/angular/commit/f09c5a7bc455a59aea133264cbf9fd9ef7509a7f) | feat | Add zoneless change detection provider as experimental ([#55329](https://github.com/angular/angular/pull/55329)) |
| [d28614b90e](https://github.com/angular/angular/commit/d28614b90eff835639747e8961fe61e874c44666) | feat | Modify EventType from an enum to an object. ([#55323](https://github.com/angular/angular/pull/55323)) |
| [1ee9f32621](https://github.com/angular/angular/commit/1ee9f32621f6d72e8038a08f5ad4a0cfe8bd6a13) | feat | Synchronize changes from internal JSAction codebase. ([#55182](https://github.com/angular/angular/pull/55182)) |
| [de7447d15e](https://github.com/angular/angular/commit/de7447d15ed964ae26f0dace4cb3b08f5cccb1c1) | fix | Angular should not ignore changes that happen outside the zone ([#55102](https://github.com/angular/angular/pull/55102)) |
| [0cec9e4f9a](https://github.com/angular/angular/commit/0cec9e4f9a90ec59f0e9838dcbd82705b1709fc0) | fix | Fix null dereference error `addEvent` ([#55353](https://github.com/angular/angular/pull/55353)) |
| [6534c035c0](https://github.com/angular/angular/commit/6534c035c099b30987d6fd1346aea454b79cc79d) | fix | Remove deprecated Testability methods ([#53768](https://github.com/angular/angular/pull/53768)) |
### service-worker
| Commit | Type | Description |
| -- | -- | -- |
| [3bc63eaaf3](https://github.com/angular/angular/commit/3bc63eaaf344712ac6de1c9618d4558d9443c848) | fix | avoid running CDs on `controllerchange` ([#54222](https://github.com/angular/angular/pull/54222)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.5"></a>
# 17.3.5 (2024-04-17)
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.4"></a>
# 18.0.0-next.4 (2024-04-10)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [2a6f809507](https://github.com/angular/angular/commit/2a6f80950756530d5fb1147addabcb31025b0a78) | fix | invalid ImageKit quality parameter ([#55193](https://github.com/angular/angular/pull/55193)) |
| [11705f58a7](https://github.com/angular/angular/commit/11705f58a77e9390163b0bc99439fb4c8928e531) | fix | skip transfer cache on client ([#55012](https://github.com/angular/angular/pull/55012)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [39624c6b12](https://github.com/angular/angular/commit/39624c6b129252af352c22c6d6f12ef153477bfc) | fix | output input flags as a literal ([#55215](https://github.com/angular/angular/pull/55215)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [bd236cc150](https://github.com/angular/angular/commit/bd236cc150e1b21932612ecf91678be77a503d18) | fix | implement getDefinitionAtPosition for Angular templates ([#55269](https://github.com/angular/angular/pull/55269)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.4"></a>
# 17.3.4 (2024-04-10)
### common
@@ -204,135 +516,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.3"></a>
# 18.0.0-next.3 (2024-04-03)
## Breaking Changes
### router
- Providers available to the routed components always
come from the injector heirarchy of the routes and never inherit from
the `RouterOutlet`. This means that providers available only to the
component that defines the `RouterOutlet` will no longer be available to
route components in any circumstances. This was already the case
whenever routes defined providers, either through lazy loading an
`NgModule` or through explicit `providers` on the route config.
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [f824911510](https://github.com/angular/angular/commit/f8249115102204dbb957a0d292ed5342ea5108e9) | fix | For `FatalDiagnosticError`, hide the `message` field without affecting the emit ([#55160](https://github.com/angular/angular/pull/55160)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [c04ffb1fa6](https://github.com/angular/angular/commit/c04ffb1fa61f5164ee5eb7c05b7d76292042ff0b) | fix | use switch statements to narrow Angular switch blocks ([#55168](https://github.com/angular/angular/pull/55168)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [666d646575](https://github.com/angular/angular/commit/666d646575800e9326eebd513776f8e92b0357e9) | feat | Add event delegation library to queue up events and replay them when the application is ready ([#55121](https://github.com/angular/angular/pull/55121)) |
| [146306a141](https://github.com/angular/angular/commit/146306a1417c378920d80a6d91fd847f22e407ab) | feat | add support for i18n hydration ([#54823](https://github.com/angular/angular/pull/54823)) |
| [840c375255](https://github.com/angular/angular/commit/840c375255dc381674bb27746d9ababd14567c33) | fix | do not save point-in-time `setTimeout` and `rAF` references ([#55124](https://github.com/angular/angular/pull/55124)) |
| [231e0a3528](https://github.com/angular/angular/commit/231e0a3528e152cb1de3a215d437f5104191445c) | fix | handle `ChainedInjector`s in injector debug utils ([#55144](https://github.com/angular/angular/pull/55144)) |
| [a5fa279b6e](https://github.com/angular/angular/commit/a5fa279b6e9f5ab4005d6d33107f0e1bb48d05de) | fix | prevent i18n hydration from cleaning projected nodes ([#54823](https://github.com/angular/angular/pull/54823)) |
| [f44a5e4604](https://github.com/angular/angular/commit/f44a5e460491a29e5c0cad5577bade8347d52e11) | fix | support content projection and VCRs in i18n ([#54823](https://github.com/angular/angular/pull/54823)) |
| [914e4530b0](https://github.com/angular/angular/commit/914e4530b036eb20eb553dbb47f89183458066f4) | fix | test cleanup should not throw if Zone is not present ([#55096](https://github.com/angular/angular/pull/55096)) |
| [a99cb7ce5b](https://github.com/angular/angular/commit/a99cb7ce5b77a125ab660da8ebef23ecb158e2e3) | fix | zoneless scheduler should check if Zone is defined before accessing it ([#55118](https://github.com/angular/angular/pull/55118)) |
### forms
| Commit | Type | Description |
| -- | -- | -- |
| [1c736dc3b2](https://github.com/angular/angular/commit/1c736dc3b258a502360cda40b3a00c07102ccbf5) | feat | Unified Control State Change Events ([#54579](https://github.com/angular/angular/pull/54579)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [a48afe0d94](https://github.com/angular/angular/commit/a48afe0d9478aca314e68552f4af77f4123563cd) | fix | avoid generating TS syntactic diagnostics for templates ([#55091](https://github.com/angular/angular/pull/55091)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [0c20c4075a](https://github.com/angular/angular/commit/0c20c4075af753d8e5eaecb5f7114a48ced5ad96) | fix | avoid conflicts with some greek letters in control flow migration ([#55113](https://github.com/angular/angular/pull/55113)) |
### platform-browser
| Commit | Type | Description |
| -- | -- | -- |
| [45ae7a6b60](https://github.com/angular/angular/commit/45ae7a6b60019bd49b8a58122a0d5bcbda7e245b) | feat | add withI18nSupport() in developer preview ([#55130](https://github.com/angular/angular/pull/55130)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [87f3f27f90](https://github.com/angular/angular/commit/87f3f27f9087d757e18e8e2a0f2fca6f2a2c7edf) | feat | Allow resolvers to return `RedirectCommand` ([#54556](https://github.com/angular/angular/pull/54556)) |
| [3839cfbb18](https://github.com/angular/angular/commit/3839cfbb18fcc70cae5a6ba4ba7676b1c4acf7a0) | fix | Routed components never inherit `RouterOutlet` `EnvironmentInjector` ([#54265](https://github.com/angular/angular/pull/54265)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.2"></a>
# 18.0.0-next.2 (2024-03-28)
## Breaking Changes
### compiler-cli
- * Angular no longer supports TypeScript versions older than 5.4.
### core
- `ComponentFixture.whenStable` now matches the
`ApplicationRef.isStable` observable. Prior to this change, stability
of the fixture did not include everything that was considered in
`ApplicationRef`. `whenStable` of the fixture will now include unfinished
router navigations and unfinished `HttpClient` requests. This will cause
tests that `await` the `whenStable` promise to time out when there are
incomplete requests. To fix this, remove the `whenStable`,
instead wait for another condition, or ensure `HttpTestingController`
mocks responses for all requests. Try adding `HttpTestingController.verify()`
before your `await fixture.whenStable` to identify the open requests.
Also, make sure your tests wait for the stability promise. We found many
examples of tests that did not, meaning the expectations did not execute
within the test body.
In addition, `ComponentFixture.isStable` would synchronously switch to
true in some scenarios but will now always be asynchronous.
### router
- When a a guard returns a `UrlTree` as a redirect, the
redirecting navigation will now use `replaceUrl` if the initial
navigation was also using the `replaceUrl` option. If this is not
desirable, the redirect can configure new `NavigationBehaviorOptions` by
returning a `RedirectCommand` with the desired options instead of `UrlTree`.
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [7fc7f3f05f](https://github.com/angular/angular/commit/7fc7f3f05f0139dd773032fd5ad308f8d2a9fcf5) | fix | capture all control flow branches for content projection in if blocks ([#54921](https://github.com/angular/angular/pull/54921)) |
| [a369f43fbd](https://github.com/angular/angular/commit/a369f43fbdf45456bbae1caf71ef7becd15d1e90) | fix | capture switch block cases for content projection ([#54921](https://github.com/angular/angular/pull/54921)) |
| [eb625d3783](https://github.com/angular/angular/commit/eb625d37839c3b9f20a2ffb3af06426f9910c8ac) | fix | declare for loop aliases in addition to new name ([#54942](https://github.com/angular/angular/pull/54942)) |
| [bfd0bd574e](https://github.com/angular/angular/commit/bfd0bd574e9a2e1489a007393caae266512c0f04) | fix | invoke method-based tracking function with context ([#54960](https://github.com/angular/angular/pull/54960)) |
| [e1650e3b13](https://github.com/angular/angular/commit/e1650e3b13556ab09c919cfdf97913fa0291622c) | fix | throw error if item name and context variables conflict ([#55045](https://github.com/angular/angular/pull/55045)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [5bd188a394](https://github.com/angular/angular/commit/5bd188a394d30053099e2c83fe79136d590e5399) | feat | add partial compilation support for deferred blocks ([#54908](https://github.com/angular/angular/pull/54908)) |
| [b02b31a915](https://github.com/angular/angular/commit/b02b31a915333e680cf96de5d0f965a6e2639028) | feat | drop support for TypeScript older than 5.4 ([#54961](https://github.com/angular/angular/pull/54961)) |
| [78188e877a](https://github.com/angular/angular/commit/78188e877a4db8655bdd3dc5012b70b12a7234de) | fix | add diagnostic if initializer API is used outside of an initializer ([#54993](https://github.com/angular/angular/pull/54993)) |
| [694ba79cbf](https://github.com/angular/angular/commit/694ba79cbf7aaed1079b1fabf53ea446162fc933) | fix | report cases where initializer APIs are used in a non-directive class ([#54993](https://github.com/angular/angular/pull/54993)) |
| [6219341d26](https://github.com/angular/angular/commit/6219341d267ae7689299835b90f0afa0fe61e213) | fix | report errors when initializer APIs are used on private fields ([#54981](https://github.com/angular/angular/pull/54981)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [a600a39d0c](https://github.com/angular/angular/commit/a600a39d0cf9bb8fc2b6786e6f31acb78b7acc6e) | feat | add support for fallback content in ng-content ([#54854](https://github.com/angular/angular/pull/54854)) |
| [658cf8c384](https://github.com/angular/angular/commit/658cf8c3840b637284a5bb6c9751226d24ccbf9f) | fix | `ComponentFixture` stability should match `ApplicationRef` ([#54949](https://github.com/angular/angular/pull/54949)) |
| [2fc11eae9e](https://github.com/angular/angular/commit/2fc11eae9ea65160866bf7ba46c10520ae9a141f) | fix | account for re-projected ng-content elements with fallback content ([#54854](https://github.com/angular/angular/pull/54854)) |
| [1c0ec56c46](https://github.com/angular/angular/commit/1c0ec56c462cf18fb38aae29858165a08b5a2a82) | fix | correctly project single-root content inside control flow ([#54921](https://github.com/angular/angular/pull/54921)) |
| [86a359b399](https://github.com/angular/angular/commit/86a359b399456e62335a0bcfe7c7fb48b7c2b781) | fix | establish proper injector resolution order for `@defer` blocks ([#55079](https://github.com/angular/angular/pull/55079)) |
| [e02bcf89cf](https://github.com/angular/angular/commit/e02bcf89cf77c3118c649a7db68e66a78f16155c) | fix | Fix clearing of pending task in zoneless cleanup implementation ([#55074](https://github.com/angular/angular/pull/55074)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [cf73983fdc](https://github.com/angular/angular/commit/cf73983fdc5fca955fbe729b231a207fc5cd70fd) | fix | include transferCache when cloning HttpRequest ([#54939](https://github.com/angular/angular/pull/54939)) |
| [13554f9637](https://github.com/angular/angular/commit/13554f9637c222671253e733114cfbc815c6d33d) | fix | manage different body types for caching POST requests ([#54980](https://github.com/angular/angular/pull/54980)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [6d1b82df32](https://github.com/angular/angular/commit/6d1b82df32049cfaba2f6a50b9639b6e3b722170) | fix | allow external projects to use provided compiler options ([#55035](https://github.com/angular/angular/pull/55035)) |
| [4166dfc1b6](https://github.com/angular/angular/commit/4166dfc1b62a83b60203bfe45a6d4aa7148a0b23) | fix | prevent underlying TS Service from handling template files ([#55003](https://github.com/angular/angular/pull/55003)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [63688714ae](https://github.com/angular/angular/commit/63688714aeb788a24b030f9f9cdcc55e7fb0d758) | fix | account for variables in imports initializer ([#55081](https://github.com/angular/angular/pull/55081)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [60f1d681e0](https://github.com/angular/angular/commit/60f1d681e0ba66d3d94b0819f2c612f095c2d3d3) | fix | preserve replaceUrl when returning a urlTree from CanActivate ([#54042](https://github.com/angular/angular/pull/54042)) |
| [eae75ff3f9](https://github.com/angular/angular/commit/eae75ff3f9f564b919debe3f9fa41ed1b073a22c) | fix | RouterLinkActive will always remove active classes when links are not active ([#54982](https://github.com/angular/angular/pull/54982)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.2"></a>
# 17.3.2 (2024-03-28)
### compiler
@@ -363,55 +546,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.1"></a>
# 18.0.0-next.1 (2024-03-20)
## Breaking Changes
### platform-browser-dynamic
- No longer used `RESOURCE_CACHE_PROVIDER` APIs have been removed.
### platform-server
- deprecated `platformDynamicServer` has been removed. Add an `import @angular/compiler` and replace the usage with `platformServer`
- deprecated `ServerTransferStateModule` has been removed. `TransferState` can be use without providing this module.
- deprecated `useAbsoluteUrl` and `baseUrl` been removed from `PlatformConfig`. Provide and absolute `url` instead.
- Legacy handling or Node.js URL parsing has been removed from `ServerPlatformLocation`.
The main differences are;
- `pathname` is always suffixed with a `/`.
- `port` is empty when `http:` protocol and port in url is `80`
- `port` is empty when `https:` protocol and port in url is `443`
### router
- This change allows `Route.redirectTo` to be a function
in addition to the previous string. Code which expects `redirectTo` to
only be a string on `Route` objects will need to be adjusted.
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [879bd80b57](https://github.com/angular/angular/commit/879bd80b571368bdc6e65c5415d98ad0f546267a) | fix | capture data bindings for content projection purposes in blocks ([#54876](https://github.com/angular/angular/pull/54876)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [6aff144232](https://github.com/angular/angular/commit/6aff14423238f8995da8104e60c0baca26df2020) | fix | symbol feature detection for the compiler ([#54711](https://github.com/angular/angular/pull/54711)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [314112de99](https://github.com/angular/angular/commit/314112de99bb97475a0d8bdbddf84a3b3ce4a8fb) | fix | Prevent `markForCheck` during change detection from causing infinite loops ([#54900](https://github.com/angular/angular/pull/54900)) |
### platform-browser-dynamic
| Commit | Type | Description |
| -- | -- | -- |
| [eb20c1a8b1](https://github.com/angular/angular/commit/eb20c1a8b18e2e080c856e3e1bf7bcd02f3bfd28) | refactor | unused `RESOURCE_CACHE_PROVIDER` API has been removed ([#54875](https://github.com/angular/angular/pull/54875)) |
### platform-server
| Commit | Type | Description |
| -- | -- | -- |
| [07ac017731](https://github.com/angular/angular/commit/07ac017731f0e08ea3736f1f212093a28648a304) | refactor | remove deprecated `platformDynamicServer` API ([#54874](https://github.com/angular/angular/pull/54874)) |
| [e8b588d8b7](https://github.com/angular/angular/commit/e8b588d8b7fc014aaef99d4b0c1e4567b4aa195d) | refactor | remove deprecated `ServerTransferStateModule` API ([#54874](https://github.com/angular/angular/pull/54874)) |
| [3b1967ca64](https://github.com/angular/angular/commit/3b1967ca64479df9137b3ad7a0d04dbaff6496f4) | refactor | remove deprecated `useAbsoluteUrl` and `baseUrl` from `PlatformConfig` ([#54874](https://github.com/angular/angular/pull/54874)) |
| [2357d3566c](https://github.com/angular/angular/commit/2357d3566c4d18dc40cbda6644ed459ef7703893) | refactor | remove legacy URL handling logic ([#54874](https://github.com/angular/angular/pull/54874)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [2b802587f2](https://github.com/angular/angular/commit/2b802587f27186baa493c1dd01f42d568b652f38) | feat | Allow Route.redirectTo to be a function which returns a string or UrlTree ([#52606](https://github.com/angular/angular/pull/52606)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.1"></a>
# 17.3.1 (2024-03-20)
### compiler
@@ -425,79 +559,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.0"></a>
# 18.0.0-next.0 (2024-03-14)
## Breaking Changes
### core
- `OnPush` views at the root of the application need to
be marked dirty for their host bindings to refresh. Previously, the host
bindings were refreshed for all root views without respecting the
`OnPush` change detection strategy.
- The `ComponentFixture` `autoDetect` feature will no
longer refresh the component's host view when the component is `OnPush`
and not marked dirty. This exposes existing issues in components which
claim to be `OnPush` but do not correctly call `markForCheck` when they
need to be refreshed. If this change causes test failures, the easiest
fix is to change the component to `ChangeDetectionStrategy.Default`.
- When Angular runs change detection, it will continue to
refresh any views attached to `ApplicationRef` that are still marked for
check after one round completes. In rare cases, this can result in infinite
loops when certain patterns continue to mark views for check using
`ChangeDetectorRef.detectChanges`. This will be surfaced as a runtime
error with the `NG0103` code.
- The `ComponentFixture.autoDetect` feature now executes
change detection for the fixture within `ApplicationRef.tick`. This more
closely matches the behavior of how a component would refresh in
production. The order of component refresh in tests may be slightly
affected as a result, especially when dealing with additional components
attached to the application, such as dialogs. Tests sensitive to this
type of change (such as screenshot tests) may need to be updated.
Concretely, this change means that the component will refresh _before_
additional views attached to `ApplicationRef` (i.e. dialog components).
Prior to this change, the fixture component would refresh _after_ other
views attached to the application.
- The exact timing of change detection execution when
using event or run coalescing with `NgZone` is now the first of either
`setTimeout` or `requestAnimationFrame`. Code which relies on this
timing (usually by accident) will need to be adjusted. If a callback
needs to execute after change detection, we recommend `afterNextRender`
instead of something like `setTimeout`.
- Newly created and views marked for check and reattached
during change detection are now guaranteed to be refreshed in that same
change detection cycle. Previously, if they were attached at a location
in the view tree that was already checked, they would either throw
`ExpressionChangedAfterItHasBeenCheckedError` or not be refreshed until
some future round of change detection. In rare circumstances, this
correction can cause issues. We identified one instance that relied on
the previous behavior by reading a value on initialization which was
queued to be updated in a microtask instead of being available in the
current change detection round. The component only read this value during
initialization and did not read it again after the microtask updated it.
### router
- Guards can now return `RedirectCommand` for redirects
in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree`
values in `Route` types will need to be adjusted.
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [9b424d7224](https://github.com/angular/angular/commit/9b424d7224db46edb16c81979c7e231d5e3db5e9) | fix | preserve original reference to non-deferrable dependency ([#54759](https://github.com/angular/angular/pull/54759)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [64f870c12b](https://github.com/angular/angular/commit/64f870c12bae1ad66509f0d65f8d3e051aae6eaa) | fix | `ApplicationRef.tick` should respect OnPush for host bindings ([#53718](https://github.com/angular/angular/pull/53718)) ([#53718](https://github.com/angular/angular/pull/53718)) |
| [8cad4e8cbe](https://github.com/angular/angular/commit/8cad4e8cbe2baf20dae7b7ef1f4253a4940cbba0) | fix | `ComponentFixture` `autoDetect` respects `OnPush` flag of host view ([#54824](https://github.com/angular/angular/pull/54824)) |
| [ba8e465974](https://github.com/angular/angular/commit/ba8e46597435a827670f10b971b2c58f7033b180) | fix | Change Detection will continue to refresh views while marked for check ([#54734](https://github.com/angular/angular/pull/54734)) |
| [24bc0ed4f2](https://github.com/angular/angular/commit/24bc0ed4f2de47bd998338d73cba394fb45dd497) | fix | ComponentFixture autodetect should detect changes within ApplicationRef.tick ([#54733](https://github.com/angular/angular/pull/54733)) |
| [10c5cdb49c](https://github.com/angular/angular/commit/10c5cdb49c51c95086febd37f4d88a9b944d7e1c) | fix | ensure change detection runs in a reasonable timeframe with zone coalescing ([#54578](https://github.com/angular/angular/pull/54578)) |
| [ad045efd4b](https://github.com/angular/angular/commit/ad045efd4b1565e01c14399998143538ebfbfd99) | fix | Ensure views marked for check are refreshed during change detection ([#54735](https://github.com/angular/angular/pull/54735)) |
| [700c0520bb](https://github.com/angular/angular/commit/700c0520bb638952ba41a8d8260cf12afb078c0e) | fix | Update ApplicationRef.tick loop to only throw in dev mode ([#54848](https://github.com/angular/angular/pull/54848)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [8735af08b9](https://github.com/angular/angular/commit/8735af08b976b30cf236a83f9e8b64b5ff62e9f3) | feat | Add ability to return `UrlTree` with `NavigationBehaviorOptions` from guards ([#45023](https://github.com/angular/angular/pull/45023)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.0"></a>
# 17.3.0 (2024-03-13)
### compiler
+5 -5
View File
@@ -32,7 +32,7 @@ Stack Overflow is a much better place to ask questions since:
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
If you would like to chat about the question in real-time, you can reach out via [our Discord server][discord].
If you would like to chat about the question in real-time, you can reach out via [the Angular community Discord server][discord].
## <a name="issue"></a> Found a Bug?
@@ -138,7 +138,7 @@ If we ask for changes via code reviews then:
git push
```
For more info on working with fixup commits see [here](docs/FIXUP_COMMITS.md).
For more info on working with fixup commits see [here](./contributing-docs/using-fixup-commits.md).
That's it! Thank you for your contribution!
@@ -207,7 +207,7 @@ To ensure consistency throughout the source code, keep these rules in mind as yo
* All public API methods **must be documented**.
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#formatting-your-source-code).
An automated formatter is available, see [DEVELOPER.md](contributing-docs/building-and-testing-angular#formatting-your-source-code).
## <a name="commit"></a> Commit Message Format
@@ -302,7 +302,7 @@ There are currently a few exceptions to the "use package name" rule:
* `dev-infra`: used for dev-infra related changes within the directories /scripts and /tools
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
* `docs-infra`: used for docs-app (angular.dev) related changes within the /adev directory of the repo
* `migrations`: used for changes to the `ng update` migrations.
@@ -392,7 +392,7 @@ The following documents can help you sort out issues with GitHub accounts and mu
[coc]: https://github.com/angular/code-of-conduct/blob/main/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[corporate-cla]: https://cla.developers.google.com/about/google-corporate
[dev-doc]: https://github.com/angular/angular/blob/main/docs/DEVELOPER.md
[dev-doc]: ./contributing-docs/building-and-testing-angular.md
[github]: https://github.com/angular/angular
[discord]: https://discord.gg/angular
[individual-cla]: https://cla.developers.google.com/about/google-individual
+2 -2
View File
@@ -101,7 +101,7 @@ Angular is cross-platform, fast, scalable, has incredible tooling, and is loved
## Ecosystem
<p>
<img src="/docs/images/angular-ecosystem-logos.png" alt="angular ecosystem logos" width="500px" height="auto">
<img src="/contributing-docs/images/angular-ecosystem-logos.png" alt="angular ecosystem logos" width="500px" height="auto">
</p>
- [Angular Command Line (CLI)][cli]
@@ -113,7 +113,7 @@ Angular is cross-platform, fast, scalable, has incredible tooling, and is loved
## Upgrading
Check out our [upgrade guide](https://update.angular.io/) to find out the best way to upgrade your project.
Check out our [upgrade guide](https://angular.dev/update-guide/) to find out the best way to upgrade your project.
## Contributing
+1 -1
View File
@@ -1,3 +1,3 @@
Angular is part of Google [Open Source Software Vulnerability Reward Program](https://bughunters.google.com/about/rules/6521337925468160/google-open-source-software-vulnerability-reward-program-rules). For vulnerabilities in Angular, please submit your report [here](https://bughunters.google.com/report).
For more information, check out [Angular's security policy](https://angular.io/guide/security).
For more information, check out [Angular's security policy](https://angular.dev/best-practices/security).
+4 -28
View File
@@ -75,7 +75,7 @@ yarn_install(
"//:.yarnrc",
"//:tools/npm-patches/@bazel+jasmine+5.8.1.patch",
"//tools:postinstall-patches.js",
"//tools/esm-interop:patches/npm/@angular+build-tooling+0.0.0-56d0b1f597b9e4b5d99f289f6904a220802164c1.patch",
"//tools/esm-interop:patches/npm/@angular+build-tooling+0.0.0-239d56b71911f9fa1eeefb6e4505dbe7b0cd81a7.patch",
"//tools/esm-interop:patches/npm/@bazel+concatjs+5.8.1.patch",
"//tools/esm-interop:patches/npm/@bazel+esbuild+5.7.1.patch",
"//tools/esm-interop:patches/npm/@bazel+protractor+5.7.1.patch",
@@ -94,30 +94,6 @@ yarn_install(
yarn_lock = "//:yarn.lock",
)
yarn_install(
name = "aio_example_deps",
# Rename the default js_library target from "node_modules" as this obscures the
# the source directory stamped as a filegroup in the manual BUILD contents below.
all_node_modules_target_name = "node_modules_all",
data = [
YARN_LABEL,
"//:.yarnrc",
],
# Disabled because, when False, yarn_install preserves the node_modules folder
# with bin symlinks in the external repository. This is needed to link the shared
# set of deps for example e2es.
exports_directories_only = False,
manual_build_file_contents = """\
filegroup(
name = "node_modules_files",
srcs = ["node_modules"],
)
""",
package_json = "//aio/tools/examples/shared:package.json",
yarn = YARN_LABEL,
yarn_lock = "//aio/tools/examples/shared:yarn.lock",
)
load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies")
aspect_bazel_lib_dependencies()
@@ -167,10 +143,10 @@ cldr_xml_data_repository(
# sass rules
http_archive(
name = "io_bazel_rules_sass",
sha256 = "845061fad5cb42a353ac394fe6450ec9f21d337acf5b98011ef29ddcb33e3671",
strip_prefix = "rules_sass-9f8be59f5175d0dd3438d7da994b2782299e0c2c",
sha256 = "47c50aa960ddf875a2a2dd7efd1c839e5f8598725c00014680122b0e48d0ec7f",
strip_prefix = "rules_sass-b222c61b3d3879ec45b66062b2c706a72f3d80bb",
urls = [
"https://github.com/bazelbuild/rules_sass/archive/9f8be59f5175d0dd3438d7da994b2782299e0c2c.zip",
"https://github.com/bazelbuild/rules_sass/archive/b222c61b3d3879ec45b66062b2c706a72f3d80bb.zip",
],
)
+2 -4
View File
@@ -79,9 +79,8 @@ APPLICATION_DEPS = [
"@npm//@lezer/javascript",
"@npm//@lezer/common",
"@npm//@xterm/xterm",
"@npm//@xterm/addon-fit",
"@npm//algoliasearch",
"@npm//xterm",
"@npm//xterm-addon-fit",
"@npm//angular-split",
"@npm//zone.js",
]
@@ -90,7 +89,6 @@ TEST_DEPS = APPLICATION_DEPS + [
"@npm//@angular/platform-browser-dynamic",
"@npm//@types/jasmine",
"@npm//@types/node",
"@npm//assert",
"@npm//jasmine",
"@npm//jasmine-core",
"@npm//karma-chrome-launcher",
@@ -177,7 +175,7 @@ architect_test(
],
chdir = package_name(),
data = ensure_local_package_deps(TEST_DEPS) + TEST_FILES + APPLICATION_ASSETS + [
"//aio/tools:windows-chromium-path",
"//adev/tools:windows-chromium-path",
"@npm//@angular/build-tooling/bazel/browsers/chromium",
],
env = {
+17 -1
View File
@@ -24,14 +24,30 @@ yarn
yarn docs
```
If you are having issues with the docs building, see the [FAQs](#faqs) section.
## Contributing
Want to report a bug, contribute some code, or improve the documentation? Excellent!
Read through our [contributing guidelines](CONTRIBUTING.md) to learn about our submission process, coding rules, and more.
Read through our [contributing guidelines](/CONTRIBUTING.md) to learn about our submission process, coding rules, and more.
And if you're new, check out one of our issues labeled as <kbd>[help wanted](https://github.com/angular/angular/labels/help%20wanted)</kbd> or <kbd>[good first issue](https://github.com/angular/angular/labels/good%20first%20issue)</kbd>.
### Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
## FAQs
### The build is failing and I'm seeing `bazel:bazel failed: missing input file` messages.
This is most likely due to a bazel dependency / caching issue. To resolve this, run the following command:
```
# Try this first
yarn bazel clean
# If that doesn't work, try it with the expunge flag
yarn bazel clean --expunge
```
+8 -2
View File
@@ -20,15 +20,21 @@
"builder": "@angular/build:application",
"options": {
"externalDependencies": ["path"],
"define": {
// We need this until xterm 5.6.0 is released
// see https://github.com/xtermjs/xterm.js/pull/4940
"self": "this"
},
"outputPath": "dist/angular-dev",
"index": "src/index.html",
"browser": "src/main.ts",
"server": "src/main.server.ts",
"polyfills": ["src/polyfills.ts", "zone.js"],
"ssr": true,
"polyfills": [],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/robots.txt", "src/assets"],
"styles": ["@angular/docs/styles/global-styles.scss"],
"styles": ["@angular/docs/styles/global-styles.scss", "./src/local-styles.scss"],
"scripts": [],
"webWorkerTsConfig": "tsconfig.worker.json",
"optimization": {
+1 -1
View File
@@ -5,7 +5,7 @@
"ignore": ["**/.*"],
"headers": [
{
"source": "assets/tutorials/common/*.jpg",
"source": "assets/images/tutorials/common/*.jpg",
"headers": [
{
"key": "Cross-Origin-Resource-Policy",
+1 -1
View File
@@ -1,7 +1,7 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
const {getAdjustedChromeBinPathForWindows} = require('../aio/tools/windows-chromium-path');
const {getAdjustedChromeBinPathForWindows} = require('../adev/tools/windows-chromium-path');
process.env.CHROME_BIN = getAdjustedChromeBinPathForWindows();
+1 -1
View File
@@ -130,7 +130,7 @@ function httpGet(url, options = {}) {
] = `token ${process.env.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN}`;
// User agent is required
// https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#user-agent-required
options.headers['User-Agent'] = `AIO_Angular_CLI_Sources_Update`;
options.headers['User-Agent'] = `ADEV_Angular_CLI_Sources_Update`;
return new Promise((resolve, reject) => {
get(url, options, (res) => {
+82
View File
@@ -0,0 +1,82 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {ViewportScroller} from '@angular/common';
import {
Injectable,
inject,
ApplicationRef,
afterNextRender,
EnvironmentInjector,
} from '@angular/core';
import {Scroll, Router} from '@angular/router';
import {filter, firstValueFrom, map, switchMap, tap} from 'rxjs';
@Injectable({providedIn: 'root'})
export class AppScroller {
private readonly router = inject(Router);
private readonly viewportScroller = inject(ViewportScroller);
private readonly appRef = inject(ApplicationRef);
private readonly injector = inject(EnvironmentInjector);
disableScrolling = false;
private _lastScrollEvent?: Scroll;
private canScroll = false;
private cancelScroll?: () => void;
get lastScrollEvent(): Scroll | undefined {
return this._lastScrollEvent;
}
constructor() {
this.viewportScroller.setHistoryScrollRestoration('manual');
this.router.events
.pipe(
filter((e): e is Scroll => e instanceof Scroll),
tap((e) => {
this.cancelScroll?.();
this.canScroll = true;
this._lastScrollEvent = e;
}),
filter(() => !this.disableScrolling),
switchMap((e) => {
return firstValueFrom(
this.appRef.isStable.pipe(
filter((stable) => stable),
map(() => e),
),
);
}),
)
.subscribe(() => {
this.scroll();
});
}
scroll() {
if (!this._lastScrollEvent || !this.canScroll) {
return;
}
// Prevent double scrolling on the same event
this.canScroll = false;
const {anchor, position} = this._lastScrollEvent;
// Don't scroll during rendering
this.cancelScroll = afterNextRender(
{
write: () => {
if (position) {
this.viewportScroller.scrollToPosition(position);
} else if (anchor) {
this.viewportScroller.scrollToAnchor(anchor);
} else {
this.viewportScroller.scrollToPosition([0, 0]);
}
},
},
{injector: this.injector},
).destroy;
}
}
+4 -4
View File
@@ -1,11 +1,11 @@
@defer (when isBrowser) {
<adev-progress-bar />
<adev-progress-bar />
}
<button (click)="focusFirstHeading()" class="adev-skip">Skip to main content</button>
<div class="adev-nav"></div>
@if (displaySecondaryNav()) {
<adev-secondary-navigation />
<adev-secondary-navigation />
}
<div class="docs-app-main-content">
<!--
@@ -22,9 +22,9 @@
}
}
}
<router-outlet />
<router-outlet />
@if (displayFooter()) {
<footer adev-footer></footer>
<footer adev-footer></footer>
}
</div>
+7 -1
View File
@@ -11,10 +11,12 @@ import {AppComponent} from './app.component';
import {provideRouter} from '@angular/router';
import {routes} from './routes';
import {Search, WINDOW} from '@angular/docs';
import {CURRENT_MAJOR_VERSION} from './core/providers/current-version';
describe('AppComponent', () => {
const fakeSearch = {};
const fakeWindow = {};
const fakeWindow = {location: {hostname: 'angular.dev'}};
const fakeCurrentMajorVersion = 19;
it('should create the app', () => {
TestBed.configureTestingModule({
@@ -28,6 +30,10 @@ describe('AppComponent', () => {
provide: Search,
useValue: fakeSearch,
},
{
provide: CURRENT_MAJOR_VERSION,
useValue: fakeCurrentMajorVersion,
},
],
});
const fixture = TestBed.createComponent(AppComponent);
+25 -23
View File
@@ -8,9 +8,11 @@
import {DOCUMENT, isPlatformBrowser} from '@angular/common';
import {
afterNextRender,
ChangeDetectionStrategy,
Component,
inject,
NgZone,
Injector,
OnInit,
PLATFORM_ID,
signal,
@@ -23,17 +25,18 @@ import {
getActivatedRouteSnapshotFromRouter,
IS_SEARCH_DIALOG_OPEN,
SearchDialog,
WINDOW,
} from '@angular/docs';
import {Footer} from './core/layout/footer/footer.component';
import {Navigation} from './core/layout/navigation/navigation.component';
import {SecondaryNavigation} from './core/layout/secondary-navigation/secondary-navigation.component';
import {ProgressBarComponent} from './core/layout/progress-bar/progress-bar.component';
import {ESCAPE, SEARCH_TRIGGER_KEY} from './core/constants/keys';
import {HeaderService} from './core/services/header.service';
@Component({
standalone: true,
selector: 'adev-root',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
CookiePopup,
Navigation,
@@ -46,12 +49,14 @@ import {ESCAPE, SEARCH_TRIGGER_KEY} from './core/constants/keys';
],
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
host: {
'(window:keydown)': 'setSearchDialogVisibilityOnKeyPress($event)',
},
})
export class AppComponent implements OnInit {
private readonly document = inject(DOCUMENT);
private readonly ngZone = inject(NgZone);
private readonly router = inject(Router);
private readonly window = inject(WINDOW);
private readonly headerService = inject(HeaderService);
currentUrl = signal('');
displayFooter = signal(false);
@@ -61,7 +66,6 @@ export class AppComponent implements OnInit {
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
ngOnInit(): void {
this.setSearchDialogVisibilityOnKeyPress();
this.closeSearchDialogOnNavigationSkipped();
this.router.events
.pipe(
@@ -72,6 +76,8 @@ export class AppComponent implements OnInit {
this.currentUrl.set(url);
this.setComponentsVisibility();
this.displaySearchDialog.set(false);
this.updateCanonicalLink(url);
});
this.focusFirstHeadingOnRouteChange();
@@ -86,6 +92,10 @@ export class AppComponent implements OnInit {
h1?.focus();
}
private updateCanonicalLink(absoluteUrl: string) {
this.headerService.setCanonical(absoluteUrl);
}
private setComponentsVisibility(): void {
const activatedRoute = getActivatedRouteSnapshotFromRouter(this.router as any);
@@ -105,24 +115,16 @@ export class AppComponent implements OnInit {
});
}
private setSearchDialogVisibilityOnKeyPress(): void {
this.ngZone.runOutsideAngular(() => {
this.window.addEventListener('keydown', (event: KeyboardEvent) => {
if (event.key === SEARCH_TRIGGER_KEY && (event.metaKey || event.ctrlKey)) {
this.ngZone.run(() => {
event.preventDefault();
this.displaySearchDialog.update((display) => !display);
});
}
private setSearchDialogVisibilityOnKeyPress(event: KeyboardEvent): void {
if (event.key === SEARCH_TRIGGER_KEY && (event.metaKey || event.ctrlKey)) {
event.preventDefault();
this.displaySearchDialog.update((display) => !display);
}
if (event.key === ESCAPE && this.displaySearchDialog()) {
this.ngZone.run(() => {
event.preventDefault();
this.displaySearchDialog.set(false);
});
}
});
});
if (event.key === ESCAPE && this.displaySearchDialog()) {
event.preventDefault();
this.displaySearchDialog.set(false);
}
}
private closeSearchDialogOnNavigationSkipped(): void {
+15 -3
View File
@@ -12,8 +12,9 @@ import {
ApplicationConfig,
ENVIRONMENT_INITIALIZER,
ErrorHandler,
VERSION,
inject,
provideZoneChangeDetection,
provideExperimentalZonelessChangeDetection,
} from '@angular/core';
import {
DOCS_CONTENT_LOADER,
@@ -44,12 +45,14 @@ import {ExampleContentLoader} from './core/services/example-content-loader.servi
import {ReuseTutorialsRouteStrategy} from './features/tutorial/tutorials-route-reuse-strategy';
import {routes} from './routes';
import {ReferenceScrollHandler} from './features/references/services/reference-scroll-handler.service';
import {CURRENT_MAJOR_VERSION} from './core/providers/current-version';
import {AppScroller} from './app-scroller';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(
routes,
withInMemoryScrolling({anchorScrolling: 'enabled', scrollPositionRestoration: 'enabled'}),
withInMemoryScrolling(),
withViewTransitions({
onViewTransitionCreated: ({transition, to}) => {
const router = inject(Router);
@@ -68,10 +71,20 @@ export const appConfig: ApplicationConfig = {
},
}),
),
provideExperimentalZonelessChangeDetection(),
provideClientHydration(),
provideHttpClient(withFetch()),
provideAnimationsAsync(),
{
provide: CURRENT_MAJOR_VERSION,
useValue: Number(VERSION.major),
},
{provide: ENVIRONMENT, useValue: environment},
{
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useValue: () => inject(AppScroller),
},
{
provide: ENVIRONMENT_INITIALIZER,
multi: true,
@@ -91,7 +104,6 @@ export const appConfig: ApplicationConfig = {
deps: [DOCUMENT],
},
{provide: TitleStrategy, useClass: ADevTitleStrategy},
provideZoneChangeDetection({eventCoalescing: true}),
ReferenceScrollHandler,
],
};
+3 -2
View File
@@ -8,5 +8,6 @@
export const GITHUB = 'https://github.com/angular/angular';
export const X = 'https://x.com/angular';
export const MEDIUM = 'https://blog.angular.io';
export const YOUTUBE = 'https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw';
export const MEDIUM = 'https://blog.angular.dev';
export const YOUTUBE = 'https://www.youtube.com/angular';
export const DISCORD = 'https://discord.gg/angular';
+4 -5
View File
@@ -7,12 +7,11 @@
*/
export const VERSIONS_CONFIG = {
currentVersion: 'stable',
historicalVersionsLinkPattern: 'https://v{{version}}.angular.dev',
mainVersions: [
aDevVersionsLinkPattern: 'https://{{prefix}}{{version}}angular.dev',
aioVersions: [
{
version: 'stable',
url: 'https://angular.dev',
version: 'v17',
url: 'https://v17.angular.io/docs',
},
{
version: 'v16',
+2
View File
@@ -17,6 +17,7 @@ export enum PagePrefix {
PLAYGROUND = 'playground',
REFERENCE = 'reference',
TUTORIALS = 'tutorials',
UPDATE = 'update-guide',
}
// The enum with the default pages for each main tab
@@ -25,4 +26,5 @@ export enum DefaultPage {
REFERENCE = 'api',
TUTORIALS = 'tutorials',
PLAYGROUND = 'playground',
UPDATE = 'update-guide',
}
@@ -77,6 +77,8 @@
}
.adev-version-picker {
overflow-y: auto;
max-height: 90vh;
top: 30px;
left: 10px;
position: absolute;
@@ -86,8 +88,8 @@
padding-inline: 0;
}
li button {
min-height: fit-content;
li a {
line-height: 1em;
}
@include mq.for-tablet {
@@ -82,7 +82,8 @@
>
<a aria-label="Angular homepage" routerLink="/">
<!-- Logo Symbol -->
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
@if(!isUwu) {
<svg class="angular-logo" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
<g clip-path="url(#a)">
<path
fill="url(#b)"
@@ -125,6 +126,14 @@
</clipPath>
</defs>
</svg>
} @else {
<img
src="assets/images/uwu.png"
style="width: auto; margin: 0"
class="uwu-logo"
alt="Angular logo"
height="34"/>
}
</a>
<!-- Version picker for v18+ -->
@@ -156,14 +165,14 @@
<ul class="adev-mini-menu adev-version-picker" cdkMenu>
@for (item of versions(); track item) {
<li>
<button
<a
type="button"
cdkMenuItem
(click)="redirectToDocsVersion(item.url)"
[href]="item.url"
[attr.aria-label]="item.displayName"
>
<span>{{ item.displayName }}</span>
</button>
</a>
</li>
}
</ul>
@@ -371,6 +380,24 @@
</svg>
</a>
</li>
<li>
<a [href]="DISCORD" cdkMenuItem title="Angular Discord" target="_blank" rel="noopener">
<!-- Discord Icon -->
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 127.14 96.36"
width="20"
height="20"
fill="none"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,110.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"
/>
</svg>
</a>
</li>
</ul>
</ng-template>
</div>
@@ -69,6 +69,7 @@
padding-block-end: 2rem;
box-sizing: border-box;
&.adev-nav-primary--next,
&.adev-nav-primary--rc {
// change nav background to indicate this is the rc docs
background: linear-gradient(
@@ -79,11 +80,6 @@
color-mix(in srgb, var(--bright-blue), transparent 60%) 90%,
);
}
&.adev-nav-primary--next {
// change nav background to indicate this is the rc docs
background-color: color-mix(in srgb, var(--orange-red), transparent 60%);
}
&.adev-nav-primary--deprecated {
// change nav background to indicate this is an outdated version of the docs
@@ -251,6 +247,10 @@
}
}
.adev-nav-item--logo a {
height: 34px;
}
.adev-close-nav {
display: none;
@include mq.for-phone-only {
@@ -27,10 +27,10 @@ import {
isApple,
IS_SEARCH_DIALOG_OPEN,
} from '@angular/docs';
import {NavigationEnd, Router, RouterLink} from '@angular/router';
import {ActivatedRoute, NavigationEnd, Router, RouterLink} from '@angular/router';
import {filter, map, startWith} from 'rxjs/operators';
import {DOCS_ROUTES, REFERENCE_ROUTES, TUTORIALS_ROUTES} from '../../../routes';
import {GITHUB, MEDIUM, X, YOUTUBE} from '../../constants/links';
import {GITHUB, MEDIUM, X, YOUTUBE, DISCORD} from '../../constants/links';
import {PagePrefix} from '../../enums/pages';
import {Theme, ThemeManager} from '../../services/theme-manager.service';
import {VersionManager} from '../../services/version-manager.service';
@@ -79,10 +79,14 @@ export class Navigation implements OnInit {
readonly X = X;
readonly MEDIUM = MEDIUM;
readonly YOUTUBE = YOUTUBE;
readonly DISCORD = DISCORD;
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
// We can't use the ActivatedRouter queryParams as we're outside the router outlet
readonly isUwu = 'location' in globalThis ? location.search.includes('uwu') : false;
miniMenuPositions = [
new ConnectionPositionPair(
{originX: 'end', originY: 'center'},
@@ -127,10 +131,6 @@ export class Navigation implements OnInit {
this.closeMobileNavOnPrimaryRouteChange();
}
redirectToDocsVersion(versionUrl: string): void {
this.window.location.href = versionUrl;
}
setTheme(theme: Theme): void {
this.themeManager.setTheme(theme);
}
@@ -199,7 +199,8 @@ export class Navigation implements OnInit {
this.activeRouteItem.set(PagePrefix.DOCS);
} else if (
urlAfterRedirects.startsWith(PagePrefix.REFERENCE) ||
urlAfterRedirects.startsWith(PagePrefix.API)
urlAfterRedirects.startsWith(PagePrefix.API) ||
urlAfterRedirects.startsWith(PagePrefix.UPDATE)
) {
this.activeRouteItem.set(PagePrefix.REFERENCE);
} else if (urlAfterRedirects === PagePrefix.PLAYGROUND) {
@@ -1,5 +1,5 @@
<div [attr.id]="SECONDARY_NAV_ID" class="adev-secondary-nav-mask" [class.docs-nav-secondary--open]="isSecondaryNavVisible()" (docsClickOutside)="close()" [docsClickOutsideIgnore]="[PRIMARY_NAV_ID]">
<div class="docs-nav-secondary docs-scroll-track-transparent" [style.transform]="translateX()" [style.transition]="transition">
<div class="docs-nav-secondary docs-scroll-track-transparent" [style.transform]="translateX()" [style.transition]="transition()">
<!-- Secondary Nav -->
@if (navigationItems && navigationItems.length > 0) {
<docs-navigation-list
@@ -14,6 +14,7 @@ import {
PLATFORM_ID,
computed,
inject,
signal,
} from '@angular/core';
import {takeUntilDestroyed, toObservable} from '@angular/core/rxjs-interop';
import {
@@ -64,19 +65,19 @@ export class SecondaryNavigation implements OnInit {
private readonly router = inject(Router);
private readonly window = inject(WINDOW);
isSecondaryNavVisible = this.navigationState.isMobileNavVisible;
primaryActiveRouteItem = this.navigationState.primaryActiveRouteItem;
maxVisibleLevelsOnSecondaryNav = computed(() =>
readonly isSecondaryNavVisible = this.navigationState.isMobileNavVisible;
readonly primaryActiveRouteItem = this.navigationState.primaryActiveRouteItem;
readonly maxVisibleLevelsOnSecondaryNav = computed(() =>
this.primaryActiveRouteItem() === PagePrefix.REFERENCE ? 1 : 2,
);
navigationItemsSlides = this.navigationState.expandedItems;
readonly navigationItemsSlides = this.navigationState.expandedItems;
navigationItems: NavigationItem[] | undefined;
translateX = computed(() => {
const level = this.navigationState.expandedItems()?.length ?? 0;
return `translateX(${-level * 100}%)`;
});
transition: string = '0ms';
transition = signal('0ms');
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
@@ -182,7 +183,7 @@ export class SecondaryNavigation implements OnInit {
return;
}
setTimeout(() => {
this.transition = `${ANIMATION_DURATION}ms`;
this.transition.set(`${ANIMATION_DURATION}ms`);
}, ANIMATION_DURATION);
}
@@ -0,0 +1,3 @@
import {InjectionToken} from '@angular/core';
export const CURRENT_MAJOR_VERSION = new InjectionToken<number>('CURRENT_MAJOR_VERSION');
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {Component, Inject} from '@angular/core';
import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
import {MAT_SNACK_BAR_DATA, MatSnackBarAction, MatSnackBarRef} from '@angular/material/snack-bar';
export interface ErrorSnackBarData {
@@ -16,6 +16,7 @@ export interface ErrorSnackBarData {
@Component({
selector: 'error-snack-bar',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
{{ message }}
<button
@@ -28,8 +29,8 @@ export interface ErrorSnackBarData {
{{ actionText }}
</button>
`,
imports: [MatSnackBarAction],
standalone: true,
imports: [MatSnackBarAction],
styles: `:host { display: flex; align-items: center; button { margin-left: 16px }}`,
})
export class ErrorSnackBar {
@@ -0,0 +1,32 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {TestBed} from '@angular/core/testing';
import {HeaderService} from './header.service';
import {link} from 'fs';
describe('HeaderService', () => {
let service: HeaderService;
beforeEach(() => {
service = TestBed.inject(HeaderService);
});
it('setCanonical', () => {
// setCanonical assumes there is a preexisting element
const linkEl = document.createElement('link');
linkEl.setAttribute('rel', 'canonical');
document.querySelector('head')?.appendChild(linkEl);
service.setCanonical('/some/link');
expect(document.querySelector('link[rel=canonical]')!.getAttribute('href')).toBe(
'https://angular.dev/some/link',
);
});
});
@@ -0,0 +1,32 @@
import {DOCUMENT} from '@angular/common';
import {Injectable, inject} from '@angular/core';
const ANGULAR_DEV = 'https://angular.dev';
/**
* Information about the deployment of this application.
*/
@Injectable({providedIn: 'root'})
export class HeaderService {
private readonly document = inject(DOCUMENT);
/**
* Sets the canonical link in the header.
* It supposes the header link is already present in the index.html
*
* The function behave invariably and will always point to angular.dev,
* no matter if it's a specific version build
*/
setCanonical(absolutePath: string): void {
const pathWithoutFragment = this.normalizePath(absolutePath).split('#')[0];
const fullPath = `${ANGULAR_DEV}/${pathWithoutFragment}`;
this.document.querySelector('link[rel=canonical]')?.setAttribute('href', fullPath);
}
private normalizePath(path: string): string {
if (path[0] === '/') {
return path.substring(1);
}
return path;
}
}
@@ -8,17 +8,52 @@
import {TestBed} from '@angular/core/testing';
import {VersionManager} from './version-manager.service';
import {INITIAL_ADEV_DOCS_VERSION, VersionManager} from './version-manager.service';
import {WINDOW} from '@angular/docs';
import {CURRENT_MAJOR_VERSION} from '../providers/current-version';
describe('VersionManager', () => {
const fakeWindow = {location: {hostname: 'angular.dev'}};
const fakeCurrentMajorVersion = 19;
let service: VersionManager;
beforeEach(() => {
TestBed.configureTestingModule({});
TestBed.configureTestingModule({
providers: [
{
provide: WINDOW,
useValue: fakeWindow,
},
{
provide: CURRENT_MAJOR_VERSION,
useValue: fakeCurrentMajorVersion,
},
],
});
service = TestBed.inject(VersionManager);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should contain correct number of Angular Docs versions', () => {
// Note: From v2 to v17 (inclusive), there were no v3
const expectedAioDocsVersionsCount = 15;
// Last stable version and next
const expectedRecentDocsVersionCount = 2;
const expectedPreviousAdevVersionsCount = fakeCurrentMajorVersion - INITIAL_ADEV_DOCS_VERSION;
expect(service['getAioVersions']().length).toBe(expectedAioDocsVersionsCount);
expect(service['getRecentVersions']().length).toBe(expectedRecentDocsVersionCount);
expect(service['getAdevVersions']().length).toBe(expectedPreviousAdevVersionsCount);
expect(service.versions().length).toBe(
expectedAioDocsVersionsCount +
expectedRecentDocsVersionCount +
expectedPreviousAdevVersionsCount,
);
});
});
@@ -6,8 +6,10 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {Injectable, VERSION, computed, signal} from '@angular/core';
import {Injectable, computed, inject, signal} from '@angular/core';
import {VERSIONS_CONFIG} from '../constants/versions';
import {WINDOW} from '@angular/docs';
import {CURRENT_MAJOR_VERSION} from '../providers/current-version';
export interface Version {
displayName: string;
@@ -17,39 +19,84 @@ export interface Version {
export type VersionMode = 'stable' | 'deprecated' | 'rc' | 'next' | number;
export const INITIAL_DOCS_VERSION = 17;
export const VERSION_PATTERN_PLACEHOLDER = '{{version}}';
export const INITIAL_ADEV_DOCS_VERSION = 18;
export const VERSION_PLACEHOLDER = '{{version}}';
export const MODE_PLACEHOLDER = '{{prefix}}';
@Injectable({
providedIn: 'root',
})
export class VersionManager {
private readonly currentMajorVersion = inject(CURRENT_MAJOR_VERSION);
private readonly window = inject(WINDOW);
// Note: We can assume that if the URL starts with v{{version}}, it is documentation for previous versions of Angular.
// Based on URL we can indicate as well if it's rc or next Docs version.
private get currentVersionMode(): VersionMode {
const hostname = this.window.location.hostname;
if (hostname.startsWith('v')) return 'deprecated';
if (hostname.startsWith('rc')) return 'rc';
if (hostname.startsWith('next')) return 'next';
return 'stable';
}
versions = signal<Version[]>([
...VERSIONS_CONFIG.mainVersions.map((item) =>
this.mapToVersion(item as Pick<Version, 'url' | 'version'>),
),
...this.getHistoricalVersions(),
...this.getRecentVersions(),
...this.getAdevVersions(),
...this.getAioVersions(),
]);
currentDocsVersion = computed(() => {
return this.versions().find(
(version) => version.version.toString() === VERSIONS_CONFIG.currentVersion,
(version) => version.version.toString() === this.currentVersionMode,
);
});
private getHistoricalVersions(): Version[] {
const historicalVersions: Version[] = [];
for (let version = Number(VERSION.major) - 1; version >= INITIAL_DOCS_VERSION; version--) {
historicalVersions.push({
url: VERSIONS_CONFIG.historicalVersionsLinkPattern.replace(
VERSION_PATTERN_PLACEHOLDER,
version.toString(),
),
// List of Angular Docs versions which includes current version, next and rc.
private getRecentVersions(): Version[] {
return [
{
url: this.getAdevDocsUrl('next'),
displayName: `next`,
version: 'next',
},
// Note: 'rc' should not be visible for now
// {
// url: this.getAdevDocsUrl('rc'),
// displayName: `rc`,
// version: 'rc',
// },
{
url: this.getAdevDocsUrl(this.currentMajorVersion),
displayName: this.getVersion(this.currentMajorVersion),
version: this.currentVersionMode,
},
];
}
// List of Angular Docs versions hosted on angular.dev domain.
private getAdevVersions(): Version[] {
const adevVersions: Version[] = [];
for (
let version = this.currentMajorVersion - 1;
version >= INITIAL_ADEV_DOCS_VERSION;
version--
) {
adevVersions.push({
url: this.getAdevDocsUrl(version),
displayName: this.getVersion(version),
version,
version: 'deprecated',
});
}
return historicalVersions;
return adevVersions;
}
// List of Angular Docs versions hosted on angular.io domain.
private getAioVersions(): Version[] {
return VERSIONS_CONFIG.aioVersions.map((item) =>
this.mapToVersion(item as Pick<Version, 'url' | 'version'>),
);
}
private mapToVersion(value: Pick<Version, 'url' | 'version'>): Version {
@@ -60,14 +107,23 @@ export class VersionManager {
}
private getVersion(versionMode: VersionMode): string {
if (versionMode === 'stable') {
return 'v17';
// Temporarily commenting out till this works correctly
// return `v${VERSION.major}`;
if (versionMode === 'stable' || versionMode === 'deprecated') {
return `v${this.currentMajorVersion}`;
}
if (Number.isInteger(versionMode)) {
return `v${versionMode}`;
}
return versionMode.toString();
}
private getAdevDocsUrl(version: VersionMode): string {
const docsUrlPrefix = isNaN(Number(version)) ? `` : 'v';
return VERSIONS_CONFIG.aDevVersionsLinkPattern
.replace(MODE_PLACEHOLDER, docsUrlPrefix)
.replace(
VERSION_PLACEHOLDER,
`${version.toString() === 'stable' ? '' : `${version.toString()}.`}`,
);
}
}
@@ -8,6 +8,7 @@ $width-breakpoint: 950px;
container-name: embedded-editor;
height: 100%;
position: relative;
border: 1px solid var(--senary-contrast);
}
// The entire thing - editor, terminal, console
@@ -9,6 +9,7 @@
import {NgIf, isPlatformBrowser} from '@angular/common';
import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef,
@@ -44,11 +45,12 @@ export const LARGE_EDITOR_WIDTH_BREAKPOINT = 950;
export const LARGE_EDITOR_HEIGHT_BREAKPOINT = 550;
@Component({
standalone: true,
selector: EMBEDDED_EDITOR_SELECTOR,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [AngularSplitModule, CodeEditor, Preview, Terminal, NgIf, MatTabsModule, IconComponent],
templateUrl: './embedded-editor.component.html',
styleUrls: ['./embedded-editor.component.scss'],
imports: [AngularSplitModule, CodeEditor, Preview, Terminal, NgIf, MatTabsModule, IconComponent],
providers: [EditorUiState],
})
export class EmbeddedEditor implements OnInit, AfterViewInit, OnDestroy {
@@ -8,7 +8,7 @@
import {Injectable} from '@angular/core';
import {Terminal} from '@xterm/xterm';
import {FitAddon} from 'xterm-addon-fit';
import {FitAddon} from '@xterm/addon-fit';
import {InteractiveTerminal} from './interactive-terminal';
export enum TerminalType {
@@ -2,7 +2,7 @@
// SASS imports, here we're importing a CSS asset
//
// stylelint-disable-next-line @angular/no-import
@import 'xterm/css/xterm.css';
@import '@xterm/xterm/css/xterm.css';
.docs-tutorial-terminal {
display: block;
+2 -1
View File
@@ -8,13 +8,14 @@
import {CommonModule} from '@angular/common';
import {DocContent, DocViewer} from '@angular/docs';
import {Component, inject} from '@angular/core';
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import {toSignal} from '@angular/core/rxjs-interop';
import {ActivatedRoute} from '@angular/router';
import {map} from 'rxjs/operators';
@Component({
selector: 'docs-docs',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, DocViewer],
styleUrls: ['./docs.component.scss'],
@@ -7,6 +7,7 @@
*/
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EnvironmentInjector,
@@ -20,6 +21,7 @@ import {EmbeddedEditor, EmbeddedTutorialManager} from '../../../editor';
@Component({
selector: 'adev-code-editor',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [EmbeddedEditor],
template: `
+58 -48
View File
@@ -2,60 +2,70 @@
<div class="adev-top">
<div class="adev-top-content">
<!-- Banner(s) can be edited here! -->
<a href="https://goo.gle/angular-dot-dev" class="adev-banner" target="_blank">
<h1 tabindex="-1">Welcome to Angular.dev &#8212; the new home for Angular!</h1>
<p class="adev-banner-cta">Read about our launch</p>
<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>
</div>
</div>
<div class="adev-canvas"></div>
<div class="adev-logo">
<div class="adev-logo-wordmark">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 982 241"
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
>
<g clip-path="url(#wordmark_a)">
<path
fill="url(#wordmark_b)"
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
/>
<path
fill="url(#wordmark_c)"
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
/>
</g>
<defs>
<radialGradient
id="wordmark_c"
cx="0"
cy="0"
r="1"
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#FF41F8" />
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
</radialGradient>
<linearGradient
id="wordmark_b"
x1="0"
x2="982"
y1="192"
y2="192"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#F0060B" />
<stop offset="0" stop-color="#F0070C" />
<stop offset=".526" stop-color="#CC26D5" />
<stop offset="1" stop-color="#7702FF" />
</linearGradient>
<clipPath id="wordmark_a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
</defs>
</svg>
@if (!isUwu) {
<svg
class="angular-logo"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 982 241"
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
>
<g clip-path="url(#wordmark_a)">
<path
fill="url(#wordmark_b)"
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
/>
<path
fill="url(#wordmark_c)"
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
/>
</g>
<defs>
<radialGradient
id="wordmark_c"
cx="0"
cy="0"
r="1"
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#FF41F8" />
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
</radialGradient>
<linearGradient
id="wordmark_b"
x1="0"
x2="982"
y1="192"
y2="192"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#F0060B" />
<stop offset="0" stop-color="#F0070C" />
<stop offset=".526" stop-color="#CC26D5" />
<stop offset="1" stop-color="#7702FF" />
</linearGradient>
<clipPath id="wordmark_a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
</defs>
</svg>
} @else {
<img
src="assets/images/uwu.png"
class="uwu-logo"
alt="Angular logo"
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
/>
}
</div>
</div>
<div class="adev-scale">
+6 -8
View File
@@ -13,7 +13,6 @@ import {
Component,
ElementRef,
Injector,
NgZone,
OnDestroy,
OnInit,
PLATFORM_ID,
@@ -21,7 +20,7 @@ import {
inject,
} from '@angular/core';
import {WINDOW, shouldReduceMotion, isIos} from '@angular/docs';
import {RouterLink} from '@angular/router';
import {ActivatedRoute, RouterLink} from '@angular/router';
import {injectAsync} from '../../core/services/inject-async';
@@ -45,11 +44,12 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
private readonly document = inject(DOCUMENT);
private readonly injector = inject(Injector);
private readonly ngZone = inject(NgZone);
private readonly platformId = inject(PLATFORM_ID);
private readonly window = inject(WINDOW);
private readonly activatedRoute = inject(ActivatedRoute);
protected readonly tutorialFiles = TUTORIALS_HOMEPAGE_DIRECTORY;
protected readonly isUwu = 'uwu' in this.activatedRoute.snapshot.queryParams;
private element!: HTMLDivElement;
private homeAnimation?: HomeAnimation;
private intersectionObserver: IntersectionObserver | undefined;
@@ -63,7 +63,7 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
}
}
ngAfterViewInit(): void {
ngAfterViewInit() {
this.element = this.home.nativeElement;
if (isPlatformBrowser(this.platformId)) {
@@ -74,10 +74,8 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
// at the end of the page, and to load the embedded editor.
this.initIntersectionObserver();
if (this.isWebGLAvailable() && !shouldReduceMotion()) {
this.ngZone.runOutsideAngular(async () => {
await this.loadHomeAnimation();
});
if (this.isWebGLAvailable() && !shouldReduceMotion() && !this.isUwu) {
this.loadHomeAnimation();
}
}
}
@@ -2,7 +2,7 @@
display: block;
padding: var(--layout-padding);
padding-block-end: 100px;
height: calc(98vh);
height: 100vh;
width: 100%;
box-sizing: border-box;
@@ -11,17 +11,19 @@ import {
ChangeDetectionStrategy,
Component,
DestroyRef,
EnvironmentInjector,
OnInit,
ViewChild,
afterNextRender,
inject,
signal,
} from '@angular/core';
import {DOCUMENT, NgFor, NgIf, ViewportScroller} from '@angular/common';
import {DOCUMENT, NgFor, NgIf} from '@angular/common';
import {MatTabGroup, MatTabsModule} from '@angular/material/tabs';
import {takeUntilDestroyed, toSignal} from '@angular/core/rxjs-interop';
import {distinctUntilChanged, filter, map, take} from 'rxjs/operators';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {distinctUntilChanged, map} from 'rxjs/operators';
import {DocContent, DocViewer} from '@angular/docs';
import {ActivatedRoute, Router, RouterLink, Scroll} from '@angular/router';
import {ActivatedRoute, Router, RouterLink} from '@angular/router';
import {ApiItemType} from './../interfaces/api-item-type';
import {ReferenceScrollHandler} from '../services/reference-scroll-handler.service';
import {
@@ -34,6 +36,7 @@ import {
API_REFERENCE_TAB_BODY_CLASS_NAME,
API_REFERENCE_TAB_URL_ATTRIBUTE,
} from '../constants/api-reference-prerender.constants';
import {AppScroller} from '../../../app-scroller';
@Component({
selector: 'adev-reference-page',
@@ -51,15 +54,7 @@ export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
private readonly document = inject(DOCUMENT);
private readonly router = inject(Router);
private readonly scrollHandler = inject(ReferenceScrollHandler);
private readonly scroller = inject(ViewportScroller);
private scrollEvent = toSignal(
this.router.events.pipe(
filter((e): e is Scroll => e instanceof Scroll),
take(1),
),
{initialValue: null},
);
private cardsDisplayedOnInit = false;
private readonly appScroller = inject(AppScroller);
ApiItemType = ApiItemType;
@@ -70,28 +65,24 @@ export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
membersMarginTopInPx = this.scrollHandler.membersMarginTopInPx;
selectedTabIndex = signal(0);
constructor() {
this.appScroller.disableScrolling = true;
}
ngOnInit(): void {
this.setPageContent();
}
ngOnDestroy() {
this.appScroller.disableScrolling = false;
}
ngAfterViewInit(): void {
this.setActiveTab();
if (this.canDisplayCards()) {
this.cardsDisplayedOnInit = true;
}
this.listenToTabChange();
}
membersCardsLoaded(): void {
const event = this.scrollEvent();
if (this.cardsDisplayedOnInit && event) {
// Cards loaded after scroll event happened. We have to handle the scroll event manually
if (event.position) {
this.scroller.scrollToPosition(event.position);
} else if (event.anchor) {
this.scroller.scrollToAnchor(event.anchor);
}
}
this.scrollHandler.setupListeners(API_TAB_CLASS_NAME);
}
@@ -35,6 +35,7 @@ export function mapApiManifestToRoutes(): Route[] {
),
},
data: {
label: api.name,
displaySecondaryNav: true,
},
});
@@ -11,7 +11,6 @@ import {
DestroyRef,
EnvironmentInjector,
Injectable,
NgZone,
OnDestroy,
afterNextRender,
inject,
@@ -27,6 +26,8 @@ import {
MEMBER_ID_ATTRIBUTE,
} from '../constants/api-reference-prerender.constants';
import {WINDOW} from '@angular/docs';
import {Router, Scroll} from '@angular/router';
import {AppScroller} from '../../../app-scroller';
export const SCROLL_EVENT_DELAY = 20;
export const SCROLL_THRESHOLD = 20;
@@ -41,8 +42,9 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
private readonly destroyRef = inject(DestroyRef);
private readonly document = inject(DOCUMENT);
private readonly injector = inject(EnvironmentInjector);
private readonly ngZone = inject(NgZone);
private readonly window = inject(WINDOW);
private readonly router = inject(Router);
private readonly appScroller = inject(AppScroller);
private readonly cardOffsetTop = new Map<string, number>();
private resizeObserver: ResizeObserver | null = null;
@@ -58,6 +60,23 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
this.setupMemberCardListeners();
this.setScrollEventHandlers();
this.listenToResizeCardContainer();
this.setupFragmentChangeListener();
}
private setupFragmentChangeListener() {
this.router.routerState.root.fragment
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((fragment) => {
// If there is no fragment or the scroll event has a position (traversing through history),
// allow the scroller to handler scrolling instead of going to the fragment
if (!fragment || this.appScroller.lastScrollEvent?.position) {
this.appScroller.scroll();
return;
}
const card = this.document.getElementById(fragment) as HTMLDivElement | null;
this.scrollToCard(card);
});
}
updateMembersMarginTop(selectorOfTheElementToAlign: string): void {
@@ -75,35 +94,30 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
return;
}
this.ngZone.runOutsideAngular(() => {
fromEvent(tocContainer, 'click')
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((event) => {
// Get the card member ID from the attributes
const target =
event.target instanceof HTMLButtonElement
? event.target
: this.findButtonElement(event.target as HTMLElement);
const memberId = this.getMemberId(target);
fromEvent(tocContainer, 'click')
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((event) => {
// Get the card member ID from the attributes
const target =
event.target instanceof HTMLButtonElement
? event.target
: this.findButtonElement(event.target as HTMLElement);
const memberId = this.getMemberId(target);
if (memberId) {
const card = this.document.querySelector<HTMLDivElement>(`#${memberId}`);
this.scrollToCard(card);
}
});
});
if (memberId) {
this.router.navigate([], {fragment: memberId, replaceUrl: true});
}
});
}
private setupMemberCardListeners(): void {
this.ngZone.runOutsideAngular(() => {
this.getAllMemberCards().forEach((card) => {
this.cardOffsetTop.set(card.id, card.offsetTop);
fromEvent(card, 'click')
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.scrollToCard(card);
});
});
this.getAllMemberCards().forEach((card) => {
this.cardOffsetTop.set(card.id, card.offsetTop);
fromEvent(card, 'click')
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.router.navigate([], {fragment: card.id, replaceUrl: true});
});
});
}
@@ -113,9 +127,7 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
takeUntilDestroyed(this.destroyRef),
);
this.ngZone.runOutsideAngular(() => {
scroll$.subscribe(() => this.setActiveCodeLine());
});
scroll$.subscribe(() => this.setActiveCodeLine());
}
private listenToResizeCardContainer(): void {
@@ -209,12 +221,10 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
this.resizeObserver?.disconnect();
this.resizeObserver = new ResizeObserver((_) => {
this.ngZone.run(() => {
const offsetTop = tabBody.getBoundingClientRect().top;
if (offsetTop) {
this.membersMarginTopInPx.set(offsetTop);
}
});
const offsetTop = tabBody.getBoundingClientRect().top;
if (offsetTop) {
this.membersMarginTopInPx.set(offsetTop);
}
});
this.resizeObserver.observe(tabBody);
@@ -8,7 +8,7 @@
import {FocusMonitor} from '@angular/cdk/a11y';
import {DOCUMENT} from '@angular/common';
import {DestroyRef, ElementRef, Injectable, NgZone, inject, signal} from '@angular/core';
import {DestroyRef, ElementRef, Injectable, inject, signal} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {fromEvent, combineLatest} from 'rxjs';
import {map, filter} from 'rxjs/operators';
@@ -33,7 +33,6 @@ export class SplitResizerHandler {
private readonly destroyRef = inject(DestroyRef);
private readonly document = inject(DOCUMENT);
private readonly focusMonitor = inject(FocusMonitor);
private readonly ngZone = inject(NgZone);
private container!: ElementRef<any>;
private content!: ElementRef<HTMLDivElement>;
@@ -151,13 +150,11 @@ export class SplitResizerHandler {
takeUntilDestroyed(this.destroyRef),
)
.subscribe(([_, keyEvent]) => {
this.ngZone.run(() => {
const shift = keyEvent.key === 'ArrowLeft' ? -1 : 1;
const shift = keyEvent.key === 'ArrowLeft' ? -1 : 1;
const contentWidth = this.getCurrentContainerWidth(this.content.nativeElement);
const editorWidth = this.getCurrentContainerWidth(this.editor!.nativeElement);
this.setWidthOfTheContainers(contentWidth + shift, editorWidth - shift);
});
const contentWidth = this.getCurrentContainerWidth(this.content.nativeElement);
const editorWidth = this.getCurrentContainerWidth(this.editor!.nativeElement);
this.setWidthOfTheContainers(contentWidth + shift, editorWidth - shift);
});
}
@@ -105,7 +105,7 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
margin-block-start: var(--layout-padding);
cursor: col-resize;
align-self: stretch;
height: var(--fixed-content-height);
height: 100vh;
&::before {
content: '';
@@ -133,7 +133,7 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
width: 100%;
min-width: 300px;
padding-block-start: var(--layout-padding);
height: var(--fixed-content-height);
height: 100vh;
}
.adev-split-tutorial {
@@ -143,7 +143,7 @@ export default class Tutorial implements AfterViewInit {
await Promise.all(
Object.entries(this.embeddedTutorialManager.answerFiles()).map(([path, contents]) =>
nodeRuntimeSandbox.writeFile(path, contents),
nodeRuntimeSandbox.writeFile(path, contents as string | Buffer),
),
);
@@ -161,7 +161,7 @@ export default class Tutorial implements AfterViewInit {
await Promise.all(
Object.entries(this.embeddedTutorialManager.tutorialFiles()).map(([path, contents]) =>
nodeRuntimeSandbox.writeFile(path, contents),
nodeRuntimeSandbox.writeFile(path, contents as string | Buffer),
),
);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,191 @@
<div class="page docs-viewer">
<h1 tabindex="-1">Update Guide</h1>
<div class="wizard">
<div>
<h2>Select the options that match your update</h2>
<h3>Angular versions</h3>
<div class="adev-version-selector">
<span class="adev-template-select">
From v.
<button [cdkMenuTriggerFor]="templatesMenuFrom">
<span>{{ from.name }}</span>
<docs-icon>expand_more</docs-icon>
</button>
<ng-template #templatesMenuFrom>
<ul class="adev-template-dropdown" cdkMenu>
@for (version of versions; track $index) {
<li>
<button cdkMenuItem type="button" (click)="from=version; showUpdatePath()">
<span>{{ version.name }}</span>
</button>
</li>
}
</ul>
</ng-template>
</span>
<span>
<span class="adev-template-select">
To v.
<button [cdkMenuTriggerFor]="templatesMenuTo">
<span>{{ to.name }}</span>
<docs-icon>expand_more</docs-icon>
</button>
<ng-template #templatesMenuTo>
<ul class="adev-template-dropdown" cdkMenu>
@for (version of versions; track $index) {
<li>
<button cdkMenuItem type="button" (click)="to=version; showUpdatePath()">
<span>{{ version.name }}</span>
</button>
</li>
}
</ul>
</ng-template>
</span>
</span>
</div>
@if (from.number >= futureVersion || to.number >= futureVersion) {
<div class="docs-alert docs-alert-critical">
<p>
<strong>Warning:</strong>
Plans for releases after the current major release are not finalized and may change.
These recommendations are based on scheduled deprecations.
</p>
</div>
}
@if (from.number > to.number) {
<div class="docs-alert docs-alert-critical">
<p>
<strong>Warning:</strong>
We do not support downgrading versions of Angular.
</p>
</div>
}
@if ((to.number - from.number > 150) && from.number > 240) {
<div class="docs-alert docs-alert-critical">
<p>
<strong>Warning:</strong>
Be sure to follow the guide below to migrate your application to the new version. You
can't run
<code>ng update</code>
to update Angular applications more than one major version at a time.
</p>
</div>
}
<h3>Application complexity</h3>
<mat-button-toggle-group
(change)="level = $event.value;"
[value]="level"
style="margin-bottom:16px;"
>
<mat-button-toggle [value]="1">Basic</mat-button-toggle>
<mat-button-toggle [value]="2">Medium</mat-button-toggle>
<mat-button-toggle [value]="3">Advanced</mat-button-toggle>
</mat-button-toggle-group>
@if (level === 1) {
<p>Shows information for all Angular developers.</p>
} @else if (level === 2) {
<p>Shows information that's of interest to more advanced Angular developers.</p>
} @else if (level === 3) {
<p>Shows all the information we have about this update.</p>
}
<h3>Other dependencies</h3>
@for (option of optionList; track $index) {
<div>
<mat-checkbox
(change)="options[option.id] = $event.checked; showUpdatePath()"
[checked]="options[option.id]"
>I use {{option.name}} {{option.description}}</mat-checkbox
>
</div>
}
@if (from.number < 600) {
<h4>Package Manager</h4>
<mat-button-toggle-group
(change)="packageManager = $event.value; showUpdatePath()"
[value]="packageManager"
>
<mat-button-toggle value="npm install">npm</mat-button-toggle>
<mat-button-toggle value="yarn add">yarn</mat-button-toggle>
</mat-button-toggle-group>
}
<button
type="button"
(click)="showUpdatePath()"
class="docs-primary-btn show-button"
[attr.text]="'Show me how to update!'"
>
Show me how to update!
</button>
</div>
</div>
<hr />
<!-- RECOMMENDATIONS SECTION -->
@if (
beforeRecommendations.length > 0 || duringRecommendations.length > 0 || afterRecommendations.length > 0
) {
<div class="recommendations">
<h2>{{title}}</h2>
<h3>Before you update</h3>
@for (r of beforeRecommendations; track $index) {
<div class="adev-recommentation-item">
<mat-checkbox></mat-checkbox>
<div [innerHTML]="r.renderedStep"></div>
</div>
}
@if (beforeRecommendations.length <= 0) {
<div>
<em>You don't need to do anything before moving between these versions.</em>
</div>
}
<h3>Update to the new version</h3>
@if (duringRecommendations.length > 0) {
<div>
<em>Review these changes and perform the actions to update your application.</em>
</div>
}
@for (r of duringRecommendations; track $index) {
<div class="adev-recommentation-item">
<mat-checkbox></mat-checkbox>
<div [innerHTML]="r.renderedStep"></div>
</div>
}
@if (duringRecommendations.length <= 0) {
<div>
<em>There aren't any recommendations for moving between these versions.</em>
</div>
}
<h3>After you update</h3>
@for (r of afterRecommendations; track $index) {
<div class="adev-recommentation-item">
<mat-checkbox></mat-checkbox>
<div [innerHTML]="r.renderedStep"></div>
</div>
}
@if (afterRecommendations.length <= 0) {
<div>
<em>You don't need to do anything after moving between these versions.</em>
</div>
}
</div>
}
</div>
@@ -0,0 +1,100 @@
.page {
padding: var(--layout-padding);
max-width: var(--page-width);
container: update-guide-page / inline-size;
}
h3,
h4 {
margin-block-start: 2em;
}
.wizard {
padding-inline: 1rem;
.show-button {
display: block;
margin-block-start: 2rem;
}
}
.adev-version-selector {
display: flex;
gap: 1rem;
}
.adev-template-dropdown {
border: 1px solid var(--senary-contrast);
border-radius: 0.25rem;
padding: 0;
transform: translateY(-0.7rem);
max-height: 200px;
overflow-y: auto;
li {
list-style: none;
width: 198px;
box-sizing: border-box;
button {
background: var(--page-background);
font-size: 0.875rem;
width: 100%;
text-align: left;
padding-block: 0.5rem;
color: var(--quaternary-contrast);
transition:
color 0.3s ease,
background 0.3s ease;
font-weight: 400;
&:hover {
background: var(--senary-contrast);
color: var(--primary-contrast);
}
}
}
}
.adev-template-select {
margin-block-end: 0.5rem;
// cdk select button
button {
font-size: 0.875rem;
border: 1px solid var(--senary-contrast);
border-radius: 0.25rem;
width: 200px;
display: inline-flex;
justify-content: space-between;
align-items: center;
padding-block: 0.5rem;
font-weight: 400;
transition: border 0.3s ease;
span {
color: var(--primary-contrast);
transition: color 0.3s ease;
margin-inline-start: 0.1rem;
}
docs-icon {
font-size: 1.3rem;
color: var(--quaternary-contrast);
transition: color 0.3s ease;
}
}
}
.adev-recommentation-item {
display: flex;
align-items: center;
> div {
margin-inline-start: 2rem;
}
// Code blocks are generable from the markdown, we need to opt-out of the scoping
::ng-deep code {
cursor: pointer;
}
}
@@ -0,0 +1,297 @@
import {ChangeDetectionStrategy, Component, HostListener, inject} from '@angular/core';
import {Step, RECOMMENDATIONS} from './recommendations';
import {Clipboard} from '@angular/cdk/clipboard';
import {CdkMenuModule} from '@angular/cdk/menu';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatInputModule} from '@angular/material/input';
import {MatCardModule} from '@angular/material/card';
import {MatGridListModule} from '@angular/material/grid-list';
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {IconComponent} from '@angular/docs';
import {ActivatedRoute, Router} from '@angular/router';
import {marked} from 'marked';
interface Option {
id: keyof Step;
name: string;
description: string;
}
@Component({
selector: 'adev-update-guide',
templateUrl: './update.component.html',
styleUrl: './update.component.scss',
imports: [
MatCheckboxModule,
MatInputModule,
MatCardModule,
MatGridListModule,
MatButtonToggleModule,
CdkMenuModule,
IconComponent,
],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class AppComponent {
protected title = '';
protected level = 1;
protected options: Record<string, boolean> = {
ngUpgrade: false,
material: false,
windows: isWindows(),
};
protected readonly optionList: Option[] = [
{id: 'ngUpgrade', name: 'ngUpgrade', description: 'to combine AngularJS & Angular'},
{id: 'material', name: 'Angular Material', description: ''},
{id: 'windows', name: 'Windows', description: ''},
];
protected packageManager: 'npm install' | 'yarn add' = 'npm install';
protected beforeRecommendations: Step[] = [];
protected duringRecommendations: Step[] = [];
protected afterRecommendations: Step[] = [];
protected readonly versions = [
{name: '18.0', number: 1800},
{name: '17.0', number: 1700},
{name: '16.0', number: 1600},
{name: '15.0', number: 1500},
{name: '14.0', number: 1400},
{name: '13.0', number: 1300},
{name: '12.0', number: 1200},
{name: '11.0', number: 1100},
{name: '10.2', number: 1020},
{name: '10.1', number: 1010},
{name: '10.0', number: 1000},
{name: '9.1', number: 910},
{name: '9.0', number: 900},
{name: '8.2', number: 820},
{name: '8.1', number: 810},
{name: '8.0', number: 800},
{name: '7.2', number: 720},
{name: '7.1', number: 710},
{name: '7.0', number: 700},
{name: '6.1', number: 610},
{name: '6.0', number: 600},
{name: '5.2', number: 520},
{name: '5.1', number: 510},
{name: '5.0', number: 500},
{name: '4.4', number: 440},
{name: '4.3', number: 430},
{name: '4.2', number: 420},
{name: '4.1', number: 410},
{name: '4.0', number: 400},
{name: '2.4', number: 204},
{name: '2.3', number: 203},
{name: '2.2', number: 202},
{name: '2.1', number: 201},
{name: '2.0', number: 200},
];
protected from = this.versions.find((version) => version.name === '17.0')!;
protected to = this.versions.find((version) => version.name === '18.0')!;
protected futureVersion = 1900;
protected readonly steps: Step[] = RECOMMENDATIONS;
private readonly clipboard = inject(Clipboard);
private readonly router = inject(Router);
private readonly activatedRoute = inject(ActivatedRoute);
constructor() {
const queryMap = this.activatedRoute.snapshot.queryParamMap;
// Detect settings in URL
this.level = parseInt(queryMap.get('l')!, 10) || this.level;
// Detect versions of from and to
const versions = queryMap.get('v');
if (versions) {
const [from, to] = versions.split('-');
this.from = this.versions.find((version) => version.name === from)!;
this.to = this.versions.find((version) => version.name === to)!;
this.showUpdatePath();
}
}
@HostListener('click', ['$event.target'])
copyCode({tagName, textContent}: Element) {
if (tagName === 'CODE') {
// TODO: add a toast notification
this.clipboard.copy(textContent!);
}
}
async showUpdatePath() {
this.beforeRecommendations = [];
this.duringRecommendations = [];
this.afterRecommendations = [];
// Refuse to generate recommendations for downgrades
if (this.to.number < this.from.number) {
alert('We do not support downgrading versions of Angular.');
return;
}
const labelTitle = 'Guide to update your Angular application';
const labelBasic = 'basic applications';
const labelMedium = 'medium applications';
const labelAdvanced = 'advanced applications';
this.title = `${labelTitle} v${this.from.name} -> v${this.to.name}
for
${this.level < 2 ? labelBasic : this.level < 3 ? labelMedium : labelAdvanced}`;
// Find applicable steps and organize them into before, during, and after upgrade
for (const step of this.steps) {
if (step.level <= this.level && step.necessaryAsOf > this.from.number) {
// Check Options
// Only show steps that don't have a required option
// Or when the user has a matching option selected
let skip = false;
for (const option of this.optionList) {
// Skip steps which require an option not set by the user.
if (step[option.id] && !this.options[option.id]) {
skip = true;
}
// Skip steps which require **not** using an option which **is** set
// by the user.
if (step[option.id] === false && this.options[option.id]) {
skip = true;
}
}
if (skip) {
continue;
}
// Render and replace variables
step.renderedStep = await marked(this.replaceVariables(step.action));
// If you could do it before now, but didn't have to finish it before now
if (step.possibleIn <= this.from.number && step.necessaryAsOf >= this.from.number) {
this.beforeRecommendations.push(step);
// If you couldn't do it before now, and you must do it now
} else if (step.possibleIn > this.from.number && step.necessaryAsOf <= this.to.number) {
this.duringRecommendations.push(step);
} else if (step.possibleIn <= this.to.number) {
this.afterRecommendations.push(step);
}
}
}
// Update the URL so users can link to this transition
this.router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: {v: `${this.from.name}-${this.to.name}`, l: this.level},
queryParamsHandling: 'merge',
});
// Tell everyone how to upgrade for v6 or earlier
this.renderPreV6Instructions();
}
private getAdditionalDependencies(version: number): string {
if (version < 500) {
return `typescript@'>=2.1.0 <2.4.0'`;
} else if (version < 600) {
return `typescript@2.4.2 rxjs@^5.5.2`;
} else {
return `typescript@2.7.x rxjs@^6.0.0`;
}
}
private getAngularVersion(version: number): string {
if (version < 400) {
return `'^2.0.0'`;
} else {
const major = Math.floor(version / 100);
const minor = Math.floor((version - major * 100) / 10);
return `^${major}.${minor}.0`;
}
}
private async renderPreV6Instructions(): Promise<void> {
let upgradeStep: Step;
const additionalDeps = this.getAdditionalDependencies(this.to.number);
const angularVersion = this.getAngularVersion(this.to.number);
const angularPackages = [
'animations',
'common',
'compiler',
'compiler-cli',
'core',
'forms',
'http',
'platform-browser',
'platform-browser-dynamic',
'platform-server',
'router',
];
// Provide npm/yarn instructions for versions before 6
if (this.to.number < 600) {
const actionMessage = `Update all of your dependencies to the latest Angular and the right version of TypeScript.`;
if (isWindows()) {
const packages =
angularPackages
.map((packageName) => `@angular/${packageName}@${angularVersion}`)
.join(' ') +
' ' +
additionalDeps;
upgradeStep = {
step: 'General Update',
action: `${actionMessage}
If you are using Windows, you can use:
\`${this.packageManager} ${packages}\``,
} as Step;
} else {
const packages = `@angular/{${angularPackages.join(',')}}@${angularVersion} ${additionalDeps}`;
upgradeStep = {
step: 'General update',
action: `${actionMessage}
If you are using Linux/Mac, you can use:
\`${this.packageManager} ${packages}\``,
} as Step;
}
// Npm installs typescript wrong in v5, let's manually specify
// https://github.com/npm/npm/issues/16813
if (this.packageManager === 'npm install' && this.to.number === 500) {
upgradeStep.action += `
\`npm install typescript@2.4.2 --save-exact\``;
}
upgradeStep.renderedStep = await marked(upgradeStep.action);
this.duringRecommendations.push(upgradeStep);
}
}
private replaceVariables(action: string): string {
let newAction = action;
newAction = newAction.replace(
'${packageManagerGlobalInstall}',
this.packageManager === 'npm install' ? 'npm install -g' : 'yarn global add',
);
newAction = newAction.replace('${packageManagerInstall}', this.packageManager);
return newAction;
}
}
/** Whether or not the user is running on a Windows OS. */
function isWindows(): boolean {
if (typeof navigator === 'undefined') {
return false;
}
const platform = navigator.platform.toLowerCase();
return platform.includes('windows') || platform.includes('win32');
}
-87
View File
@@ -1,87 +0,0 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {
inject,
Injector,
afterNextRender,
ENVIRONMENT_INITIALIZER,
ApplicationRef,
} from '@angular/core';
import {WINDOW} from '@angular/docs';
import {ɵafterNextNavigation as afterNextNavigation, Router} from '@angular/router';
import {firstValueFrom, filter, take} from 'rxjs';
/**
* An environment initializer that listens for browser navigate events,
* makes the browser navigation transition wait for the Angular Router navigation to fully render,
* and then restores scroll position and focus.
*/
export const SCROLL_INITIALIZER = {
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useFactory: () => {
const window = inject(WINDOW);
const injector = inject(Injector);
const router = inject(Router);
const applicationRef = inject(ApplicationRef);
return () => {
const navigation = window.navigation;
if (!navigation) {
return;
}
navigation.addEventListener('navigate', (navigateEvent) => {
if (!navigateEvent.canIntercept) {
return;
}
navigateEvent.intercept({
scroll: 'manual',
// Wait for router to respond to and process this navigation
handler: () =>
waitForFullNavigationRender(router, injector, applicationRef, navigateEvent),
});
});
};
},
};
async function waitForFullNavigationRender(
router: Router,
injector: Injector,
applicationRef: ApplicationRef,
navigateEvent: NavigateEvent,
) {
// Wait for the Router to process the navigation event and finish navigating
await afterNextNavigationPromise(router);
// Wait for Angular to run change detection, which activates routes
await afterNextRenderPromise(injector);
// Wait for any pending render tasks that might have happened when activating routes
await afterStablePromise(applicationRef);
navigateEvent.scroll();
}
/** Creates a promise that resolves after the next render */
function afterNextRenderPromise(injector: Injector) {
return new Promise<void>((resolve) => {
afterNextRender(resolve, {injector});
});
}
function afterNextNavigationPromise(router: Router) {
return new Promise<void>((resolve) => {
afterNextNavigation(router, resolve);
});
}
function afterStablePromise(applicationRef: ApplicationRef) {
return firstValueFrom(
applicationRef.isStable.pipe(
filter((stable) => stable),
take(1),
),
);
}
+8
View File
@@ -41,6 +41,12 @@ const referencePageRoutes = mapNavigationItemsToRoutes(
},
);
const updateGuidePageRoute: Route = {
path: referenceNavigationItems.find((r) => r.path === DefaultPage.UPDATE)!.path,
loadComponent: () => import('./features/update/update.component'),
data: commonReferenceRouteData,
};
const cliReferencePageRoutes = mapNavigationItemsToRoutes(
referenceNavigationItems.filter((r) => r.path?.startsWith(`${PagePrefix.CLI}/`)),
{
@@ -61,6 +67,7 @@ const docsReferencePageRoutes = mapNavigationItemsToRoutes(
referenceNavigationItems.filter(
(r) =>
r.path !== DefaultPage.REFERENCE &&
r.path !== DefaultPage.UPDATE &&
!r.path?.startsWith(`${PagePrefix.API}/`) &&
!r.path?.startsWith(`${PagePrefix.CLI}/`),
),
@@ -143,6 +150,7 @@ export const routes: Route[] = [
...SUB_NAVIGATION_ROUTES,
...API_REFERENCE_ROUTES,
...FOOTER_ROUTES,
updateGuidePageRoute,
],
},
// Error page
+47 -3
View File
@@ -228,6 +228,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/templates/control-flow',
contentPath: 'guide/templates/control-flow',
},
{
label: 'Local template variables with @let',
path: 'guide/templates/let-template-variables',
contentPath: 'guide/templates/let-template-variables',
},
{
label: 'Pipes',
children: [
@@ -640,6 +645,12 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
{
label: 'Experimental features',
children: [
{label: 'Zoneless', path: 'guide/experimental/zoneless', contentPath: 'guide/zoneless'},
],
},
],
},
{
@@ -679,9 +690,9 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'tools/cli/end-to-end',
},
{
label: 'ESBuild',
path: 'tools/cli/esbuild',
contentPath: 'tools/cli/esbuild',
label: 'Migrating to new build system',
path: 'tools/cli/build-system-migration',
contentPath: 'tools/cli/build-system-migration',
},
{
label: 'Build environments',
@@ -1040,6 +1051,10 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
label: 'config',
path: 'cli/generate/config',
},
{
label: 'directive',
path: 'cli/generate/directive',
},
{
label: 'enum',
path: 'cli/generate/enum',
@@ -1233,6 +1248,11 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'errors/NG0507',
contentPath: 'reference/errors/NG0507',
},
{
label: 'NG0602: HTML content was altered after server-side rendering',
path: 'errors/NG0602',
contentPath: 'reference/errors/NG0602',
},
{
label: 'NG05104: Root element was not found',
path: 'errors/NG05104',
@@ -1248,6 +1268,21 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'errors/NG0912',
contentPath: 'reference/errors/NG0912',
},
{
label: 'NG0913: Runtime Performance Warnings',
path: 'errors/NG0913',
contentPath: 'reference/errors/NG0913',
},
{
label: 'NG0950: Required input is accessed before a value is set.',
path: 'errors/NG0950',
contentPath: 'reference/errors/NG0950',
},
{
label: 'NG0951: Child query result is required but no value is available.',
path: 'errors/NG0951',
contentPath: 'reference/errors/NG0951',
},
{
label: 'NG0955: Track expression resulted in duplicated keys for a given collection',
path: 'errors/NG0955',
@@ -1358,6 +1393,11 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'extended-diagnostics/NG8109',
contentPath: 'reference/extended-diagnostics/NG8109',
},
{
label: 'NG8111: Functions must be invoked in event bindings',
path: 'extended-diagnostics/NG8111',
contentPath: 'reference/extended-diagnostics/NG8111',
},
],
},
{
@@ -1370,6 +1410,10 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'reference/versions',
contentPath: 'reference/versions',
},
{
label: 'Update guide',
path: 'update-guide',
},
{
label: 'Configurations',
children: [
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

+17 -17
View File
@@ -1,19 +1,19 @@
{
"name": "Angular",
"short_name": "Angular",
"icons": [
{
"src": "/assets/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/assets/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
"name": "Angular",
"short_name": "Angular",
"icons": [
{
"src": "/assets/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/assets/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

Before

Width:  |  Height:  |  Size: 311 KiB

After

Width:  |  Height:  |  Size: 311 KiB

Before

Width:  |  Height:  |  Size: 260 KiB

After

Width:  |  Height:  |  Size: 260 KiB

Before

Width:  |  Height:  |  Size: 211 KiB

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

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