Commit Graph

4542 Commits

Author SHA1 Message Date
Joey Perrott 31fdf0fbea refactor: migrate core to prettier formatting (#55488)
Migrate formatting to prettier for core from clang-format

PR Close #55488
2024-04-29 09:49:19 -07:00
Andrew Scott be17de53d4 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:15 -07:00
Kristiyan Kostadinov 91b1f24d03 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 4a7402f75d docs: update ChangeDetectionStrategy links (#55553)
fixes #54227
fixes #50943

PR Close #55553
2024-04-26 09:31:41 -07:00
Andrew Scott 356ec6508b 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 bf8814c6c3 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
Alan Agius 2bd166537b 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:21 -07:00
Tom Wilkinson f1d6f867b9 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:58 -07:00
Andrew Scott 7e89753eef 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:34 -07:00
Kristiyan Kostadinov 97eea8d50e 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
Pawel Kozlowski 90389add7a 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 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
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 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
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
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
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
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
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
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 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
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
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
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
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
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
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
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 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
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
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