This commit updates the `bootstrapApplication` method to get the
`NgZone` instance from DI. This will allow a future change to enable
developers to configure `NgZone` in DI rather than adding the options to
the top level like in `bootstrapModuleFactory` (which is done in order
to get the NgZone instance without going through DI).
PR Close#49557
This commit removes a code that increments the `rendererCreateComment` counter unnecessarily. The counter gets incemented even in hydration scenarios where we do not create a comment node. The counter still gets incemented in the right locations (when we *actually* create a node).
PR Close#49656
Adds ability for `RouterOutlet` to bind `Router` information to the routed
component's inputs. This commit also exposes some helpers for
implementers of custom outlets to do their own input binding if desired.
Resolves#18967
PR Close#49633
* Prevent reads of signals during the notification process. This shouldn't
ever be triggered by user code but is more of a preventative for
internal misuse. Reading a signal during notification would/could create
glitches where the values being read are not updated to reflect the
values being updated by the notification.
* Prevent signal writes inside of computed's. These are meant to be
derived values and should not have any side-effects like writing new
values to other signals
* Prevent signal writes inside of effects by default. Writing to signal
values during the execution of an effect can lead to the
`ExpressionChangedAfterItHasBeenCheckedError` if writing to signals
that represent global state which is read in a parent component. This is
mostly just a problem for `OnPush`/`CheckAlways` components, but with
signals being new and pure signal components not even available yet,
it will be the majority for a long time.
PR Close#49631
The change in effect timing collided with the introduction of these
rxjs-interop tests, resulting in them failing after the merge.
This commit adjusts the tests to rely on the real effect timing.
PR Close#49651
This commit removed the deprecated `EventManager` method `addGlobalEventListener`.
BREAKING CHANGE: Deprecated `EventManager` method `addGlobalEventListener` has been removed as it is not used by Ivy.
PR Close#49645
This commit implements an RxJS operator `takeUntilDestroyed` which
terminates an Observable when the current context (component, directive,
etc) is destroyed. `takeUntilDestroyed` will inject the current `DestroyRef`
if none is provided, or use one provided as an argument.
PR Close#49154
This commit adds the basic sketch for the implementation of `fromObservable`
and `fromSignal`, the two basic primitives which form the RxJS interop layer
with signals.
PR Close#49154
This commit adds the infrastructure for `@angular/core/rxjs-interop`, a new
core entrypoint which provides bidirectional interoperability between
Angular's built-in reactivity system of synchronous signals, and the RxJS
`Observable` abstraction.
The new entrypoint is set up as an empty shell in this commit, with its
implementation to follow in a followup.
PR Close#49154
We've been experimenting with the DeepReadonly type that would make
signal values deeply read-only and prevent accidental changes without
going to the owner of data. What we've found out during the experiments
is that additional safety net has more drawbacks than benefits: it just
introduces too much friction to be practical for daily usage.
PR Close#49154
This commit adds a logic to output basic hydration stats into a console. This is also helpful to ensure that hydration is enabled and works.
PR Close#49617
This commit adds a new metric into the `ngDevMode` to count a number of components that skipped hydration (where `ngSkipHydration` attribute was applied).
PR Close#49617
This commit updates the `effect` primitive and significantly changes the
timing of effect execution.
Previously, effects were scheduled via the microtask queue. This commit
changes effects to run throughout the change detection process instead.
Running effects this way avoids needing additional rounds of change
detection to resolve effects, with the tradeoff that they're harder to use
for model-to-model synchronization (which can be seen as a good thing).
PR Close#49641
This commit consolidates the `RendererFactory` and `Sanitizer` properties
of `LView` onto a single object, the `LViewEnvironment`. These properties
are both set from DI when the root view is created, and not overridden when
child views are created (but inherited from the parent view).
This is a precursor commit to adding the `EffectManager` into the
`LViewEnvironment`.
PR Close#49641
When navigating in the Router, the current approach does the redirects
and the creation of the `RouterStateSnapshot` in two separate steps
(applyRedirects and recognize). These two steps duplicate the route
matching logic, resulting in user code on routes being executing twice
(custom `UrlMatcher` and `canMatch` guards). This also duplicates the
complex matching logic in two places, which increases the bundle size
and maintenance burden.
This commit combines the `applyRedirects` and `recognize` steps into a
single matching algorithm.
fixes#26081
PR Close#49163
This change extends the effect API surface so effects can, optionally,
return a cleanup function. Such function, if returned, is executed
prior to the subsequent effect run.
PR Close#49625
This commits adds `makeStateKey`, `StateKey` and `TransferState` methods in `@angular/core` as public API and deprecated the same exported symbols in `@angular/platform-browser`.
DEPRECATED: `makeStateKey`, `StateKey` and `TransferState` exports have been moved from `@angular/platform-browser` to `@angular/core`. Please update the imports.
```diff
- import {makeStateKey, StateKey, TransferState} from '@angular/platform-browser';
+ import {makeStateKey, StateKey, TransferState} from '@angular/core';
```
PR Close#49563
Setting the `nonce` attribute using the property is not supported by Domino. This change update the usage to use `setAttribute` and also add a test to verify that the `nonce` is set when it should.
PR Close#49624
Signal functions are marked with a `[SIGNAL]` symbol property, which was
previously set to `true`.
This commit changes the `[SIGNAL]` property to have the `ReactiveNode` as
its value instead. This doesn't change the behavior of the signal library
itself, but exposes the signal internals in a way where developer tooling
can look at any signal and interact with its dependency graph.
PR Close#49529
Previously the signals implementation maintained separate interfaces for
`Producer` and `Consumer` nodes, with implementers choosing to implement
one or both interfaces. Operations defined against those interfaces were
exposed as importable functions to be called with the object implementing
the relevant contract as the first argument.
This commit refactors the implementation to merge both abstractions into a
single `ReactiveNode` base class, which represents both producers and
consumers in the graph. Implementers choose to interact with a subset of the
`ReactiveNode` API depending on their role in the graph. Operations are now
available as protected methods on the base class, instead of separate
functions.
PR Close#49529
Previously, effects were queued in the global microtask queue and executed
directly. This had an undesired consequence: whichever effect scheduled
first determined the zone in which all other effects would run, *and* that
zone depended on where the signal happened to be set which triggered that
first effect. This behavior would be extremely unpredictable.
This commit adds zone awareness to the effect API. effects now capture the
current zone when they're created, and this zone is used to run the effect
callback regardless of which zone set the signal.
PR Close#49529
This commit adds a `DeepReadonly` type to the signals API, and makes signal
getters return an immutable version of their value type. This doesn't
prevent all mutation but adds some friction against modifying the values
within signals outside of the proper mutation APIs.
PR Close#49529
The `effect` implemented in the signal library is useful for testing but
does not integrate with Angular. This commit moves that code to the
actual framework package and integrates it with automatic cleanup via
`DestroyRef`. A simpler effect implementation is used in the signal tests to
test the `Watch` primitive.
Further commits will update the scheduling to tie effects together with
change detection.
PR Close#49529
This commit switches the `signal` and `computed` APIs to accept an optional
options argument as their second argument, instead of an equality function
directly. The equality function has moved to an option in the options
argument.
PR Close#49529
This commit renames the `SettableSignal` interface to align with recent
naming changes. `WritableSignal` is considered a more suitable name since
it supports more mutation operations than just directly setting.
PR Close#49529
This commit adds an assertion function to the public API, which allows
authors of functions which rely on `inject` to validate that they're being
called with the right context. This mostly produces a nicer error message
than calling `inject()` and relying on Angular's default error message for
that.
PR Close#49529
This fixes two cases where DOM node navigation during hydration would be broken. It also fixes an infinite loop on clearing DOM during skip hydration blocks
PR Close#49615
This commit implements a simple tracker of the pending tasks during initial rendering. The class allows adding and removing tasks from the set. The class also exposes a promise that gets resolved once the last task is removed.
This tracker is needed to keep track of ongoing processes like Router navigation (and potentially HTTP requests) and acts as a signaling mechanism to SSR and hydration that the application is in the "stable" state and a serialization can be performed.
This class would also act as a future replacement for the `ApplicationRef.isStable` for zoneless applications.
PR Close#49576
When navigating in the Router, the current approach does the redirects
and the creation of the `RouterStateSnapshot` in two separate steps
(applyRedirects and recognize). These two steps duplicate the route
matching logic, resulting in user code on routes being executing twice
(custom `UrlMatcher` and `canMatch` guards). This also duplicates the
complex matching logic in two places, which increases the bundle size
and maintenance burden.
This commit combines the `applyRedirects` and `recognize` steps into a
single matching algorithm.
fixes#26081
PR Close#49163
`ComponentRef.setInput` currently sets the input on the component regardless
of the previous value the method was called with. This results in
different behavior from bindings in templates, which only set inputs
when the value differs in the `Object.is` check from its previous value.
BREAKING CHANGE: ComponentRef.setInput will only set the input on the
component if it is different from the previous value (based on `Object.is`
equality). If code relies on the input always being set, it should be
updated to copy objects or wrap primitives in order to ensure the input
value differs from the previous call to `setInput`.
PR Close#49607
Currently we are unsafely unquoting CSS values which in some cases causes valid values to become invalid and invalid values to become valid.
Example:
```html
<div style="width:"1px;""></div>
```
In the above case, `width` has an invalid value of `"1px"`, however the compiler will transform it to `1px` which makes it valid.
On the other hand, in the below case
```html
<div style="content:"foo""></div>
```
`content` has a valid value of `"foo"`, but since the compiler unwraps it to `foo` it becomes invalid. For correctness, we should not remove quotes.
```js
const div = document.createElement('div');
div.style.width='"1px"';
div.style.content='foo';
div.style.width; // ''
div.style.content; // ''
div.style.width='1px';
div.style.content='"foo"';
div.style.width; // '1px'
div.style.content; // '"foo"'
```
More information about values can be found https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
PR Close#49460
Currently when the value of a styling property that has a unit is empty string a invalid value is generated.
Example:
`[style.width.px] = ""` will generate a value of `"px"`, when instead it should be `""`.
This causes browser to reset the value to an empty string. This is however not the case in Domino with changes in https://github.com/angular/domino/commit/bfc9114d1eb5b7591c43a7c6aef6ad50d24e369f.
This commit fixes the issues and generate correct values.
PR Close#49460
The class-based guard and resolver interfaces are deprecated. The
`Router` types only support functional guards definitions. Classes can
still be used as the underlying implementation of functional guards and
resolvers but there will not be an interface requiring a specific structure
for those classes.
There are also helper functions like `mapToCanActivate` that allow
converting the existing class-based guards directly to functional guards
at the route definition. This will be done in a separate migration.
PR Close#49337
This commit updates the serialization logic to avoid serializing a path for a node that was content projected (based on template information), but is not present in the DOM. This can happen if a <ng-content> is used with the *ngIf="false", for example: `<ng-content *ngIf="false" />`.
PR Close#49590
This commit updates the `LView` in Angular to be a `Consumer` of
signals. If a signal is read when executing a template, it marks the
view dirty. In addition, if a signal is read when executing host
bindings, it also marks views dirty.
One interesting thing about signal reads in host bindings
is that they perform a bit better than what we can do with today's
APIs. In order to re-execute host bindings for an `OnPush` component that
might have changed, you would probably inject `ChangeDetectorRef` and call
`markForCheck`. This will mark the _current component_ and parents
dirty. However, host bindings are executed as part of refreshing the
_parent_ so there is really no need to re-execute the current component
if the only thing that changed is the host bindings. When a signal is
read in host bindings, it marks the parent dirty and not the component
that defined the host binding.
Additionally, this commit avoids allocating a full consumer for each
`LView` by re-using a consumer until template execution results in a
signal read. At this point, we assign that consumer to the `LView` and
create a new consumer to "tentatively" use for the future `LView`
template executions.
Co-authored-by: Dylan Hunn <github@dylanhunn.com>
PR Close#49153
The `moduleId` directive field does not have any effect as of Ivy. In
View Engine it was used for resolving template and styles relative
to the component source location- but ultimately this is not needed
as the Angular compiler knows the source file location at build time,
and at runtime never even consulted `moduleId`. An XHR is always issue
using the extact specified URL.
For Angular CLI users, relative URLs in JIT are still possible because
the CLI has a TS transform that will replace the references with actual
Webpack imports.
`moduleId` does not seem worth keeping in the future, as it's not used
currently, and even if we would consider supporting relative JIT resource
URLs through it, it would be deeply coupled to CommonJS `module.id`.
DEPRECATED: The `@Directive`/`@Component` `moduleId` property is now
deprecated. It did not have any effect for multiple major versions and
will be removed in v17.
PR Close#49496
Previously, we've annotated all disconnected DOM nodes, even if they are not used in content projection. However, this situation is only possible in content projection and if it happens in other cases (for example, when a node was removed using direct DOM manipulations), this should be a mismatch error.
PR Close#49549
`entryComponents` have been deprecated since version 9, because with Ivy they weren't necessary. These changes remove any remaining references.
BREAKING CHANGE:
* `entryComponents` has been deleted from the `@NgModule` and `@Component` public APIs. Any usages can be removed since they weren't doing anyting.
* `ANALYZE_FOR_ENTRY_COMPONENTS` injection token has been deleted. Any references can be removed.
PR Close#49484
This commit updates parts of the FW to be ES2022 complaint.
These changes are needed to fix the following problems problems with using properties before they are initialized.
Example
```ts
class Foo {
bar = this.buz;
constructor(private buz: unknown){}
}
```
PR Close#49559
This commit updates parts of the FW to be ES2022 complaint.
These changes are needed to fix the following problems problems with using properties before they are initialized.
Example
```ts
class Foo {
bar = this.buz;
constructor(private buz: unknown){}
}
```
PR Close#49332