Compare commits

...

471 Commits

Author SHA1 Message Date
Dylan Hunn d6391eed23 release: cut the v18.0.0 release 2024-05-22 10:54:42 -07:00
Paweł Kubiak e3aa2b59ba fix(docs-infra): calculate list of Angular Docs versions based on VERSION (#56002)
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 #56002
2024-05-22 17:27:05 +00:00
Andrew Scott a6eedbc2e8 docs: Add experimental and zoneless to nav (#55834)
PR Close #55834
2024-05-22 10:18:54 -07:00
Kristiyan Kostadinov b7f2fd4739 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:33 -07:00
Matthieu Riegler f8a2ad6e99 docs: Add v18 to update guide (#55993)
PR Close #55993
2024-05-22 16:03:02 +00:00
Joey Perrott 3ac0511aad 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 ef96158899 release: cut the v18.0.0-rc.3 release 2024-05-21 14:37:26 -07:00
arturovt e598634c10 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 58b2fc4f81 docs: update robot.txt to index angular.dev (#55617)
PR Close #55617
2024-05-21 13:41:06 -07:00
Tom Wilkinson b79b6c14de 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 999bfac737 build: update actions/checkout digest to a5ac7e5 (#55889)
See associated pull request for more information.

PR Close #55889
2024-05-21 12:19:37 -07:00
Sasidharan SD cbe3a029fa docs: fix broken publish library link (#55895)
PR Close #55895
2024-05-21 12:15:12 -07:00
Ben Hong 81c99ac5b9 docs: add missing border on embedded editor (#55926)
PR Close #55926
2024-05-21 12:14:18 -07:00
Matthieu Riegler 0c75267ebf docs(docs-infra): Add update guide to adev (#55638)
PR Close #55638
2024-05-21 12:01:59 -07:00
Joey Perrott a44a4689ca 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 33d0102304 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 5052d4c998 docs(common): fix FormatWidth.Short description (#55821)
PR Close #55821
2024-05-20 23:39:24 -07:00
Andrew Kushnir 77eb4ca061 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:19 -07:00
cexbrayat 4f4f41016e 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 c881c3e0c6 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 0cbd73c6e9 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 e923a76400 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 9f7227cb8f 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:42 -07:00
arturovt 3657358270 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:30 -07:00
Charles Lyding b7f67b4453 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
Rahat Ahmed 239d4f0c9e 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 a78144ac21 docs: fix broken link in signals/model (#55811)
PR Close #55811
2024-05-17 12:25:46 -07:00
Jens Kuehlers f0f85dbe2f 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 0147e0b85a 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 8d93597a82 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:15:05 -07:00
Matthieu Riegler 0e16654be4 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:08 -07:00
Thomas Nguyen f8a6ebd977 docs: Add documentation for event replay (#55802)
PR Close #55802
2024-05-17 10:10:08 -07:00
Paul Gschwendtner 69a83993b3 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 6025424fea 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 eba92cfa55 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 3055b924af 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:18 -07:00
Alan Agius a768c90ee7 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:33 -07:00
cexbrayat 69085ea26e fix(core): error about provideExperimentalCheckNoChangesForDebug uses wrong name (#55824)
The error about `provideExperimentalCheckNoChangesForDebug` mentions `provideCheckNoChangesForDebug` instead.

PR Close #55824
2024-05-16 09:02:29 -07:00
Andrew Scott e6d8f7459e release: cut the v18.0.0-rc.2 release 2024-05-15 15:50:11 -07:00
Andrew Scott e76bebd409 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:27 -07:00
Thomas Nguyen 88fb94693a 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 2e27ca9ddf 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:26 -07:00
Angular Robot 5775fd245e 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 762f97e153 build: update dependency gulp-conventional-changelog to v5 (#55669)
See associated pull request for more information.

PR Close #55669
2024-05-15 08:52:31 -07:00
Pawel Kozlowski a141478940 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:28 -07:00
Angular Robot c15965721e build: update scorecard action dependencies (#55786)
See associated pull request for more information.

PR Close #55786
2024-05-15 08:48:34 -07:00
Andrew Scott eda86d5347 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 c4b2f18709 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 43525988b8 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 3b1b4e20c1 refactor(core): Move preventDefault to Dispatcher (#55756)
This is a simple move.

PR Close #55756
2024-05-14 14:35:00 -07:00
Joey Perrott 6850ff18b6 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:27 -07:00
Sasidharan SD 55d694275b docs: fix production mode broken link (#55794)
PR Close #55794
2024-05-14 12:21:30 -07:00
Alex Rickabaugh 1fd63e9cff 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 e7782d4d04 build: update all non-major dependencies (#55785)
See associated pull request for more information.

PR Close #55785
2024-05-14 11:33:19 -07:00
Joey Perrott e205dcb21b 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 bb4a4016a9 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 beedb685bf build: update cross-repo angular dependencies (#55781)
See associated pull request for more information.

PR Close #55781
2024-05-14 10:54:18 -07:00
Andrew Kushnir 8902312e0f docs: add a note about development status of zone.js (#55746)
PR Close #55746
2024-05-14 10:53:43 -07:00
Thomas Nguyen bfb5f2ba59 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 89e860cc30 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 9d1acd6e92 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 dc0c55c930 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:10 -07:00
Angular Robot a028943895 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:34 -07:00
Sasidharan SD 179c678e6b docs: add inspecting injector section in devtools (#55764)
PR Close #55764
2024-05-13 11:17:50 -07:00
Matthieu Riegler 5f3742de6c 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 db4e46684b docs: add service worker images (#55780)
PR Close #55780
2024-05-13 11:14:50 -07:00
Angular Robot 574a7bc666 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 6906ff0131 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 cd96464335 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 028a1d0af7 docs: fix devtools links (#55766)
PR Close #55766
2024-05-13 11:08:32 -07:00
Charles Lyding db8fb02f6a 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 eb31f2c775 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:04 -07:00
iteriani 7c9d37d798 refactor(core): Remove enums from event-dispatch. (#55421)
These cause optimization issues in external.

PR Close #55421
2024-05-13 09:12:45 -07:00
Andrew Kushnir 897e8dbf08 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 72b107b2a7 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 d00f9e85bb 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 61007dced0 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:15 -07:00
Ben Hong 28a24b6f79 docs: fix visible code snippets in first-app tutorial (#55742)
PR Close #55742
2024-05-08 15:46:52 -07:00
Alan Agius f9aac834f5 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:30 -07:00
Doug Parker 84f16391a5 release: bump Angular DevTools to version 1.0.16 (#55715)
PR Close #55715
2024-05-08 11:11:43 -07:00
Doug Parker dc6a02fa48 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:09:05 -07:00
Andrew Kushnir a9dd754ad5 release: cut the v18.0.0-rc.1 release 2024-05-08 09:03:17 -07:00
Matthieu Riegler e70167217b docs: uwu (#55666)
PR Close #55666
2024-05-07 14:57:26 -07:00
Alan Agius 129639359a 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 a916047a83 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:56 -07:00
Andrew Scott 6b97aec621 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:14 -07:00
Andrew Scott 9eb7478e5d 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:43 -07:00
Angular Robot 42263e167a 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:38 -07:00
Tom Wilkinson 1b631ae52e 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 bdd6d3c4d8 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:17 -07:00
arturovt 2646c4050d 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:34 -07:00
Paul Gschwendtner 232ec657e8 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:49 -07:00
Angular Robot fdf4941d4b 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
AleksanderBodurri a5f29f9127 refactor(devtools): remove git sha stamping from devtools build (#55694)
This stamping is interfering with publishing to the Firefox addons store by brining in the entirety of the `.git` directory as part of the source code necessary for a reproducible build, which Firefox requires as part of it's approval process.

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

PR Close #55694
2024-05-06 16:02:44 -07:00
Andrew Scott b721e5d9c8 refactor(core): private export token that indicates if zone scheduling is provided (#55690)
This is needed internally to determine whether to provide zone or
zoneless by default.

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

PR Close #55327
2024-05-06 16:01:01 -07:00
Rahat Ahmed 8483721f32 refactor(core): Remove unused JSNAMESPACE_SUPPORT from event-dispatch (#55619)
The usage of this option has been removed from google3 code, so we don't
need to keep it around anymore.

PR Close #55619
2024-05-06 14:58:26 -07:00
Andrew Scott 0510930a25 fix(core): TestBed should not override NgZone from initTestEnvironment (#55226)
Prior to this change, `NgZone` was provided by default in TestBed in a
location that would override anything configured in
`TestBed.initTestEnvironment`. This change moves the default `NgZone`
provider to the `RootScopeModule` and these providers can be overridden
by the ones in `additionalModuleTypes`, which are assigned from the
first argument of `initTestEnvironment`. This makes it possible to
configure Zone globally for all tests as opposed to needing to repeat it
in `configureTestingModule` of each suite.

PR Close #55226
2024-05-06 13:33:17 -07:00
Alan Agius a040fb720a fix(compiler): maintain multiline CSS selectors during CSS scoping (#55509)
Previously, multiline selectors were being converted into single lines, resulting in sourcemap disruptions due to shifts in line numbers.

Closes #55508

PR Close #55509
2024-05-06 12:39:50 -07:00
Andrew Kushnir 5c8c2eb60c refactor(animations): make async animations code compatible with Closure compiler (#55686)
Closure compiler optimizations in g3 require `.then` to be present for a dynamic import (or an import should be `await`ed) to detect the set of imported symbols. Currently, the `.then` is located at a later stage in the file, which confuses static code analysis. This change adds the `.then((m) => m)` workaround to satisfy Closure compiler constraints.

PR Close #55686
2024-05-06 12:35:24 -07:00
Alan Agius b74a17e1e2 ci: update Renovate configuration: replace matchPackagePatterns with matchDepPatterns (#55683)
This commit addresses a warning in Renovate regarding a deprecated behavior that will be phased out in the future.

```
WARNING: To prevent future issues, replace the usage of matchPackagePatterns with matchDepPatterns (repository=angular/angular, baseBranch=main)
       "packageRule": {
         "matchPackagePatterns": ["^@bazel/.*", "^build_bazel.*"],
         "groupName": "bazel setup",
         "schedule": ["at any time"]
       },
       "packageName": "bazelbuild/rules_nodejs",
       "depName": "build_bazel_rules_nodejs"
```

PR Close #55683
2024-05-06 12:34:10 -07:00
Alan Agius 5a83e61c2a ci: remove stopUpdatingLabel setting (#55683)
This commit removes the 'stopUpdatingLabel' option from Renovate settings. This option caused pull requests to not automatically rebase when  conflicting.

PR Close #55683
2024-05-06 12:34:09 -07:00
Alan Agius e71e869112 fix(platform-server): remove event dispatch script from HTML when hydration is disabled (#55681)
Prior to this commit, the included event dispatcher remained in the HTML even when hydration was disabled.

PR Close #55681
2024-05-06 12:33:09 -07:00
Angular Robot 4a01e5a532 build: lock file maintenance (#55680)
See associated pull request for more information.

PR Close #55680
2024-05-06 12:32:19 -07:00
Alan Agius 073b168677 build: remove mermaid from deps (#55664)
This dependency is now pulled via `@angular/docs`

PR Close #55664
2024-05-06 12:31:28 -07:00
Alan Agius d9b339fdbc fix(http): resolve withRequestsMadeViaParent behavior with withFetch (#55652)
This commit addresses dependency injection defects when using the `withFetch` API. Formerly, utilizing `withFetch` led to the automatic setting of `HttpBackend` to `FetchBackend`, which proved problematic in certain scenarios. Notably, conflicts arose when integrating `withRequestsMadeViaParent` and manually overriding tokens, as observed in instances like `InMemoryWebApiModule`.

PR Close #55652
2024-05-06 12:29:53 -07:00
cexbrayat 8459ee46cb fix(migrations): handle more cases in HttpClientModule migration (#55640)
This commit handles two cases that were breaking applications when using the new migration:

- tests using `HttpClientModule` in `TestBed.configureTestingModule` were broken as the import was removed, but the module is still present in the test configuration. It now properly adds `provideHttpClient(withInterceptorsFromDi())` and related imports to the test.
- tests using `HttpClientTestingModule` were migrated to use `provideHttpClient(withInterceptorsFromDi())` but the necessary imports were not added. They are now added by the migration.

PR Close #55640
2024-05-06 12:29:18 -07:00
Andrew Scott 3de1bc6866 docs: small updates to zoneless docs (#55636)
PR Close #55636
2024-05-06 12:28:36 -07:00
iteriani 6baa3bcc57 refactor(core): Allow the container and the listenable element to be configurable for early event contract. (#55586)
This will allow a multi-app application to listen to early events from different elements and place them
on a separate field on the window.

PR Close #55586
2024-05-06 08:15:54 -07:00
Angular Robot f1dc74fd1b build: update cross-repo angular dependencies (#55422)
See associated pull request for more information.

PR Close #55422
2024-05-03 13:00:19 -07:00
Alan Agius 0a8f6a71d8 ci: use application builder for integration tests (#55660)
This updates the integration tests to use the application builder.

PR Close #55660
2024-05-03 11:21:07 -07:00
Alan Agius fd9bf3a214 ci: delate aio-payloads.json (#55659)
This file is no longer used.

PR Close #55659
2024-05-03 11:20:13 -07:00
Alan Agius a97ac32241 ci: add adev build as part of the CI process (#55662)
Currently, this is not which caused main to be broken because breakages where not caught during PR

PR Close #55662
2024-05-03 10:20:59 -07:00
Alan Agius 9a6a4cca2f build: fix adev build (#55662)
adev is broken at head

PR Close #55662
2024-05-03 10:20:59 -07:00
Alan Agius 05fa8e23cd build: update integration tests lock files (#55661)
This should fix CI.

PR Close #55661
2024-05-03 09:17:18 -07:00
Alan Agius a733525f70 build: remove tslint and codelyzer deps from integration tests (#55658)
These are redundant.

PR Close #55658
2024-05-03 08:15:42 -07:00
cexbrayat 3b2dbf5a65 docs: typo in RedirectFunction description (#55653)
PR Close #55653
2024-05-03 08:08:12 -07:00
Matthieu Riegler 23f914f101 fix(platform-browser): Use the right namespace for mathML. (#55622)
Prior to this change, MathML element were created with the wrong namespace resulting in regular DOM `Element`.

This commit fixes this.

Related to #55608 (but doesn't fix it entirely).

PR Close #55622
2024-05-03 08:07:32 -07:00
Angular Robot 333a925475 build: update dependency typescript to v5.4.5 (#55042)
See associated pull request for more information.

PR Close #55042
2024-05-03 08:06:42 -07:00
Alan Agius bf884270af build: update cross-repo angular dependencies (#55654)
See associated pull request for more information.

PR Close #55654
2024-05-03 08:04:41 -07:00
arturovt 6e02e50fa1 fix(zone.js): add missing APIs to Node.js fs patch (#54396)
This commit updates the list of Node.js `fs` APIs to be patched because
they haven't been updated for a long time. It adds `opendir,lutimes,writev`.
For example, the `opendir` method was added to Node.js in version 12.12.0 in
2019, causing some of the APIs to potentially be always called within the
`<root>` context.

**Note:** There are missing unit tests for these changes because in unit tests,
`fs` is patched by Bazel's Node.js rules and its `node_patches.cjs`. However,
the APIs are successfully patched in the real production code and are called
with the correct context.

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

PR Close #55639
2024-05-02 14:46:32 -07:00
Andrew Scott b8c0084c50 refactor(core): Update coalescing to just use patched timers in root zone (#55366)
Rather than attempting to use the native timing functions, this commit
simplifies the logic significantly by using the global timer functions
as they are, either patched or unpatched. When Zone is defined, we run
the timers in the root zone. This has more predictable behavior and
timing than (a) using both patched and unpatched versions of timers in
different places (b) trying to get an unpatched timer and failing due to
environment specifics and patches that aren't ZoneJS.

PR Close #55366
2024-05-02 14:43:10 -07:00
Andrew Kushnir 93dc65a674 refactor(core): mark @defer APIs as stable (#55625)
This commit removes the `@developerPreview` annotation from the `@defer` APIs, effectively promoting them (and the entire feature!) to stable.

PR Close #55625
2024-05-02 14:42:00 -07:00
Doug Parker 73de8b6f8d release: bump Angular DevTools to 1.0.15 (#55643)
PR Close #55643
2024-05-02 13:37:42 -07:00
Rahat Ahmed 662bca47f6 refactor(core): Turn off JSNAMESPACE_SUPPORT by default (#55598)
All usages in google3 have been deleted so this should be a no-op. Next I'll clean up all the configurations turning this off and then delete the option entirely.

PR Close #55598
2024-05-02 12:34:24 -07:00
twerske 8dbeafea47 docs: style the nav based on version type (#55628)
PR Close #55628
2024-05-02 12:33:27 -07:00
Kristiyan Kostadinov 91b007e58f fix(compiler): add math elements to schema (#55631)
Fixes that we didn't have the MathML elements in the schema. Note that we can't discover which tag names are available by looking at globally-available classes, because all MathML elements are `MathMLElement` rather than something like `SVGCircleElement`. As such, I ended up having to hardcode the currently-available tags.

Fixes #55608.

PR Close #55631
2024-05-02 11:12:15 -07:00
cexbrayat da5ef5213a docs: typos in NG0956 (#55630)
PR Close #55630
2024-05-02 11:10:59 -07:00
Angular Robot 4a45910904 build: update io_bazel_rules_sass digest to 9f8be59 (#55602)
See associated pull request for more information.

PR Close #55602
2024-05-02 11:06:56 -07:00
iteriani 8432d75b9a refactor(core): Remove jsaction from element after handling the event. (#55549)
This also adds a test to make sure that the event contract is still listening to other events, especially in the case where we may want partial hydration in the future.

PR Close #55549
2024-05-02 11:04:59 -07:00
Andrew Scott 243f573797 Revert "fix(core): render hooks should not specifically run outside the Angular zone (#55399)" (#55624)
This reverts commit 7e89753eef.

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

PR Close #55624
2024-05-02 11:00:39 -07:00
Andrew Scott d5edfde6ee fix(core): afterRender hooks registered outside change detection can mark views dirty (#55623)
This commit fixes an error in the looping logic of `ApplicationRef.tick`
when the tick skips straight to render hooks. In this case, if a render
hook makes a state update that requires a view refresh, we would never
actually refresh the view and just loop until we hit the loop limit.

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

Fixes #55475.

PR Close #55605
2024-05-01 15:10:32 -07:00
Emma Twersky ce672c6829 docs: update press kit to reduce confusion (#55611)
PR Close #55611
2024-05-01 15:09:39 -07:00
Matthieu Riegler 9aa47c1983 docs: fix missing example (#55584)
preview is hidding was responsible for hidding the content.

fixes #55583

PR Close #55584
2024-05-01 15:07:58 -07:00
Angular Robot ccc0902dd2 build: update actions/checkout digest to 0ad4b8f (#55537)
See associated pull request for more information.

PR Close #55537
2024-05-01 15:07:24 -07:00
Tom Wilkinson 4837621df8 refactor(core): Move action resolution into a standalone class. (#55523) (#55621)
This refactor will enable moving this functionality into the dispatcher.

PR Close #55523

PR Close #55621
2024-05-01 15:02:22 -07:00
Tom Wilkinson 7dce62bb05 refactor(core): Remove STOP_PROPAGATION define. (#55582) (#55621)
This define has been removed at head, and now legacy stop propagation
behavior can be opted into at the LegacyDispatcher level, if necessary.

PR Close #55582

PR Close #55621
2024-05-01 15:02:22 -07:00
Tom Wilkinson d1721c3d51 refactor(core): Add a boostrapCustomEvent method. (#55603) (#55621)
This can replace CUSTOM_EVENT_SUPPORT by allowing users to bootstrap
custom event support separately from the `EventContract`.

PR Close #55603

PR Close #55621
2024-05-01 15:02:22 -07:00
Rahat Ahmed e58ff4a6dd docs(core): Add event-dispatch README.md (#55521)
PR Close #55521
2024-05-01 11:53:26 -07:00
Andrew Kushnir 92a1e59529 release: cut the v18.0.0-rc.0 release 2024-05-01 11:47:42 -07:00
Doug Parker 78e4af0f0a release: bump DevTools to 1.0.14 (#55545)
PR Close #55545
2024-04-30 17:02:00 -07:00
Andrew Scott 122478c202 refactor(core): Ensure animations are flushed before running render hooks (#55564)
This commit ensures we flush animations by calling renderFactory
begin/end in cases where the ApplicationRef._tick happens in a mode that
skips straight to the render hooks.

PR Close #55564
2024-04-30 15:39:57 -07:00
Ben Hong 354cd9cd57 docs: add README for adev site (#55578)
PR Close #55578
2024-04-30 14:04:56 -07:00
Angular Robot 43b604bedf build: lock file maintenance (#55575)
See associated pull request for more information.

PR Close #55575
2024-04-30 14:04:00 -07:00
Andrew Scott e7225dd06d docs: Reference page anchor scroll consistency (#55566)
The docs-viewer loads asynchronously and can happen after the scroll
event has happened and the Router has attempted to scroll to the
requested position/anchor. This commit saves the scroll event and
handles it again if the cards are loaded after scrolling happens.

PR Close #55566
2024-04-30 14:03:08 -07:00
twerske 76fd874039 docs: fix formatting for signal inputs guide (#55275)
PR Close #55275
2024-04-30 14:02:14 -07:00
Serge K Lebedev 0c82c10e59 docs(changelog): remove duplicate mutate removal entry in 17.0.0 (#53471)
PR Close #53471
2024-04-30 14:00:43 -07:00
Paul Gschwendtner 8226327799 build: improve incremental rebuilds of compliance tests (#55594)
Currently whenever a compliance test case TS file is modified, all
compliance tests in repository are rebuilt in partial compilation mode.
This is inefficient and also slows down local development where one may
use a wildcard to run all test targets inside `/test/compliance/...`.

This commit fixes this.

PR Close #55594
2024-04-30 09:22:46 -07:00
Pawel Kozlowski 8f99946d1d docs(core): add documentation for errors NG0955 and NG0956 (#55591)
This commit adds detailed description for the errors NG0955 and NG0956.
Those errors correspond to the check introduced in the built-in for loop.

PR Close #55591
2024-04-30 09:21:34 -07:00
Angular Robot 09613c194a build: update scorecard action dependencies (#55589)
See associated pull request for more information.

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

fixes #53985

PR Close #55105
2024-04-30 09:19:14 -07:00
Joey Perrott f7ba9d26cf ci: complete migration to prettier formatting (#55580)
Format the remaining unformatted files in the repository

PR Close #55580
2024-04-29 14:00:17 -07:00
Mikal Callahan 3113d8414c docs(docs-infra): allow file renaming in code editor (#54989)
Any filename but the main.ts is now editable.

PR Close #54989
2024-04-29 13:42:27 -07:00
Matthieu Riegler 1595c9dbc2 docs: add mention of the HTTP client for interceptors (#55551)
fixes #53911

PR Close #55551
2024-04-29 13:41:12 -07:00
Matthieu Riegler 3eadaf0f2a docs: fix broken link to error doc (#55547)
PR Close #55547
2024-04-29 13:40:03 -07:00
ahmadhakeem18 3c46d3f518 docs: update NgClass example description to match the example's behavior (#55209)
Co-authored-by: Sonu Kapoor <sonukapoor@users.noreply.github.com>

PR Close #55209
2024-04-29 13:39:19 -07:00
ahmadhakeem18 d3dce326d7 docs: show the difference between pseudo classes angular uses and native ones in runtime (#53819)
PR Close #53819
2024-04-29 13:35:34 -07:00
Doug Parker 0dcae69aaf refactor(compiler): add handler attribute to XMB output (#54865)
This allows tracking of which tools generated which XMB files and helps attribute Angular usage.

PR Close #54865
2024-04-29 11:56:32 -07:00
Joey Perrott 89dfb24b3a refactor: migrate compiler-cli to prettier formatting (#55485)
Migrate formatting to prettier for compiler-cli from clang-format

PR Close #55485
2024-04-29 10:25:45 -07:00
Joey Perrott 9d898982ad refactor: migrate zone.js to prettier formatting (#55427)
Migrate formatting to prettier for zone.js from clang-format

PR Close #55427
2024-04-29 09:52:07 -07:00
Joey Perrott 26ad8dd9f4 refactor: migrate core to prettier formatting (#55488)
Migrate formatting to prettier for core from clang-format

PR Close #55488
2024-04-29 09:49:21 -07:00
Andrew Scott b5ec30a929 refactor(core): Permit disabling autoDetect for zoneless fixture (#55494)
The caveat here is that this needs to be done before creating the
fixture. There are some technical issues to overcome with disabling it
after it was already enabled, related to detaching from `ApplicationRef`
without other side effects.

PR Close #55494
2024-04-26 09:42:16 -07:00
Kristiyan Kostadinov f93e5180be fix(migrations): resolve multiple structural issues with HttpClient migration (#55557)
Fixes several issues with the `HttpClient` migration that showed up after I tried updating the Material docs site to the latest v18 release. Includes:
* The migration was assuming that all Angular decorators have at least one argument. This led to a null pointer error that broke the v18 update process when I was testing it.
* The migration incorrectly reimplemented the detection of classes with Angular decorators. This can cause code to be migrated incorrectly and doesn't handle cases like import aliases. I've switched it to use the existing tooling for detecting decorated classes.
* The migration was trying to migrate directives, even though they don't support the `imports` field.
* The migration was detecting `TestBed.configureTestingModule` calls using a raw string match which is very fragile and can be broken by the user's formatting.
* There were syntax errors in the unit tests.
* There were type checking errors in the unit tests, for example none of them were importing the Angular decorators that they were migrating.

There's more room for improvement, but this should resolve the most glaring issues without having to rewrite too much.

PR Close #55557
2024-04-26 09:32:31 -07:00
Matthieu Riegler 21532f8eb8 docs: update ChangeDetectionStrategy links (#55553)
fixes #54227
fixes #50943

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

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

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

PR Close #55550
2024-04-26 09:29:37 -07:00
iteriani 7a976784c0 refactor(platform-server): Update event_replay_spec to more match production code. (#55517)
Notably, do evals where in SSR we evaluate a contract binary and evaluate scripts.

PR Close #55517
2024-04-25 14:58:12 -07:00
Matthieu Riegler a39f2ff92d refactor(devtools): hide hydration error when the component tree is collapsed (#54912)
This commit improves the devtools UX.

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

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

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

Fixes #53704

PR Close #54912
2024-04-25 14:57:23 -07:00
Andrew Scott 9ec01367b7 refactor(core): Do not duplicate change detection with run coalescing (part 2) (#55403)
This commit prevents doubling change detections when the zoneless
scheduler is notified first, followed by the zone becomeing unstable
(effectively "scheduling" zone-based change detection). When run
coalescing is enabled, this would otherwise result in the zoneless
scheduler running change detection first and then change detection
running again because of the run coalescing since both scheduler use the
same timing function (and then it would be FIFO).

PR Close #55403
2024-04-25 14:31:17 -07:00
Andrew Scott a80fa8d1a5 refactor(core): Omit listeners from out-of-zone scheduling when using ZoneJS (#55492) (#55525)
In Angular today, a bound listener automatically marks the view for
check. When using ZoneJS, these listeners are most often executed in the
Angular Zone as well, so synchronization (`ApplicationRef.tick`) will
eventually happen. _However_, developers can opt out of zone-patching
for events in several ways, and often do this for very frequent
listeners like `mousemove`, `resize`, and `scroll`. We do not want to
break existing expectations that these are now "safe" events to have
listeners for by automatically scheduling change detection regardless of
whether the listener executed inside or outside the Angular zone.

In contrast, in order for developers to more easily transition to zoneless,
we need to be able to ensure that components which are using `OnPush`
are, for the most part, compatible with zoneless as well. Because listeners
automatically mark the component for check, developers using `OnPush`
did not/do not need to also call `ChangeDetectorRef.markForCheck` or a
similar API. Unfortunately, this means that we need to consider the
listener callbacks as a notification to schedule a `tick` when Zoneless
is enabled. In the future, we would like to have an opt-out for this
(i.e. signal components) since it's not really how we _want_ things to work.

Also includes the fix for #54919 that got reverted only because it was
easier to revert the set of conflicting commits

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

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

PR Close #55532
2024-04-25 12:50:46 -07:00
Matthieu Riegler ce0a1cbd46 docs: fix the file naming for the NG05000 error (#55519)
PR Close #55519
2024-04-25 12:49:56 -07:00
Andrew Scott e4b0989cb2 docs: Add some zoneless documentation (#55500)
Probably needs more work, but it's a start

PR Close #55500
2024-04-25 12:49:16 -07:00
Tom Wilkinson ae29f04f7b refactor(core): Remove A11Y_SUPPORT_IN_DISPATCHER behavior. (#55497)
The only use case internally has been removed and this can be
accomplished with A11Y_CLICK_SUPPORT_DEFERRED.

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

fixes #55299

PR Close #55399
2024-04-25 09:06:39 -07:00
Kristiyan Kostadinov a5c57c7484 fix(core): resolve error for multiple component instances that use fallback content (#55478)
Currently fallback content for `ng-content` gets declared and rendered out in one go. This breaks down if multiple instances of the same component are used where one doesn't render the fallback content while the other one does, because the `TNode` for the content has to be created during the first creation pass.

These changes resolve the issue by always _declaring_ the template, but only rendering it if the slot is empty.

Fixes #55466.

PR Close #55478
2024-04-25 09:04:01 -07:00
ice-blaze 5ad2f5f18b refactor(forms): replace errors with hasError() (#55379)
Material documentation use hasError. For homogeneity reason, this commit
will adopt material style.

Fixes #55378

PR Close #55379
2024-04-25 08:57:30 -07:00
Kirk Larkin 242fec847e docs: Update lightweight-injection-tokens.md (#55490)
PR Close #55490
2024-04-25 08:55:46 -07:00
yuichi.imori 10040e99e9 docs: Correct code references in Tutorial 01. (#55506)
PR Close #55506
2024-04-25 08:55:08 -07:00
Ben Hong 1e58aa00b8 docs: update security guide link references (#55514)
PR Close #55514
2024-04-25 08:54:31 -07:00
Ben Hong dcf737ee56 fix(docs-infra): add cookie consent gtag event default state (#54574)
This PR sets a default state for cookie consent of 'denied'. The other part of the PR exists in the angular/dev-infra repo which will grant permission when the user accepts the cookie banner.

PR Close #54574
2024-04-25 08:53:07 -07:00
Pawel Kozlowski 44c0ed83a6 fix(core): hide implementation details of ExperimentalPendingTasks (#55516)
The ExperimentalPendingTasks service was accidently exposing one of its
internal fields as a public one. This commit fixes this by marking the
field in question as private.

PR Close #55516
2024-04-25 08:51:01 -07:00
Andrew Kushnir 2a3db67cdf release: cut the v18.0.0-next.6 release 2024-04-25 08:34:43 -07:00
Andrew Kushnir e478180b9b docs: release notes for the v17.3.6 release 2024-04-25 08:28:37 -07:00
Andrew Kushnir e3d5607caf Revert "refactor(core): Ensure DOM removal happens when no app views need refresh (#55132)" (#55524)
This reverts commit a07ea069e5.

PR Close #55524
2024-04-24 16:35:57 -07:00
Andrew Kushnir 28905ab9ae Revert "refactor(animations): Ensure async animations applies changes when loaded in zoneless (#55132)" (#55524)
This reverts commit 9ab36cfe0a.

PR Close #55524
2024-04-24 16:35:57 -07:00
Andrew Kushnir 70b478ff59 Revert "refactor(core): Omit listeners from out-of-zone scheduling when using ZoneJS (#55492)" (#55524)
This reverts commit 617bc3337d.

PR Close #55524
2024-04-24 16:35:57 -07:00
Andrew Scott 617bc3337d refactor(core): Omit listeners from out-of-zone scheduling when using ZoneJS (#55492)
In Angular today, a bound listener automatically marks the view for
check. When using ZoneJS, these listeners are most often executed in the
Angular Zone as well, so synchronization (`ApplicationRef.tick`) will
eventually happen. _However_, developers can opt out of zone-patching
for events in several ways, and often do this for very frequent
listeners like `mousemove`, `resize`, and `scroll`. We do not want to
break existing expectations that these are now "safe" events to have
listeners for by automatically scheduling change detection regardless of
whether the listener executed inside or outside the Angular zone.

In contrast, in order for developers to more easily transition to zoneless,
we need to be able to ensure that components which are using `OnPush`
are, for the most part, compatible with zoneless as well. Because listeners
automatically mark the component for check, developers using `OnPush`
did not/do not need to also call `ChangeDetectorRef.markForCheck` or a
similar API. Unfortunately, this means that we need to consider the
listener callbacks as a notification to schedule a `tick` when Zoneless
is enabled. In the future, we would like to have an opt-out for this
(i.e. signal components) since it's not really how we _want_ things to work.

PR Close #55492
2024-04-24 12:25:08 -07:00
Pawel Kozlowski ac863ded48 feat(core): provide ExperimentalPendingTasks API (#55487)
The new ExperimentalPendingTasks API lets developers to add and remove
tasks that control applications stability: a pending task prevents
application from being stable.

This API is important for all the use-cases that depend on the concept
of stability and SSR serialization is a notable example.

Closes #53381

PR Close #55487
2024-04-24 11:23:10 -07:00
Andrew Scott d0c2e1beb8 docs: fix public API from primitives (#55515)
PR Close #55515
2024-04-24 11:22:05 -07:00
Alan Agius cf2e1b3e5d refactor(platform-server): add link that explains nonce application/json (#55505)
Add a link to the specs explaining why nonce is not needed for `application/json`.

PR Close #55505
2024-04-24 10:48:38 -07:00
Joey Perrott b28d0bf704 ci: update @angular/ng-dev (#55513)
Update @angular/ng-dev to latest version

PR Close #55513
2024-04-24 10:46:01 -07:00
Andrew Scott 9ab36cfe0a refactor(animations): Ensure async animations applies changes when loaded in zoneless (#55132)
Async animations currently works in Zones because the render factory
promise resolve causes change detection to happen.

fixes #54919

PR Close #55132
2024-04-24 10:33:47 -07:00
Andrew Scott a07ea069e5 refactor(core): Ensure DOM removal happens when no app views need refresh (#55132)
This change ensures that `ApplicationRef.tick` flushes animations by
calling `rendererFactory2.end`. This might not have happened before if
there were no views that needed to be refreshed.

This is also likely to fix a potential regression caused by #53718 even
in zone apps where animations don't get flushed when no views attached
to ApplicationRef are dirty.

PR Close #55132
2024-04-24 10:33:47 -07:00
Andrew Kushnir 307bc1d6b6 refactor(platform-server): event contract script should follow event dispatch script (#55502)
This commit fixes an issue where event contract init script was injected into the page before the inlined event dispatch script. That resulted in runtime exceptions, since event contract relies on some code being present on a page already.

PR Close #55502
2024-04-24 10:32:36 -07:00
Andrew Kushnir fc90549c9b refactor(core): event replay should account for pages with no events (#55502)
This commit updates the logic to take into account a situation when Event Replay feature is enabled (using `withEventReplay()` method), but there were no events configured in an application. In this case, there is no need to setup an event dispatcher and trigger event replay.

PR Close #55502
2024-04-24 10:32:35 -07:00
Andrew Kushnir bbd0cbfacf refactor(core): disable property renaming for the event dispatch script (#55502)
This commit updates Terser config to disable property renaming for the event delegation script (that we later inline into the HTML during SSR). The problem is that event dispatcher relies on some functions on the EventContract class to have original names after after minification, we loose an ability to call those functions.

PR Close #55502
2024-04-24 10:32:35 -07:00
Tom Wilkinson 4bf3d89dae refactor(core): Remove stop propagation beahavior. (#55435)
This removes stop propagation behavior from `EventContract` and removes
the associated stop propagation logic.

PR Close #55435
2024-04-24 09:12:34 -07:00
Tom Wilkinson 98e861395c refactor(core): Split Dispatcher into base class. (#55372)
This will enable refactoring existing usages of the Dispatcher that use
APIs that we do not intend to support, like registerGlobalHandler and
registerEventInfoHandlers to use the LegacyDispatcher.

PR Close #55372
2024-04-24 09:10:04 -07:00
iteriani 811fe001c9 refactor(core): Replay events from the event contract using the dispatcher. (#55467)
This should accomplish event replay during full page hydration.

PR Close #55467
2024-04-23 16:08:36 -07:00
Angular Robot 2e2ca5e9d9 build: update scorecard action dependencies (#55473)
See associated pull request for more information.

PR Close #55473
2024-04-23 15:17:40 -07:00
fdonzello c001b05c77 refactor(forms): added control name in console errors (#55397)
When a formControlName is used without a parent formGroup, an error is
logged in the console. Before this commit, there was no information
about which control had the issue. Now, it's reported and the
troubleshoot is much faster.

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

fixes #55235

PR Close #55271
2024-04-23 15:12:39 -07:00
Angular Robot 86967af904 build: lock file maintenance (#55343)
See associated pull request for more information.

PR Close #55343
2024-04-23 13:37:56 -07:00
Leonardo Collazo Klenina b1e63491bb Update making-requests.md (#55390)
docs(http): change "buffer.length" to "buffer.byteLength"

property "length" does not exist on type "ArrayBuffer" but "byteLength" does
PR Close #55390
2024-04-23 13:34:33 -07:00
Joey Perrott 5a10f405d3 fix(core): complete the removal of deprecation async function (#55491)
Remove the `async` function in favor of using `waitForAsync` instead.

BREAKING CHANGE: `async` has been removed, use `waitForAsync` instead.

PR Close #55491
2024-04-23 13:29:46 -07:00
Kirk Larkin 79a33e4366 docs: Update dependency-injection.md (#55432)
PR Close #55432
2024-04-23 13:29:14 -07:00
Kirk Larkin 86ad37a446 docs: Update dependency-injection-context.md (#55455)
PR Close #55455
2024-04-23 13:27:15 -07:00
Kirk Larkin 62bbed8f5a docs: Update dependency-injection-providers.md (#55454)
PR Close #55454
2024-04-23 13:26:16 -07:00
Kirk Larkin cd390c26a8 docs: Update creating-injectable-service.md (#55449)
PR Close #55449
2024-04-23 13:25:54 -07:00
Kirk Larkin 89a5c7e6f8 docs: Update creating-injectable-service.md (#55449)
PR Close #55449
2024-04-23 13:25:54 -07:00
Angular Robot f4d894b58a docs: update Angular CLI help [main] (#55409)
Updated Angular CLI help contents.

PR Close #55409
2024-04-23 13:24:22 -07:00
lilbeqiri bb673ff458 docs: improve grammar at tutorial steps (#55414)
Fix the grammar issues at some of the tutorial pages making sure they sound correctly.

PR Close #55414
2024-04-23 13:22:58 -07:00
vladboisa 900b5e7dfd docs(docs-infra): fix broken links (#55446)
Add the missing folder's for links

Fixes #55442

docs(docs-infra): fix template reference link

Change the broken link

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

PR Close #55407
2024-04-23 13:16:15 -07:00
Joey Perrott 1f288b269a ci: reenable integration tests (#55463)
Begin running integration tests again after they were unintentionally disabled

PR Close #55463
2024-04-23 13:13:20 -07:00
Alan Agius 5674c644ab fix(platform-server): add nonce attribute to event record script (#55495)
This commit fixes an issue where the nonce attribute was not added when `CSP_NONCE` token was provided.

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

Fixes #55475.

PR Close #55480
2024-04-23 13:06:52 -07:00
Alan Agius bcce85af72 refactor(animations): remove deprecated matchesElement from AnimationDriver (#55479)
BREAKING CHANGE: Deprecated `matchesElement` method has been removed from `AnimationDriver` as it is unused.

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

PR Close #55477
2024-04-23 13:06:03 -07:00
Alan Agius cba336d4f1 refactor(platform-browser): remove deprecated transfer state APIs (#55474)
BREAKING CHANGE: Deprecated `StateKey`, `TransferState` and `makeStateKey` have been removed from `@angular/platform-browser`, use the same APIs from `@angular/core`.

PR Close #55474
2024-04-23 13:05:38 -07:00
Angular Robot 1e54956025 build: update actions/checkout action to v4.1.3 (#55472)
See associated pull request for more information.

PR Close #55472
2024-04-23 13:05:13 -07:00
Matthieu Riegler 8f62aac6ea docs(docs-infra): improve filtering performances on API page (#55470)
Identity tracking was not a good choice here 🙃

PR Close #55470
2024-04-23 13:04:51 -07:00
Matthieu Riegler 7aff867c78 docs: fix links to packages. (#55469)
fixes #55458

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

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

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

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

PR Close #55406
2024-04-23 13:02:49 -07:00
Matthieu Riegler 8dab93fe2c docs: adev tutorials use v17. (#55437)
Partial revert of #54891. Webcontainers do not support node ^18.19.1 which is required by the v18 CLI.

Until this is solved by the stackblitz team, we're stucked with v17 based tutorials

PR Close #55437
2024-04-23 13:00:45 -07:00
Matthieu Riegler d34c033902 refactor(common): Deprecate Local Data API functions (#54483)
Ahead of delegating the i18n subsystem to the `Intl` API, this commit introduce the intention to remove those functions from the public API.

DEPRECATED: `getCurrencySymbol`, `getLocaleCurrencyCode`, `getLocaleCurrencyName`, `getLocaleCurrencySymbol`, `getLocaleDateFormat`, `getLocaleDateTimeFormat`, `getLocaleDayNames`, `getLocaleDayPeriods`, `getLocaleDirection`, `getLocaleEraNames`, `getLocaleExtraDayPeriodRules`, `getLocaleExtraDayPeriods`, `getLocaleFirstDayOfWeek`, `getLocaleId`, `getLocaleMonthNames`, `getLocaleNumberFormat`, `getLocaleNumberSymbol`, `getLocalePluralCase`, `getLocaleTimeFormat`, `getLocaleWeekEndRange`, `getNumberOfCurrencyDigits`

PR Close #54483
2024-04-23 12:22:43 -07:00
Matthieu Riegler f914f6a362 feat(migrations): Migration schematics for HttpClientModule (#54020)
This migration will allow developers to migrate the deprecated `HttpClientModule`, `HttpClientJsonpModule` & `HttpClientXsrfModule` to their respective provider functions.

PR Close #54020
2024-04-23 12:12:31 -07:00
Matthieu Riegler ef665a40a5 refactor(http): Deprecate HttpClientModule & related modules (#54020)
This commit deprecates the `HttpClientModule` and other related http modules. Those can be replaced by provider function only.

Angular is an opinionated framework, feature guidance will help developer choose the recommended way to enable feature (like Http requests here).

Note: This is not an indication of deprecation for `NgModule`. The deprecated module's only purpose here was to define providers. This can be done directly by the provide function pattern.

DEPRECATED: `HttpClientModule`, `HttpClientXsrfModule` and `HttpClientJsonpModule`

As mentionned, those modules can be replaced by provider function only.

PR Close #54020
2024-04-23 12:12:31 -07:00
iteriani 3d84c988cd refactor(core): Make some minor changes to facilitate testing and usage of event-dispatch. (#55411)
The change in the index is to allow the framework to add a type to the object that is passed from the contract to the dispatcher. ie

registerDispatcher(contract, (eventInfo: EventInfoWrapper) => ...).

The latter is to return the event contract so that tests can clean it up.

PR Close #55411
2024-04-23 11:05:44 -07:00
Andrew Scott f84d7dde87 test(core): Wait for zone stability before test completion (#55468)
Need to wait for microtaskEmty to emit or test will leak into others.

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

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

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

Resolves #54864.

PR Close #55374
2024-04-22 12:01:36 -07:00
Matthieu Riegler aea5f05c59 docs: change aio to adev for the issue template (#55347)
PR Close #55347
2024-04-22 11:58:18 -07:00
Matthieu Riegler bd784fca99 docs: fix link to inject-based-di tutorial. (#55453)
Fixes #55451

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

PR Close #55448
2024-04-22 11:52:38 -07:00
Alan Agius b0f1552ffe build: use installed deps from main repo (#55433)
This commit updates the zone.js types tests to use the deps installed in the main repo

PR Close #55433
2024-04-22 11:40:07 -07:00
Alan Agius cb7fd67656 ci: disable updates to zone.js types test (#55433)
This breaks renovate
```
### ⚠ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

 - any of the package files in this branch needs updating, or
 - the branch becomes conflicted, or
 - you click the rebase/retry checkbox if found above, or
 - you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

##### File name: packages/zone.js/test/typings/yarn.lock

```
error Package "zone.js" refers to a non-existing file '"/tmp/renovate/repos/github/angular/angular/dist/bin/packages/zone.js/npm_package"'.
```

PR Close #55433
2024-04-22 11:40:06 -07:00
Matthieu Riegler bac5ba328e refactor(http): remove direct usage of HttpStatusCode (#55434)
PR #51670 removed the usage of `const enum`. As a consequence HttpStatusCode that were previously inlined now pull and retains the (fairly large) `HttpStatusCode` enum.

By intermediate constants, we prevent the framework from pulling this big enum by default.

PR Close #55434
2024-04-22 11:36:51 -07:00
Andrew Kushnir ba0036c5c3 refactor(platform-server): remove inlined JSAction script when no events to replay (#55428)
JSAction script is inlined into the HTML by the build process to avoid extra blocking request. The script looks like this:

```
<script type="text/javascript" id="ng-event-dispatch-contract">...</script>
```

This commit updates the logic to remove JSAction if event replay feature is disabled or if there are no events to replay.

PR Close #55428
2024-04-22 11:36:21 -07:00
Alan Agius b153459aaf build: update event dispatch contract to be outputted in IIFE (#55377)
This script is intended to be inlined in the HTML and thus IIFE should be preffered.

PR Close #55377
2024-04-22 11:35:48 -07:00
Matthieu Riegler ebfba7751d docs: add anchors to packages on api page (#55338)
PR Close #55338
2024-04-22 11:28:41 -07:00
Angular Robot a877a62884 build: update actions/cache digest to 0c45773 (#54950)
See associated pull request for more information.

PR Close #54950
2024-04-22 11:26:53 -07:00
Julien Saguet 6f88d80758 feat(http): allow caching requests with different origins between server and client (#55274)
Expose `HTTP_TRANSFER_CACHE_ORIGIN_MAP` injection token in public api. This is useful when different origins are used to access the same APIs between server and browser.

Fixes #53702

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

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

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

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

PR Close #55233
2024-04-22 11:25:20 -07:00
Pawel Kozlowski 832fafc6b5 refactor(core): warn developers about collection re-creation in @for loop (#55314)
This commit introduces a check plus an associated warning for situations where
the combination of the collection change and the tracking expression resulted
in the entire view structure managed by @for to be re-created.

The check uses the following conditions before raising a warning:
- the entire collection was re-created and there were no other operations (ex.: move);
- views in a collection are considered "expensive" to re-create;
- a developer is using tracking by identity.

The last condition tries to capture cases where changes to immutable data
collections can cause significent performance and / or corectness problems.

Note that this warning might be "overreacting" and report cases where
the collection re-creation is the intended behavior. Still, the assumption is that
most of the time it is undesired.

PR Close #55314
2024-04-22 11:24:11 -07:00
Andrew Scott 74333e6221 refactor(core): conditionally read data from apply args (#55465)
This commit fixes an error in a previous commit which attempted to read
`data` from the first item in the apply args array, even if it was not
defined.

PR Close #55465
2024-04-22 09:49:05 -07:00
Joey Perrott b1dffa4abe refactor: migrate platform-* to prettier formatting (#55423)
Migrate formatting to prettier for platform-* from clang-format

PR Close #55423
2024-04-19 13:49:24 -07:00
Joey Perrott 488c711a57 refactor: migrate localize to prettier formatting (#55423)
Migrate formatting to prettier for localize from clang-format

PR Close #55423
2024-04-19 13:49:24 -07:00
Joey Perrott a2aca69bd3 refactor: migrate forms to prettier formatting (#55423)
Migrate formatting to prettier for forms from clang-format

PR Close #55423
2024-04-19 13:49:24 -07:00
Angular Robot a743d37f1c build: update scorecard action dependencies (#55419)
See associated pull request for more information.

PR Close #55419
2024-04-19 13:26:38 -07:00
Alan Agius 15f19820b0 build: update Domino to 8f228f8862540c6ccd14f76b5a1d9bb5458618af (#55424)
This contains the fix for https://github.com/angular/angular/issues/55416

PR Close #55424
2024-04-19 13:24:25 -07:00
Thomas Nguyen a730f09ae9 feat(core): Add a public API to establish events to be replayed and an attribute to mark an element with an event handler. (#55356)
These will be consumed by the event-dispatch contract to replay events. The contract and the dispatcher inclusion will be in followups.

PR Close #55356
2024-04-19 13:12:21 -07:00
Angular Robot b67e11a521 build: update cross-repo angular dependencies (#54891)
See associated pull request for more information.

PR Close #54891
2024-04-19 08:51:09 -07:00
Alan Agius 164dde45e6 refactor(migrations): remove v17 migrations (#55391)
This commit removes of migrations introduced in version 17, along with the relocation of a migration from 17.3 to version 18. This ensures that this is ran for users who may have updated from one minor to another without executing `ng update`

PR Close #55391
2024-04-19 06:31:28 -07:00
Matthieu Riegler 4d61501031 docs: fix filePath for manual api docs. (#55388)
Path should have a leading slash.

PR Close #55388
2024-04-19 06:30:34 -07:00
Matthieu Riegler 1bea1fe8a0 docs: improvements for API pages (#55388)
* add link for source files
* add deprecation message for methods
* add usage notes for methods

Fixes #55196
Fixes #52641

PR Close #55388
2024-04-19 06:30:34 -07:00
Kristiyan Kostadinov 7a16d7e969 fix(compiler-cli): don't type check the bodies of control flow nodes in basic mode (#55360)
Angular only checks the contents of template nodes in full type checking mode. After v17, the new control flow always had its body checked, even in basic mode, which started revealing compilation errors for apps that were using the schematic to automatically switch to the new syntax.

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

Fixes #52969.

PR Close #55360
2024-04-19 06:29:56 -07:00
Pawel Kozlowski e67a730688 refactor(core): warn about duplicated keys when using built-in @for (#55243)
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.

PR Close #55243
2024-04-19 06:28:58 -07:00
Andrew Scott a0eebcd6d1 refactor(core): Add error tracking for infinite notifications (#55231)
This commit adds helpful stack information for the case when change
detection continues to be triggered in the event loop and would cause
the browser to freeze.

PR Close #55231
2024-04-19 06:25:46 -07:00
Andrew Scott b47ac4d7c7 refactor(core): Account for Promise.resolve(() => updateState()) pattern in zoneless (#55231)
There is an existing pattern that zone-based applications use to avoid
`ExpressionChangedAfterItHasBeenCheckedError` which is also used in
`NgModel`: update the state in a microtask instead of doing it
synchronously. This defers the state update to another round of change
detection, and with ZoneJS, also still executes in the same event loop.
These types of changes across multiple rounds of change detection were
still executed before the browser paint.

This update allows the `NgModel` workaround to continue working in
Zoneless. This may not be permanent and is certainly still not
advisable. Render hooks (`afterNextRender`/`afterRender`) will execute between these
rounds of change detection when they are intended to be run after all
DOM updates completed.

PR Close #55231
2024-04-19 06:25:46 -07:00
Alan Agius 8eacb6e4b9 feat(http): exclude caching for authenticated HTTP requests (#55034)
This update modifies the transfer cache logic to prevent caching of HTTP requests that require authorization. To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`

BREAKING CHANGE: 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,
})
```

Closes: #54745

PR Close #55034
2024-04-19 06:25:22 -07:00
Joey Perrott ca517d7f2c refactor: migrate language-service to prettier formatting (#55405)
Migrate formatting to prettier for language-service from clang-format

PR Close #55405
2024-04-18 14:18:38 -07:00
Joey Perrott 8f69c83b84 refactor: migrate compiler to prettier formatting (#55398)
Migrate formatting to prettier for compiler from clang-format

PR Close #55398
2024-04-18 14:18:08 -07:00
Joey Perrott a5b5b7d5ef refactor: migrate core/primitives to prettier formatting (#55387)
Migrate formatting to prettier for core/primitives from clang-format

PR Close #55387
2024-04-17 15:55:32 -07:00
Andrew Scott 4a42961393 feat(router): withNavigationErrorHandler can convert errors to redirects (#55370)
This commit adds the ability to return `RedirectCommand` from the error
handler provided by `withNavigationErrorHandler`. This will prevent the
error from being surfaced in the `events` observable of the Router and
instead convert the error to a redirect. This allows developers to
have more control over how the Router handles navigation errors. There
are some cases when the application _does not_ want the URL to be reset
when an error occurs.

resolves #42915

PR Close #55370
2024-04-17 15:53:02 -07:00
Andrew Scott 18a43b56e5 refactor(core): Prevent running change detection twice with run coalescing and zoneless (#55352)
This commit ensures we correctly handle the exit from the zone.run in
the zoneless scheduler. Run coalescing would delay the `onMicrotaskEmpty` event
until after we have exited the change detection triggered by the
zoneless scheduler and mean that the subscription cannot determine if
`ApplicationRef.tick` should be skipped.

PR Close #55352
2024-04-17 15:50:59 -07:00
Gerald Monaco 5f06ca8f55 feat(core): add HOST_TAG_NAME token (#54751)
For ideal DOM usage, you would not unwrap an ElementRef outside of the browser. However, it's reasonable to want to find the tag name of the host node on the server, and so this introduces a HOST_TAG_NAME token that can be injected to read this value.

PR Close #54751
2024-04-17 15:50:31 -07:00
Angular Robot e1eae847db build: update github/codeql-action action to v3.25.0 (#55358)
See associated pull request for more information.

PR Close #55358
2024-04-17 18:02:48 +02:00
Pawel Kozlowski 011cc06411 release: cut the v18.0.0-next.5 release 2024-04-17 17:55:10 +02:00
Pawel Kozlowski 9d2704c258 docs: release notes for the v17.3.5 release 2024-04-17 17:49:40 +02:00
Tom Wilkinson a34267b72e refactor(core): Switch stopPropagation default to false (#55351)
Flip `stopPropagation` constructor parameter default to `false` for
`EventContract` and `EventContractMultiContainer`. Change type for
`EventContract` to `false` to indicate that no values besides `false`
should be passed. This enables removing all usages of `stopPropagation`
in `EventContract` and leaving only usages of `stopPropagation = true`
for `EventContractMultiContainer`.

PR Close #55351
2024-04-17 11:29:38 +02:00
Tom Wilkinson 0cec9e4f9a fix(core): Fix null dereference error addEvent (#55353)
When `cleanUp` is called `containerManager` is set to null. Currently
the `EventContract` API assumes that users know not to call further
methods on `EventContract`, but this lead to a bug in a downstream app,
b/333750059. So instead, this makes a defensive check to make sure it's
not null.

PR Close #55353
2024-04-17 11:29:00 +02:00
Alan Agius 9f5e90e03d build: make JSA contract binary accessible (#55361)
This commit integrates the JSA contract binary into the NPM package and ensures its accessibility by including it in the package exports. This adjustment is essential for enabling Angular CLI to effectively access and inject the script. Additionally, sourcemaps are removed from the minified bundle to prevent their inclusion in the HTML page.

PR Close #55361
2024-04-17 10:37:31 +02:00
Andrew Scott ff686f3ca5 refactor(core): Permit detectChanges with zoneless ComponentFixture (#55325)
This commit loosens the restrictions on calling `ComponentFixture.detectChanges`
when using the zoneless scheduler. While we don't necessarily think it's
a good idea, the thought is that it's unnecessary mental overhead to
diverge behaviors in the API when zoneless is enabled versus when it is
not. Instead, these opinionated restrictions can be considered when we
look at new testing APIs.

PR Close #55325
2024-04-17 08:07:52 +02:00
Ben Hong c778977445 docs: update v0 render to v17 (#55368)
PR Close #55368
2024-04-17 08:01:26 +02:00
Alan Agius 3b0de30b37 refactor(common): remove deprecated isPlatformWorkerApp and isPlatformWorkerUi API (#55302)
BREAKING CHANGE: The deprecated `isPlatformWorkerUi` and `isPlatformWorkerApp` have been removed without replacement, as they serve no purpose since the removal of the WebWorker platform.

PR Close #55302
2024-04-17 08:00:01 +02:00
Doug Parker 5f859727e2 release: bump Angular DevTools version to 1.0.13 (#55371)
PR Close #55371
2024-04-17 07:53:11 +02:00
Andrew Scott de7447d15e fix(core): Angular should not ignore changes that happen outside the zone (#55102)
When Angular receives a clear indication that change detection should
run again, this should not be ignored, regardless of what Zone it
happened in. This change updates the default change detection scheduling
approach of Zone-based applications to ensure a change detection will
run when these events happen outside the Angular zone (which includes,
for example, updating a signal that's read in a template, setting an
input of a `ComponentRef`, attaching a view marked for check, calling
`ChangeDetectorRef.markForCheck`, etc.).

This does not apply to applications using `NoopNgZone` or those which
have a custom `NgZone` implementation without ZoneJS.

The impact of this change will most often be seen in existing unit tests. Tests
execute outside the Angular Zone and this can mean that state in the
test is not fully recognized by Angular. Now that Angular will ensure
change detection _does_ run, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior. Often, this should 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.

fixes #55238
fixes #53844
fixes #53841
fixes #52610
fixes #53566
fixes #52940
fixes #51970
fixes #51768
fixes #50702
fixes #50259
fixes #50266
fixes #50160
fixes #49940
fixes #49398
fixes #48890
fixes #48608
fixes #45105
fixes #42241
fixes #41553
fixes #37223
fixes #37062
fixes #35579
fixes #31695
fixes #24728
fixes #23697
fixes #19814
fixes #13957
fixes #11565
fixes #15770
fixes #15946
fixes #18254
fixes #19731
fixes #20112
fixes #22472
fixes #23697
fixes #24727
fixes #47236

BREAKING CHANGE:

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`.

PR Close #55102
2024-04-16 17:27:04 -07:00
Alex Rickabaugh a5623dc14b Revert "refactor(core): warn about duplicated keys when using built-in @for (#55243)" (#55373)
This reverts commit 9f7b9ed87a. Reason: g3
users reported a bug in the logic that produces false warnings in some
cases.

PR Close #55373
2024-04-16 17:11:08 -07:00
Andrew Scott e6425f7bc1 refactor(core): use patched timers in root zone for zoneless scheduler (#55367)
Rather than attempting to use the native timing functions, this commit
simplifies the logic significantly by using the global timer functions
as they are, either patched or unpatched. When Zone is defined, we run
the timers in the root zone. This has more predictable behavior and
timing than (a) using both patched and unpatched versions of timers in
different places (b) trying to get an unpatched timer and failing due to
environment specifics and patches that aren't ZoneJS.

We will try to update the coalescing behavior of ZoneJS in a future PR
to also just use the patched version of the timers instead of the
"fakeTopEvent" workaround with the native timers.

PR Close #55367
2024-04-16 16:31:19 -07:00
Andrew Scott f09c5a7bc4 feat(core): Add zoneless change detection provider as experimental (#55329)
This commit adds the zoneless change detection provider function to the
public API surface as experimental.

PR Close #55329
2024-04-16 20:51:25 +02:00
Andrew Scott 785c3c1dd4 refactor(core): Calling ApplicationRef.tick should cancel scheduled change detections (#55290)
This commit ensures that manually calling ApplicationRef.tick will
result in any scheduled change detections being canceled. There is no
need for the scheduled one to run because it was manually done by the
`tick` already.

PR Close #55290
2024-04-16 20:50:35 +02:00
Andrew Scott c3a5acb8cc refactor(core): change detection should not be scheduled during appRef.tick (#55290)
This commit ensures that change detection is not scheduled if the
scheduler is notified during an applicationRef.tick

PR Close #55290
2024-04-16 20:50:35 +02:00
arturovt 3bc63eaaf3 fix(service-worker): avoid running CDs on controllerchange (#54222)
This commit updates the implementation of `ngswAppInitializer` to configure
the `controllerchange` event listener outside of the Angular zone. This adjustment
is made to prevent unnecessary change detections, as the `controllerchange` event
is unrelated to view updates.

**NOTE**: This change may result in breaking unit tests that implicitly rely on a
specific number and sequence of change detections for their assertions to pass.

PR Close #54222
2024-04-16 17:29:59 +02:00
Matthieu Riegler e606ac6023 refactor(core): transform Predicate from interface to type (#54566)
This interface should have been a type as there are no other properties

PR Close #54566
2024-04-16 17:26:53 +02:00
Kristiyan Kostadinov 4eb0165750 fix(compiler): remove support for unassignable expressions in two-way bindings (#55342)
Two-way bindings are meant to represent a property binding to an input and an event binding to an output, e.g. `[(ngModel)]="foo"` represents `[ngModel]="foo" (ngModelChange)="foo = $event"`. Previously due to a quirk in the template parser, we accidentally supported unassignable expressions in two-way bindings.

In #54154 the quirk was fixed, but we kept support or some common expression because of internal usages. Now the internal usages have been cleaned up so the backwards-compatibility code can be deleted.

Externally a migration was added in #54630 that will automatically fix any places that depended on the old behavior.

BREAKING CHANGE:
Angular only supports writable expressions inside of two-way bindings.

PR Close #55342
2024-04-16 17:26:09 +02:00
Thomas Nguyen d28614b90e feat(core): Modify EventType from an enum to an object. (#55323)
This is needed to reduce the binary size of the event contract.

PR Close #55323
2024-04-16 15:36:45 +02:00
Thomas Nguyen bce5e2344f feat(core): Add build target for jsaction contract binary. (#55319)
Right now this binary sits at 9.5kb. Additional changes to the library will
be done to reduce the binary size, such as converting event_type from
an enum to an object, and other code size reductions.

PR Close #55319
2024-04-16 12:09:08 +02:00
Kristiyan Kostadinov 7d5bc1c628 fix(compiler): remove container index from conditional instruction (#55190)
Stops passing in the `containerIndex` argument to the `conditional` instruction since it isn't being used anymore.

PR Close #55190
2024-04-16 10:23:30 +02:00
cexbrayat 32eb23defb refactor(compiler): duplicate instructions in template pipeline (#54776)
Both `textInterpolate` and `collateInterpolationArgs` were doing the same work.

PR Close #54776
2024-04-16 10:21:52 +02:00
Matthieu Riegler 9afa2ea345 refactor(compiler-cli): include filepath for DocEntry (#55201)
This is allow the API docs to provide a direct link to implementation on github.

PR Close #55201
2024-04-15 17:41:45 +02:00
Pawel Kozlowski 43cf23954e refactor(migrations): exit developer preview for built-in control flow (#55348)
This commit removes the warning about developer preview in our
built-in control flow migration.

PR Close #55348
2024-04-15 17:29:12 +02:00
Pawel Kozlowski f17d0b414e docs: exit developer preview for built-in control flow (#55348)
This commit removes the warning about developer preview in our
built-in control flow documentation page.

PR Close #55348
2024-04-15 17:29:12 +02:00
Paul Gschwendtner 3471c41ca9 build(docs-infra): fix playground lezer parsing (#55349)
When we started fixing the version mismatch with local 1st-party
packages, we also re-routed all dependencies like `@lezer/javascript`
into `adev/node_modules`. This works fine, but results in a different
version mismatch because the codemirror dependencies may resolve the
Angular version from `/node_modules`- causing some subtle complex
runtime error.

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

Fixes #55298.

PR Close #55349
2024-04-15 16:36:39 +02:00
Pawel Kozlowski 9f7b9ed87a refactor(core): warn about duplicated keys when using built-in @for (#55243)
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.

PR Close #55243
2024-04-15 16:10:27 +02:00
Pawel Kozlowski cfed97d2a9 docs: update public APIs golden after doc changes (#55346)
Build got broken after merging https://github.com/angular/angular/pull/54577
due to the missing golden files update for the public API.

PR Close #55346
2024-04-15 14:19:54 +02:00
hansi_reit 5eda3bf5f0 docs: add missing usage-notes (#54577)
Fixes #54228

PR Close #54577
2024-04-15 12:25:40 +02:00
Matthieu Riegler 3af54d5114 docs: fix links to output function (#55335)
fixes #55334

PR Close #55335
2024-04-15 11:09:33 +02:00
Andrew Scott 571a61beeb refactor(core): add the fakeTopEvent workaround to zoneless scheduler (#55324)
Add the same fix to the zoneless scheduler that was needed for zone
coalescing (#36839).

PR Close #55324
2024-04-12 16:10:06 -07:00
Andrew Scott e41a52286f Revert "refactor: move example generation into adev, removing content from aio (#55263)" (#55326)
This reverts commit 9bc15994ce.

PR Close #55326
2024-04-12 14:57:05 -07:00
Matthieu Riegler 5cf5f04460 build: bump to node 18.20 to support v18 (#55162)
The v18 CLI requires node `^18.19.1`, so we need to bump the node version to be able to run ADEV with v18.

PR Close #55162
2024-04-12 14:51:44 -07:00
Andrew Scott 6534c035c0 fix(core): Remove deprecated Testability methods (#53768)
This commit removes the long-deprecated Testability methods that track
pending tasks. This is done by NgZone today and will be done by other
APIs in zoneless.

BREAKING CHANGE: Testability methods `increasePendingRequestCount`,
`decreasePendingRequestCount` and `getPendingRequestCount` have been
removed. This information is tracked with zones.

PR Close #53768
2024-04-12 14:49:23 -07:00
Andrew Scott fdd560ea14 feat(core): Add ability to configure zone change detection to use zoneless scheduler (#55252)
This commit adds a configuration option to zone-based change detection
which allows applications to enable/disable the zoneless scheduler.
When the zoneless scheduler is enabled in zone-based applications,
updates that happen outside the Angular zone will still result in a
change detection being scheduled. Previously, Angular change detection
was solely based on the state of the Angular Zone.

PR Close #55252
2024-04-12 12:29:05 -07:00
Andrew Scott c9abe775d0 docs: Simply redirect function example for router (#55317)
PR Close #55317
2024-04-12 10:43:26 -07:00
Andrew Scott 11523c1cb7 docs(router): Add some additional docs for new Router features (#55184)
This commit adds some additional documentation for recent router
features.

PR Close #55184
2024-04-12 10:22:04 -07:00
Angular Robot c3e34f1822 build: update babel dependencies to v7.24.4 (#55257)
See associated pull request for more information.

PR Close #55257
2024-04-12 10:21:24 -07:00
Mo Ibrahim f947dd5ba4 docs: fix repeated note in "Add an Input to the component" section (#55306)
PR Close #55306
2024-04-12 10:14:01 -07:00
Jeremy Elbourn 145356c22e docs: add team docs for when to use dev preview and experimental (#55308)
Adds a brief team doc for when to use developer preview and experimental
API tags.

PR Close #55308
2024-04-12 10:10:50 -07:00
Charles Lyding 5c29416d3e refactor(language-service): add a plugin factory initialize helper (#55264)
An implementation of a TypeScript server plugin module factory has
been added to the main plugin code which minimizes the amount of
infrastructure code necessary to directly setup the Angular plugin.
This is not yet used externally but can be integrated in the future.

PR Close #55264
2024-04-12 18:21:29 +02:00
Angular Robot 75a186e321 build: update io_bazel_rules_sass digest to c3f163f (#55307)
See associated pull request for more information.

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

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

PR Close #55255
2024-04-11 20:50:19 +02:00
Thomas Nguyen 1ee9f32621 feat(core): Synchronize changes from internal JSAction codebase. (#55182)
1: Remove USE_EVENT_PATH, which has no users.

2: Create a new `EventActionInfo` object to represent actions, update all `EventInfoWrapper` users.

3: Fix `stopPropagation` behavior in JSAction Dispatcher - it should only `stopPropagation` if an action is found, which is only known during normal dispatch rather than global.

PR Close #55182
2024-04-11 17:27:39 +02:00
ehlemur 6fef658cc3 docs(core): add missing space (#55287)
Add missing space after period in section describing producers and consumers.

PR Close #55287
2024-04-11 17:25:33 +02:00
Chinthoorie 0a8c48e76e refactor(compiler-cli): move config initialization into constructor (#54975)
refactor(compiler-cli): move config initialization into constructor
PR Close #54975
2024-04-11 11:20:17 +02:00
Andrew Scott aae062e8db release: cut the v18.0.0-next.4 release 2024-04-10 16:18:45 -07:00
Andrew Scott 69927ce103 docs: release notes for the v17.3.4 release 2024-04-10 15:17:39 -07:00
Andrew Scott 19a238dfee Revert "refactor(core): warn about duplicated keys when using built-in @for (#55243)" (#55293)
This reverts commit e3696ad0d6.
caused a test failure internally

PR Close #55293
2024-04-10 13:45:49 -07:00
Rahat Ahmed 92debf4476 ci: Merge primitives-shared and primitives-event-dispatch groups (#55273)
This simplifies the approvals necessary for the event dispatch directory

PR Close #55273
2024-04-10 10:59:43 -07:00
Angular Robot 66e8cd2f8a docs: update Angular CLI help [main] (#55267)
Updated Angular CLI help contents.

PR Close #55267
2024-04-10 10:51:43 -07:00
Angular Robot bc9114a547 build: update github/codeql-action action to v3.24.10 (#55258)
See associated pull request for more information.

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

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

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

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

This causes a version mismatch, leading to issues like:

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

This commit attempts to fix this by:

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

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

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

PR Close #54946
2024-04-10 10:40:41 -07:00
Pawel Kozlowski e3696ad0d6 refactor(core): warn about duplicated keys when using built-in @for (#55243)
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.

PR Close #55243
2024-04-10 10:39:23 -07:00
Alan Agius 9b903c52d8 docs: remove ng doc link (#55284)
This command has been removed in version 18.

PR Close #55284
2024-04-10 10:38:41 -07:00
Andrew Scott acf5f73a7b Revert "fix(core): TestBed should not override NgZone from initTestEnvironment (#55226)" (#55286)
This reverts commit e9a0c86766.
flakes and broken tests. needs more investigation.

PR Close #55286
2024-04-10 10:37:42 -07:00
Andrew Scott 6993146a25 refactor(http): Do not contribute to stability when using provideHttpClientTesting (#54974)
`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests (https://github.com/angular/angular/commit/28c68f709cdc930e12bac51a266e7bf790656034).

Today, `PendingTasks` contribute to `ApplicationRef.isStable` but do not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended and we plan to make these two
stability indicators the same again, like they were when it was solely
based on the state of the Zone.

By aligning the two behaviors again, this would include all pending
tasks in the stability of fixtures. After investigation, this seems
likely to be a pretty large breaking change. Tests appear to quite often use
`await fixture.whenStable` when there are unfinished requests that have
not been mocked or flushed.

This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` automatically but only when using
`HttpClientTesting`. In this scenario, requests need to be expected and
flushed manually for them to resolve. When the test backend and controllers
aren't used, requests should resolve on their own so `await fixture.whenStable`
shouldn't be particularly affected or problematic.

PR Close #54974
2024-04-10 09:27:40 -07:00
Angular Robot cae993c3b7 build: lock file maintenance (#55241)
See associated pull request for more information.

PR Close #55241
2024-04-09 15:22:11 -07:00
Matthieu Riegler 3547e1e769 refactor(forms): emit status/value event in a consistant order (#55198)
We emit `ValueChangeEvent` first and then `StatusChangeEvent`

PR Close #55198
2024-04-09 15:21:39 -07:00
Angular Robot 4be03d64ee build: update all non-major dependencies (#55164)
See associated pull request for more information.

PR Close #55164
2024-04-09 15:20:52 -07:00
Jeffrey Smith 11705f58a7 fix(common): skip transfer cache on client (#55012)
transfer cache interceptor should not run again on the client as it is intended for server to client handoff

PR Close #55012
2024-04-09 14:45:36 -07:00
Charles Lyding bd236cc150 fix(language-service): implement getDefinitionAtPosition for Angular templates (#55269)
The `getDefinitionAtPosition` function may be called by consumers instead
of `getDefinitionAndBoundSpan` with the later of which already implemented.
The `getDefinitionAtPosition` result is a subset of what `getDefinitionAndBoundSpan`
returns and currently delegates to that function.

PR Close #55269
2024-04-09 14:04:21 -07:00
Matthieu Riegler 1c6553e823 refactor(compiler-cli): Link to adev (#55043)
Replace aio links with to adev guides

PR Close #55043
2024-04-09 12:23:09 -07:00
Matthieu Riegler d364f6ecc9 docs: redirect upgrade guide to aio (#55043)
Adev doesn't document upgrade anymore.

PR Close #55043
2024-04-09 12:23:09 -07:00
Matthieu Riegler f45fbb0f43 docs: remove deprecation details link (#55043)
PR Close #55043
2024-04-09 12:23:09 -07:00
Matthieu Riegler 457d02cca3 docs: Use new Urls to drop the docs url mapper (#55043)
PR Close #55043
2024-04-09 12:23:09 -07:00
Martin Machava 216199dd4d docs(forms): validate email field with proper validator (#55142)
PR Close #55142
2024-04-09 12:15:29 -07:00
Matthieu Riegler 4b31a88592 refactor(core): Remove zone assertion from hydration cleanup. (#55214)
In zoneless apps with hydration, this assertion was throwing.

Fixes #52160

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

PR Close #55141
2024-04-09 11:21:05 -07:00
Joey Perrott 9bc15994ce refactor: move example generation into adev, removing content from aio (#55263)
Remove the content from aio and set up the example generation in adev

PR Close #55263
2024-04-09 11:18:48 -07:00
Matthieu Riegler 323611141b docs: split CLI subcommands in separate doc page (#55185)
PR Close #55185
2024-04-09 11:05:18 -07:00
Matthieu Riegler 9d76cc367b docs: update readme link (#55155)
fixes#55153

PR Close #55155
2024-04-09 10:32:49 -07:00
cexbrayat 9c776d6802 docs(forms): add docs for emitEvent flag (#55249)
PR Close #55249
2024-04-09 10:31:10 -07:00
Angular Robot 18ba2bbc4b docs: update Angular CLI help [main] (#55251)
Updated Angular CLI help contents.

PR Close #55251
2024-04-09 10:29:52 -07:00
Jessica Janiuk f83da4f94f ci: required by is optional for primitives (#55265)
This adjusts the need for required by in PR reviews for shared primitives.

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

PR Close #55247
2024-04-08 14:33:24 -07:00
Mahdi Lazraq 6484ac21f9 docs: add closing tag in hierarchical injectors documentation (#54954)
PR Close #54954
2024-04-08 14:11:18 -07:00
Andrew Mayer 2eb83c6e86 docs: update links to calling-compilecomponents intesting-utility-apis (#55055)
PR Close #55055
2024-04-08 14:08:38 -07:00
Andrew Mayer 76d00b253d docs: update links to the calling-compilecomponents section (#55055)
PR Close #55055
2024-04-08 14:08:37 -07:00
Charles Lyding ed6df68914 refactor(language-service): use compiler for current program instance (#55097)
Within the language service, the Angular compiler instance can provide
access to the current TypeScript program via `getCurrentProgram`. By
using the compiler, the need to pass around the program driver is no longer
required and can also be removed as an instance field of the Angular language
service class. This change also provides a higher assurance that the correct
program is being used throughout each language service request.

PR Close #55097
2024-04-08 13:49:31 -07:00
gwario faafadb436 docs: fix typo in event-binding documentation (#55189)
PR Close #55189
2024-04-08 13:47:36 -07:00
Pawel Kozlowski 9bb570b1e2 refactor(core): use performance API for zone options (#55086)
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 #55086
2024-04-08 13:43:44 -07:00
Angular Robot 2de06cae72 build: update io_bazel_rules_sass digest to 147f7fa (#55208)
See associated pull request for more information.

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

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

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

PR Close #55129
2024-04-08 11:31:12 -07:00
Matthieu Riegler 59c166a2bc docs: remove link to resources (#55224)
The page doesn't exist anymore on ADEV.
Fixes #55221

PR Close #55224
2024-04-08 11:28:48 -07:00
Andrew Scott e9a0c86766 fix(core): TestBed should not override NgZone from initTestEnvironment (#55226)
Prior to this change, `NgZone` was provided by default in TestBed in a
location that would override anything configured in
`TestBed.initTestEnvironment`. This change moves the default `NgZone`
provider to the `RootScopeModule` and these providers can be overridden
by the ones in `additionalModuleTypes`, which are assigned from the
first argument of `initTestEnvironment`. This makes it possible to
configure Zone globally for all tests as opposed to needing to repeat it
in `configureTestingModule` of each suite.

PR Close #55226
2024-04-08 11:28:07 -07:00
Andrew Scott dda9d9aa91 refactor(core): No need for zone.root.run in zoneless scheduler (#55230)
Now that #55092 has merged, we now consistently get the `setTimeout` and
`rAF` implementations that are not patched by zone. There's no longer a
need to run them in the root zone.

PR Close #55230
2024-04-08 11:27:05 -07:00
Mohamed 13d37e0b43 docs: fix broken logo link (#55239)
replace logo in main readme

PR Close #55239
2024-04-08 11:26:03 -07:00
Angular Robot 3583d679fd build: update dependency madge to v7 (#55245)
See associated pull request for more information.

PR Close #55245
2024-04-08 10:43:15 -07:00
Angular Robot a84cb62522 build: lock file maintenance (#55145)
See associated pull request for more information.

PR Close #55145
2024-04-05 11:08:44 -07:00
Andrew Scott 59c7538f0c refactor(core): treat embedded views attached to AppRef as transplants (#55154)
PR #55099 updated zoneless behavior to treat all views attached to
`ApplicationRef` as `OnPush`. Put another way, Zoneless change detection
will only refresh view trees that notified Angular of a change. This
generally works as expected but there was one situation where it did
not.

Some views are logically linked to their declaration locations and
should refresh when the declaration refreshes. These views are called
"transplanted views" and work correctly when inserted into another view
container. This change updates the logic to also work when they are
attached directly to `ApplicationRef`.

PR Close #55154
2024-04-05 10:56:28 -07:00
Johnny Gérard 58e2f47426 test(common): update ImageKit low quality test (#55193)
For commit cd911a8008

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

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

PR Close #55220
2024-04-04 21:27:18 -07:00
Kristiyan Kostadinov 39624c6b12 fix(compiler): output input flags as a literal (#55215)
Previously the input flags were being generated as a reference to an enum member for better readability and under the assumption that minifiers would inline the values. That doesn't appear to be the case so these changes switch to using the literal values instead.

PR Close #55215
2024-04-04 11:13:52 -07:00
ashish-sharma4u 493c1922bf docs: bind 'occupation' property to UserComponent (#54935)
added the binding of occupation property which was missing in UserComponent

Co-authored-by: Sonu Kapoor <sonukapoor@users.noreply.github.com>

PR Close #54935
2024-04-04 11:12:51 -07:00
Matthieu Riegler 9ad4ed13bd docs: use structural directives workflow for structural directives docs. (#55212)
fixes #53078

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

PR Close #55205
2024-04-03 16:05:17 -07:00
Jessica Janiuk 4e25e402f8 release: cut the v18.0.0-next.3 release 2024-04-03 15:28:04 -07:00
Jessica Janiuk 6f960afd31 ci: fixes jsaction path name (#55199)
This updates the jsaction path to be event-dispatch.

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

PR Close #55197
2024-04-03 18:08:15 +00:00
Matthieu Riegler 1c736dc3b2 feat(forms): Unified Control State Change Events (#54579)
This commit introduces a new method to subscribe to on every `AbstractControl` subclass.
It allows to track value, pristine, touched and status changes on a given control.

Fixes #10887

PR Close #54579
2024-04-03 17:12:04 +00:00
Jessica Janiuk 2ff74dcd95 ci: Add primitives groups to pullapprove (#53404)
This adds the shared primitives reviewers groups and list of reviewers
to the pullapprove rules.

PR Close #53404
2024-04-03 17:06:04 +00:00
Gerald Monaco 45ae7a6b60 feat(platform-browser): add withI18nSupport() in developer preview (#55130)
Expose withI18nSupport() as a hydration feature to enable i18n hydration

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

Resolves #55137.

PR Close #55144
2024-04-03 15:26:47 +00:00
James f5773196ec docs: fix typo in first-app/steps/06-property-binding/README.md (#55181)
PR Close #55181
2024-04-03 00:14:14 +00:00
Joey Perrott 894c1c5f10 refactor: apply prettier formatting to integration (#54653)
Apply prettier formatting to integration directories

PR Close #54653
2024-04-02 20:42:04 +00:00
Joey Perrott ade024407d fix(docs-infra): remove part aio infra (#54929)
Remove parts of the aio infra

PR Close #54929
2024-04-02 18:38:04 +00:00
Jessica Janiuk 199150849b ci: bump ng-dev hashes (#55172)
This updates ng-dev to the latest hash fixing the merge files query.

PR Close #55172
2024-04-02 18:32:21 +00:00
Andrew Scott 58942dbe93 refactor(core): Update method of grabbing native setTimeout and rAF (#55092)
As mentioned in https://github.com/angular/angular/pull/54600#discussion_r1528372804
a more effective way of getting the unpatched version of a zone-patched
API is to grab it from global[Zone.__symbol__('apiname')].

PR Close #55092
2024-04-02 16:21:54 +00:00
ivanwonder 104dfd4cef refactor(language-service): support showing tags info in the completion (#51140)
The Angular VSCode extension will support showing the tags info in this

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

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

PR Close #51140
2024-04-02 16:21:01 +00:00
Dylan Hunn f824911510 fix(compiler): For FatalDiagnosticError, hide the message field without affecting the emit (#55160)
We want to hide `.message` from users, but the previous approach is not compatible with a specific [TS 3.7 flag](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier) ("using class fields to specialize properties from base classes also won’t work"). I received a request from the TS team to fix this, so they can enable that flag.

Instead, we just override `message` to `never` in the .d.ts using `declare`.

PR Close #55160
2024-04-02 16:20:23 +00:00
Kristiyan Kostadinov c04ffb1fa6 fix(compiler-cli): use switch statements to narrow Angular switch blocks (#55168)
In #52110 we had to use `if` statements to represent `switch` blocks, because TypeScript had a bug when narrowing the type of parenthesized `switch` statements. Now that it has been fixed by TypeScript and we don't support any version that has the broken behavior, we can go back to generating `switch` statements in the TCB which are simpler and better represent the user's code.

PR Close #55168
2024-04-02 16:19:47 +00:00
Thomas Nguyen 666d646575 feat(core): Add event delegation library to queue up events and replay them when the application is ready (#55121)
This adds the JSAction library from the Wiz framework to core/primitives.

PR Close #55121
2024-04-02 16:09:13 +00:00
Andrew Scott 840c375255 fix(core): do not save point-in-time setTimeout and rAF references (#55124)
Grabbing and saving the references to global `setTimeout` and `rAF`
implementations at a certain point in time can be problematic, espcially
in tests. Tests might call something like `jasmine.clock().install();`
and `jasmine.clock().uninstall();`. If the install happens before we
grab the implementation and then the uninstall happens after, our
scheduling function will be broken because it would have saved a reference to
the jasmine `setTimeout` implementation, which would have since been
cleaned up and will throw  an error when attempting to access `delayedFunctionScheduler`.

There are other scenarios that may apply, not even just for tests, when
patches are applied and removed to the globals.

PR Close #55124
2024-04-01 11:00:11 -07:00
garrettld e18a0ed1a3 fix(devtools): fix padding in property tree view (#54648)
This import was missed when switching devtools to standalone.

fixes #54622

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

PR Close #55128
2024-04-01 10:00:06 -07:00
Andrew Scott 940a3587b7 refactor(router): prevent navigationErrorHandler from breaking transition subscription (#55152)
Following up on #55068, this change prevents errors in the handler from
breaking navigations.

PR Close #55152
2024-04-01 09:47:54 -07:00
Andrew Scott 3839cfbb18 fix(router): Routed components never inherit RouterOutlet EnvironmentInjector (#54265)
This commit ensures components in the route config predictably always
get their providers from the hierarchy available to routes rather than
sometimes being dependent on where they are inserted.

fixes #53369

BREAKING CHANGE: 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.

PR Close #54265
2024-04-01 09:19:13 -07:00
Andrew Scott 87f3f27f90 feat(router): Allow resolvers to return RedirectCommand (#54556)
Returning a `RedirectCommand` from a resolver can be interpreted as
distinctly different from regular resolved data. When a resolver returns
`RedirectCommand` we can interperet this as an intention to redirect in
the same way as other guards.

resolves #29089

PR Close #54556
2024-03-30 10:52:44 -07:00
Paweł Kubiak 8a8181a54d fix(docs-infra): scrolling experience in API Reference (#55133)
Fix scrolling experience in API Reference:
- set correct margin top for members container (right side) which is aligned with tabs (left side)
- prevent scroll on focus
- remove redundant blur calls

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

PR Close #54558
2024-03-29 16:46:19 -07:00
Andrew Scott 7d4dd08591 test(core): Update hybrid mode scheduling test to wait for fixture stable (#55076)
Now that pending tasks contribute to fixture stability, the tests can be
simplified.

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

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

Fixes #55085.

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

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

Fixes  #54778

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

Changing path for correctly displaying in adev

PR Close #54795
2024-03-29 13:06:42 -07:00
Johnny Gérard 50da50103f docs(common): clean up comment (#55088)
PR Close #55088
2024-03-29 13:02:44 -07:00
Angular Robot 418b7dff4b build: lock file maintenance (#55022)
See associated pull request for more information.

PR Close #55022
2024-03-29 12:59:32 -07:00
Andrew Scott 38bb95a8f5 Revert "refactor(compiler): add support for the new search element (#54945)" (#55127)
This reverts commit 367b3ee6e9.
The search element is not a void element but existing components may use
the same selector and be used as a void element.

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

PR Close #55126
2024-03-29 12:48:27 -07:00
Matthieu Riegler 1ae460c387 docs: remove unused examples (#55110)
fixes #52660

PR Close #55110
2024-03-29 11:58:31 -07:00
Jessica Janiuk e4fde98279 ci: Update workflows to use latest dev infra hash (#55123)
This bumps the hash for dev-infra dependencies to utilize the latest build and changes

PR Close #55123
2024-03-29 11:51:30 -07:00
Andrew Scott 3974c2184e refactor(core): All views attached to application are treated as OnPush in zoneless (#55099)
This change treats all views attached to `ApplicationRef` as `OnPush`,
meaning that they have to be explicitly marked for check in order to be
refreshed when a tick happens. This prevents "accidentally" refreshing
views which have `Default` change detection as a side effect of running
change detection from an unrelated notification.

In addition, this change helps us achieve one of the big goals of the
project: that we can provide a testing experience which gives developers
more confidence that a component is zoneless-compatible. Because
`ComponentFixture` change detection is run through `ApplicationRef`
instead of `ChangeDetectorRef` when zoneless is enabled, this ensures
that the component under test has correctly been marked for check in
order to be updated. Without this, calling
`ComponentFixture.detectChanges` would allow a test to _force_ change
detection on a view when Angular would have otherwise not known that it
needed to be updated. Calling `ComponentFixture.detectChanges` on a component
which is not marked for check will now omit refreshing component view.

PR Close #55099
2024-03-29 10:42:21 -07:00
Angular Robot a122bd14ea build: update dependency gulp to v5 (#55108)
See associated pull request for more information.

PR Close #55108
2024-03-29 10:13:07 -07:00
Matthieu Riegler 367b3ee6e9 refactor(compiler): add support for the new search element (#54945)
See #whatwg/html#5811
Spec: https://html.spec.whatwg.org/multipage/grouping-content.html#the-search-element

fixes #54944

PR Close #54945
2024-03-29 10:01:54 -07:00
Andrew Scott a99cb7ce5b fix(core): zoneless scheduler should check if Zone is defined before accessing it (#55118)
zoneless scheduler should check if Zone is defined before accessing it

fixes #55116

PR Close #55118
2024-03-29 09:59:00 -07:00
Angular Robot 218c5bd2b3 build: update dependency @babel/core to v7.24.3 (#55038)
See associated pull request for more information.

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

Fixes #53390

PR Close #53716
2024-03-29 09:40:11 -07:00
Dan Wahlin 1b8bf1d4b8 docs: fix typo in control-flow.md (#54976)
PR Close #54976
2024-03-29 09:39:31 -07:00
Gerald Monaco a5fa279b6e fix(core): prevent i18n hydration from cleaning projected nodes (#54823)
Rework the i18n cleanup behavior to more closely match that of containers. Specifically, we assume that nodes are going to be claimed unless they are part of a branching ICU block.

During hydration, we then track which ICU case was active at serialization time, and which was active during hydration. Any remaining cases that weren't used during hydration are then cleaned up.

PR Close #54823
2024-03-29 09:35:43 -07:00
Gerald Monaco f44a5e4604 fix(core): support content projection and VCRs in i18n (#54823)
Modifies the i18n pre-hydration logic to correctly support content projection and elements that act as view containers.

PR Close #54823
2024-03-29 09:35:43 -07:00
Gerald Monaco 146306a141 feat(core): add support for i18n hydration (#54823)
Add support for hydrating i18n blocks. This is accomplished by serializing information about selected ICU cases for a block during server-side rendering.

During hydration, this data is read and is used to traverse both an AST of the translated message and the DOM, in parallel, to map each LView with an RNode.

Finally, this mapping is used while nodes are being created (either via i18n or their respective instructions) to locate existing nodes.

PR Close #54823
2024-03-29 09:35:43 -07:00
vladboisa 1c11d89e9e docs(docs-infra): rephrase sentence to make sense (#54914)
Remove the confuse sentences with 2 categories, and rephrase

Fixes #54792

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

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

PR Close #55112
2024-03-29 09:22:10 -07:00
Andrew Scott 860de662b6 refactor(router): Navigation promise should resolve false instead of null on skip (#55068)
This commit updates the internal resolve value of the navigation promise
to use `false` instead of `null` when a navigation is skipped. The
navigation promise type requires `boolean` so the correct resolution to
match the truthy/falsiness of the currently resolved value, `null`, is
`false` instead.

PR Close #55068
2024-03-29 09:16:47 -07:00
Andrew Scott 2794084d74 refactor(router): move navigation error handler call to location of error emit (#55068)
This commit moves the call to the error handler to the location where
the error event emits instead of having it indirectly work through the
events subscription. This change would also allow the handler to return
a value which can be handled by the navigation transition.

PR Close #55068
2024-03-29 09:16:47 -07:00
Andrew Scott 17369ed1e9 refactor(router): Correct resolve value for error handler case (#55068)
This commit fixes the types on the error handler resolve and reject
functions and also ensures that the resolve value matches the API type
(`boolean`, not "any random value returned from `errorHandler`"). This
could be considered a breaking change but I would argue instead that
relying on the return value of the error handler is API misuse because
the promise returned by the router navigation _does not_ include `any`
in its type.

PR Close #55068
2024-03-29 09:16:46 -07:00
Andrew Scott 4073d3854f refactor(router): fix internal types of resolve and reject promises (#55068)
This commit fixes the internal types for the resolve and reject
functions used for the router navigation Promise. These are currently
typed as `any`.

PR Close #55068
2024-03-29 09:16:46 -07:00
Andrew Scott 0b450ffa6f refactor(core): Move private export testing file to src (#55103)
This matches the private export approach for files in other packages.

PR Close #55103
2024-03-28 16:35:25 -07:00
Andrew Scott ac0a51ce3d refactor(core): Update SchedulingMode to be regular enum (#55103)
Angular recently gained a local compilation mode (see commit 345dd6d).
This is intended to be used with the TypeScript compiler option isolatedModules, which bans imports of const enums.

PR Close #55103
2024-03-28 16:35:24 -07:00
Matthieu Riegler d839c58031 docs(docs-infra): improve styling for deprecated CLI option (#54794)
Related to #54770

PR Close #54794
2024-03-28 15:48:22 -07:00
Matthieu Riegler 431fb9740d docs(docs-infra): add margin for command aliases (#54794)
PR Close #54794
2024-03-28 15:48:22 -07:00
Matthieu Riegler ec59b2fe74 docs(docs-infra): improve space between cli command options (#54794)
fixes #54767

PR Close #54794
2024-03-28 15:48:22 -07:00
Andrew Scott ea2d42507e refactor(core): Remove unused change detection flags (#55057)
This commit removes unused change detection flags.

PR Close #55057
2024-03-28 15:47:41 -07:00
Angular Robot 474b6c22da build: update dependency puppeteer-core to v22.6.1 (#55040)
See associated pull request for more information.

PR Close #55040
2024-03-28 15:46:46 -07:00
Allan Barrantes fac8d34edc docs: remove broken link from CONTRIBUTING.md (#54953)
PR Close #54953
2024-03-28 15:06:56 -07:00
Angular Robot d992be55e6 build: update eslint dependencies to v7.4.0 (#55041)
See associated pull request for more information.

PR Close #55041
2024-03-28 15:06:06 -07:00
Andrew Scott 22dd52f460 refactor(core): re-export private exports from testing (#55101)
This commit re-exports private exports  from testing package.

PR Close #55101
2024-03-28 13:54:16 -07:00
Andrew Scott f9417ea3a8 refactor(core): Privately export SchedulingMode enum (#55100)
Expose enum for early testers so they don't have to awkwardly put `0`
for Hybrid mode.

PR Close #55100
2024-03-28 13:15:03 -07:00
Andrew Scott edfc5a9c3b refactor(core): private export token to disable fixture.detectChanges error (#55098)
While we do want to discourage `fixture.detectChanges`, it is yet to be
determined how this should be accomplished (warning, documentation, etc.). At
the moment, not being able to disable the error at all is entirely
prohibitive for existing test suites to use zoneless change detection in
tests. We would much rather allow existing test suites to disable the
error and use the zoneless change detection than prevent them from using
it entirely until all the `detectChanges` calls have been fixed.
Calling `detectChanges` manually can hide errors related to change
detection timing, but it is even worse when the "PseudoApplication"
fixture used (since it runs change detection _only_ on the component
rather than through `ApplicationRef`).

PR Close #55098
2024-03-28 13:14:27 -07:00
Garrett Darnell b87b2fc05c docs(core): fix toSignal docs (#54964)
PR Close #54964
2024-03-28 13:06:43 -07:00
Angular Robot 40e41e4d33 build: update github/codeql-action action to v3.24.9 (#55039)
See associated pull request for more information.

PR Close #55039
2024-03-28 13:05:57 -07:00
Matthieu Riegler f523415203 docs: drop glossary links (#55044)
PR Close #55044
2024-03-28 13:02:50 -07:00
Ben Hong f911aef72a docs: fix outdated security guide reference (#55069)
PR Close #55069
2024-03-28 13:01:59 -07:00
Andrew Scott 914e4530b0 fix(core): test cleanup should not throw if Zone is not present (#55096)
The test hooks should not throw if applications choose not to load ZoneJS.

fixes #48198

PR Close #55096
2024-03-28 12:12:30 -07:00
Charles Lyding a48afe0d94 fix(language-service): avoid generating TS syntactic diagnostics for templates (#55091)
Angular's template files are not valid TypeScript. Attempting to get syntactic
diagnostics from the underlying TypeScript language service will result in
a large amount of false positive errors. Only actual TypeScript files should
be analyzed by the underlying TypeScript language service for syntactic errors.

PR Close #55091
2024-03-28 12:10:40 -07:00
Ben Hong d63706e9d6 docs: add missing h1 to page for skip to main content on home page (#55052)
PR Close #55052
2024-03-28 12:09:57 -07:00
JiaLiPassion ddbf6bb038 fix(zone.js): make sure fakeasync use the same id pool with native (#54600)
Close #54323

fakeAsync should use the same timerId pool with native, so they will not
conflict.

PR Close #54600
2024-03-28 10:30:25 -07:00
Dylan Hunn 6d14fc52b9 release: cut the v18.0.0-next.2 release 2024-03-28 10:05:21 -07:00
Dylan Hunn a64eca2a9a docs: release notes for the v17.3.2 release 2024-03-28 10:00:27 -07:00
Kristiyan Kostadinov 63688714ae fix(migrations): account for variables in imports initializer (#55081)
Fixes that the control flow migration was throwing an error if the `imports` of a component are initialized to an identifier.

Fixes #55080.

PR Close #55081
2024-03-28 09:40:31 -07:00
Matthieu Riegler f17134a7a4 docs: remove AIO guides (#54829)
PR Close #54829
2024-03-28 09:37:06 -07:00
Andrew Kushnir 86a359b399 fix(core): establish proper injector resolution order for @defer blocks (#55079)
This commit updates the `@defer` logic to establish proper injector resolution order. More specifically:

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

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

PR Close #55079
2024-03-28 09:23:38 -07:00
Kristiyan Kostadinov 336916ceb0 refactor(compiler-cli): allow source file validator rule to produce a single diagnostic (#54993)
Allows for `SourceFileValidatorRule.checkNode` to produce a single diagnostic. The most common case should be one diagnostic per node so this allows us to save some array allocations.

PR Close #54993
2024-03-28 09:17:04 -07:00
Kristiyan Kostadinov 694ba79cbf fix(compiler-cli): report cases where initializer APIs are used in a non-directive class (#54993)
Expands the check for initializer APIs to also flag when the function is called on a class that isn't a component or directive.

PR Close #54993
2024-03-28 09:17:03 -07:00
Kristiyan Kostadinov 78188e877a fix(compiler-cli): add diagnostic if initializer API is used outside of an initializer (#54993)
Adds a rule that will produce a diagnostic when an initializer-based API is used outside of an initializer.

Fixes #54381.

PR Close #54993
2024-03-28 09:17:02 -07:00
Kristiyan Kostadinov 8226be6abf refactor(compiler-cli): introduce infrastructure for running additional checks against TypeScript files (#54993)
Adds the new `SourceFileValidator` that will be used to check for file-level issues that may prevent Angular from working, like invoking the `input()` function outside of an initializer. Currently only one check is planned, but this setup will allow us to easily add more in the future.

PR Close #54993
2024-03-28 09:17:01 -07:00
Kristiyan Kostadinov 3d9f01c6ec refactor(compiler-cli): add API to check if imports exist (#54993)
Adds a couple of APIs to the `ImportedSymbolsTracker` that allow us to quickly check if a specific symbol is imported in a file.

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

PR Close #55061
2024-03-28 09:14:23 -07:00
Andrew Scott e02bcf89cf fix(core): Fix clearing of pending task in zoneless cleanup implementation (#55074)
This commit fixes a mistake in #54952 where the first pending task was falsey because its ID is 0

PR Close #55074
2024-03-27 14:29:08 -07:00
Andrew Scott 80f96e7c51 refactor(core): Provide scheduler for use and coordination with zone change detection (#54952)
This commit makes the zoneless scheduler (privately) available to applications that
have ZoneJS-based change detection. This would catch any changes of
interest (signal updates, `markForCheck` calls, attaching `Dirty` views)
that happen outside the Angular Zone.

See #53844 for additional information about why this is important.
More details to come in the a future commit that makes this a public option.

PR Close #54952
2024-03-27 11:36:56 -07:00
Matthieu Riegler e523f27e67 docs: fix link to NPM release cycle page (#54793)
PR Close #54793
2024-03-27 11:33:09 -07:00
Matthieu Riegler 2a395f8917 docs: link to http security now at best-practices/security (#55060)
fixes #55058

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

PR Close #54779
2024-03-27 11:09:15 -07:00
3812 changed files with 238631 additions and 287237 deletions
+1
View File
@@ -17,6 +17,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
+7 -17
View File
@@ -56,15 +56,17 @@ build --enable_runfiles
build:release --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=release"
build:release --stamp
# Building AIO against local Angular deps requires stamping
# versions in Angular packages due to CLI version checks.
build:aio_local_deps --stamp
build:aio_local_deps --workspace_status_command="yarn -s --cwd aio local-workspace-status"
# Snapshots should also be stamped with version control information.
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
build:snapshot-build --stamp
# Angular DevTools for Firefox releases *cannot* be stamped and `--config snapshot-build-firefox` is a no-op.
# This is because Mozilla requires add-on source code to be uploaded and then they manually reproduce the build.
# If we stamp the build based on Git information such as the current commit, then reproducing the build would require
# uploading the entire `.git` directory. We already must upload the entire monorepo, and uploading `.git` as well
# exceeds the max source file size. To address this, we just *don't* stamp Firefox builds of Angular DevTools.
build:snapshot-build-firefox --nostamp
##########################################################
# AIO architect build configuration #
# See aio/angular.json for available configurations. #
@@ -74,14 +76,6 @@ build:snapshot-build --stamp
##########################################################
build --flag_alias=aio_build_config=//aio:flag_aio_build_config
####################################
# AIO first party dep substitution #
# Turn on with #
# --config=aio_local_deps #
####################################
build:aio_local_deps --//aio:flag_aio_local_deps
###############################
# Output #
###############################
@@ -118,10 +112,6 @@ common:remote --jobs=200
build:remote --google_default_credentials
# Limit the number of test jobs for on an AIO local deps build. The example tests running
# concurrently pushes the circleci executor RAM usage to its limits.
test:aio_local_deps --jobs=24
# Force remote exeuctions to consider the entire run as linux
build:remote --cpu=k8
build:remote --host_cpu=k8
@@ -8,7 +8,6 @@
"devondcarew.bazel-code",
"gkalpak.aio-docs-utils",
"ms-vscode.vscode-typescript-tslint-plugin",
"xaver.clang-format",
// The following extensions are useful when working on angular.io (i.e. inside the `aio/` directory).
//"angular.ng-template",
//"dbaeumer.vscode-eslint",
+1 -1
View File
@@ -1,4 +1,4 @@
name: 'Docs or angular.io Bug Report'
name: 'Docs or angular.dev Bug Report'
description: Report an issue in Angular's documentation or angular.io application
body:
@@ -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,71 @@
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',
redirect: {
from: `v${releaseTrains.next.version.major}-angular-dev`,
to: 'https://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": []
}
+1 -1
View File
@@ -4,7 +4,7 @@ description: 'Installs the dependencies using Yarn'
runs:
using: 'composite'
steps:
- uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4
with:
path: |
./node_modules/
+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@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel build --config=aio_local_deps //adev:build
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@5774b71c01a55c4c998f858ee37d3b77ae704c31
run: yarn bazel build //adev:build --config=release
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@8b117748ae8243f98d261a9731908867b8e3d876
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # 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@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@8b117748ae8243f98d261a9731908867b8e3d876
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
persist-credentials: false
- uses: angular/dev-infra/github-actions/branch-manager@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/branch-manager@8b117748ae8243f98d261a9731908867b8e3d876
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
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@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
with:
bazelrc: ./.bazelrc.user
+36 -44
View File
@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
node-module-directories: |
@@ -58,13 +58,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
@@ -76,13 +76,13 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
@@ -93,15 +93,17 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel test --config=aio_local_deps //adev:test
- 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 --config=release
publish-snapshots:
if: github.event_name == 'push'
@@ -109,13 +111,13 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Install node modules
run: yarn install --frozen-lockfile
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
@@ -127,7 +129,7 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
node-module-directories: |
@@ -135,9 +137,9 @@ jobs:
./packages/zone.js/node_modules
./packages/zone.js/test/typings/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
@@ -176,7 +178,7 @@ jobs:
JOBS: 2
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
# Checking out the pull request commit is intended here as we need to run the changed code tests.
@@ -184,11 +186,11 @@ jobs:
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@50bb71e51d3372ca2e359adb9069f89beeac4ae7
uses: angular/dev-infra/github-actions/saucelabs@8b117748ae8243f98d261a9731908867b8e3d876
- name: Set up Sauce Tunnel Daemon
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
env:
@@ -204,15 +206,15 @@ jobs:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@50bb71e51d3372ca2e359adb9069f89beeac4ae7
uses: angular/dev-infra/github-actions/saucelabs@8b117748ae8243f98d261a9731908867b8e3d876
- 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
@@ -246,32 +248,22 @@ jobs:
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' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel build --config=aio_local_deps //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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/commit-message-based-labels@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: angular/dev-infra/github-actions/commit-message-based-labels@8b117748ae8243f98d261a9731908867b8e3d876
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
post_approval_changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/post-approval-changes@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: angular/dev-infra/github-actions/post-approval-changes@8b117748ae8243f98d261a9731908867b8e3d876
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/google-internal-tests@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: angular/dev-infra/github-actions/google-internal-tests@8b117748ae8243f98d261a9731908867b8e3d876
with:
run-tests-guide-url: http://go/angular-g3sync-start
github-token: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
status:
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/unified-status-check@5774b71c01a55c4c998f858ee37d3b77ae704c31
- uses: angular/dev-infra/github-actions/unified-status-check@8b117748ae8243f98d261a9731908867b8e3d876
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+4 -4
View File
@@ -22,15 +22,15 @@ jobs:
version: ['https://next.angular.io/', 'https://angular.io/']
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
- name: Install node modules in aio
run: yarn install --frozen-lockfile --cwd aio
- name: Run basic e2e and deployment config tests.
@@ -44,7 +44,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5774b71c01a55c4c998f858ee37d3b77ae704c31
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
with:
cache-node-modules: true
node-module-directories: |
+4 -4
View File
@@ -25,12 +25,12 @@ jobs:
steps:
- name: 'Checkout code'
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
persist-credentials: false
- name: 'Run analysis'
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
with:
results_file: results.sarif
results_format: sarif
@@ -39,7 +39,7 @@ jobs:
# Upload the results as artifacts.
- name: 'Upload artifact'
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: SARIF file
path: results.sarif
@@ -47,6 +47,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: 'Upload to code-scanning'
uses: github/codeql-action/upload-sarif@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8
uses: github/codeql-action/upload-sarif@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5
with:
sarif_file: results.sarif
+3 -3
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
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
@@ -28,11 +28,11 @@ jobs:
# This is needed as otherwise the PR creation will fail with `shallow update not allowed` when the forked branch is not in sync.
fetch-depth: 0
- name: Generate CLI help
run: node aio/scripts/update-cli-help/index.mjs
run: node adev/scripts/update-cli-help/index.mjs
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@1421ff04811ecb45812930c5d1f61d912880e75f
uses: angular/dev-infra/github-actions/create-pr-for-changes@8b117748ae8243f98d261a9731908867b8e3d876
with:
branch-prefix: update-cli-help
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
+7 -55
View File
@@ -7,23 +7,7 @@ export const format: FormatConfig = {
'prettier': {
'matchers': [
'**/*.{yaml,yml}',
'adev/**/*.{js,ts}',
'devtools/**/*.{js,ts}',
'tools/**/*.{js,ts}',
'modules/**/*.{js,ts}',
'scripts/**/*.{js,ts}',
'packages/animations/**/*.{js,ts}',
'packages/bazel/**/*.{js,ts}',
'packages/benchpress/**/*.{js,ts}',
'packages/common/**/*.{js,ts}',
'packages/docs/**/*.{js,ts}',
'packages/elements/**/*.{js,ts}',
'packages/examples/**/*.{js,ts}',
'packages/misc/**/*.{js,ts}',
'packages/private/**/*.{js,ts}',
'packages/router/**/*.{js,ts}',
'packages/service-worker/**/*.{js,ts}',
'packages/upgrade/**/*.{js,ts}',
'**/*.{js,ts}',
// Do not format d.ts files as they are generated
'!**/*.d.ts',
@@ -31,50 +15,18 @@ export const format: FormatConfig = {
// not be modified.
'!third_party/**',
'!.yarn/**',
],
},
'clang-format': {
'matchers': [
'**/*.{js,ts}',
// TODO: burn down format failures and remove aio and integration exceptions.
'!aio/**',
'!integration/**',
// Both third_party and .yarn are directories containing copied code which should
// not be modified.
'!third_party/**',
'!.yarn/**',
// Do not format d.ts files as they are generated
'!**/*.d.ts',
// Do not format generated ng-dev script
'!dev-infra/ng-dev.js',
'!dev-infra/build-worker.js',
// Do not format compliance test-cases since they must match generated code
'!packages/compiler-cli/test/compliance/test_cases/**/*.js',
// Do not format the locale files which are checked-in for Google3, but generated using
// the `generate-locales-tool` from `packages/common/locales`.
'!packages/core/src/i18n/locale_en.ts',
'!packages/common/locales/closure-locale.ts',
'!packages/common/src/i18n/currencies.ts',
// Temporarily disable formatting for adev
'!adev/**',
// Test cases contain non valid code.
'!packages/compiler-cli/test/compliance/test_cases/**/*.{js,ts}',
// Ignore AIO as its pending removal.
'!aio/**/*.{js,ts}',
// Migrated to prettier
'!devtools/**/*.{js,ts}',
'!tools/**/*.{js,ts}',
'!modules/**/*.{js,ts}',
'!scripts/**/*.{js,ts}',
'!packages/animations/**/*.{js,ts}',
'!packages/bazel/**/*.{js,ts}',
'!packages/benchpress/**/*.{js,ts}',
'!packages/common/**/*.{js,ts}',
'!packages/docs/**/*.{js,ts}',
'!packages/elements/**/*.{js,ts}',
'!packages/examples/**/*.{js,ts}',
'!packages/misc/**/*.{js,ts}',
'!packages/private/**/*.{js,ts}',
'!packages/router/**/*.{js,ts}',
'!packages/service-worker/**/*.{js,ts}',
'!packages/upgrade/**/*.{js,ts}',
// Ignore generated javascript file(s)
'!.github/actions/deploy-docs-site/main.js',
],
},
'buildifier': true,
+1 -1
View File
@@ -1 +1 @@
18.18.2
18.20.0
+83 -22
View File
@@ -140,7 +140,7 @@ groups:
- alxhub
- crisbeto
- ~jelbourn
- jessicajaniuk
- thePunderWoman
# =========================================================
# Framework: Compiler
@@ -183,7 +183,7 @@ groups:
- crisbeto
- devversion
- dylhunn
- jessicajaniuk
- thePunderWoman
- AndrewKushnir
# =========================================================
@@ -193,7 +193,7 @@ groups:
<<: *defaults
conditions:
- >
contains_any_globs(files.exclude("packages/core/schematics/*"), [
contains_any_globs(files.exclude("packages/core/schematics/*").exclude('packages/core/primitives/*'), [
'packages/core/**/{*,.*}',
'packages/examples/core/**/{*,.*}',
'packages/platform-browser/**/{*,.*}',
@@ -358,7 +358,7 @@ groups:
- crisbeto
- devversion
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -378,7 +378,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -415,7 +415,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -438,7 +438,7 @@ groups:
- andrewseguin
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -536,7 +536,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -615,7 +615,7 @@ groups:
reviewers:
users:
- alxhub
- jessicajaniuk
- thePunderWoman
# =========================================================
# Framework: Testing
@@ -644,7 +644,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -663,7 +663,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -682,7 +682,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -778,7 +778,7 @@ groups:
- atscott
- crisbeto
- dylhunn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
# =========================================================
@@ -813,7 +813,7 @@ groups:
- AndrewKushnir
- atscott
- dylhunn
- jessicajaniuk
- thePunderWoman
- josephperrott
- pkozlowski-opensource
@@ -867,7 +867,7 @@ groups:
reviewers:
users:
- AndrewKushnir
- jessicajaniuk
- thePunderWoman
# =========================================================
# Docs: Marketing
@@ -946,7 +946,7 @@ groups:
- alxhub
- AndrewKushnir
- atscott
- jessicajaniuk
- thePunderWoman
- jelbourn
# =========================================================
@@ -1078,11 +1078,12 @@ groups:
- josephperrott
- jelbourn
- bencodezen
- jessicajaniuk
- thePunderWoman
- dylhunn
- AndrewKushnir
- alxhub
- crisbeto
- devversion
- atscott
- pkozlowski-opensource
- ~JeanMeche
@@ -1143,7 +1144,7 @@ groups:
reviewers:
users:
- AndrewKushnir
- jessicajaniuk
- thePunderWoman
- josephperrott
# =========================================================
@@ -1242,7 +1243,7 @@ groups:
- atscott
- dylhunn
- ~jelbourn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
reviews:
request: 3 # Request reviews from 3 people
@@ -1268,7 +1269,7 @@ groups:
- atscott
- dylhunn
- ~jelbourn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
reviews:
request: 2 # Request reviews from 2 people
@@ -1294,7 +1295,7 @@ groups:
- atscott
- dylhunn
- ~jelbourn
- jessicajaniuk
- thePunderWoman
- pkozlowski-opensource
####################################################################################
@@ -1318,9 +1319,69 @@ groups:
- andrewseguin
- dgp1130
- ~jelbourn
- jessicajaniuk
- thePunderWoman
- josephperrott
# =========================================================
# Primitives
# =========================================================
# Angular team required reviews
primitives:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'packages/core/primitives/**/{*,.*}',
])
reviewers:
users:
- pkozlowski-opensource # Pawel Kozlowski
- alxhub # Alex Rickabaugh
- thePunderWoman # Jessica Janiuk
- dylhunn # Dylan Hunn
- AndrewKushnir # Andrew Kushnir
- atscott # Andrew Scott
reviews:
required: 1
reviewed_for: optional
labels:
pending: 'requires: TGP'
approved: 'requires: TGP'
rejected: 'requires: TGP'
# External team required reviews
primitives-shared:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
'packages/core/primitives/**/{*,.*}',
])
reviewers:
users:
- csmick # Cameron Smick
- lannka # Hongfei Ding
- eduhmc # Eduardo Huerta-Mercado
- ehlemur # Edward Lesmes
- ellenyuan # Ellen Yuan
- jatraman # Jatin Ramanathan
- jesse-good # Jesse Costello-Good
- mturco # Matt Turco
- neonstalwart # Ben Hockey
- nicholasyu-google # Nicholas Yu
- emspishak # Eric Spishak-Thomas
- iteriani # Thomas Nguyen
- tbondwilkinson # Tom Wilkinson
- rahatarmanahmed # Rahat Ahmed
reviews:
required: 1
reviewed_for: optional
labels:
pending: 'requires: TGP'
approved: 'requires: TGP'
rejected: 'requires: TGP'
####################################################################################
# Override managed result groups
#
-1
View File
@@ -6,6 +6,5 @@
"recommendations": [
"BazelBuild.vscode-bazel",
"ms-vscode.vscode-typescript-tslint-plugin",
"xaver.clang-format",
],
}
-6
View File
@@ -1,16 +1,10 @@
{
// Format js and ts files on save with `clang-format.executable`
// If `clang-format.executable` is not being used, these two settings should be removed otherwise it will break existing formatting.
// You can instead run `yarn gulp format` to manually format your code.
"[javascript]": {
"editor.formatOnSave": true,
},
"[typescript]": {
"editor.formatOnSave": true,
},
// Please install https://marketplace.visualstudio.com/items?itemName=xaver.clang-format to take advantage of `clang-format` in VSCode.
// (See https://clang.llvm.org/docs/ClangFormat.html for more info `clang-format`.)
"clang-format.executable": "${workspaceRoot}/node_modules/.bin/clang-format",
// Exclude third party modules and build artifacts from the editor watchers/searches.
"files.watcherExclude": {
"**/.git/objects/**": true,
+299 -77
View File
@@ -1,69 +1,19 @@
<a name="18.0.0-next.1"></a>
# 18.0.0-next.1 (2024-03-20)
<a name="18.0.0"></a>
# 18.0.0 (2024-05-22)
## 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.
### 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
| 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)) |
- Angular only supports writable expressions inside of two-way bindings.
### 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
| Commit | Type | Description |
| -- | -- | -- |
| [c0788200e2](https://github.com/angular/angular/commit/c0788200e26406bacb90ee0079ea9753eebd1b32) | fix | capture data bindings for content projection purposes in blocks ([#54876](https://github.com/angular/angular/pull/54876)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [99e9474aa2](https://github.com/angular/angular/commit/99e9474aa2ccccdf4385fbac6b62b1a4585ed4b4) | fix | symbol feature detection for the compiler ([#54711](https://github.com/angular/angular/pull/54711)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="18.0.0-next.0"></a>
# 18.0.0-next.0 (2024-03-14)
## Breaking Changes
- * 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
@@ -74,12 +24,45 @@
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
@@ -108,28 +91,282 @@
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.6"></a>
# 17.3.6 (2024-04-25)
### core
| Commit | Type | Description |
| -- | -- | -- |
| [826861b1fa](https://github.com/angular/angular/commit/826861b1fa7693010743f5dd881fb31ec33eee52) | fix | DeferBlockFixture.render should not wait for stability ([#55271](https://github.com/angular/angular/pull/55271)) |
| [5cf14da35c](https://github.com/angular/angular/commit/5cf14da35cce1ea4456bae4365d3dbe6667b1881) | fix | make `ActivatedRoute` inject correct instance inside `@defer` blocks ([#55374](https://github.com/angular/angular/pull/55374)) |
| [8979fba2c5](https://github.com/angular/angular/commit/8979fba2c5813673767a133caeec9ac768d17329) | fix | skip defer timers on the server ([#55480](https://github.com/angular/angular/pull/55480)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.5"></a>
# 17.3.5 (2024-04-17)
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.4"></a>
# 17.3.4 (2024-04-10)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [53427d875d](https://github.com/angular/angular/commit/53427d875d33de16b1dbb04e76a9fe32a2b8a445) | fix | invalid ImageKit quality parameter ([#55193](https://github.com/angular/angular/pull/55193)) |
| [766548c3ec](https://github.com/angular/angular/commit/766548c3ecc06ffd8f06ed9a7d0cbb3db6f1b0f6) | fix | skip transfer cache on client ([#55012](https://github.com/angular/angular/pull/55012)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.2"></a>
# 17.3.2 (2024-03-28)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [2b7bad5151](https://github.com/angular/angular/commit/2b7bad515100cbfa40b3e8d844bae13d43fd5602) | fix | invoke method-based tracking function with context ([#54960](https://github.com/angular/angular/pull/54960)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [b478dfbfda](https://github.com/angular/angular/commit/b478dfbfda3f32fbe723a1e8725e86490422520d) | fix | report errors when initializer APIs are used on private fields ([#55070](https://github.com/angular/angular/pull/55070)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [708ba8115f](https://github.com/angular/angular/commit/708ba8115f7ad05201db5c529aefe4dd48fc64c5) | fix | establish proper injector resolution order for `@defer` blocks ([#55079](https://github.com/angular/angular/pull/55079)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [cb433af0e1](https://github.com/angular/angular/commit/cb433af0e1ba61073eb4a02ccd75cf360e9fd409) | fix | include transferCache when cloning HttpRequest ([#54939](https://github.com/angular/angular/pull/54939)) |
| [64f202cab9](https://github.com/angular/angular/commit/64f202cab9e7a5c873b17bbddd02368006426152) | fix | manage different body types for caching POST requests ([#54980](https://github.com/angular/angular/pull/54980)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [2f9d94bc4a](https://github.com/angular/angular/commit/2f9d94bc4ab5a94e620a13404aba4e094f8b2344) | fix | account for variables in imports initializer ([#55081](https://github.com/angular/angular/pull/55081)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [365fd50407](https://github.com/angular/angular/commit/365fd504077d0e7509efc3077ea4ae8bbafb01f7) | fix | RouterLinkActive will always remove active classes when links are not active ([#54982](https://github.com/angular/angular/pull/54982)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.3.1"></a>
# 17.3.1 (2024-03-20)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [c0788200e2](https://github.com/angular/angular/commit/c0788200e26406bacb90ee0079ea9753eebd1b32) | fix | capture data bindings for content projection purposes in blocks ([#54876](https://github.com/angular/angular/pull/54876)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [99e9474aa2](https://github.com/angular/angular/commit/99e9474aa2ccccdf4385fbac6b62b1a4585ed4b4) | fix | symbol feature detection for the compiler ([#54711](https://github.com/angular/angular/pull/54711)) |
<!-- CHANGELOG SPLIT MARKER -->
@@ -713,21 +950,6 @@ Live long and prosper 🖖🏻
Example after:
```typescript
items.update(itemsArray => [itemsArray, …newItem]);
```
- The `mutate` method was removed from the `WritableSignal` interface and completely
dropped from the public API surface. As an alternative please use the update method and
make immutable changes to the object.
Example before:
```typescript
items.mutate(itemsArray => itemsArray.push(newItem));
```
Example after:
```typescript
items.update(itemsArray => [itemsArray, …newItem]);
```
+1 -6
View File
@@ -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#clang-format).
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#formatting-your-source-code).
## <a name="commit"></a> Commit Message Format
@@ -389,7 +389,6 @@ The following documents can help you sort out issues with GitHub accounts and mu
[angular-group]: https://groups.google.com/forum/#!forum/angular
[coc]: https://github.com/angular/code-of-conduct/blob/main/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[corporate-cla]: https://cla.developers.google.com/about/google-corporate
@@ -398,7 +397,3 @@ The following documents can help you sort out issues with GitHub accounts and mu
[discord]: https://discord.gg/angular
[individual-cla]: https://cla.developers.google.com/about/google-individual
[js-style-guide]: https://google.github.io/styleguide/jsguide.html
[jsfiddle]: https://jsfiddle.net/
[plunker]: https://plnkr.co/edit
[runnable]: https://runnable.com/
[stackoverflow]: https://stackoverflow.com/questions/tagged/angular
+4 -19
View File
@@ -1,7 +1,7 @@
<h1 align="center">Angular - The modern web developer's platform</h1>
<p align="center">
<img src="aio/src/assets/images/logos/angular/angular_renaissance.png" alt="angular-logo" width="120px" height="120px"/>
<img src="adev/src/assets/images/press-kit/angular_icon_gradient.gif" alt="angular-logo" width="120px" height="120px"/>
<br>
<em>Angular is a development platform for building mobile and desktop web applications
<br> using TypeScript/JavaScript and other languages.</em>
@@ -63,22 +63,7 @@ Get started with Angular, learn the fundamentals and explore advanced topics on
### Local Development
To contribute to Angular docs, you can setup a local environment with the following commands:
```bash
# Clone Angular repo
git clone https://github.com/angular/angular.git
# Navigate to project directory
cd angular
# Install dependencies
yarn
# Build and run local dev server
# Note: Initial build will take some time
yarn docs
```
To contribute to the Angular Docs, check out the [Angular.dev README](adev/README.md)
## Development Setup
@@ -167,8 +152,8 @@ Join the conversation and help the community.
[angularmaterial]: https://material.angular.io/
[cli]: https://angular.dev/tools/cli
[architecture]: https://angular.dev/essentials
[componentstemplates]: https://angular.dev/tutorials/learn-angular/components-in-angular
[forms]: https://angular.dev/tutorials/learn-angular/forms
[componentstemplates]: https://angular.dev/tutorials/learn-angular/1-components-in-angular
[forms]: https://angular.dev/tutorials/learn-angular/15-forms
[api]: https://angular.dev/api
[angularelements]: https://angular.dev/guide/elements
[ssr]: https://angular.dev/guide/ssr
+12 -51
View File
@@ -2,27 +2,12 @@ workspace(
name = "angular",
managed_directories = {
"@npm": ["node_modules"],
"@aio_npm": ["aio/node_modules"],
},
)
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("//:yarn.bzl", "YARN_LABEL")
# Add a patch fix for rules_webtesting v0.3.5 required for enabling runfiles on Windows.
# TODO: Remove the http_archive for this transitive dependency when a release is cut
# for https://github.com/bazelbuild/rules_webtesting/commit/581b1557e382f93419da6a03b91a45c2ac9a9ec8
# and the version is updated in rules_nodejs.
http_archive(
name = "io_bazel_rules_webtesting",
patch_args = ["-p1"],
patches = [
"//:tools/bazel-repo-patches/rules_webtesting__windows_runfiles_fix.patch",
],
sha256 = "e9abb7658b6a129740c0b3ef6f5a2370864e102a5ba5ffca2cea565829ed825a",
urls = ["https://github.com/bazelbuild/rules_webtesting/releases/download/0.3.5/rules_webtesting.tar.gz"],
)
http_archive(
name = "build_bazel_rules_nodejs",
patches = [
@@ -65,16 +50,16 @@ load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
nodejs_register_toolchains(
name = "nodejs",
node_repositories = {
"18.18.2-darwin_arm64": ("node-v18.18.2-darwin-arm64.tar.gz", "node-v18.18.2-darwin-arm64", "9f982cc91b28778dd8638e4f94563b0c2a1da7aba62beb72bd427721035ab553"),
"18.18.2-darwin_amd64": ("node-v18.18.2-darwin-x64.tar.gz", "node-v18.18.2-darwin-x64", "5bb8da908ed590e256a69bf2862238c8a67bc4600119f2f7721ca18a7c810c0f"),
"18.18.2-linux_arm64": ("node-v18.18.2-linux-arm64.tar.xz", "node-v18.18.2-linux-arm64", "2e630e18548627f61eaf573233da7949dc0a1df5eef3f486fa9820c5f6c121aa"),
"18.18.2-linux_ppc64le": ("node-v18.18.2-linux-ppc64le.tar.xz", "node-v18.18.2-linux-ppc64le", "b0adff5cf5938266b711d6c724fb134d802e0dee40b3a3f73d162de1b3d11880"),
"18.18.2-linux_s390x": ("node-v18.18.2-linux-s390x.tar.xz", "node-v18.18.2-linux-s390x", "c70ec2074b5e2b42c55bb4b8105418b67bf8a61c500d9376a07430dfcc341fdb"),
"18.18.2-linux_amd64": ("node-v18.18.2-linux-x64.tar.xz", "node-v18.18.2-linux-x64", "75aba25ae76999309fc6c598efe56ce53fbfc221381a44a840864276264ab8ac"),
"18.18.2-windows_amd64": ("node-v18.18.2-win-x64.zip", "node-v18.18.2-win-x64", "3bb0e51e579a41a22b3bf6cb2f3e79c03801aa17acbe0ca00fc555d1282e7acd"),
"18.20.0-darwin_arm64": ("node-v18.20.0-darwin-arm64.tar.gz", "node-v18.20.0-darwin-arm64", "10066ad4dd9e03ea5c4c45ef8775420ff37b860de09bbdf87b97e0c07b1ea036"),
"18.20.0-darwin_amd64": ("node-v18.20.0-darwin-x64.tar.gz", "node-v18.20.0-darwin-x64", "062ba71618e88e06321de5caa038843c350aababa2d315f3ca7b8551f8e66c1c"),
"18.20.0-linux_arm64": ("node-v18.20.0-linux-arm64.tar.xz", "node-v18.20.0-linux-arm64", "afe51da9ffb38ac1e3a20d9a06efd403ced4bf8831ab554a02a088dd8392fd79"),
"18.20.0-linux_ppc64le": ("node-v18.20.0-linux-ppc64le.tar.xz", "node-v18.20.0-linux-ppc64le", "9e652bbf53a3e37285b11dfb9d6a9bb8b02010c3b50e5c8229d4cc10e72681da"),
"18.20.0-linux_s390x": ("node-v18.20.0-linux-s390x.tar.xz", "node-v18.20.0-linux-s390x", "a6c2a5796b9d9e9bf21da62ec89ff30b41a8108880b9eaa3c912f1ce795a7743"),
"18.20.0-linux_amd64": ("node-v18.20.0-linux-x64.tar.xz", "node-v18.20.0-linux-x64", "03eea148e56785babb27930b05ed6bf311aaa3bc573c0399dd63cad2fe5713c7"),
"18.20.0-windows_amd64": ("node-v18.20.0-win-x64.zip", "node-v18.20.0-win-x64", "1c0aab05cc6836a8f5148cca345b92ebc948a4a2013f18d117b7ade6ff05aca6"),
},
# We need at least Node 18.17 due to some transitive dependencies.
node_version = "18.18.2",
node_version = "18.20.0",
)
# Download npm dependencies.
@@ -90,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-e0ec7b60641d7f6369be45d8d02663fd50f320be.patch",
"//tools/esm-interop:patches/npm/@angular+build-tooling+0.0.0-56d0b1f597b9e4b5d99f289f6904a220802164c1.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",
@@ -109,30 +94,6 @@ yarn_install(
yarn_lock = "//:yarn.lock",
)
yarn_install(
name = "aio_npm",
# Note that we add the postinstall scripts here so that the dependencies are re-installed
# when the postinstall patches are modified.
data = [
YARN_LABEL,
"//:.yarnrc",
"//:tools/npm-patches/@bazel+jasmine+5.8.1.patch",
"//aio:tools/cli-patches/bazel-architect-output.patch",
"//aio:tools/cli-patches/patch.js",
],
# Currently disabled due to:
# 1. Missing Windows support currently.
# 2. Incompatibilites with the `ts_library` rule.
exports_directories_only = False,
manual_build_file_contents = npm_package_archives(),
package_json = "//aio:package.json",
# We prefer to symlink the `node_modules` to only maintain a single install.
# See https://github.com/angular/dev-infra/pull/446#issuecomment-1059820287 for details.
symlink_node_modules = True,
yarn = YARN_LABEL,
yarn_lock = "//aio:yarn.lock",
)
yarn_install(
name = "aio_example_deps",
# Rename the default js_library target from "node_modules" as this obscures the
@@ -206,10 +167,10 @@ cldr_xml_data_repository(
# sass rules
http_archive(
name = "io_bazel_rules_sass",
sha256 = "5633816e996a79c77f44306f6228b9ef18fc2ecb412d63b4e314a132225facba",
strip_prefix = "rules_sass-79bd239ce77c101ea1aed575678020bd2999f17d",
sha256 = "e50e1ca1b0a737d2c09efbbb886e0194d99caed617337a766b17c1ee4bae93f2",
strip_prefix = "rules_sass-fcce06104e072bbebbf92c1a244ea9f8c2fc8402",
urls = [
"https://github.com/bazelbuild/rules_sass/archive/79bd239ce77c101ea1aed575678020bd2999f17d.zip",
"https://github.com/bazelbuild/rules_sass/archive/fcce06104e072bbebbf92c1a244ea9f8c2fc8402.zip",
],
)
+32 -17
View File
@@ -1,8 +1,9 @@
load("//:packages.bzl", "link_packages")
load("@npm//@angular/build-tooling/bazel/remote-execution:index.bzl", "ENABLE_NETWORK")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
load("@npm//@angular-devkit/architect-cli:index.bzl", "architect", "architect_test")
load("@bazel_skylib//lib:collections.bzl", "collections")
load("//adev/tools/local_deps:index.bzl", "ensure_local_package_deps", "link_local_packages")
package(default_visibility = ["//visibility:public"])
@@ -30,7 +31,18 @@ TEST_FILES = APPLICATION_FILES + [
["**/*.spec.ts"],
)
APPLICATION_DEPS = link_packages([
APPLICATION_ASSETS = [
"//adev/src/assets/images",
"//adev/src/assets/textures",
"//adev/src/assets/previews",
"//adev/src/assets:tutorials",
"//adev/src/assets/icons",
"//adev/src/assets:api",
"//adev/src/assets:content",
]
APPLICATION_DEPS = [
"@npm//@angular/build",
"@npm//@angular-devkit/build-angular",
"@npm//@angular/animations",
"@npm//@angular/cdk",
@@ -50,13 +62,6 @@ APPLICATION_DEPS = link_packages([
"@npm//ogl",
"@npm//rxjs",
"@npm//typescript",
"//adev/src/assets/images",
"//adev/src/assets/textures",
"//adev/src/assets/previews",
"//adev/src/assets:tutorials",
"//adev/src/assets/icons",
"//adev/src/assets:api",
"//adev/src/assets:content",
"@npm//@typescript/vfs",
"@npm//@codemirror/state",
"@npm//@codemirror/view",
@@ -74,13 +79,15 @@ APPLICATION_DEPS = link_packages([
"@npm//@lezer/javascript",
"@npm//@lezer/common",
"@npm//@xterm/xterm",
"@npm//algoliasearch",
"@npm//xterm",
"@npm//xterm-addon-fit",
"@npm//angular-split",
])
"@npm//zone.js",
]
TEST_DEPS = APPLICATION_DEPS + link_packages([
TEST_DEPS = APPLICATION_DEPS + [
"@npm//@angular/platform-browser-dynamic",
"@npm//@angular/build-tooling/bazel/browsers/chromium",
"@npm//@types/jasmine",
"@npm//@types/node",
"@npm//assert",
@@ -90,8 +97,13 @@ TEST_DEPS = APPLICATION_DEPS + link_packages([
"@npm//karma-coverage",
"@npm//karma-jasmine",
"@npm//karma-jasmine-html-reporter",
"//aio/tools:windows-chromium-path",
])
]
# Create `npm_link` targets for all dependencies that correspond to a
# first-party Angular package that can be built from `HEAD`.
link_local_packages(
all_deps = collections.uniq(APPLICATION_DEPS + TEST_DEPS),
)
copy_to_bin(
name = "application_files_bin",
@@ -129,7 +141,7 @@ architect(
"--output-path=build",
] + config_based_architect_flags,
chdir = "$(RULEDIR)",
data = APPLICATION_DEPS + [
data = ensure_local_package_deps(APPLICATION_DEPS) + APPLICATION_ASSETS + [
":application_files_bin",
],
# Network is required to inline fonts.
@@ -149,7 +161,7 @@ architect(
"--watch",
],
chdir = package_name(),
data = APPLICATION_DEPS + [
data = ensure_local_package_deps(APPLICATION_DEPS) + APPLICATION_ASSETS + [
":application_files_bin",
],
tags = [
@@ -164,7 +176,10 @@ architect_test(
"--no-watch",
],
chdir = package_name(),
data = TEST_DEPS + TEST_FILES,
data = ensure_local_package_deps(TEST_DEPS) + TEST_FILES + APPLICATION_ASSETS + [
"//aio/tools:windows-chromium-path",
"@npm//@angular/build-tooling/bazel/browsers/chromium",
],
env = {
"CHROME_BIN": "../$(CHROMIUM)",
},
+37
View File
@@ -0,0 +1,37 @@
# [Angular.dev](https://www.angular.dev)
This site is built with Angular.
The content is written primarly in Markdown format located in `src/content`. For simple edits, you can directly edit the file on GitHub and generate a Pull Request.
## Local Development
For local development, [yarn](https://yarnpkg.com/) is the preferred package manager. You can setup a local environment with the following commands
:
```bash
# Clone Angular repo
git clone https://github.com/angular/angular.git
# Navigate to project directory
cd angular
# Install dependencies
yarn
# Build and run local dev server
# Note: Initial build will take some time
yarn docs
```
## 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.
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).
+9 -10
View File
@@ -17,11 +17,9 @@
"prefix": "adev",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"builder": "@angular/build:application",
"options": {
"externalDependencies": [
"path"
],
"externalDependencies": ["path"],
"outputPath": "dist/angular-dev",
"index": "src/index.html",
"browser": "src/main.ts",
@@ -29,11 +27,7 @@
"polyfills": ["src/polyfills.ts", "zone.js"],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/robots.txt",
"src/assets"
],
"assets": ["src/favicon.ico", "src/robots.txt", "src/assets"],
"styles": ["@angular/docs/styles/global-styles.scss"],
"scripts": [],
"webWorkerTsConfig": "tsconfig.worker.json",
@@ -99,6 +93,11 @@
}
},
"cli": {
"analytics": "dca119a9-da31-47f7-a6cb-b60541037021"
"analytics": "dca119a9-da31-47f7-a6cb-b60541037021",
"cache": {
// Disable build caching as the cache folder will just be dropped
// when run under Bazel sandboxed execution.
"enabled": false
}
}
}
+3
View File
@@ -0,0 +1,3 @@
# Generating data for `angular.dev/cli`
This script updates the Angular CLI help JSON files stored in `adev/src/content/cli/help`. This files are used to generate the [angular.dev CLI](https://angular.dev/cli) pages.
+154
View File
@@ -0,0 +1,154 @@
import {execSync} from 'node:child_process';
import {readFile, writeFile, readdir, mkdtemp, realpath, copyFile, unlink} from 'node:fs/promises';
import {tmpdir} from 'node:os';
import {get} from 'node:https';
import {dirname, resolve as resolvePath, posix, join} from 'node:path';
import {fileURLToPath} from 'node:url';
import {existsSync, constants as fsConstants} from 'node:fs';
const GITHUB_API = 'https://api.github.com/repos/';
const CLI_BUILDS_REPO = 'angular/cli-builds';
const GITHUB_API_CLI_BUILDS = posix.join(GITHUB_API, CLI_BUILDS_REPO);
const scriptDir = dirname(fileURLToPath(import.meta.url));
const CLI_HELP_CONTENT_PATH = resolvePath(scriptDir, '../../src/content/cli/help');
const CLI_SHA_PATH = join(CLI_HELP_CONTENT_PATH, 'build-info.json');
async function main() {
if (!existsSync(CLI_SHA_PATH)) {
throw new Error(`${CLI_SHA_PATH} does not exist.`);
}
const branch = process.env.GITHUB_REF;
const {sha: currentSha} = JSON.parse(await readFile(CLI_SHA_PATH, 'utf-8'));
const latestSha = await getShaFromCliBuilds(branch);
console.log(`Comparing ${currentSha}...${latestSha}.`);
const affectedFiles = await getAffectedFiles(currentSha, latestSha);
const changedHelpFiles = affectedFiles.filter((file) => file.startsWith('help/'));
if (changedHelpFiles.length === 0) {
console.log(`No 'help/**' files changed between ${currentSha} and ${latestSha}.`);
return;
}
console.log(
`The below help files changed between ${currentSha} and ${latestSha}:\n` +
changedHelpFiles.map((f) => '* ' + f).join('\n'),
);
const temporaryDir = await realpath(await mkdtemp(join(tmpdir(), 'cli-src-')));
const execOptions = {cwd: temporaryDir, stdio: 'inherit'};
execSync('git init', execOptions);
execSync('git remote add origin https://github.com/angular/cli-builds.git', execOptions);
// fetch a commit
execSync(`git fetch origin ${latestSha}`, execOptions);
// reset this repository's main branch to the commit of interest
execSync('git reset --hard FETCH_HEAD', execOptions);
// get sha when files where changed
const shaWhenFilesChanged = execSync(`git rev-list -1 ${latestSha} "help/"`, {
encoding: 'utf8',
cwd: temporaryDir,
stdio: ['ignore', 'pipe', 'ignore'],
}).trim();
// Delete existing JSON help files.
const helpFilesUnlink = (await readdir(CLI_HELP_CONTENT_PATH))
.filter((f) => f.endsWith('.json'))
.map((f) => unlink(join(CLI_HELP_CONTENT_PATH, f)));
await Promise.allSettled(helpFilesUnlink);
// Copy new help files
const tempHelpDir = join(temporaryDir, 'help');
const helpFilesCopy = (await readdir(tempHelpDir)).map((f) => {
const src = join(tempHelpDir, f);
const dest = join(CLI_HELP_CONTENT_PATH, f);
return copyFile(src, dest, fsConstants.COPYFILE_FICLONE);
});
await Promise.allSettled(helpFilesCopy);
// Write SHA to file.
await writeFile(
CLI_SHA_PATH,
JSON.stringify(
{
branchName: branch,
sha: shaWhenFilesChanged,
},
undefined,
2,
),
);
console.log('\nChanges: ');
execSync(`git status --porcelain`, {stdio: 'inherit'});
console.log(`Successfully updated help files in '${CLI_HELP_CONTENT_PATH}'.\n`);
}
/**
* Get SHA of a branch.
*
* @param {string} branch
* @param {string} headSha
* @returns Promise<string>
*/
async function getShaFromCliBuilds(branch) {
const sha = await httpGet(`${GITHUB_API_CLI_BUILDS}/commits/${branch}`, {
headers: {Accept: 'application/vnd.github.VERSION.sha'},
});
if (!sha) {
throw new Error(`Unable to extract the SHA for '${branch}'.`);
}
return sha;
}
/**
* Get the affected files.
*
* @param {string} baseSha
* @param {string} headSha
* @returns Promise<string[]>
*/
async function getAffectedFiles(baseSha, headSha) {
const {files} = JSON.parse(
await httpGet(`${GITHUB_API_CLI_BUILDS}/compare/${baseSha}...${headSha}`),
);
return files.map((f) => f.filename);
}
function httpGet(url, options = {}) {
options.headers ??= {};
options.headers[
'Authorization'
] = `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`;
return new Promise((resolve, reject) => {
get(url, options, (res) => {
let data = '';
res
.on('data', (chunk) => {
data += chunk;
})
.on('end', () => {
resolve(data);
});
}).on('error', (e) => {
reject(e);
});
});
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
+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>
+1 -1
View File
@@ -14,7 +14,7 @@ import {Search, WINDOW} from '@angular/docs';
describe('AppComponent', () => {
const fakeSearch = {};
const fakeWindow = {};
const fakeWindow = {location: {hostname: 'angular.dev'}};
it('should create the app', () => {
TestBed.configureTestingModule({
+73
View File
@@ -0,0 +1,73 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export const VERSIONS_CONFIG = {
aDevVersionsLinkPattern: 'https://{{prefix}}{{version}}angular.dev',
aioVersions: [
{
version: 'v17',
url: 'https://v17.angular.io/docs',
},
{
version: 'v16',
url: 'https://v16.angular.io/docs',
},
{
version: 'v15',
url: 'https://v15.angular.io/docs',
},
{
version: 'v14',
url: 'https://v14.angular.io/docs',
},
{
version: 'v13',
url: 'https://v13.angular.io/docs',
},
{
version: 'v12',
url: 'https://v12.angular.io/docs',
},
{
version: 'v11',
url: 'https://v11.angular.io/docs',
},
{
version: 'v10',
url: 'https://v10.angular.io/docs',
},
{
version: 'v9',
url: 'https://v9.angular.io/docs',
},
{
version: 'v8',
url: 'https://v8.angular.io/docs',
},
{
version: 'v7',
url: 'https://v7.angular.io/docs',
},
{
version: 'v6',
url: 'https://v6.angular.io/docs',
},
{
version: 'v5',
url: 'https://v5.angular.io/docs',
},
{
version: 'v4',
url: 'https://v4.angular.io/docs',
},
{
version: 'v2',
url: 'https://v2.angular.io/docs',
},
],
};
+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;
@@ -61,6 +61,9 @@
<nav
class="adev-nav-primary docs-scroll-hide"
[class.adev-nav-primary--open]="isMobileNavigationOpened()"
[class.adev-nav-primary--rc]="currentDocsVersionMode === 'rc'"
[class.adev-nav-primary--next]="currentDocsVersionMode === 'next'"
[class.adev-nav-primary--deprecated]="currentDocsVersionMode === 'deprecated'"
>
<button
type="button"
@@ -79,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)"
@@ -122,7 +126,14 @@
</clipPath>
</defs>
</svg>
<div class="adev-beta-version">Beta Docs</div>
} @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+ -->
@@ -69,6 +69,23 @@
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(
140deg,
color-mix(in srgb, var(--orange-red), transparent 60%) 0%,
color-mix(in srgb, var(--vivid-pink), transparent 40%) 15%,
color-mix(in srgb, var(--electric-violet), transparent 70%) 25%,
color-mix(in srgb, var(--bright-blue), transparent 60%) 90%,
);
}
&.adev-nav-primary--deprecated {
// change nav background to indicate this is an outdated version of the docs
background-color: color-mix(in srgb, var(--symbolic-gray), transparent 30%);
}
// div containing mobile close button and adev-nav_top
> div {
display: flex;
@@ -129,13 +146,6 @@
flex-direction: row;
}
.adev-beta-version {
font-family: 'Material Symbols Outlined';
text-transform: uppercase;
text-align: center;
line-height: normal;
}
// version dropdown button
.adev-version-button {
border: 1px solid var(--senary-contrast);
@@ -237,6 +247,10 @@
}
}
.adev-nav-item--logo a {
height: 34px;
}
.adev-close-nav {
display: none;
@include mq.for-phone-only {
@@ -27,7 +27,7 @@ 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';
@@ -83,6 +83,9 @@ export class Navigation implements OnInit {
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'},
@@ -102,6 +105,8 @@ export class Navigation implements OnInit {
openedMenu: MenuType | null = null;
currentDocsVersion = this.versionManager.currentDocsVersion;
currentDocsVersionMode = this.versionManager.currentDocsVersion()?.version;
// Set the values of the search label and title only on the client, because the label is user-agent specific.
searchLabel = this.isBrowser
? isApple
@@ -197,7 +202,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);
}
@@ -7,8 +7,9 @@
*/
import {Injector} from '@angular/core';
import {ENVIRONMENT, WINDOW} from '@angular/docs';
import {ENVIRONMENT, WINDOW, LOCAL_STORAGE} from '@angular/docs';
import {AnalyticsService} from './analytics.service';
import {MockLocalStorage} from '@angular/docs/testing';
describe('AnalyticsService', () => {
let service: AnalyticsService;
@@ -18,6 +19,7 @@ describe('AnalyticsService', () => {
let windowOnErrorHandler: (event: ErrorEvent) => void;
let mockWindow: any;
let mockLocalStorage = new MockLocalStorage();
beforeEach(() => {
gtagSpy = jasmine.createSpy('gtag');
@@ -39,6 +41,7 @@ describe('AnalyticsService', () => {
{provide: ENVIRONMENT, useValue: {}},
{provide: AnalyticsService, deps: [WINDOW]},
{provide: WINDOW, useFactory: () => mockWindow, deps: []},
{provide: LOCAL_STORAGE, useValue: mockLocalStorage},
],
});
@@ -8,7 +8,7 @@
import {inject, Injectable} from '@angular/core';
import {WINDOW, ENVIRONMENT} from '@angular/docs';
import {WINDOW, ENVIRONMENT, LOCAL_STORAGE, STORAGE_KEY, setCookieConsent} from '@angular/docs';
import {formatErrorEventForAnalytics} from './analytics-format-error';
@@ -28,6 +28,7 @@ interface WindowWithAnalytics extends Window {
export class AnalyticsService {
private environment = inject(ENVIRONMENT);
private window: WindowWithAnalytics = inject(WINDOW);
private readonly localStorage = inject(LOCAL_STORAGE);
constructor() {
this._installGlobalSiteTag();
@@ -64,6 +65,21 @@ export class AnalyticsService {
window.gtag = function () {
window.dataLayer?.push(arguments);
};
// Cookie banner consent initial state
// This code is modified in the @angular/docs package in the cookie-popup component.
// Docs: https://developers.google.com/tag-platform/security/guides/consent
if (this.localStorage) {
if (this.localStorage.getItem(STORAGE_KEY) === 'true') {
setCookieConsent('granted');
} else {
setCookieConsent('denied');
}
} else {
// In case localStorage is not available, we default to denying cookies.
setCookieConsent('denied');
}
window.gtag('js', new Date());
// Configure properties before loading the script. This is necessary to avoid
@@ -10,6 +10,7 @@ import {HttpClient} from '@angular/common/http';
import {Injectable, inject} from '@angular/core';
import {DocContent, DocsContentLoader} from '@angular/docs';
import {Router} from '@angular/router';
import {firstValueFrom} from 'rxjs';
import {map} from 'rxjs/operators';
@Injectable()
@@ -27,12 +28,13 @@ export class ContentLoader implements DocsContentLoader {
try {
this.cache.set(
path,
this.httpClient
.get(`assets/content/${path}`, {
responseType: 'text',
})
.pipe(map((contents) => ({contents, id: path})))
.toPromise(),
firstValueFrom(
this.httpClient
.get(`assets/content/${path}`, {
responseType: 'text',
})
.pipe(map((contents) => ({contents, id: path}))),
),
);
} catch {
this.router.navigateByUrl('/404');
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {Component, Inject} from '@angular/core';
import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
import {MAT_SNACK_BAR_DATA, MatSnackBarAction, MatSnackBarRef} from '@angular/material/snack-bar';
export interface ErrorSnackBarData {
@@ -16,6 +16,7 @@ export interface ErrorSnackBarData {
@Component({
selector: 'error-snack-bar',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
{{ message }}
<button
@@ -28,8 +29,8 @@ export interface ErrorSnackBarData {
{{ actionText }}
</button>
`,
imports: [MatSnackBarAction],
standalone: true,
imports: [MatSnackBarAction],
styles: `:host { display: flex; align-items: center; button { margin-left: 16px }}`,
})
export class ErrorSnackBar {
@@ -82,7 +82,7 @@ export class ThemeManager {
}
private watchPreferredColorScheme() {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {
window.matchMedia(PREFERS_COLOR_SCHEME_DARK).addEventListener('change', (event) => {
const preferredScheme = event.matches ? 'dark' : 'light';
this.setThemeBodyClasses(preferredScheme);
});
@@ -90,5 +90,5 @@ export class ThemeManager {
}
function preferredScheme(): 'dark' | 'light' {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
return window.matchMedia(PREFERS_COLOR_SCHEME_DARK).matches ? 'dark' : 'light';
}
@@ -8,17 +8,51 @@
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 {VERSION} from '@angular/core';
describe('VersionManager', () => {
const fakeWindow = {location: {hostname: 'angular.dev'}};
let service: VersionManager;
beforeEach(() => {
TestBed.configureTestingModule({});
TestBed.configureTestingModule({
providers: [
{
provide: WINDOW,
useValue: fakeWindow,
},
],
});
service = TestBed.inject(VersionManager);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should receive major version', () => {
expect(VERSION.major).not.toBe('0');
});
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 = Number(VERSION.major) - 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,75 +6,9 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {Injectable, VERSION, computed, signal} from '@angular/core';
// TODO(josephperrott): extract this out of the file into a managed location.
const VERSIONS_CONFIG = {
currentVersion: 'stable',
historicalVersionsLinkPattern: 'https://v{{version}}.angular.dev',
mainVersions: [
{
version: 'stable',
url: 'https://angular.dev',
},
{
version: 'v16',
url: 'https://v16.angular.io/docs',
},
{
version: 'v15',
url: 'https://v15.angular.io/docs',
},
{
version: 'v14',
url: 'https://v14.angular.io/docs',
},
{
version: 'v13',
url: 'https://v13.angular.io/docs',
},
{
version: 'v12',
url: 'https://v12.angular.io/docs',
},
{
version: 'v11',
url: 'https://v11.angular.io/docs',
},
{
version: 'v10',
url: 'https://v10.angular.io/docs',
},
{
version: 'v9',
url: 'https://v9.angular.io/docs',
},
{
version: 'v8',
url: 'https://v8.angular.io/docs',
},
{
version: 'v7',
url: 'https://v7.angular.io/docs',
},
{
version: 'v6',
url: 'https://v6.angular.io/docs',
},
{
version: 'v5',
url: 'https://v5.angular.io/docs',
},
{
version: 'v4',
url: 'https://v4.angular.io/docs',
},
{
version: 'v2',
url: 'https://v2.angular.io/docs',
},
],
};
import {Injectable, VERSION, computed, inject, signal} from '@angular/core';
import {VERSIONS_CONFIG} from '../constants/versions';
import {WINDOW} from '@angular/docs';
export interface Version {
displayName: string;
@@ -82,41 +16,81 @@ export interface Version {
url: string;
}
export type VersionMode = 'stable' | 'rc' | 'next' | number;
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 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(Number(VERSION.major)),
displayName: this.getVersion(Number(VERSION.major)),
version: this.currentVersionMode,
},
];
}
// List of Angular Docs versions hosted on angular.dev domain.
private getAdevVersions(): Version[] {
const adevVersions: Version[] = [];
for (let version = Number(VERSION.major) - 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 {
@@ -127,7 +101,7 @@ export class VersionManager {
}
private getVersion(versionMode: VersionMode): string {
if (versionMode === 'stable') {
if (versionMode === 'stable' || versionMode === 'deprecated') {
return `v${VERSION.major}`;
}
if (Number.isInteger(versionMode)) {
@@ -135,4 +109,15 @@ export class VersionManager {
}
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()}.`}`,
);
}
}
@@ -10,7 +10,29 @@
@for (file of files(); track file) {
<mat-tab #tab>
<ng-template mat-tab-label>
@if (tab.isActive && isRenamingFile()) {
<form
(submit)="renameFile($event, file.filename)"
(docsClickOutside)="closeRenameFile()">
<input
name="rename-file"
class="adev-rename-file-input"
#renameFileInput
(keydown)="$event.stopPropagation()"
/>
</form>
} @else {
{{ file.filename.replace('src/', '') }}
}
@if (tab.isActive && canRenameFile(file.filename)) {
<button
class="docs-rename-file"
aria-label="rename file"
(click)="onRenameButtonClick()"
>
<docs-icon>edit</docs-icon>
</button>
}
@if (tab.isActive && canDeleteFile(file.filename)) {
<button
class="docs-delete-file"
@@ -79,7 +79,8 @@
}
.adev-add-file,
.docs-delete-file {
.docs-delete-file,
.docs-rename-file {
docs-icon {
color: var(--gray-400);
transition: color 0.3s ease;
@@ -92,7 +93,8 @@
}
}
.docs-delete-file {
.docs-delete-file,
.docs-rename-file {
padding-inline-start: 0.1rem;
padding-inline-end: 0;
margin-block-start: 0.2rem;
@@ -101,7 +103,8 @@
}
}
.adev-new-file-input {
.adev-new-file-input,
.adev-rename-file-input {
color: var(--primary-contrast);
border: none;
border-radius: 0;
@@ -107,7 +107,7 @@ describe('CodeEditor', () => {
const tabs = await matTabGroup.getTabs();
const expectedLabels = files.map((file, index) => {
const label = file.filename.replace('src/', '');
if (index === 0) return `${label} delete`;
if (index === 0) return `${label} editdelete`;
return label;
});
@@ -28,9 +28,13 @@ import {EmbeddedTutorialManager} from '../embedded-tutorial-manager.service';
import {CodeMirrorEditor} from './code-mirror-editor.service';
import {DiagnosticWithLocation, DiagnosticsState} from './services/diagnostics-state.service';
import {DownloadManager} from '../download-manager.service';
import {IconComponent} from '@angular/docs';
import {ClickOutside, IconComponent} from '@angular/docs';
export const REQUIRED_FILES = new Set(['src/main.ts', 'src/index.html']);
export const REQUIRED_FILES = new Set([
'src/main.ts',
'src/index.html',
'src/app/app.component.ts',
]);
@Component({
selector: 'docs-tutorial-code-editor',
@@ -38,7 +42,7 @@ export const REQUIRED_FILES = new Set(['src/main.ts', 'src/index.html']);
templateUrl: './code-editor.component.html',
styleUrls: ['./code-editor.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [NgIf, NgFor, MatTabsModule, IconComponent],
imports: [NgIf, NgFor, MatTabsModule, IconComponent, ClickOutside],
})
export class CodeEditor implements AfterViewInit, OnDestroy {
@ViewChild('codeEditorWrapper') private codeEditorWrapperRef!: ElementRef<HTMLDivElement>;
@@ -54,6 +58,16 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
}
}
private renameFileInputRef?: ElementRef<HTMLInputElement>;
@ViewChild('renameFileInput') protected set setRenameFileInputRef(
element: ElementRef<HTMLInputElement>,
) {
if (element) {
element.nativeElement.focus();
this.renameFileInputRef = element;
}
}
private readonly destroyRef = inject(DestroyRef);
private readonly codeMirrorEditor = inject(CodeMirrorEditor);
@@ -82,6 +96,7 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
readonly errors = signal<DiagnosticWithLocation[]>([]);
readonly files = this.codeMirrorEditor.openFiles;
readonly isCreatingFile = signal<boolean>(false);
readonly isRenamingFile = signal<boolean>(false);
ngAfterViewInit() {
this.codeMirrorEditor.init(this.codeEditorWrapperRef.nativeElement);
@@ -104,6 +119,12 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
this.displayErrorsBox.set(false);
}
closeRenameFile(): void {
this.isRenamingFile.set(false);
}
canRenameFile = (filename: string) => this.canDeleteFile(filename);
canDeleteFile(filename: string) {
return !REQUIRED_FILES.has(filename);
}
@@ -118,6 +139,37 @@ export class CodeEditor implements AfterViewInit, OnDestroy {
this.matTabGroup.selectedIndex = this.files().length;
}
onRenameButtonClick() {
this.isRenamingFile.set(true);
}
async renameFile(event: SubmitEvent, oldPath: string) {
if (!this.renameFileInputRef) return;
event.preventDefault();
const renameFileInputValue = this.renameFileInputRef.nativeElement.value;
if (renameFileInputValue) {
if (renameFileInputValue.includes('..')) {
alert('File name can not contain ".."');
return;
}
// src is hidden from users, here we manually add it to the new filename
const newFile = 'src/' + renameFileInputValue;
if (this.files().find(({filename}) => filename.includes(newFile))) {
alert('File name already exists');
return;
}
await this.codeMirrorEditor.renameFile(oldPath, newFile);
}
this.isRenamingFile.set(false);
}
async createFile(event: SubmitEvent) {
if (!this.createFileInputRef) return;
@@ -340,6 +340,34 @@ export class CodeMirrorEditor {
this.changeCurrentFile(filename);
}
async renameFile(oldPath: string, newPath: string) {
const content = await this.nodeRuntimeSandbox.readFile(oldPath).catch((error) => {
// empty content if file does not exist
if (error.message.includes('ENOENT')) return '';
else throw error;
});
await this.nodeRuntimeSandbox.renameFile(oldPath, newPath).catch((error) => {
throw error;
});
this.embeddedTutorialManager.tutorialFiles.update((files) => {
delete files[oldPath];
files[newPath] = content;
return files;
});
this.embeddedTutorialManager.openFiles.update((files) => [
...files.filter((file) => file !== oldPath),
newPath,
]);
this.setProjectFiles();
this.updateVfsEnv();
this.saveLibrariesTypes();
this.changeCurrentFile(newPath);
}
async deleteFile(deletedFile: string): Promise<void> {
await this.nodeRuntimeSandbox.deleteFile(deletedFile);
@@ -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
@@ -177,6 +177,20 @@ describe('NodeRuntimeSandbox', () => {
expect(writeFileSpy).toHaveBeenCalledOnceWith(path, content);
});
it('should call renameFile with proper parameters', async () => {
setValuesToInitializeProject();
const fakeWebContainer = new FakeWebContainer();
service['webContainerPromise'] = Promise.resolve(fakeWebContainer);
const renameFileSpy = spyOn(fakeWebContainer.fs, 'rename');
const oldPath = 'oldPath';
const newPath = 'newPath';
await service.renameFile(oldPath, newPath);
expect(renameFileSpy).toHaveBeenCalledOnceWith(oldPath, newPath);
});
it('should initialize the Angular CLI based on the tutorial config', async () => {
setValuesToInitializeAngularCLI();
@@ -270,6 +270,16 @@ export class NodeRuntimeSandbox {
}
}
async renameFile(oldPath: string, newPath: string): Promise<void> {
const webContainer = await this.webContainerPromise!;
try {
await webContainer.fs.rename(oldPath, newPath);
} catch (err: any) {
throw err;
}
}
async readFile(filePath: string): Promise<string> {
const webContainer = await this.webContainerPromise!;
+2 -1
View File
@@ -8,13 +8,14 @@
import {CommonModule} from '@angular/common';
import {DocContent, DocViewer} from '@angular/docs';
import {Component, inject} from '@angular/core';
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import {toSignal} from '@angular/core/rxjs-interop';
import {ActivatedRoute} from '@angular/router';
import {map} from 'rxjs/operators';
@Component({
selector: 'docs-docs',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, DocViewer],
styleUrls: ['./docs.component.scss'],
File diff suppressed because one or more lines are too long
@@ -36,6 +36,7 @@
box-sizing: border-box;
transition: background 0.3s ease, border 0.3s ease;
h1,
p {
display: inline;
font-size: 0.875rem;
+4 -2
View File
@@ -21,7 +21,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';
@@ -48,8 +48,10 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
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;
@@ -74,7 +76,7 @@ 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()) {
if (this.isWebGLAvailable() && !shouldReduceMotion() && !this.isUwu) {
this.ngZone.runOutsideAngular(async () => {
await this.loadHomeAnimation();
});
@@ -1,8 +1,10 @@
<header class="adev-api-items-section-header">
@if (group.isFeatured) {
<docs-icon>star</docs-icon>
}
<h3>{{ group.title }}</h3>
<h3 [attr.id]="group.id">
@if (group.isFeatured) {
<docs-icon aria-hidden>star</docs-icon>
}
<a routerLink="/api" [fragment]="group.id" class="adev-api-anchor" tabindex="-1">{{ group.title }}</a>
</h3>
</header>
<ul class="adev-api-items-section-grid">
@@ -1,7 +1,7 @@
@use '@angular/docs/styles/anchor' as anchor;
.adev-api-items-section-header {
display: flex;
gap: 0.75em;
align-items: center;
svg {
fill: var(--primary-contrast);
@@ -9,6 +9,11 @@
h3 {
flex: 1;
display: flex;
gap: 0.75em;
align-items: flex-start;
margin-top: 1.43rem;
font-size: 1.25rem;
}
@@ -100,3 +105,10 @@
padding: 0.001rem 0.2rem 0.005rem;
margin-inline-start: 0.5rem;
}
.adev-api-anchor {
color: inherit;
@include anchor.docs-anchor();
}
@@ -22,6 +22,7 @@ describe('ApiItemsSection', () => {
const fakeFeaturedGroup: ApiItemsGroup = {
title: 'Featured',
id: 'featured',
isFeatured: true,
items: [
{
@@ -48,6 +49,7 @@ describe('ApiItemsSection', () => {
const fakeGroup: ApiItemsGroup = {
title: 'Example group',
id: 'example',
isFeatured: false,
items: [
{title: 'Fake Title', itemType: ApiItemType.CONST, url: 'api/fakeTitle', isFeatured: false},
@@ -7,7 +7,6 @@
*/
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
import {NgFor, NgIf} from '@angular/common';
import {RouterLink} from '@angular/router';
import {ApiItemsGroup} from '../interfaces/api-items-group';
import ApiItemLabel from '../api-item-label/api-item-label.component';
@@ -16,7 +15,7 @@ import {IconComponent} from '@angular/docs';
@Component({
selector: 'adev-api-items-section',
standalone: true,
imports: [NgIf, NgFor, ApiItemLabel, RouterLink, IconComponent],
imports: [ApiItemLabel, RouterLink, IconComponent],
templateUrl: './api-items-section.component.html',
styleUrls: ['./api-items-section.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -108,7 +108,6 @@
& > .docs-code {
box-sizing: border-box;
width: 100%;
max-height: 93vh;
overflow: hidden;
padding: 0;
@@ -119,6 +118,7 @@
button {
transition: background-color 0.3s ease;
font-family: monospace;
&.hljs-ln-line {
font-weight: 400;
@@ -154,6 +154,10 @@
}
}
.docs-reference-cli-toc {
margin-bottom: 1rem;
}
.adev-reference-tab {
min-width: 50ch;
margin-block-start: 2.5rem;
@@ -267,7 +271,9 @@
background-color: var(--octonary-contrast);
position: relative;
z-index: 10;
transition: background-color 0.3s ease, border 0.3s ease;
transition:
background-color 0.3s ease,
border 0.3s ease;
// h3 + code || # of overloads
.docs-reference-header {
@@ -352,6 +358,10 @@
}
}
.docs-deprecation-message {
border-block-end: 1px solid var(--senary-contrast);
}
.docs-param-group {
margin-block-start: 1rem;
}
@@ -404,4 +414,17 @@
margin-block-start: 0;
}
}
.docs-ref-content {
padding: 1rem 0;
&:not(:first-child) {
border-block-start: 1px solid var(--senary-contrast);
}
.docs-param-keyword {
display: block;
margin: 0 0 0.5rem 0;
}
}
}
@@ -16,12 +16,12 @@ import {
inject,
signal,
} from '@angular/core';
import {DOCUMENT, NgFor, NgIf} from '@angular/common';
import {DOCUMENT, NgFor, NgIf, ViewportScroller} from '@angular/common';
import {MatTabGroup, MatTabsModule} from '@angular/material/tabs';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {distinctUntilChanged, map} from 'rxjs/operators';
import {takeUntilDestroyed, toSignal} from '@angular/core/rxjs-interop';
import {distinctUntilChanged, filter, map, take} from 'rxjs/operators';
import {DocContent, DocViewer} from '@angular/docs';
import {ActivatedRoute, Router, RouterLink} from '@angular/router';
import {ActivatedRoute, Router, RouterLink, Scroll} from '@angular/router';
import {ApiItemType} from './../interfaces/api-item-type';
import {ReferenceScrollHandler} from '../services/reference-scroll-handler.service';
import {
@@ -51,6 +51,15 @@ export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
private readonly document = inject(DOCUMENT);
private readonly router = inject(Router);
private readonly scrollHandler = inject(ReferenceScrollHandler);
private readonly scroller = inject(ViewportScroller);
private scrollEvent = toSignal(
this.router.events.pipe(
filter((e): e is Scroll => e instanceof Scroll),
take(1),
),
{initialValue: null},
);
private cardsDisplayedOnInit = false;
ApiItemType = ApiItemType;
@@ -67,10 +76,22 @@ export default class ApiReferenceDetailsPage implements OnInit, AfterViewInit {
ngAfterViewInit(): void {
this.setActiveTab();
if (this.canDisplayCards()) {
this.cardsDisplayedOnInit = true;
}
this.listenToTabChange();
}
membersCardsLoaded(): void {
const event = this.scrollEvent();
if (this.cardsDisplayedOnInit && event) {
// Cards loaded after scroll event happened. We have to handle the scroll event manually
if (event.position) {
this.scroller.scrollToPosition(event.position);
} else if (event.anchor) {
this.scroller.scrollToAnchor(event.anchor);
}
}
this.scrollHandler.setupListeners(API_TAB_CLASS_NAME);
}
@@ -3,6 +3,11 @@
<h6>Getting Started</h6>
<h1 tabindex="-1">API Reference</h1>
</header>
@if (featuredGroup().items.length) {
<adev-api-items-section [group]="featuredGroup()" class="adev-featured-list" />
}
<form class="adev-reference-list-form">
<docs-text-field
name="query"
@@ -34,12 +39,8 @@
</ul>
</form>
@if (featuredGroup().items.length) {
<adev-api-items-section [group]="featuredGroup()" class="adev-featured-list" />
}
@for (group of filteredGroups(); track group) {
@for (group of filteredGroups(); track group.id) {
<adev-api-items-section [group]="group" />
}
<span id="deprecated-description" class="docs-deprecated-description">Deprecated</span>
</div>
@@ -77,8 +77,9 @@
justify-content: flex-start;
flex-wrap: wrap-reverse;
gap: 1.5rem;
padding-block-start: 0;
padding-block-start: 1.5rem;
padding-block-end: 2rem;
border-block: 1px solid var(--senary-contrast);
}
.adev-reference-list-form-part-two {
@@ -89,15 +90,10 @@
.adev-featured-list {
display: block;
padding-block-end: 2rem;
padding-block-start: 1.5rem;
padding-block-end: 1rem;
margin-block: 1rem;
border-block: 1px solid var(--senary-contrast);
}
.docs-deprecated-description {
display: none;
border-top: 0;
margin-top: -1.5rem;
}
.docs-api-item-label-full {
@@ -15,6 +15,7 @@ import {ApiItemType} from '../interfaces/api-item-type';
import {ApiReferenceManager} from './api-reference-manager.service';
import ApiItemLabel from '../api-item-label/api-item-label.component';
import {ApiLabel} from '../pipes/api-label.pipe';
import {ApiItemsGroup} from '../interfaces/api-items-group';
export const ALL_STATUSES_KEY = 'All';
@@ -45,11 +46,12 @@ export default class ApiReferenceList {
type = signal(ALL_STATUSES_KEY);
featuredGroup = this.apiReferenceManager.featuredGroup;
filteredGroups = computed(() => {
filteredGroups = computed((): ApiItemsGroup[] => {
return this.allGroups()
.map((group) => ({
title: group.title,
isFeatured: group.isFeatured,
id: group.id,
items: group.items.filter((apiItem) => {
return (
(this.query()
@@ -7,6 +7,7 @@
*/
import {Injectable, signal} from '@angular/core';
// This file is generated at build-time, error is expected here.
import API_MANIFEST_JSON from '../../../../../src/assets/api/manifest.json';
import {ANGULAR_PACKAGE_PREFIX, getApiUrl} from '../helpers/manifest.helper';
import {ApiItem} from '../interfaces/api-item';
@@ -14,7 +15,7 @@ import {ApiItemsGroup} from '../interfaces/api-items-group';
import {ApiManifest} from '../interfaces/api-manifest';
export const FEATURED_API_ITEMS_KEY = 'apiFeaturedItems';
export const FEATURED_GROUP_TITLE = 'Featured';
export const FEATURED_GROUP_TITLE = 'Most Common';
export type FeaturedItemsByGroup = Record<string, ApiItem[]>;
@@ -40,6 +41,7 @@ export class ApiReferenceManager {
// Represents group of the featured items.
featuredGroup = signal<ApiItemsGroup>({
title: FEATURED_GROUP_TITLE,
id: 'featured',
items: [],
isFeatured: true,
});
@@ -58,6 +60,7 @@ export class ApiReferenceManager {
groups.push({
title: packageNameWithoutPrefix,
id: packageNameWithoutPrefix.replaceAll('/', '-'),
items: packageApis
.map((api) => {
const url = getApiUrl(packageNameWithoutPrefix, api.name);
@@ -10,6 +10,7 @@ import {ApiItem} from './api-item';
export interface ApiItemsGroup {
title: string;
id: string;
items: ApiItem[];
isFeatured?: boolean;
}
@@ -160,9 +160,6 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
for (const line of Array.from(activeLines)) {
line.classList.remove(API_TAB_ACTIVE_CODE_LINE);
}
this.getAllMemberCards().forEach((card) => {
card.blur();
});
} else {
const lines = this.document.querySelectorAll<HTMLButtonElement>(
`button[${MEMBER_ID_ATTRIBUTE}="${currentActiveMemberId}"]`,
@@ -170,7 +167,7 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
for (const line of Array.from(lines)) {
line.classList.add(API_TAB_ACTIVE_CODE_LINE);
}
this.document.getElementById(`${currentActiveMemberId}`)?.focus();
this.document.getElementById(`${currentActiveMemberId}`)?.focus({preventScroll: true});
}
}
@@ -179,7 +176,9 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
return;
}
card.focus();
if (card !== <HTMLElement>document.activeElement) {
(<HTMLElement>document.activeElement).blur();
}
this.window.scrollTo({
top: card!.offsetTop - this.membersMarginTopInPx(),
@@ -211,8 +210,9 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
this.resizeObserver = new ResizeObserver((_) => {
this.ngZone.run(() => {
if (tabBody.offsetTop) {
this.membersMarginTopInPx.set(tabBody.offsetTop);
const offsetTop = tabBody.getBoundingClientRect().top;
if (offsetTop) {
this.membersMarginTopInPx.set(offsetTop);
}
});
});
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) {
<p>
<mat-checkbox
(change)="options[option.id] = $event.checked; showUpdatePath()"
[checked]="options[option.id]"
>I use {{option.name}} {{option.description}}</mat-checkbox
>
</p>
}
@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,293 @@
import {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,
})
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 isWindows = /win/i.test(navigator.platform);
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 {
const platform = navigator.platform.toLowerCase();
return platform.includes('windows') || platform.includes('win32');
}
+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
+160 -14
View File
@@ -8,6 +8,7 @@
import {NavigationItem} from '@angular/docs';
// These 2 imports are expected to be red because they are generated a build time
import FIRST_APP_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/first-app/routes.json';
import LEARN_ANGULAR_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/learn-angular/routes.json';
@@ -117,6 +118,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/components/outputs',
contentPath: 'guide/components/outputs',
},
{
label: 'output() function',
path: 'guide/components/output-fn',
contentPath: 'guide/components/output-function',
},
{
label: 'Content projection with ng-content',
path: 'guide/components/content-projection',
@@ -634,6 +640,12 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
{
label: 'Experimental features',
children: [
{label: 'Zoneless', path: 'guide/experimental/zoneless', contentPath: 'guide/zoneless'},
],
},
],
},
{
@@ -673,9 +685,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',
@@ -926,7 +938,28 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
{
label: 'ng analytics',
path: 'cli/analytics',
children: [
{
label: 'Overview',
path: 'cli/analytics',
},
{
label: 'disable',
path: 'cli/analytics/disable',
},
{
label: 'enable',
path: 'cli/analytics/enable',
},
{
label: 'info',
path: 'cli/analytics/info',
},
{
label: 'prompt',
path: 'cli/analytics/prompt',
},
],
},
{
label: 'ng build',
@@ -934,11 +967,41 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
{
label: 'ng cache',
path: 'cli/cache',
children: [
{
label: 'Overview',
path: 'cli/cache',
},
{
label: 'clear',
path: 'cli/cache/clean',
},
{
label: 'disable',
path: 'cli/cache/disable',
},
{
label: 'enable',
path: 'cli/cache/enable',
},
{
label: 'info',
path: 'cli/cache/info',
},
],
},
{
label: 'ng completion',
path: 'cli/completion',
children: [
{
label: 'Overview',
path: 'cli/completion',
},
{
label: 'script',
path: 'cli/completion/script',
},
],
},
{
label: 'ng config',
@@ -948,10 +1011,6 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
label: 'ng deploy',
path: 'cli/deploy',
},
{
label: 'ng doc',
path: 'cli/doc',
},
{
label: 'ng e2e',
path: 'cli/e2e',
@@ -962,7 +1021,80 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
{
label: 'ng generate',
path: 'cli/generate',
children: [
{
label: 'Overview',
path: 'cli/generate',
},
{
label: 'app-shell',
path: 'cli/generate/app-shell',
},
{
label: 'application',
path: 'cli/generate/application',
},
{
label: 'class',
path: 'cli/generate/class',
},
{
label: 'component',
path: 'cli/generate/component',
},
{
label: 'config',
path: 'cli/generate/config',
},
{
label: 'enum',
path: 'cli/generate/enum',
},
{
label: 'environments',
path: 'cli/generate/environments',
},
{
label: 'guard',
path: 'cli/generate/guard',
},
{
label: 'interceptor',
path: 'cli/generate/interceptor',
},
{
label: 'interface',
path: 'cli/generate/interface',
},
{
label: 'library',
path: 'cli/generate/library',
},
{
label: 'module',
path: 'cli/generate/module',
},
{
label: 'pipe',
path: 'cli/generate/pipe',
},
{
label: 'resolver',
path: 'cli/generate/resolver',
},
{
label: 'service-worker',
path: 'cli/generate/service-worker',
},
{
label: 'service',
path: 'cli/generate/service',
},
{
label: 'web-worker',
path: 'cli/generate/web-worker',
},
],
},
{
label: 'ng lint',
@@ -1122,6 +1254,16 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'errors/NG0912',
contentPath: 'reference/errors/NG0912',
},
{
label: 'NG0955: Track expression resulted in duplicated keys for a given collection',
path: 'errors/NG0955',
contentPath: 'reference/errors/NG0955',
},
{
label: 'NG0956: Tracking expression caused re-creation of the DOM structure',
path: 'errors/NG0956',
contentPath: 'reference/errors/NG0956',
},
{
label: 'NG1001: Argument Not Literal',
path: 'errors/NG1001',
@@ -1143,9 +1285,9 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'reference/errors/NG3003',
},
{
label: 'NG5000: Hydration with unsupported Zone.js instance.',
path: 'errors/NG5000',
contentPath: 'reference/errors/NG5000',
label: 'NG05000: Hydration with unsupported Zone.js instance.',
path: 'errors/NG05000',
contentPath: 'reference/errors/NG05000',
},
{
label: 'NG6100: NgModule.id Set to module.id anti-pattern',
@@ -1234,6 +1376,10 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'reference/versions',
contentPath: 'reference/versions',
},
{
label: 'Update guide',
path: 'update-guide',
},
{
label: 'Configurations',
children: [
+2 -2
View File
@@ -8,6 +8,7 @@ copy_to_directory(
"//adev/src/content",
"//adev/src/content/best-practices",
"//adev/src/content/best-practices/runtime-performance",
"//adev/src/content/cli/help:cli_docs",
"//adev/src/content/ecosystem",
"//adev/src/content/ecosystem/service-workers",
"//adev/src/content/guide",
@@ -38,7 +39,6 @@ copy_to_directory(
"//adev/src/content/tutorials",
"//adev/src/content/tutorials/first-app:first-app-guides",
"//adev/src/content/tutorials/learn-angular:learn-angular-guides",
"//aio/content/cli/help:cli_docs",
"//packages/animations:animations_docs",
"//packages/animations/browser:animations_browser_docs",
"//packages/animations/browser/testing:animations_browser_testing_docs",
@@ -74,7 +74,7 @@ copy_to_directory(
"//tools/manual_api_docs/elements:elements_docs",
],
replace_prefixes = {
"aio/content/cli/**/": "cli/",
"adev/src/content/cli/help/cli_docs_html": "cli/",
"adev/src/content": "",
"packages/**/": "api/",
"tools/**/": "api/",

Before

Width:  |  Height:  |  Size: 3.4 MiB

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

+3 -3
View File
@@ -76,15 +76,15 @@ The following example shows how to make a progress bar accessible by using host
The ARIA attribute `aria-valuenow` is bound to the user's input.
* In the template, the `aria-label` attribute ensures that the control is accessible to screen readers.
<docs-code-multifile
path="adev/src/content/examples/accessibility/src/app/app.component.ts"
preview>
<docs-code-multifile>
<docs-code
path="adev/src/content/examples/accessibility/src/app/progress-bar.component.ts"
language="ts"
linenums
highlight="[12, 20]"/>
<docs-code
path="adev/src/content/examples/accessibility/src/app/app.component.html"
language="html"
linenums
highlight="[8, 9]"/>
</docs-code-multifile>
@@ -59,8 +59,6 @@ If Angular handles an event within a component with OnPush strategy, the framewo
As an example, if Angular handles an event within `MainComponent`, the framework will run change detection in the entire component tree. Angular will ignore the subtree with root `LoginComponent` because it has `OnPush` and the event happened outside of its scope.
<img alt="Change detection propagation from OnPush component" src="assets/images/best-practices/runtime-performance/on-push-trigger.svg">
```mermaid
graph TD;
app[AppComponent] --- header[HeaderComponent];
@@ -19,7 +19,7 @@ For example, in the preceding screenshot, the second recorded change detection c
Here are several techniques to remove slow computations:
* **Optimizing the underlying algorithm**. This is the recommended approach. If you can speed up the algorithm that is causing the problem, you can speed up the entire change detection mechanism.
* **Caching using pure pipes**. You can move the heavy computation to a pure [pipe](/guide/pipes). Angular reevaluates a pure pipe only if it detects that its inputs have changed, compared to the previous time Angular called it.
* **Caching using pure pipes**. You can move the heavy computation to a pure [pipe](guide/pipes). Angular reevaluates a pure pipe only if it detects that its inputs have changed, compared to the previous time Angular called it.
* **Using memoization**. [Memoization](https://en.wikipedia.org/wiki/Memoization) is a similar technique to pure pipes, with the difference that pure pipes preserve only the last result from the computation where memoization could store multiple results.
* **Avoid repaints/reflows in lifecycle hooks**. Certain [operations](https://web.dev/avoid-large-complex-layouts-and-layout-thrashing/) cause the browser to either synchronously recalculate the layout of the page or re-render it. Since reflows and repaints are generally slow, you want to avoid performing them in every change detection cycle.
@@ -35,7 +35,7 @@ class AppComponent implements OnInit {
The preceding snippet instructs Angular to call `setInterval` outside the Angular Zone and skip running change detection after `pollForUpdates` runs.
Third-party libraries commonly trigger unnecessary change detection cycles because they weren't authored with Zone.js in mind. Avoid these extra cycles by calling library APIs outside the Angular zone:
Third-party libraries commonly trigger unnecessary change detection cycles when their APIs are invoked within the Angular zone. This phenomenon particularly affects libraries that setup event listeners or initiate other tasks (such as timers, XHR requests, etc.). Avoid these extra cycles by calling library APIs outside the Angular zone:
<docs-code header="Move the plot initialization outside of the Zone" language='ts' linenums>
import { Component, NgZone, OnInit } from '@angular/core';
@@ -57,3 +57,67 @@ class AppComponent implements OnInit {
Running `Plotly.newPlot('chart', data);` within `runOutsideAngular` instructs the framework that it shouldn’t run change detection after the execution of tasks scheduled by the initialization logic.
For example, if `Plotly.newPlot('chart', data)` adds event listeners to a DOM element, Angular does not run change detection after the execution of their handlers.
But sometimes, you may need to listen to events dispatched by third-party APIs. In such cases, it's important to remember that those event listeners will also execute outside of the Angular zone if the initialization logic was done there:
<docs-code header="Check whether the handler is called outside of the Zone" language='ts' linenums>
import { Component, NgZone, OnInit, output } from '@angular/core';
import * as Plotly from 'plotly.js-dist-min';
@Component(...)
class AppComponent implements OnInit {
plotlyClick = output<Plotly.PlotMouseEvent>();
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.createPlotly();
});
}
private async createPlotly() {
const plotly = await Plotly.newPlot('chart', data);
plotly.on('plotly_click', (event: Plotly.PlotMouseEvent) => {
// This handler will be called outside of the Angular zone because
// the initialization logic is also called outside of the zone. To check
// whether we're in the Angular zone, we can call the following:
console.log(NgZone.isInAngularZone());
this.plotlyClick.emit(event);
});
}
}
</docs-code>
If you need to dispatch events to parent components and execute specific view update logic, you should consider re-entering the Angular zone to instruct the framework to run change detection or run change detection manually:
<docs-code header="Re-enter the Angular zone when dispatching event" language='ts' linenums>
import { Component, NgZone, OnInit, output } from '@angular/core';
import * as Plotly from 'plotly.js-dist-min';
@Component(...)
class AppComponent implements OnInit {
plotlyClick = output<Plotly.PlotMouseEvent>();
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.createPlotly();
});
}
private async createPlotly() {
const plotly = await Plotly.newPlot('chart', data);
plotly.on('plotly_click', (event: Plotly.PlotMouseEvent) => {
this.ngZone.run(() => {
this.plotlyClick.emit(event);
});
});
}
}
</docs-code>
The scenario of dispatching events outside of the Angular zone may also arise. It's important to remember that triggering change detection (for example, manually) may result to the creation/update of views outside of the Angular zone.

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