Commit Graph

11561 Commits

Author SHA1 Message Date
Kristiyan Kostadinov 7368b8aaeb fix(core): host directive validation not picking up duplicate directives on component node (#52073)
Fixes that, depending on the matching and import order, in some cases we weren't throwing the error saying that a directive matched multiple times on the same element.

Fixes #52072.

PR Close #52073
2023-10-09 12:39:19 -07:00
Miles Malerba acac9ea070 refactor(compiler): Separate param map serialization into a helper class (#51988)
Cleans up the i18n placeholder resolution phase by extracting the
details of how the map is serialized into its own class, instead of
mixing it with the phase's traversal logic.

PR Close #51988
2023-10-09 12:35:15 -07:00
Miles Malerba ed2a20f490 refactor(compiler): Fix subTemplateIndex on template tags (#51988)
Template instructions exist in the parent view, but for the purposes of
the i18n placeholders, they should use the subTemplateIndex of the i18n
op wrapping their view.

PR Close #51988
2023-10-09 12:35:15 -07:00
Miles Malerba 371cd58eec refactor(compiler): Fix advance instructions for i18n expressions (#51988)
The custom logic in the generate advance phase for i18n expressions did
not work in all cases. Instead we add a new phase to update the
expression's target op, and then allow the standard advance generation
code to determine the number of advance instructions needed.

Co-authored-by: Dylan Hunn <dylhunn@users.noreply.github.com>

PR Close #51988
2023-10-09 12:35:15 -07:00
Miles Malerba 24b88b6f43 refactor(compiler): Add values for sub-template placeholders (#51988)
Fills in values for sub-template placeholders in i18n messages. This
includes both the tag placeholders for ng-template tags, as well as
merging in any placeholders from the child i18n block.

PR Close #51988
2023-10-09 12:35:15 -07:00
Miles Malerba c3a83a8cec refactor(compiler): Add sub-template index to child i18n instructions (#51988)
Adds an additional sub-template index parameter to child i18n blocks
that are propagated from the root block. This additional paramete
indicates the index of the template in the i18n message.

Co-authored-by: Dylan Hunn <dylhunn@users.noreply.github.com>

PR Close #51988
2023-10-09 12:35:15 -07:00
Miles Malerba d8bc6aa129 refactor(compiler): Propagate i18n blocks through child templates (#51988)
Adds a phase to the template pipeline to recursively create child i18n
blocks for ng-template views existing inside an i18n block.

PR Close #51988
2023-10-09 12:35:15 -07:00
Jeremy Elbourn 7bfe20707f feat(compiler): extract api for fn overloads and abtract classes (#52040)
This commit adds support for extracting function overloads. Interestingly, this worked in an earlier version when the code was extracting all statements in every source file, but the existing compiler API for extracting all exported declarations from an entry-point only returns the first function declaration in cases when there are overloads.

This also marks abstract classes as abstract, required inputs as required, and filters out Angular-private APIs.

PR Close #52040
2023-10-09 12:03:20 -07:00
Andrew Kushnir 422e8582c4 refactor(core): support OnPush components in @defer blocks (#52095)
This commit adds the code to mark newly created embedded views (that represent `@defer` block states) as dirty to indicate that the view sgould be checked during the next change detection cycle.

Resolves #52094.

PR Close #52095
2023-10-09 10:55:38 -07:00
Kristiyan Kostadinov 386e1e9500 fix(compiler): work around TypeScript bug when narrowing switch statements (#52110)
We type check `@switch` blocks by generating identical TS `switch` statements in the TCB, however TS currently has a bug where parenthesized `switch` block expressions don't narrow their types. Since we use parenthesized expressions to wrap AST nodes for diagnostics, this will bug will affect all Angular-generated `switch` statements.

These changes work around the issue by generating `if`/`else if`/`else` statements that represent the `switch`.

Some alternatives that were considered:
1. Moving the `switch` expression to a constant - this is fairly simple to implement, but it won't fully resolve the narrowing issue since the same constant will have to be used in expressions inside the different cases.
2. Removing the outer-most parenthesis from the switch expression - this works and allows us to continue using switch statements, but because we use parenthesized expressions to map diagnostics to their template locations, I wasn't sure if it won't lead to worse template dignostics.

Fixes #52077.

PR Close #52110
2023-10-09 10:54:28 -07:00
Andrew Scott 023a181ba5 feat(language-service): Implement outlining spans for control flow blocks (#52062)
This commit implements the getOutlingSpans to retrieve Angular-specific
outlining spans. At the moment, these spans are limited to control-flow
blocks in templates.

This is required for folding ranges (https://github.com/angular/vscode-ng-language-service/issues/1930)

PR Close #52062
2023-10-09 10:20:26 -07:00
Pawel Kozlowski 28a5925f53 fix(common): use === operator to match NgSwitch cases (#51504)
This change adjust the equality comparator used by NgSwitch - now it
defaults to === from previously used ==. This change is based on the
following reasoning:
- align behaviour with the built-in switch block);
- improve performance (avoid type coercion);
- enable better type-checking.

BREAKING CHANGE:

the NgSwitch directive now defaults to the === equality operator,
migrating from the previously used ==. NgSwitch expressions and / or
individual condition values need adjusting to this stricter equality
check. The added warning message should help pinpointing NgSwitch
usages where adjustements are needed.

Fixes #33873

PR Close #51504
2023-10-09 10:10:21 -07:00
Nicolas Frizzarin e25006b341 refactor(router): refactor documentation withHashLocation return type (#52016)
This improve the documentation of withHashLocation function by returning the correct type.

PR Close #52016
2023-10-09 08:54:44 -07:00
Kristiyan Kostadinov 753eb2459e build: fix broken symbols test (#52092)
Fixes a test that is broken on the main branch.

PR Close #52092
2023-10-09 08:06:11 -07:00
Pawel Kozlowski 00128e3853 fix(core): drop mutate function from the signals public API (#51821) (#51986)
This change removes the `mutate` method from the `WritableSignal` interface and
completely drops it from the public API surface.

The initial API proposal for Angular signals included the mutate method, allowing
in-place modification of JS objects, without changing their references (identity).
This was based on the reasoning that identity change on modification is not necessary
as we can send the “modified” notification through the signals graph.
Unfortunately the signal-specific change notification is lost as soon as we read
signal value outside of a reactive context (outside of a reactive graph).
In other words - any code outside of the Angular signals library can’t know
that an object is modified.

Secondly, to make the mutate method work, we’ve defaulted the signal value equality function
to the one that considers non-primitive values as always different.
This is unfortunate for people working with immutable data structures
(this is notably the case for the popular state management libraries)
as the default equality function de-optimizes memoization in computed,
making the application less performant.

Given the above reasons we prefer to remove the mutate method in the signals library -
at least for now. There are just too many sharp edges and tradeoffs that we don’t fully
understand yet.

BREAKING CHANGE:

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]);
```

PR Close #51986
2023-10-06 15:12:00 -07:00
Alex Rickabaugh 8914eaf86d refactor(core): add consumerOnSignalRead hook to ReactiveNode (#51986)
This hook allows a consumer to create `ReactiveNode`s with custom behavior
when signals are read.

PR Close #51986
2023-10-06 15:12:00 -07:00
Alex Rickabaugh 8f5cbcc845 refactor: move signals code into primitives package (#51986)
This commit reorganizes the Angular code a bit, and moves signals into a
newly defined `@angular/core/primitives` location. This will be used inside
g3 to allow non-Angular targets to depend on the signals core without
incurring a dependency on the whole framework.

PR Close #51986
2023-10-06 15:12:00 -07:00
Alex Rickabaugh b91d143fe4 refactor(core): extract signals API away from the 'signals' package (#51986)
This commit refactors the signals API surface of Angular out of the
//packages/core/src/signals package. This is done in preparation of moving
the core signals package into a new 'primitives' package that's decoupled
from the public API.

PR Close #51986
2023-10-06 15:11:59 -07:00
Andrew Kushnir 2e16b0e0ea ci: update @defer symbol test golden file (#52088)
This commit updates `@defer` symbol test golden file to account for an extra symbol that was added in a different PR.

PR Close #52088
2023-10-06 13:04:55 -07:00
Alex Castle 048f400efc feat(core): add warnings for oversized images and lazy-lcp (#51846)
Add warnings for two image-related performance problems that apply beyond just apps using NgOptimizedImage.

PR Close #51846
2023-10-06 12:14:32 -07:00
Adrien Crivelli 85843e8212 fix(common): allow to specify only some properties of DatePipeConfig (#51287)
The code already supports `DatePipeConfig` to have only some properties
set, and not all. But the typing disallows it. This aligns the typing
with the code.

PR Close #51287
2023-10-06 12:13:13 -07:00
Matthieu Riegler 7dde42a5df feat(http): allow customization of the HttpTransferCache. (#52029)
`provideClientHydration()` accepts new `HydrationFeature` : `HttpTransferCacheOptions`.

`withHttpTransferCacheOptions` accepts an option object:
* `includeHeaders` : list of headers entries to keep in the cache with the request
* `filter` a callback to determine if a request should be cached
* `includePostRequests`: to include POST requests in the allowed methods

Implements some of the features requested in #50117

PR Close #52029
2023-10-06 12:12:47 -07:00
Andrew Kushnir b88cc9eccb test(core): add symbol tracking for @defer feature (#52065)
This commit adds a bundling test, which also includes symbol tracking for `@defer` feature.

PR Close #52065
2023-10-06 12:11:29 -07:00
Andrew Scott b6b9eae7e7 Revert "fix(core): drop mutate function from the signals public API (#51821)" (#52081)
This reverts commit c7ff9dff2c.
requires cleanup of 2 uses internally first

PR Close #52081
2023-10-06 10:31:48 -07:00
Kristiyan Kostadinov 17078a3fe1 fix(compiler): pipes used inside defer triggers not being picked up (#52071)
Fixes that the compiler wasn't picking up pipes used inside defer block triggers as dependencies. We had implemented the `visitDeferredTrigger` visitor method, but it wasn't being called, because we weren't going through the `visitAll` method of the deferred block. We don't use `visitAll`, because child nodes have to be processed differently than the connected blocks and triggers.

Fixes #52068.

PR Close #52071
2023-10-06 08:52:57 -07:00
Andrew Kushnir 486cc611a5 refactor(core): add focusin event to on hover trigger of @defer block (#52059)
This commit adds the `focusin` event to `on hover` trigger of `@defer` block to improve compatibility with screen readers.

PR Close #52059
2023-10-06 08:46:21 -07:00
Andrew Kushnir 317ed8e10e test(compiler-cli): drop unused config option from tests (#52066)
The `_enabledBlockTypes` config option was removed recently, since we've enabled @-syntax by default. This commit removes `_enabledBlockTypes` references from the `compiler-cli` test cases.

PR Close #52066
2023-10-06 08:41:53 -07:00
Andrew Kushnir f06d97e86d test(core): await all async work to be completed before checking test results (#52064)
This change should help make currently flaky test more stable.

PR Close #52064
2023-10-06 08:33:38 -07:00
Andrew Kushnir 22fa9fe488 docs: recommend enabling fetch support in HttpClient when using SSR (#52056)
PR Close #52056
2023-10-05 16:54:58 -07:00
Andrew Kushnir 760bfdc4bf refactor(http): warn when HttpClient doesn't use fetch during SSR (#52037)
This commit adds a logic to produce a warning in case HttpClient doesn't use fetch during SSR.
It's recommended to use `fetch` for performance and compatibility reasons.

PR Close #52037
2023-10-05 16:52:41 -07:00
Pawel Kozlowski 05d1fac41f test(core): more tests around built-in for (#52045)
Add some more tests around list diffing (created in
a different branch while working in the list diffing).

PR Close #52045
2023-10-05 16:21:58 -07:00
Pawel Kozlowski 0fb742402e test(core): move control flow acceptance tests (#52045)
Moves each control flow test (if, switch, for) into their
corresponding file.

PR Close #52045
2023-10-05 16:21:58 -07:00
Pawel Kozlowski 5b88d136af feat(core): mark core signal APIs as stable (#51821)
This change marks core signal APIs as stable and exit
developer preview for the main signal building blocks.

PR Close #51821
2023-10-05 14:40:50 -07:00
Pawel Kozlowski c7ff9dff2c fix(core): drop mutate function from the signals public API (#51821)
This change removes the `mutate` method from the `WritableSignal` interface and
completely drops it from the public API surface.

The initial API proposal for Angular signals included the mutate method, allowing
in-place modification of JS objects, without changing their references (identity).
This was based on the reasoning that identity change on modification is not necessary
as we can send the “modified” notification through the signals graph.
Unfortunately the signal-specific change notification is lost as soon as we read
signal value outside of a reactive context (outside of a reactive graph).
In other words - any code outside of the Angular signals library can’t know
that an object is modified.

Secondly, to make the mutate method work, we’ve defaulted the signal value equality function
to the one that considers non-primitive values as always different.
This is unfortunate for people working with immutable data structures
(this is notably the case for the popular state management libraries)
as the default equality function de-optimizes memoization in computed,
making the application less performant.

Given the above reasons we prefer to remove the mutate method in the signals library -
at least for now. There are just too many sharp edges and tradeoffs that we don’t fully
understand yet.

BREAKING CHANGE:

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]);
```

PR Close #51821
2023-10-05 14:40:50 -07:00
Dylan Hunn 04169e15d0 refactor(language-service): Prepare to support blocks in the langauge service (#52038)
Two key refactors to enable deeper language service support for blocks:

(1) We now generate accurate source spans for the various block types. Additionally, all the top-level source spans for a block are now *inclusive* of all the connected or descending blocks. This helps the language service visit connected blocks.

(2) The language service's template visitor was previously skipping over the AST nodes corresponding to several block types. We are now careful to visit all such nodes.

PR Close #52038
2023-10-05 14:35:00 -07:00
Matt Lewis 65786b2b96 fix(platform-browser): prevent duplicate stylesheets from being created (#52019)
Fixes a bug with REMOVE_STYLES_ON_COMPONENT_DESTROY when a component is destroyed and re-created, its previous stylesheets will not be re-used and instead a new stylesheet will still be created each time.

PR Close #52019
2023-10-05 14:06:56 -07:00
Andrew Kushnir caa8eb28d5 refactor(core): add after and minimum parameter support to @defer blocks (#52009)
This commit adds runtime code to support `after` and `minimum` parameters in the `@placeholder` and `@loading` blocks. The code uses the `TimerScheduler` service added earlier for `on timer` triggers.

PR Close #52009
2023-10-05 13:35:42 -07:00
Kristiyan Kostadinov 40c53577b8 refactor(compiler): introduce unknown block node (#52047)
Adds an `UnknownBlock` node to the Ivy AST to represent blocks that haven't been recognized by the compiler. This will make it easier to integrate blocks into the language service.

PR Close #52047
2023-10-05 13:10:05 -07:00
Kristiyan Kostadinov a90d85ad40 refactor(compiler): recover from incomplete blocks (#52047)
Adds some logic to treat incomplete blocks as empty blocks so that we can recover from them. Also logs an error about the incomplete block.

PR Close #52047
2023-10-05 13:10:05 -07:00
Kristiyan Kostadinov a687ef9d27 refactor(compiler): handle incomplete blocks in the lexer (#52047)
Updates the lexer to parse blocks as incomplete, instead of throwing errors. This will allow us to better handle them further down in the pipeline.

PR Close #52047
2023-10-05 13:10:05 -07:00
Paul Gschwendtner ced66d4007 revert: fix(core): allow toSignal in reactive contexts (#52049)
Revert (with improvements of): dcf18dc74c

We recently landed a change that allows `toSignal` to be called
from within reactive contexts (e.g. `effect`/`computed`). After
more thorough investigatio and consideration with the team, we
feel like allowing `toSignal` to be called in such contexts is
encouraging non-ideal / hard-to-notice code patterns.

e.g. a new subscription to an observable is made every time `toSignal`
is invoked. There is no caching done here. Additionally, multiple new
subscriptions can trigger unintended side-effects- that may slow down
the app, result in incorrect/unexpected behavior or perform unnecessary
work.

Users should instead move the `toSignal` call outside of the `computed`
or `effect` and then read the signal values from within their `computed`. e.g.

```ts
computed(() => {
  const smth = toSignal(coldObservable$)
  return smth() + 2;
}
```

--> should instead be:

```ts
const smth = toSignal(coldObsverable$);
computed(() => smth() + 2);
```

In cases where a new subscription for each invocation is actually intended, a manual
subscription can be made. That way it's also much more obvious to users
that they are triggering side-effects every time, or causing new
subscriptions.

PR Close #52049
2023-10-05 11:08:05 -07:00
Paul Gschwendtner 4427e1ebc2 feat(core): create function to assert not running inside reactive context (#52049)
Some functions or code should never run inside reactive contexts. A
function to assert that will help putting guard rails in place.

PR Close #52049
2023-10-05 11:08:05 -07:00
Thomas Wilkinson 91c4da6709 refactor(router): move location methods into state_manager.ts (#52032)
This is a preparatory refactor to enable a new version of
state_manager.ts that uses the Navigation API rather than
History API

PR Close #52032
2023-10-05 11:02:07 -07:00
Pawel Kozlowski 2da3551a70 feat(benchpress): report gc and render time spent in script (#50771)
GC and render events can happen _while_ running scripts as well as
outside of the script blocks. The new metric entries capture both
the gc and render time happening in the scrip blocks.

PR Close #50771
2023-10-05 10:52:26 -07:00
Jeremy Elbourn a7fa25306f feat(compiler): extract api docs for interfaces (#52006)
This adds API doc extraction for interfaces, largely using the same code paths for classes. The primary difference between classes and interfaces is that classes have member _declarations_ while interfaces have member _signatures_. This largely doesn't matter for the purposes of extraction, but the types are distinct with no common base types, so we have to do a fair amount of type unioning and aliasing.

PR Close #52006
2023-10-04 11:58:09 -07:00
Alex Castle dde3fdabbd feat(common): upgrade warning to logged error for lazy-loaded LCP images using NgOptimizedImage (#52004)
Upgrade the existing warning so it now logs an error instead, when an LCP element is determined to not be usings the `priority` attribute. Error is logged, not thrown.

PR Close #52004
2023-10-04 11:36:01 -07:00
Joey Perrott 5269cae788 build: lock file maintenance (#51834)
Update the lock file.

PR Close #51834
2023-10-04 11:31:27 -07:00
Andrew Scott 08482f2c7d fix(language-service): Retain correct language service when ts.Project reloads (#51912)
When the `ts.Project` creates the language service plugin (in this case,
the Angular Language Service), it sets the project's language service to
the new language service returned by the plugin create:
https://sourcegraph.com/github.com/microsoft/TypeScript@b12af0fa2bbd4b015e59adcfb49988cea7f919a1/-/blob/src/server/project.ts?L2035-2044

The project may be reloaded in response to various events, such as a
change to the tsconfig file, which then recreates the plugin. When this
happens, the language service that gets passed to the plugin `create`
function will not be the typescript language service, but rather the
previous instance of the new language service returned by the last call
to `create`.

This commit ensures that subsequent calls to `create` for the
`NgLanguageService` plugin for a project after the first call are able
to retrieve and hold on to the _TypeScript_ language service.

fixes https://github.com/angular/vscode-ng-language-service/issues/1923

PR Close #51912
2023-10-04 11:27:43 -07:00
Dylan Hunn 422a3db2a8 refactor(compiler): Enable passing and nearly-passing Template Pipeline tests (#51950)
A couple tests were already passing, and just needed to be enabled. This includes tests pertaining to:
* ng-template
* host binding styling slots
* and host animation bindings
* some literal tests (which were missing some $foo$ escaped names)

We add pipeline-specific versions of the following tests, and enable them:
* A local refs test. The consts for the element attributes and the consts for local reference are collected in the reverse order, but the emitted template is functionally the same.
* A safe accesstest. Consider the expression `$any(val)?.foo`. `TemplateDefinitionBuilder` extracts a temporary variable: `($tmp_0_0$ = $ctx$.val) == null ? null : $tmp_0_0$.foo`. It presumably does this because it considers the `$any(...)` to be a function call. However, this is not a real call, so Template Pipeline safely ignores it and declines to generate a temporary.
* Another local refs test. AttributeMarker.Template is emitted at the end of the const array (instead of the middle)

PR Close #51950
2023-10-04 09:00:54 -07:00
Dylan Hunn 4b4dd2bf3a refactor(compiler): Don't emit properties on structural ng-templates (#51950)
Consider an `ng-template` which is generated as a result of a structural directive:

```
<div *ngFor="let inner of items"
             (click)="onClick(inner)"
             [title]="getTitle()"
             >
```

This should logically expand into something like the following:

```
<ng-template [ngForOf]="..." >
        <div (click)="..." [title]="..."></div>
</ng-template>
```

Note that the `(click)` handler and the `[title]` property are only present on the inner div, *not* on the enclosing generated `ng-template`.

Previously, Template Pipeline would place these bindings on *both* the tempate and the inner element.

However, we can't just remove them completely, because these bindings should still be matchable on the generated `ng-template` (which is very surprising, but nonetheless true).

We resolve this issue with two improvements:
(1) The ingestion step is now much smarter about determining not only if a binding is on a template element, but whether it actually targets that template element.
(2) We use `ExtractedAttributeOp` directly, rather than going through `BindingOp`, to cause the `ng-template` to still receive these bindings in its `consts` array for matching purposes.

PR Close #51950
2023-10-04 09:00:54 -07:00