Commit Graph

2929 Commits

Author SHA1 Message Date
Matthieu Riegler d497be7aca refactor(core): Use the nullish coalescing assignment in render3 functions (#49698)
The usage of `??=` make the code more clear & concise.

PR Close #49698
2023-04-05 09:45:53 -07:00
Matthieu Riegler 3b863ddc1e refactor(core): Remove ReflectiveInjector symbol (#48103)
The `ReflectiveInjector` symbol has been deprecated in v5 (11 major versions ago). This commit removes ReflectiveInjector and related symbols.

BREAKING CHANGE: The `ReflectiveInjector` and related symbols were removed. Please update the code to avoid references to the `ReflectiveInjector` symbol. Use `Injector.create` as a replacement to create an injector instead.

PR Close #48103
2023-04-04 16:43:53 -07:00
Matthieu Riegler 061f3d1086 feat(core): Drop public factories property for IterableDiffers : Breaking change (#49598)
The `factories` property was marked as deprecated in v4 to make it private. Let's move it to private.

PR Close #49598
2023-04-04 15:13:01 -07:00
Matthieu Riegler d71cde8dab refactor(core): remove ɵmakeDecorator from private exports (#49300)
`makeDecorator` is unused outside of core and is not part of the public API (not exported).

PR Close #49300
2023-04-04 15:10:16 -07:00
Matthieu Riegler 41992a2979 refactor(core): remove #9100 todos. (#49408)
This commit includes a change on the `ViewRef.onDestroy` signature.

PR Close #49408
2023-04-04 15:01:48 -07:00
Guillaume Weghsteen b35fa73968 feat(core): change the URL sanitization to only block javascript: URLs (#49659)
In modern browsers, the 'javascript:' URL scheme is the only scheme that
can execute JavaScript when passed in a navigation URL context (e.g.
`a.href` value). Validate URL shemes to only contain characters allowed
in the URL specification ([a-zA-Z-+.]), and that are not javascript
(case insensitive). This is not a breaking change. The URL sanitization
is loosen.

PR Close #49659
2023-04-04 15:01:13 -07:00
Andrew Kushnir 761e02d912 feat(platform-browser): add a public API function to enable non-destructive hydration (#49666)
This commit adds the `provideClientHydration` function to the public API. This function can be used to enable the non-destructive Angular hydration.

Important note: the non-destructive hydration feature is in Developer Preview mode, learn more about it at https://angular.io/guide/releases#developer-preview.

Before you can get started with hydration, you must have a server side rendered (SSR) application. Follow the [Angular Universal Guide](https://angular.io/guide/universal) to enable server side rendering first. Once you have SSR working with your application, you can enable hydration by visiting your main app component or module and importing `provideClientHydration` from `@angular/platform-browser`. You'll then add that provider to your app's bootstrapping providers list.

```typescript
import {
  bootstrapApplication,
  provideClientHydration,
} from '@angular/platform-browser';
// ...
bootstrapApplication(RootCmp, {
  providers: [provideClientHydration()]
});
```

Alternatively if you are using NgModules, you would add `provideClientHydration` to your root app module's provider list.

```typescript
import {provideClientHydration} from '@angular/platform-browser';
import {NgModule} from '@angular/core';

@NgModule({
  declarations: [RootCmp],
  exports: [RootCmp],
  bootstrap: [RootCmp],
  providers: [provideClientHydration()],
})
export class AppModule {}
```

You can confirm hydration is enabled by opening Developer Tools in your browser and viewing the console. You should see a message that includes hydration-related stats, such as the number of components and nodes hydrated.

Co-authored-by: jessicajaniuk <72768744+jessicajaniuk@users.noreply.github.com>
Co-authored-by: alan-agius4 <17563226+alan-agius4@users.noreply.github.com>

PR Close #49666
2023-04-03 22:13:47 -07:00
Matthieu Riegler b2327f4df1 feat(core): Allow typeguards on QueryList.filter (#48042)
To match the behaviour of Array.filter, typeguards can now be used on QueryList.filter to narrow the return type.

Fixes #38446

BREAKING CHANGE: QueryList.filter now supports type guard functions, which will result in type narrowing. Previously if you used type guard functions, it resulted in no changes to the return type. Now the type would be narrowed, which might require updates to the application code that relied on the old behavior.

PR Close #48042
2023-04-03 19:35:35 -07:00
Jessica Janiuk 4b673d5ed7 docs: Add error page for NG0504 error (#49689)
This adds a detailed error page for the hydration invalid ngSkipHydration host error.

PR Close #49689
2023-04-03 19:19:27 -07:00
Jessica Janiuk 9e9e1313a9 docs: Add error page for NG0503 error (#49689)
This adds a detailed error page for the hydration unsupported projection of DOM nodes error.

PR Close #49689
2023-04-03 19:19:26 -07:00
Jessica Janiuk f1566f3325 docs: Add error pages for NG0501 and NG0502 errors (#49689)
This adds a detailed error pages for the hydration missing siblings and hydration missing node errors.

PR Close #49689
2023-04-03 19:19:26 -07:00
Jessica Janiuk b7c5acb542 docs: Add error page for NG0500 hydration node mismatch error (#49689)
This adds a detailed error page for the hydration node mismatch error.

PR Close #49689
2023-04-03 19:19:26 -07:00
Andrew Kushnir 61bedaf930 refactor(core): handle a case when ngSkipHydration is applied to the root node of an application (#49675)
This commit updates the logic to handle a case when the `ngSkipHydration` attribute is applied to the root node of an app. In this case, the hydration info should not be serialized and the contents of the app on the client should be cleared up before initial rendering.

PR Close #49675
2023-04-03 19:11:47 -07:00
Pawel Kozlowski a5f1737d1c feat(core): expose onDestroy on ApplicationRef (#49677)
This change exposes the onDestroy callback on the ApplicationRef
as the public API. It is useful for cases where people need to
execute cleanup logic on application teardown.

Closes #49087

PR Close #49677
2023-04-03 15:01:18 -07:00
Andrew Scott d7d6514add feat(core): Add ability to configure NgZone in bootstrapApplication (#49557)
This commit adds a provider function that allows developers to configure
the `NgZone` instance for the application. In the future, this provider
will be used for applications to specifically opt-in to change detection
powered by ZoneJS rather than it being provided by default.

This API does _not_ specifically provide support for developers to define their own
`NgZone` implementation or opt in to `NoopNgZone` directly. Both of
these are possible today, but are effectively unsupported (applications
that use these are left to their own devices to run change detection at
the appropriate times). That said, developers can still use DI in
`bootstrapApplication` to provide an `NgZone` implementation instead,
it's just not specifically available in the
`provideZoneChangeDetection` function.

PR Close #49557
2023-03-31 11:56:10 -07:00
Andrew Scott 58c1faf507 refactor(core): update bootstrapApplication to get NgZone from providers (#49557)
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
2023-03-31 11:56:09 -07:00
Andrew Kushnir 6c1895f5da refactor(core): avoid incrementing a dev mode counter unnecessarily (#49656)
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
2023-03-31 11:49:13 -07:00
Andrew Scott e9dd7f0028 refactor(core): Prevent reads and writes to signals at certain times (#49631)
* 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
2023-03-30 16:09:12 -07:00
Alex Rickabaugh 8997bdc03b feat(core): prototype implementation of @angular/core/rxjs-interop (#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
2023-03-30 09:44:38 -07:00
Pawel Kozlowski 267c5e8ca5 refactor(core): remove DeepReadonly type wrapper for signals (#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
2023-03-30 09:44:38 -07:00
Andrew Kushnir d786856c46 refactor(core): output hydration stats into a console in dev mode (#49617)
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
2023-03-30 09:42:05 -07:00
Andrew Kushnir 91eac28e2c refactor(core): add a counter for components that skipped hydration (#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
2023-03-30 09:42:05 -07:00
Vinit Neogi 337922709a docs(core): fix view hierarchy links (#49629)
fixes incorrect links to view-hierarchy (currently view-tree)

Fixes #49623

PR Close #49629
2023-03-30 09:39:39 -07:00
Alex Rickabaugh 06e74a5583 refactor(core): run effects during change detection (#49641)
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
2023-03-30 09:37:47 -07:00
Alex Rickabaugh e254671efc refactor(core): consolidate LView state from injectors (#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
2023-03-30 09:37:47 -07:00
Andrew Scott cbe6807a46 refactor(core): Add default implementation for WeakRef (#49639)
This commit adds a default implementation for WeakRef that uses strong references
when the browser does not natively support WeakRef.

PR Close #49639
2023-03-29 15:33:27 -07:00
Pawel Kozlowski 9c5fd50de4 feat(core): effects can optionally return a cleanup function (#49625)
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
2023-03-29 10:40:17 -07:00
Alan Agius c024574f46 feat(core): expose makeStateKey, StateKey and TransferState (#49563)
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
2023-03-29 10:18:02 -07:00
Alex Rickabaugh ef149defb9 refactor(core): expose ReactiveNode privately on signal functions (#49529)
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
2023-03-28 18:47:58 -07:00
Alex Rickabaugh 9e40250d27 refactor(core): unify signal producer/consumer into nodes (#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
2023-03-28 18:47:58 -07:00
Alex Rickabaugh 29047aaae3 refactor(core): run effects in the zone in which they're created (#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
2023-03-28 18:47:58 -07:00
Alex Rickabaugh 069d4c08ec refactor(core): make signal values deeply immutable at the type level (#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
2023-03-28 18:47:58 -07:00
Alex Rickabaugh c262069635 refactor(core): move effect to render3 and add DestroyRef integration (#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
2023-03-28 18:47:58 -07:00
Alex Rickabaugh 1869a829e4 refactor(core): switch signal and computed to take options argument (#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
2023-03-28 18:47:58 -07:00
Alex Rickabaugh 3945511b1d refactor(core): rename SettableSignal to WritableSignal (#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
2023-03-28 18:47:58 -07:00
Alex Rickabaugh 89d291c367 feat(core): add assertInInjectionContext (#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
2023-03-28 18:47:58 -07:00
Jessica Janiuk 84a0fa3e8a refactor(core): Fixes hydration navigation and dom removal bugs (#49615)
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
2023-03-28 16:57:36 -07:00
Andrew Kushnir 478c5ac150 refactor(core): internal tracker of pending tasks during initial rendering (#49576)
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
2023-03-28 16:19:31 -07:00
Andrew Scott be23b7ce65 fix(core): ComponentRef.setInput only sets input when not equal to previous (#49607)
`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
2023-03-28 12:39:11 -07:00
Alan Agius fdafdb78dc fix(core): set style property value to empty string instead of an invalid value (#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
2023-03-28 11:35:38 -07:00
Andrew Kushnir 22688b8ff3 refactor(core): handle <ng-content> with *ngIf during hydration (#49590)
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
2023-03-27 12:53:12 -07:00
Andrew Scott 9b65b84cb9 feat(core): Mark components for check if they read a signal (#49153)
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
2023-03-27 11:19:06 -07:00
Paul Gschwendtner 316c91b1a4 fix(core): deprecate moduleId @Component property (#49496)
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
2023-03-24 10:27:10 -07:00
Andrew Scott 22a64128f0 refactor(core): Update error message for missing injectable (#49503)
Update error message to specifically mention BrowserModule, as this is
commonly forgotten.

PR Close #49503
2023-03-24 10:26:48 -07:00
Andrew Kushnir f1d3be3dee refactor(core): only annotate disconnected nodes in content projection (#49549)
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
2023-03-23 13:55:38 -07:00
Kristiyan Kostadinov 585e34bf6c feat(core): remove entryComponents (#49484)
`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
2023-03-23 10:38:03 -07:00
Andrew Scott 8d91d74d46 refactor(core): Remove NG_DEV_MODE const (#49530)
From Joost: The locally defined NG_DEV_MODE does not work with ESBuild, as it doesn’t fold recursively

PR Close #49530
2023-03-22 15:31:48 -07:00
Jessica Janiuk 0851bd5283 refactor(core): Improve hydration error handling (#49502)
This adds user friendly error messages outlining exactly where hydration
mismatches occur and what was expected with easy to read stringified
DOM. It also includes a pointer to exactly where the mismatch happened
and lets the user know what was expected.

PR Close #49502
2023-03-22 11:47:41 -07:00
Andrew Kushnir 8ea1fb7396 refactor(core): exclude disconnected nodes from hydration (#49471)
This commit updates the hydration logic to handle situations where DOM nodes might end up
being disconnected from the DOM tree. We serialize ids of those nodes into the hydration
state transfer data and use the information to switch from hydration to the regular "creation
mode" at runtime.

This situation may happen during the content projection, when some nodes don't make it
into one of the content projection slots (for example, when there is no default
<ng-content /> slot in projector component's template).

Note: we leverage the fact that we have this information available in the DOM emulation
layer (in Domino) for now. Longer-term solution should not rely on the DOM emulation and
only use internal data structures and state to compute this information.

PR Close #49471
2023-03-22 10:04:56 -07:00
Alan Agius 41f27ad086 refactor(platform-server): remove renderApplication overload that accepts a component (#49463)
This commit removes the `renderApplication` overload that accepts a root component as the first parameter.

BREAKING CHANGE:

`renderApplication` method no longer accepts a root component as first argument. Instead, provide a bootstrapping function that returns a `Promise<ApplicationRef>`.

Before
```ts
const output: string = await renderApplication(RootComponent, options);
```

Now
```ts
const bootstrap = () => bootstrapApplication(RootComponent, appConfig);
const output: string = await renderApplication(bootstrap, options);
```

PR Close #49463
2023-03-22 16:40:31 +01:00