This commit adds extra logic to produce a diagnostic in case `@Component.deferredImports` contain types from imports that also bring eager symbols. This would result in retaining a regular import and generating a dynamic import, which would not allow to defer-load dependencies.
PR Close#53899
The new type testing infrastructure was introduced for the input-as-signals
authoring functions. This commit modifies this infrastructure to make it more
generic and support queries-as-signals.
PR Close#53829
This commit update the logic to enable `register` and `resolve` phases for local compilation. Those phases will be useful for local compilation in certain cases (will be used in followup PRs).
PR Close#53901
This commit splits the query implementation and instructions
into a separate files. This is a pattern frequently used by
other functional areas of the framework and is a preparation for
introducing queries-as-signals where we are going to see more
instructions delegating to the same core functionality.
PR Close#53922
Currently when the extended type check fails due to an import reference
that cannot be generated, the fatal diagnostic is not caught and
not properly exposed as a `ts.Diagnostic` that can be gracefully
handled. This is inconsistent to non-extended type checking diagnostics.
This is problematic because Angular CLI applications currently fail in
obscure ways because:
- the CLI does not expect `getDiagnosticsForFile` to actually throw
runtime errors.
- the CLI does not seem to properly print these errors given the
parallel workers and build excection, and those errors are
especially hard to debug because there is no `stack` for
`FatalDiagnosticError`'s.
Example: `MyDir` is not exported and the type check block cannot reference it.
PR Close#53896
Prior to this commit, `TestBed` would require tests call `flushEffects`
or `fixture.detectChanges` in order to execute effects. In general, we
want to discourage authoring tests like this because it makes the timing
of change detection and effects differ from what happens in the
application. Instead, developers should perform actions and `await` (or
`flush`/`tick` when using `fakeAsync`) some `Promise` so that Angular
can react to the changes in the same way that it does in the
application.
Note that this still _allows_ developers to flush effects synchronously
with `flushEffects` and `detectChanges` but also enables the <action>,
`await` pattern described above.
PR Close#53843
This commit updates the logic of the `TemplateDefinitionBuilder` to support local compilation and generate a single dependency function for all explicitly deferred deps within a component.
PR Close#53591
This commit updates the `DeferredSymbolTracker` class to take info account the `onlyExplicitDeferDependencyImports` flag. The `DeferredSymbolTracker` class also exposes a new API to register import declarations as explicitly deferred, which will be used in followup commits.
PR Close#53591
This commit updates typechecker to store full Pipe metadata in internal data strctures, so that this information is available to more places in the code, which will be updated in a followup commit.
PR Close#53591
This commit updates a few places to extract the logic into a separate functions which will be reused in a few places in followup commits.
PR Close#53591
Enables signal inputs for existing Zone based components.
This is a next step we are taking to bring signal inputs earlier to the Angular community.
The goal is to enable early access for the ecosystem to signal inputs, while we are continuing
development of full signal components as outlined in the RFC. This will allow the ecosystem
to start integrating signals more deeply, prepare for future migrations, and improves code quality
and DX for existing components (especially for OnPush).
Based on our work on full signal components, we've gathered more information and learned
new things. We've improved the API by introducing a way to intuitively declare required inputs,
as well as improved the API around initial values. We even support non-primitive initial values
as the first argument to the `input` function now.
```ts
@Directive({..})
export class MyDir {
firstName = input<string>(); // string|undefined
lastName = input.required<string>(); // string
age = input(0); // number
```
PR Close#53872
This allows us to ensure signal inputs and a potential JIT transform
remain single file compilation compatible. The consequences are that
options need to be statically analyzable more strictly, compared to
loosened restrictions with static interpretation where e.g. `alias`
can be defined through a shared variable.
PR Close#53872
Adds infrastructure to run signal input tests with JIT (using the
transform) and AOT. Acceptance tests for signal inputs will run with
both variants. In the future we can consider expanding this
infrastructure for all of our acceptance tests, but that's a different
story.
PR Close#53808
Improves the recognition of the `input`/`input.required` functions to
not depend on external module resolution. This is useful for local
compilation and for transforms operating on a single file/ isolated
module.
PR Close#53808
Currently when someone declares a signal or non-signal input on a static
class member, the compiler will not yield any diagnostic. We can detect
these mistakes and report a diagnostic to help our users.
PR Close#53808
This commit addds two diagnostics for two scenarios where signal inputs
are declared incorrectly:
- a signal input is also annotated with `@Input` in the TypeScript
sources.
- a signal input is also declared in the `inputs` option of
`@Directive/`@Component`.
PR Close#53808
Given that the TCB output changes with signal inputs, and one of our
important considerations was auto-completion, we need some unit tests
that verify and guarantee proper completion with signal inputs being
bound in templates. This commit adds these.
PR Close#53808
This commit adds a transform for supporting input signals in JIT
environments. The transform will be wired up for Angular CLI
applications automatically. An integration test verifies that this fixes
unit testing with signal inputs.
The transform basically will take the signal input metadata and
transform it into `@Input` decorators that can provide static
information to the Angular JIT runtime when the directive/component
definition is compiled.
PR Close#53808
This commit does two things:
- exposes `addImports` so that it can be used by transforms that we are
adding to the compiler. e.g. the signal input to `@Input` transform.
- `updates `addImports` to support/use the transform context factory.
This will allow us to write proper transforms using `addImports`. Also
leverages this in the Ivy JS/DTS transforms.
PR Close#53808
Moves the signal input class member extraction logic into the dedicated
input function file. This makes the code for signal inputs more
self-contained.
This commit then re-exposes the function as part of `ngtsc/annotations`
so that it can be used later for a transform that will take the signal
input metadata and translate it into a `@Input` decorator. This allows
us to remove code duplication and guarantees consistency/correctness
PR Close#53808
We recently landed a commit to introduce support for generic type
checking of signal inputs. For that we had to implement logic that
will generate imports for inline type constructors. This required
changes to the context logic and `TypeCtorOp` file-level op.
This commit ensures that everything is working as expected, specifically
in cases where an inline type ctor is generated and imports would be
needed to unwrap the class members for `InputSignal`.
PR Close#53808
This commit creates a small http server Angular application playground
for playing with signal inputs. This is useful for development and also
validates some of the common input patterns.
PR Close#53808
Whenever a required input is accessed too early in a
directive/component, the signal input will throw an error.
This is necessary so that we can support required inputs
with intuitive typings that do not include `undefined` for
the short period of time where Angular is creating the component and
then assigning inputs later (Angular currently has no way of setting
inputs as part of the class creation when `new Dir()` happens)
PR Close#53808
Adds signal input compliance tests, ensuring linking works as expected,
partial output is generated properly, types are inferred properly, and
that the full, or linked output matches our expected runtime structure.
PR Close#53808
As we introduced the new partial output for signal inputs, we also need
to update the linker code to be able to parse this. This commit adds
this functionality.
In the follow-up commit, compliance tests for linking, partial output,
and full compilations are added.
PR Close#53808
As part of testing we did accidentally use `bitwiseAnd` for the input
flags, given we started without an extra flag for `HasTransform`.
This commit teaches the compiler to support emitting bitwise OR
and uses it when combining input flags, fully re-enabling transforms
for signal components after the new flag mechanism was introduced in
previous commits.
PR Close#53808
This commit changes the `HasTransform` flag to be only concerned with
decorator inputs. This allows us to automatically detect signal input
transforms without reliance on the flag, resulting in less complexity in
the compiler (as outlined in the design doc) and various other places,
while it also allows us to simplify JIT support for signal inputs
because there would be no need to capture the "hasTransform" state in
the decorator so that JIT can generate the according input flags.
`isSignal` will still persist as an input flag to allow for monomorphic
and highly efficient distinguishing at runtime, whether an input is
signal based or not. JIT transform will also need to propagate this
information to the runtime somehow.
PR Close#53808
We are adding internal support for declaring signal inputs via the
`@Input` decorator. This is needed for JIT unit testing, or JIT
applications.
In JIT, Angular is not able to recognize signal inputs due to the
lack of static reflection metadata. Decorators attach their information
on the class- without it needing to be instantiated. This allows Angular
to know inputs when preparing/generating the directive definition. With
signal inputs this is not possible- so we need a way to tell Angular
about inputs for JIT applications. We've decided that this is not
something users should have to deal with, so a transform will be added
in a follow-up that will automatically derive/and add the decorators
for signal inputs when requested in JIT environments.
PR Close#53808
In some cases, the input files for a partial output generation
compliance tests may be invalid and lead to compilation errors.
The golden partial would be silently generated with the remaining
test cases. Instead of hiding errors, we will now print these and
cause the script to fail properly.
Note that the error logging is pretty minimalistic, but it's sufficient.
PR Close#53808
The linker AST is abstracted to be agnostic of the underlying
implementation AST. i.e. TS AST or Babel AST.
This abstraction also intends to provide some type-safety-ness to
parsing of various partial declarations. This commit improves type
safety further by fixing that `AstValue'`s were not checked for
assignability of `T`- potentially hiding issues/unaccounted values.
Additionally, we fix that `getObject()` does not properly narrow
union types to actual object literals. This happend because e.g. arrays
are of type `object`. We can improve type safety here. Using `Record`
did not help as an array would still assign to that.
PR Close#53808
This commit moves the implementation of the change detection scheduler
used for testing to angular/core along with a (private export) provider function.
Note: Naming of the provider function is absolutely not final (and not
public API). I would prefer one that did not mention "zones"
but the easiest thing for now is to have a "Zone" and "Zoneless" naming
scheme.
PR Close#53579
This commit removes the testability features that are internal only.
This simplifies the implementation of testability which will need
updates to support zoneless. Those updates will be easier to manage if
the Testability implementation is simpler.
While protractor is indeed officially EOL, we will still need to do some
updates to support teams migrating to zoneless that have protractor
tests.
As far as protractor's own use of `whenStable`, it does not read the
internal only methods either:
https://github.com/angular/protractor/blob/master/lib/clientsidescripts.js
Anything else depending on these values are not following the defined public API
contract.
PR Close#53767
Make Zone.js compatible with moduleDetection:force by turning files that
are currently incompatible from scripts into modules using an empty
export statement.
PR Close#53445
This commit updates the router integration tests to cover both the
classic History and the new Navigation API. There is more work to be
done here, but this commit works to prove the efficacy of the
`FakeNavigation` implementation.
PR Close#53799
We generate `advance` instructions before most update instructions and the majority of `advance` calls are advancing by one. We can save some bytes for the most common case by omitting the parameter for `advance(1)` altogether.
PR Close#53845
This PR provides strict type definition for the window.ng object used
for both console debugging and devtools. `GlobalDevModeUtils` now
gathers all type information about all methods exposed on window.ng.
PR Close#53439
This addresses the offset issue caused when a switch case was empty with no spaces or children being affected by the markers that were added, but not accounted for in offset. The markers are not needed for empty content and can be safely removed in this case.
fixes: #53779
PR Close#53839
This commit ensures that change detection runs when an `LView` is
removed. Change detection is required because DOM nodes aren't actually
removed until the animation engine flushes and this doesn't happen until
the end of `detectChangesInternal` (`rendererFactory.end`).
PR Close#53812
The `afterRender` hooks currently run after `ApplicationRef.tick` but
also run after any call to `ChangeDetectorRef.detectChanges`. This is
problematic because code which uses `afterRender` cannot expect the
component it's registered from to be rendered when the callback
executes. If there is a call to `ChangeDetectorRef.detectChanges` before
the global change detection, that will cause the hooks to run earlier
than expected.
This behavior is somewhat of a blocker for the zoneless project. There
is plenty of application code that do things like `setTimeout(() =>
doSomethingThatExpectsComponentToBeRendered())`, `NgZone.onStable(() =>
...)` or `ApplicationRef.onStable...`. `ApplicationRef.onStable` is a
should likely work similarly, but all of these are really wanting an API
that is `afterRender` with the requirement that the hook runs after the
global render, not an individual CDRef instance.
This change updates the `afterRender` hooks to only run when
`ApplicationRef.tick` happens.
fixes#52429fixes#53232
PR Close#52455
This is a follow up to 5c1d441029
which added the `info` property to navigation requests. `RouterLink` now
supports passing that transient navigation info to the navigation
request.
This info object can be anything and doesn't have to be serializable.
One use-case might be for passing the element that was clicked. This
might be useful for something like view transitions. In the "animating
with javascript" example from the blog (https://stackblitz.com/edit/stackblitz-starters-cklnkm)
those links could have done this instead of needing to create a separate
directive that tracks clicks.
PR Close#53784
This commit removes a hack that deletes `Event` from the global context
when using domino. Instead, it sets the global event to domino's
implementation of `Event`.
PR Close#53659
Instead of computing the bit input flags at compile-time and inling
the final bit flag number, we will use the `InputFlags` enum directly.
This is a little more code in the compiler side, but will allow us to
have better debuggable development code, and also prevents problems
where runtime flag bitmasks differ from the compiler flag bitmasks.
This is in practice a noop for optimized applications as the enum values
would be inlined anyway. This matches existing compiler emit for e.g.
change detection strategy, or view encapsulation enums.
PR Close#53571
The linker compliance tests were disabled with a Babel update and
nobody realized for quite a while, via
https://github.com/angular/angular/pull/49914.
As we've came across this lost coverage, which also is quite
impactful as all libraries depend on linked output- I've took initiative
to debug the root cause as there was no follow-up.
https://github.com/angular/angular/issues/51647.
It turned out to be a highly complex issue that is non-trivial to fix,
but at least we should try to resurrect the significant portion of test
coverage by still running the linker tests- avoiding regressions, or
unexpected issues (like with defer being developed). We can work on
re-enabling and fixing source-maps separately.
Tracked via https://github.com/angular/angular/issues/51647.
PR Close#53571
The linker compliance tests did not run for a while. There were a couple
of new tests that were not passing as this wasn't flagged on CI. This commit fixes this.
Fortunately there was no problematic code that did indicate issues with linking.
In the follow-up commit, we fix the compliance test infrastructure to
re-enable linker testing..
One clear issue is still that the defer blocks are not handled properly
in linked output- hence making defer not actually "lazy" for compiled
libraries. This needs to be handled separately by the framework team.
PR Close#53571
This commit adds a final test for input signals, integrating all major
parts:
* type-checking
* compiler detection
* compiler emit
* API signature tests
PR Close#53571
Adds tests that allow us to ensure that the `input` API works as
expected and that resulting return types match our expectations- without
silently regressing in the future, or missing potential edge-cases.
Testing signatures is hard because of covariance and contravariance,
especially when it comes to the different semantics of `ReadT` and
`WriteT` of input signals. We enable reliable testing by validating the
`d.ts` of the "fake directive class". This ensures clear results,
compared to relying on e.g. type assertions that might
accidentally/silently pass due to covariance/contravariance or
biavariance in the type system.
PR Close#53571
Consider a snippet like:
```
const x = directiveDef.inputs || EMPTY_OBJ
```
this currently results in `x` being inferred as just `{}`- ending up
turning of potential future assignment checks. This surfaced in the
`DirectiveDefinition` -> `DirectiveDef` conversion.
Note: This has the effect that assigning `EMPTY_OBJ` to a field of
anything would _always_ pass. It's questionable if this rather impacts
type-safety in a more negative way. There seem to be trade-offs in both
ways... Maybe worth considering just using `{}` directly as fallbacks in
some places, and treating this as an unique symbol?!
https://www.typescriptlang.org/play?#code/MYewdgzgLgBAHgLhmApgNxQJxgXhgbwF8YBDCZdLAbgCgbRJYAHJfGmDmAGxC6SkwBXFABoahAD6CwAExQAzAJaoZuZIK5dS5EmACeteuGgxBapjAkT4VIA
PR Close#53571
This commit introduces a new enum for capturing additional metadata
about inputs. Called `InputFlags`. These will be built up at compile
time and then propagated into the runtime logic, in a way that does
not require additional lookup dictionaries data structures, or
additional memory allocations for "common inputs" that do not have any flags.
The flags will incorporate information on whether an input is signal
based. This can then be used to avoid megamorphic accesses when such
input is set- as we'd not need to check the input field value. This also
avoids cases where an input signal may be used as initial value for an
input (as we'd not incorrectly detect the input as a signal input then).
The new metadata emit will be useful for incorporating additional
metadata for inputs, such as whether they are required etc (although
required inputs are a build-time only construct right now- but this is a
good illustration of why input flags can be useful). An alternative
could have been to have an additional boolean entry for signal inputs,
but allocating a number with more flexible input flags seems more future
proof and more reasonable andreadable.
More information on the megamorphic access when updating an input
signal
https://docs.google.com/document/d/1FpnFruviKb6BFTQfMAP2AMEqEB0FI7z-3mT_qm7lzX8/edit.
PR Close#53571
Currently when a base class defines an input with a transform, derived
classes re-defining the input via `@Input`, or `inputs: [<..>]`, end up
inherting the transform due to a bug in the inherit definitions feature.
This commit fixes this. We verified in the Google codebase that this is
an unlikely occurrence and it's trivial to fix on user side by removing
the re-declaration/override, or explictly adding the necessary
transform.
Conceptually, the behavior was quite inconsistent as everything else of
inputs was overridden as expected. i.e. alias, required state etc. The
exception were input transforms. This commit fixes this.
PR Close#53571
At this point, we have the following pieces in place:
* the input signature is implemented
* the compiler properly parses and recognizes signal inputs
* the compiler supports type-checking of signal inputs
* input signal metadata is passed to partial output
This commit adds a naive runtime solution to distinguishing between
signal inputs and decorator inputs when the `property` instruction
invokes. This is not ideal and non-performant as we introduce additional
megamorphic reads for every property instruction invocation, or if we'd
use `instanceof`, introducing a hard dependency on `InputSignal` and
risking potentially slower detection.
This code exists purely for testing, to enable playing with input
signals in the playground. In a future commit, we will pass around the
input signal metadata at runtime and can perform highly optimized checks
to distinguish between signal or non-signal inputs- when assigning
values.
More information: https://docs.google.com/document/d/1FpnFruviKb6BFTQfMAP2AMEqEB0FI7z-3mT_qm7lzX8/edit#heading=h.oloxympe902x
PR Close#53571
This commit introduces the runtime `InputSignal` implementation.
Input initializers using `input` or `input.required` will result in
an instance of `InputSignal` to be created.
An input signal extends the signal primtive, with a couple of small
differences:
- it's a readonly signal. There is no public `set` or `update`.
- equality is non-configurable. As per CD semantics, the value is
guaranteed to be different when the `property` instruction attempts
to update an input signal.
- we support a `transform` function, that allows transforming input
values. The transform is called whenever the input is set. An
alternative could have been to follow computed-semantics and call the
transform upon accessing, if dirty.
In the future, we might change this to extend the computed reactive
node, so that we can support computed inputs that do not rely on
continious bound value assignments. See signal based components RFC.
PR Close#53571
For the implementation of input signals, we want to extend the signal
primitive. The basic methods exposed here are not suitable as we'd like
to store additional metadata on the reactive node, and also have a
custom getter (for required inputs and throwing).
To enable this, one small piece was missing. This commit exposes it and
also improves type safety, now that `SignalNode` is typed properly after
the previous commit.
PR Close#53571
The `SignalNode` interface, describing the reactive node for a `Signal`,
seemingly exposes the `SIGNAL` symbol as a class member. This is not
true as the `SIGNAL` reactive node only exists on the getter function,
as a way to retrieve the signal underlying reactive node.
This commit fixes this, enabling improved type-safety later, in a
follow-up commit where `SIGNAL_NODE` can now be typed to match the
`SignalNode` interface (unlike now where it's typed as just `object`).
PR Close#53571
This commit adds additional type-check transform tests for signal
inputs. These tests verify some of the problems with covariance,
contravariance and bivariance that we were suspecting to be problematic
if we would assign `InputSignal`'s directly to the type constructors.
PR Close#53571
This flag is not actually read anywhere. It doesn't even have any effect
on the traversal algorithm because embedded views are always refreshed
in `Global` traversal mode during the refresh of their parent views.
PR Close#53715
The `ComponentFixture` code needlessly dances around the `ngZone` being
`null` when the `ComponentFixtureNoNgZone` option is set. Instead, it
can use the `NoopNgZone` to get the same effect without needing to have
checks all over the place for its presence.
PR Close#53670
In #52931, Kristiyan fixed a TemplateDefinitionBuilder bug in which derived alias variables in for loops (`$even`, `$first`, etc) were referring to the wrong level of nested `@for` block. (These variables are unique because they become inlined expressions, and are not "real" context variables.) He fixed this by appending level information to the generated alias name.
Template Pipeline actually suffered from the same bug. We fix it in a very similar way -- in particular, whenever these derived context variables are used, we make them depend on versions of `$index` and `$count` that have been suffixed with the xref of the enclosing repeater.
I have added a few more pipeline goldens, because we are not quite as clever as TDB about only generating the duplicate suffixed index and count variables when inside nested loops. This is fine, since in the long run, we want to refactor it more fundamentally.
I have also added a TODO to fix this more rigorously. In particular, it would be nice if we had proper support for shadowed variables, as well as unlimited levels of variables depending on one another.
PR Close#53662
Template pipeline previously mangled CSS property names like
`--camelCase` when used in host style bindings. Note: It still *does*
mangle these names in static style attrs, both in host bindings and on
elements. This is clearly wrong, but is consistent with what TDB does
today.
PR Close#53665
Currently compiling input transform in local mode breaks, since compiler does static analysis for the transform function, and this cannot be done in local mode if the function is imported from another compilation unit. In this fix the static analysis is ditched in local mode.
PR Close#53645
Fixes that the `BrowserViewportScroller` was throwing an error during server-side rendering because it was accessing `window` directly. Also removes some assertions that aren't necessary anymore.
Fixes#53682.
PR Close#53683
The diagnostic was catching the following case:
```ts
name = signal('Angular');
```
but not the following ones:
```ts
name = signal('Angular').asReadonly();
name = computed(() => 'Angular');
name!: Signal<string>
```
This was not catched in the tests because the type of `Signal` is different than the one actually used in core.
It turns out the real type forces the diagnostic to check both the `symbol.tsType.symbol` and the `symbol.tsType.aliasSymbol`.
PR Close#53585
It's possible for attributes to have a namespace, we need to handle this
possiblity for both attribute instructions and attributes extracted to
the consts array.
PR Close#53646
`effect` was expecting an `ErrorHandler` in its constructor which can lead to a circular DI error if an effect is used inside a custom `ErrorHandler`. These changes inject the `ErrorHandler` only when reporting errors.
Fixes#52680.
PR Close#53713
Use of the `SpyLocation` is problematic because it prevents location
APIs from reaching the platform level (`PlatformLocation`) and
`PathLocationStrategy`. This makes it difficult to test interactions
with those providers, including the ability to use the `Navigation` API,
which will live at the platform level.
PR Close#53640
In order to provide a reasonable experience for Angular without Zones,
we need a mechanism to run change detection when we receive a change
notification. There are several existing APIs today that serve as the
change notification: `ChangeDetectorRef.markForCheck`, signal updates,
event listeners (since they mark the view dirty), and attaching a view to
either the `ApplicationRef` or `ChangeDetectorRef`. These operations
are now paired with a notification to the change detection scheduler.
The concrete implementation for this scheduler is still being designed.
However, this gives us a starting point to partner with teams to
experiment with what that might look like.
PR Close#53499
The way we were handling ICU placeholders was not compatible with using
interpolations on attributes of elements inside the ICU. This change
refactors the handling of ICU placeholders and unifies the way
expression and tag placeholders work inside ICUs.
The new approach modifies the ingest logic to add the placeholder on to
the TextOp rather than the TextInterpolationOp. This is because, in
ICUs, we may need multiple i18n expressions created from the
interpolation expressions to roll up into the same placeholder. ICUs
essentially do the interpolation at compile time, combining the static
strings with special placeholder strings that represent the expression
values.
PR Close#53643
Consider a case when an explicit `this` read is inside a template with a context that also provides the variable name being read:
```
<ng-template let-a>{{this.a}}</ng-template>
```
Clearly, `this.a` should refer to the class property `a`. However, in today's Angular, `this.a` will refer to `let-a` on the template context.
Amazingly, both TemplateDefinitionBuilder and the Typecheck block have the same bug, and are consistent with each other! This is because `ImplicitReceiver` extends `ThisReceiver` in the parser AST, which is an insane gotcha.
In this commit, I patch the template pipeline to emulate this behavior as well.
To actually fix this nastiness, we have to:
- Update `ingest.ts` in the Template Pipeline (see the corresponding comment)
- Check `type_check_block.ts` in the Typecheck block code (see the corresponding comment)
- Turn off legacy TemplateDefinitionBuilder
- Fix g3, and release in a major version
PR Close#53594
`ng-content` elements, and thus their corresponding projection instructions, can have many attributes on them. Some of these attributes may result in special behavior. For example, `ngProjectAs` and `i18n-foo` both result in special const collection, into the approprate BindingKind slot in the const array. Additionally, `i18n-foo` needs to recieve all the additional i18n attribute processing.
We solve this by subjecting `ng-content` attributes to all the same pipeline logic that applies to attributes on elements, and then allow the element const collection phase to collect them.
PR Close#53594
For regular templates, any listener will have its name const collected into the bindings section of the element consts.
In contrast, host bindings omit listener names from their hostAttrs. This is a strange and inconsistent behavior, so we hide it behind a compatiblity mode flag.
PR Close#53594
We has some special behavior for naming identifiers in Template Pipline, for the sake of compatibility with TDB's source maps tests. However, this has the potential to cause a variable name collision in a particular special case (when the identifier is `ctx`). We add a special check for this, and also tuck all the backwards-compatible naming code inside a compatibility block.
PR Close#53594
This commit updates the `ApplicationRef.isStable` implementation to use
a single `Observable` to manage the state. This simplifies the mental
model quite a bit and removes the need for rx operators like
`distinctUntilChanged` and `combineLatest`.
PR Close#53576
The formatting that would preserve attribute indents completely missed attributes that start on new lines rather than the same line as the opening element.
PR Close#53636
In cases where CommonModule was unsafe to remove but other imports were present, the symbol check would be skipped. This should run for all the possibly removed symbols for safety.
PR Close#53637
When an application does not use zones, it does not need a default value
for the zone stableness token. This will allow zoneless applications to
tree-shake a lot of rxjs operators out of `ApplicationRef`.
Note that at the moment, `provideZoneChangeDetection` is included in all
applications as well as the `TestBed` environment. It is not currently
possible to remove the zone stable code as a result. This will be
possible only when we make zones an opt-in rather than opt-out.
PR Close#53505
The InitialRenderPendingTasks currently attempts to only contribute to
ApplicationRef stableness one time to support SSR. This isn't actually
how the switchMap works in reality. This commit updates
the isStable observable to be more clear that it's always a combination
of the zone stableness and pending tasks.
In addition, this commit renames the service to just be PendingTasks
because it doesn't directly relate to rendering. While the purpose is
to track things that might cause rendering to happen, we don't know if the
tasks will affect rendering at all.
PR Close#53534
During formatting, attribute indentation is changed, and that can affect internationalized strings. This fix detects if an attribute value string is left open and skips formatting on those lines.
PR Close#53625
It's possible for the user to create a host attrbiute binding with a
name that makes it _look_ like a class binding `{['class.foo']: ''}`, we
were previously treating these as actual class property bindings. This
change fixes the logic so that only true property bindings cam be
converted to class property bindings.
Note: A user who added an attribute like the above almost certainly
intended to create an actual class property binding. It would be nice if
we could add a diagnostic to warn them about this.
PR Close#53626
Further refine the template pipeline's behavior w.r.t. duplicate values
in the consts array to better align its behavior with TDB. In particular
this means allowing duplicate values for classes and styles.
PR Close#53596
Adds a test for handling of duplicate bindings. Fow now we replicate the
TDB behavior in template pipeline, which is: For style and class text
attributes, only keep the last one. For all other text attributes, add
all of the values to the consts array.
PR Close#53596
The for loop tracking function doesn't allow references to local template variables, aside from `$index` and the item which are passed in as parameters. We enforce this by rewriting all variable references to the components scope.
The problem is that the logic that rewrites the references first walks the view tree and then checks if the variable is `$index` or the item. This is problematic in nested for loops, because it'll find the `$index` of the parent.
These changes resolve the issue by checking for `$index` and the item first.
Fixes#53600.
PR Close#53604
Core bundles were retaining the `Version` class and `VERSION` constant, because we stamp out the current version in the DOM. This shouldn't be necessary, because any usage of `0.0.0-PLACEHOLDER` will be replaced with the current version at build time. These changes remove the reference so it can be tree shaken away.
PR Close#53598
Changes template pipeline to be less aggressive in const collecting
attrs, to match the behavior of template definition builder. There is
nothing wrong with the more aggressive const collection, and in fact it
would be good to re-enable it later, but for now this makes it easier to
transition from TDB to template pipeline.
Also adds a test to verify that sensitive iframe attributes are properly
validated.
PR Close#53580
The version of rxjs used to build the repository has been updated to v7.
This required only minimal changes to the code. Most of which were type
related only due to more strict types in v7. The behavior in those cases
was left intact. The most common type related change was to handle the
possibility of `undefined` with `toPromise` which was always possible with
v6 but the types did not reflect the runtime behavior. The one change that
was not type related was to provide a parameter value to the `defaultIfEmpty`
operator. It no longer defaults to a value of `null` if no default is provided.
To provide the same behavior the value of `null` is now passed to the operator.
PR Close#53500
fetch support AbortSignal, zone.js schedules a macroTask when fetch()
```
fetch(..., {signal: abortSignal});
```
we should also be able to cancel fetch with `zoneTask.cancel` call.
So this commit create an internal AbortSignal to handle
`zoneTask.cancel()` call and also delegate the `options.signal` from the
user code.
PR Close#49595
Close#49591
```
const ac = new AbortController();
addEventListener(eventName, handler, {signal: ac.signal);`
ac.abort();
```
Currently `zone.js` doesn't support the `signal` option, this PR allows
the user to use AbortContoller to remove the event listener.
PR Close#49595
This addresses the case where modules are being used and declared in the same file as the component. It is unclear whether its safe to remove the common module in this case, so best to leave it.
PR Close#53575
TemplateDefinitionBuilder is apparently more careful about when it attempts to split namespaces in attribute values. However, we are doing this on style attributes, which might start with a single `:`. Rather than refactor our logic to only try to split namespaces in some cases, we can just add an option to make namespace splitting fail gracefully. We only use this option for attributes, not elements.
Note also: the compiled code for this, while "correct" is absolutely insane. Maybe we should consider fixing this, as a matter of principle.
PR Close#53574
Some elements may have multiple bindings with the same name. We should accept and emit them all, as long as they have different kinds.
Co-authored-by: Miles Malerba <mmalerba@users.noreply.github.com>
PR Close#53574
The template pipeline was previously not reserving a variable slot for the result of the `deferWhen` instruction, which caused the `defer when` feature to crash at runtime.
PR Close#53574
When an element is self-closing, it will cause an `element` instruction to be emitted (instead of `elementStart`/`elementEnd`). In that case, we should use map whole source span for the instruction, not just the starting span.
PR Close#53574
The template pipeline was producing slightly different names than TemplateDefinitionBuilder for defer deps functions. I have added a workaround in the name of backwards compatibility, to avoid suffixing the const pool function names.
PR Close#53574
Previously when we found an ICU that was the only translatable content
in its i18n block, we assigned the block's i18n context to the ICU.
However, we neglected to set the contextKind to inidcate that the
context was associated with an ICU. As of this change we now set the
correct contextKind.
This change also refactors the context creation to explicitly separate
creation of contexts for attributes, root i18n blocks, child i18n
blocks, and ICUs. This allows us to more easily ensure that contexts are
shared appropriately between i18n blocks and ICUs.
Finally, this change also refactors the i18n message extraction pahse to
simplify how contexts are converted to i18n messages. This
simplification should make it easier to merge i18n contexts and i18n
messages into a single op in a future refactor.
PR Close#53557
When a view has the `Dirty` flag and is reattached, we should ensure that it is
reached and refreshed during the next change detection run from above.
In addition, when a view is created and attached, we should ensure that it is reached
and refreshed during change detection. This can happen if the view is
created and attached outside a change run or when it is created and
attached after its insertion view was already checked. In both cases, we
should ensure that the view is reached and refreshed during either the
current change detection or the next one (if change detection is not
already running).
We can achieve this by creating all views with the `Dirty` flag set.
However, this does happen to be a breaking change in some scenarios.
The one identified internally was actually depending on change detection
_not_ running immediately because it relied on an input value that was
set using `ngModel`. Because `ngModel` sets its value in a `Promise`, it
is not available until the _next_ change detection cycle. Ensuring
created views run in the current change change detection will result in
different behavior in this case.
Making option the default is the solution to #52928. That will have to
wait for a major version.
PR Close#53022
Whenever an input of a directive changes, the semantic symbol should
reflect this change for the type check API. This is important because
signal inputs require special output in the type checking blocks- hence
we need to ensure that such type checking blocks are re-generated
properly.
Test verify that incremental type-checking builds work as expected now.
PR Close#53521
Whenever a signal input is captured in a type check block, we will
insert an import. This will change the import graph so that the full
TypeScript program cannot be structurally re-used.
We can fix this trivially by ensuring the import graph remains stable,
by always generating an import to e.g. `@angular/core`. This fixes the
issue nicely for type-check block files. A test verifies this.
For inline code, such as TCB inline or the type constructors inline,
this fix is not applicable because we would change user-input source files,
adding new edges that would not exist for subsequent builds- causing the
program to be not re-used completely. One idea was to rely on the
existing edge that can be assumed to exist for directive code files.
This is true technically, but in practice TS does not deduplicate
imports- so our new namespace import when referencing our symbols will
invalidate the re-use. We will address this in a follow-up. There are a
couple of options, such as working with the TS team, updating the
existing edge, or inlining our helpers as well.
PR Close#53521
This commit adds the last remaining piece for signal input
type-checking. Bound values to signal inputs are already checked
properly at this point, but inference of generic directive/component
types through their inputs is not implemented.
This commit fixes this. To achieve this, there are a couple of potential
solutions. The generics of a directive are inferred based on input
value expressions using a so-called type constructor. The constructor
looks something like this:
```
const _ctor = <T>(v: Pick<Dir<T>, 'input1', 'input2'>) => Dir<T>;
_ctor({input1: expr1, input2: expr2});
```
This works very well for non-signal inputs where the class member is
directly holding the input values. For signal inputs, this does NOT
work because the class member will actually hold the `InputSignal`
instance. There are a couple of solutions to this:
1. Calling `_ctor` with an `InputSignal<typeof value>`
2. Converting the `_ctor` input signal fields to their write types
(unwrapping the input signals).
We've decided to go with the second option as TypeScript is very
sensitive with assignments and its checks. i.e. co-variance,
contravariance or bivariance. Semantically it makes more sense to unwrap
the input signal "write type" directly and "assign to it". This is safer
and conceptually also easier to follow. A type constructor continues to
only receive the "expresison values". This simplifies code as well.
It's worth noting that the unwrapping as per option 2 also comes at a
cost. We need to be able to generate imports in type constructors. This
was not possible until the previous commit because inline type constructors
did not have an associated type-check block `Environment` and we were
missing access to expression translation and correct import generation.
Overall, solution 2 is now implemented as works as expected. This commit
adds additional unit tests to ensure this.
PR Close#53521
For signal inputs we are looking at generating additional code inside
type constructors. This code is planned to reference an external type
from `@angular/core` to unwrap `InputSignal`'s class fields.
The existing `Environment` class contains helpers for emitting such
references / and translating them from the output AST. We extract
this logic into a superclass for only emitting references. A similar
type already existed to avoid circular dependencies- but now we have
actual use-cases to populate this as a base class.
This allows us to create more-suitable minimal emit environments
when we e.g. generate type constructors inline- which are not
part of any type check block. The existing `Environment` class is scoped
to type check blocks and therefore was not suitable.
PR Close#53521
Signal inputs do not need coercion members for their transforms. That is
because the `InputSignal` type- which is accessible in the class member-
already holds the type of potential "write values". This eliminates the
need for coercion members which were simply used to somehow capture this
write type (especially when libraries are consumed and only `.d.ts` is
available).
We can simplify this, and also significantlky loosen restrictions
of transform functions- given that we can fully rely on TypeScript for
inferring the type. There is no requirement in being able to
"transplant" the type into different places- hence also allowing
supporting transform functions with generics, or overloads.
In a follow-up commit, once more parts are place, there will be some
compliance tests to ensure these new "loosend restrictions".
PR Close#53521
This commit ensures that the type-check diagnostic testing
infrastructure is prepared to validate signal inputs. i.e. providing the
necessary "mocks" in the fake "d.ts" of `@angular/core`.
The commit then sets up a Golang-style table driven testing environment
that allows us to validate/verify signal input type-checking in a
readable way.
With this infrastructure set up, this commit defines an initial set
of unit tests for type checking of input signals.
PR Close#53521
This commit introduces the initial type-checking for signal inputs.
To enable type-checking od signal inputs, there are a couple of tricks
needed. It's not trivial as it would look like at first glance.
Initial attempts could have been to generate additional statements in
type-checking blocks for signal inputs to simply call a method like
`InputSignal#applyNewValue`. This would seem natural, as it would match
what will happen at runtime, but this would break the language-service
auto completion in a highly subtle way. Consider the case where multiple
directives match the same input. Consider the directives have some
overlap in accepted input values, but they also have distinct diverging
values, like:
```ts
class DirA {
value = input<'apple'|'shared'>();
}
class DirB {
value = input<'orange'|'shared'>();
}
```
In such cases, auto completion for the binding expression should suggest
the following values: `apple`, `shared`, `orange` and `undefined`.
The language service achieves this by getting completions in the
type-check block where the user expression would live. This BREAKS if
we'd have multiple places where the expression from the user is used.
Two different places, or more, surface additional problems with
diagnostic collection. Previously diagnostics would surface the union
type of allowed values, but with multiple places, we'd have to work with
potentially 1+ diagnostics. This is non-ideal.
Another important consideration is test coverage. It might sound
problematic to consider the existing test infrastructure as relevant,
but in practice, we have thousands of diagnostic type check block tests
that would greatly benefit if the general emit structure would still
match conceptually. This is another bonus argument on why changing the
way inputs are applied is probably an option we should consider as a
last resort.
Ultimately, there is a good solution where we unwrap directive signal
inputs, based on metadata, and access a brand type field on the
`InputSignal`. This ensures auto-completion continues to work as is, and
also the structure of type check blocks doesn't change conceptually. In
future commits we also need to handle type-inference for generic signal
inputs.
Note: Another alternative considered, in terms of using metadata or not.
We could have type helpers to unwrap signal inputs using type helpers
like: `T extends InputSignal<any, WriteT> ? WriteT : T`. This would
allow us to drop the input signal metadata dependency, but in reality,
this has a few issues:
- users might have `@Input`'s passing around `InputSignal`'s. This is
unlikely, but shows that the solution would not be fully correct.
- we need the metadata regardless, as we plan on accessing it at runtime
as well, to distinguish between signal inputs and normal inputs when
applying new values. This was not clear when this option was
considered initially.
PR Close#53521
This commit captures the metadata on whether an input is signal based or
not, in the `.d.ts` of directives and components. This exposes this
information to consumers of the directives. This is needed because
libraries may use signal inputs, and we need to know whether bound
inputs to this library are signal-based or not- so that we can generate
proper type-checking code (account for `InputSignal` or not).
Additionally, this commit introduces a new structure for the partial
compilation output of directive inputs. With the current emit, inputs
are captured in a data structure that is equivalent to the internal data
structure passed to `defineDirective` (the full compilation output).
This worked fine as we only captured a few strings, but in ends up
being a bad practice because partial compilation output should NOT
capture internal data structures that might be specific to a certian
Angular core version. Instead, we introduce a new "future proof"
structure that:
- can hold additional metadata in backwards-compatible ways, like
`isSignal` or `isRequired`.
- can be parsed trivially using the `AstHost` for the linker, instead of
having to unwrap/parse an array structure.
The new structure is only emitted when we discover that some inputs are
signal based (or ultimately end up configuring input flags). This is
done for backwards compatibility, so that libraries without signal
inputs remain compatible with older linker versions. In the future,
this might be the only emit.
Compliance tests for this follow in future commits, when the linker
portion is also in place. This commit specialices on the code
generation. With the linker, and compliance test infrastructure fixed
(that is broken right now), we can test the full integration.
PR Close#53521
When working on integrating a new metadata field for inputs, I realized
there are quite a lot of duplications of interfaces. Turns out, the
facade input map type can be replaced in favor of just
`R3DirectiveInput`- even improving type safety-ness of e.g. the wrapped
node expressions of transform functions.
PR Close#53521
This commit defines the initial metadata for inputs passed around in
the compiler-cli. Inputs will now capture additional metadata on whether
they are signal-based or not. This is stored on a per-input basis as
a Zone component may contain both, signal inputs or `@Input` inputs.
The metadata is later used for type-checking, for partial output
generation, or full compilation output generation.
PR Close#53521
This commit introduces a function for declaring inputs in
components. The function is called `input`. It comes in two flavors:
- `input` for optional inputs with initial values
- `input.required` for required inputs
Inputs are declared as class members, like with `@Input`- except that
the class field will no longer hold the input value directly. Angular
takes control over the input field and exposes the input value as a
signal. The runtime implementation will follow in future commits.
This commit simply introduces:
- initial compiler detection to recognize such inputs in classes
- the initial signature of `input` and `input.required`.
Note: the defer size test is flawed and there is no minification- hence
this commit also needs to incorporate the new dependency graph changes.
PR Close#53521
The behavior of `ApplicationRef.isStable` changed in 16.1 due to
28c68f709c.
This change added a `share` to the `isStable` observable, which prevents
additional subscribers from getting a value until a new one emits. One
solution to the problem would be `shareReplay(1)`. However, that would
increase the bundle size since we do not use `shareReplay` elsewhere.
Instead, we don't even really need to share the observable.
The `Observable` available in `ApplicationRef.isStable` before the above commit
was the zone stable observable, without a `share`. The new behavior adds
only an additional observable to the stream, `hasPendingTasks` (a `BehaviorSubject`).
The observables in this stream are not expensive to subscribe to. The
only one with side effects is the `isStable` (because it subscribes to
onStable), but that one already has the `share` operator on it.
Omitting the `share` in `ApplicationRef` also means that applications on `zoneless` will not
have to pay the cost of the operator when we make zones optional because
the zone stable observable is the only place we use it.
PR Close#53541
Internationalization is whitespace sensitive. This change updates the formatting code to process for i18n attributes and prevent reformatting those sections of the template.
PR Close#53538
Using http://a as the base URL returns / instead of the actual base path when using the file:// protocol. Using document.baseURI addresses this.
Fixes#53546
PR Close#53547
This commit updates the name of the 'performance.mark'
counter used to track feature usage. It now matches
the name agreed upon by W3C for this use case:
https://github.com/w3c/user-timing/pull/108
PR Close#53542
This fix handles the common case where an ngswitch might have invalid syntax post migration. This is likely due to using elements other than case or default underneath the ngswitchcase. This will fail out of the migration for that file when these cases are detected with a useful console message.
fixes: #53234
PR Close#53530
In the case that a template has some sort of structural issue prior to migrating, like a tag that is not properly closed resulting in invalid HTML post migration, this will attempt to parse the html after migrating and revert to the original structure. An error during migration will be reported out instead.
PR Close#53530
`o.WrappedNodeExpr` can show up in some cases, when a host binding's value is inside a TS expression.
It's an open question whether we will need to support all of the TS expression types as a result.
PR Close#53478
For some reason, the parser reuses the same field to store the animation phase and the event target. We were incorrectly interpreting the presence of any value on that field as an animation phase, leading us to incorrectly emit synthetic listener instructions for listeners on events with targets. This bug is now fixes.
PR Close#53478
`$any` should be interpreted as a cast, not as a context read of a variable called `$any`. This already worked in template compilations, but the relevant phase was not enabled for host bindings.
PR Close#53478
Fixes that the compiler was throwing an error if an ambient type is used inside of an input `transform` function. The problem was that the reference emitter was trying to write a reference to the ambient type's source file which isn't necessary.
Fixes#51424.
PR Close#51474
Prior to this commit when a route is not matched and the application was running in production mode an `[Error]: NG04002` was logged in the console. This however, is not actionable when the application is running on the server where there can be multiple pages being rendered at the same time.
Now we change this to also log the route example: `[Error]: NG04002: 'products/Jeep'`.
Closes#53522
PR Close#53523
The ops for the implicit variables in `@for` loops (e.g. `$index`) are marked as being mandatory which means that they're generated even if they aren't used. These changes make them optional so they're only added when necessary.
PR Close#53515
Adds support for sanitizing host bindings. Since the tag name of the
element the host binding is being set on isn't always known, we have to
consider multiple possible security contexts.
This commit also adds additional tests to help verify correct behavior
of the sanitization logic for different edge cases.
PR Close#53513
The formatting logic would eliminate all newlines in updated template code. This adds start and end markers for tracking when the formatter is in a block of template code that changed or not. It should leave behind any newlines that are outside of a migrated section.
fixes: #53494
PR Close#53508
When migrating a component and the associated external template, if errors occur, the component should not remove the common module imports. This fix should allow the application to still build in that instance.
PR Close#53502
The `nodejs-websocket` package has been replace with the `ws` package.
Both provide `WebSocket` server support and both of zero transitive
dependencies. However, the `ws` package has ~78 million weekly downloads
and was last updated this week (as of the writing of this commit) while
the `nodejs-websocket` package has ~7,600 weekly downloads and was last
update 5 years ago. The `ws` package is also already a transitive dependency
of the repository which allows for a reduction in the total dependency count
for the repository.
PR Close#53482
Previously we generated an intermediate expression which was later
converted into a symbol import expression for the sanitizer function.
This commit simplifies the behavior by just generating the symbol import
from the beginning
PR Close#53473
Use the DomElementSchemaRegistry to determine the correct security
context for static attributes, and pass it along during ingestion. Then
during the resolve sanitizers phase, use the security context to
determine if a trusted value function is needed
PR Close#53473
The changes Observable (impl: EventEmitter) on the QueryList is initalized
lazy - it is created only if someone calls a geter to get a hand on its
instance. But the destroy method was calling this getter thus creating
a new Observable even if no one subscribed to it.
This commit changes the destroy logic to skip creation of an EventEmitter
if it wasn't initialized.
PR Close#53498
The `base64-js` package was only used in tests that were run only on
Node.js. On Node.js, `Buffer` is available which can natively perform
base64 conversion. By using `Buffer in these Node.js only tests, the
`base64-js` package can be removed from the repository.
PR Close#53464
Consider the case:
```
<button *ngIf="true" [@anim]="field"></button>
```
Only the inner `button` should recieve a `property` instruction for the animation binding. We were previously emitting one for the implicit `ng-template` as well, and collecting it into the consts for the `ng-template`. Both of these issues are now fixed.
PR Close#53457
The behavior of explicit bindings on `ng-template`s was untested, and we differed from `TemplateDefinitionBuilder` significantly. We now have much more similar behavior, although not 100% identical.
For example, consider this templarte:
```
<ng-template l="l1" [p]="p1" [attr.a]="a1" [class.c]="c1"></ng-template>
```
It's not clear what a class binding on an `ng-template` would actually do. Nonetheless, it's well-defined behavior in TemplateDefinitionBuilder, which emits `property` instructions for all three bindings, and people actually do this in google3.
Note that some of these bindings don't really make much sense, but we have to support them for compatibility purposes.
See comments for an in-depth explanation of all the logic.
Also, add a test to exercise the problematic case.
PR Close#53457
It turns out that `BindingFlags.BindingTargetsTemplate` is actally a redundant property! It will be true in either of the following cases:
1. The template is a normal non-structural `ng-template`. We already know this from `TemplateKind`.
2. The binding came from `templateAttrs` (instead of `attrs`). We have this information in `BindingFlags.IsStructuralTemplateAttribute`.
Therefore, I can just eliminate `BindingFlags.BindingTargetsTemplate`. There's no reason to keep `BindingFlags` around for a single value, so I convert `BindingFlags.IsStructuralTemplateAttribute` to a boolean parameter (with the eventual goal of eliminating it entirely).
Additionally, because element binding ingestion now calls `ir.createBindingOp` inline, it was difficult to compare it to template binding ingestion, which uses the `createTemplateBinding` helper. I have changed the parameter order of `createTemplateBinding` to closely mimic `ir.createBindingOp`. This will both make the code easier to read, and allow me to easily replace one with the other in the future.
Lastly: the template binding ingestion function is the site of much of the binding ingestion complexity. Add an explanatory function comment.
PR Close#53457
Previously, we had `ingestBindings` and `ingestBinding`, which required tons of cases to support both elements and templates.
Now, we have two separate functions, `ingestElementBindings` and `ingestTemplateBindings`.
Thanks to the previous refactoring work, `ingestBinding` is now extremely compact. In fact, it's so compact that, in the elements case, it can just be inlined! Therefore, element binding ingestion is now quite easy to read.
The template case continues to be pretty gnarly, although I have already removed some code. In subsequent commits, we will simplify it even further.
PR Close#53457
Currently Template Pipeline's ingest phase is very complex, especially when it comes to ingesting bindings.
In this commit, we make some superficial simplifications, in preparation for a larger refactoring. For example, we pull out common code such as `convertAstWithInterpolation` and the `i18n.Message` checks. This enormously shrinks the main binding ingestion functions.
In addition, we reorder the binding kind and flags code above `ingestBindings`, so that `ingestBindings` and `ingestBinding` can be viewed together.
PR Close#53457
The Template Pipeline has had a number of tricky bugs involving bindings on structural elements.
Consider this template:
```
<div *ngIf="true" [class.bar]="field"></div>
```
We were incorrectly emitting `ɵɵclassProp` on *both* the template's view, and the inner view. The solution is to just emit an extracted attribute on the enclosing template, so it still shows up in the const array, but does not affect the update block.
We will refactor binding ingestion soon, but this commit improves our correctness before any big refactor.
PR Close#53457
In the original `Promise` impelmentation, zone.js follow the spec from
https://promisesaplus.com/#point-51.
```
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(p1);
p1 === p2; // false
```
in this case, `p2` should be the same status with `p1` but they are
still different instances.
And for some edge case.
```
class MyPromise extends Promise {
constructor(sub) {
super((res) => res(null));
this.sub = sub;
}
then(onFufilled, onRejected) {
this.sub.then(onFufilled, onRejected);
}
}
const p1 = new Promise(setTimeout(res), 100);
const myP = new MyPromise(p1);
const r = await myP;
r === 1; // false
```
So in the above code, `myP` is not the same instance with `p1`,
and since `myP` is resolved in constructor, so `await myP` will
just pass without waiting for `p1`.
And in the current `tc39` spec here https://tc39.es/ecma262/multipage/control-abstraction-objects.html#sec-promise-resolve
`Promise.resolve(subP)` should return `subP`.
```
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(p1);
p1 === p2; // true
```
So the above `MyPromise` can wait for the `p1` correctly.
PR Close#53423
This change replaces the implementation of the multi-map used to store
detached views while reconciling lists. The new implementation optimizes
memory allocation for such map and avoid arrays allocation when there are
no duplicated keys.
PR Close#52245
The repository currently has two globbing packages. To minimize the number of packages in
the framework repository, the uses of the `glob` package are being converted
to `fast-glob` which is used by the tooling repository. The change is mostly mechanical
and in this change the build and test scripts are converted.
PR Close#53397
These patches are no longer necessary with the current state of the
type packages and the code within the repository. The types are now
included in the already required babel.d.ts file for the relevant
babel packages (currently: `@babel/core` and `@babel/generator`).
PR Close#53441
The `@babel/core` package provides the functionality of multiple other babel packages
without the need to directly depend or import the other babel packages. Since the
`@babel/core` package is already used and imported in the locations that previously
used the other babel packages, an overall reduction in both imports and dependencies
is possible. Six babel related packages were able to be removed from the root `package.json`
and one (also present in the aforementioned six) was removed as a dependency from the
`@angular/localize` package. Unfortunately, the functionality used from the `@babel/generator`
package is not provided by `@babel/core` and is still present. Further refactoring may
allow its removal as well in the future.
The following packages were removed:
* @babel/parser
* @babel/template
* @babel/traverse
* @babel/types
* @types/babel__template
* @types/babel__traverse
PR Close#53441
Phases that walk through the views by following template and repeater
ops need to remember to check the empty view as well for repeaters. This
commit adds fixes for phases that were missing it, or comments
explaining why its not handled.
PR Close#53440
@for does not use actual TemplateOps, but instead has a similar
RepeaterCreateOp. This commit adds support for this op to the relevant
i18n phases.
PR Close#53440
When using ternaries or other expressions in bound if / else cases, it is possible that line breaks could end up affecting template replacement.
fixes: #53428
PR Close#53435
This separates application and platform code into even more files. This now removes
the ciruclar dependency between scheduling and application ref.
PR Close#53371
To support the development of component specific HMR capabilities, the build/serve
tooling may need to directly process styles to match the view encapsulation
expectations of individual components. To allow for this scenario and to avoid tooling
to need to re-implement the emulated encapsulation logic, an private API is now
available in the `@angular/compiler` package named `encapsulateStyle` that converts
a stylesheet content string to an encapsulated form. This function is not considered
part of the public API nor does it have any of its respective support or versioning guarantees.
PR Close#53363
This test actually passes, template pipeline just orders the translated
messages and consts array differently. Since the order isn't important,
we just fork off an alternate golden file for template pipeline.
PR Close#53459
I discovered this failure while looking at presubmit results. We appear to still have ordering issues, when more update ops are present.
PR Close#53405
While running a g3 presubmit, I discovered two related novel failure modes:
1. Simple case: this new test uses an `ngFor` structural directive, which binds a context variable. That variable is immediately used in an attribute binding. It looks like we generate an extra attribute instruction, which might result in an invalid property read at runtime.
2. Complex case: this is another attribute binding, this time on a structural element, inside of an `ng-template`. Not sure what's going on here.
PR Close#53405
Previously, binding ops only knew whether they applied to a structural template (and even this was actually very misleading!).
Now, binding ops have full information about what kind of template they apply to, if any (e.g. plain template, structural template, etc). Additionally, each binding knows whether it `IsStructuralTemplateAttribute`, which is a property of the binding rather than the template target.
In the future, we should refactor this to unify the various flags that can describe binding types, as well as the flags that describe template targets, into a single and comprehensive field on binding ops.
PR Close#53405
Previously, we created i18n contexts for i18n attributes in ingest. This turned out to be the wrong approach, because we don't always want to produce i18n messages for all i18n attributes! In fact, several kinds of i18n attributes on elements with structural directives should not produce their own messages.
This commit also contains related refactors to fix one such structural directives test.
PR Close#53405
When a binding is present on an element with a structural directive, that binding is parsed onto *both* the synthetic `ng-template`, as well as the inner element. However, we do not want to create different i18n messages for both bindings; we only want to generate a new i18n message for the inner, "real" element.
PR Close#53405
Listener instructions should not be inside the i18n block. In order to avoid this, we ingest bindings on an element before starting the i18n block.
We previously missed this case because almost all bindings result in *update* instructions, which don't need to be ordered relative to i18nStart/i18nEnd create instructions. However, listeners are the only kind of binding that gets ingested into the create block.
PR Close#53405
Previously, our i18n slot moving process was buggy. Specifically, it was not resilient to cases in which a create op consumed a slot, but no update ops depended on that slot.
The new algorithm fixes this issue, and is also easier to understand.
PR Close#53405
The PR https://github.com/angular/angular/pull/52465 introduced short-circuit for
the signal equality invocation - with the reasoning that the equality function
should never return false for arguments with the same references. In practice it
turned out that it is rather surprising and the subsequent PR
https://github.com/angular/angular/pull/52532 added a warning when the short-circuit
was taking priority over the equality function.
Still, the presence of the short-circuit prevents people from mutating objects in
place and based on https://github.com/angular/angular/issues/52735 this is a common
and desired scenario. This change removes the short-circuit altogether and thus
fixes the mentioned issue.
We do recognize that removing short-circuit exposes developers to the potentially
surprising logic where mutated in-place change won't be propagated throug the
reactivity graph (due to the deault equality function). But we assume that this might
be less surprising / more desirable as compared to the short-circuit logic.
Fixes#52735
PR Close#53446
This change fixes and issue where the expectation was that change
detection always goes through `detectChangesInView`. In reality,
`detectChangesInternal` directly calls `refreshView`
and refreshes a view directly without checking if it was dirty (to my discontent).
This update changes the implementation of `detectChangesInternal` to
actually be "detect changes" not "force refresh of root view and detect
changes". In addition, it adds the refresh flag to APIs that were
previously calling `detectChangesInternal` so we get the same behavior
as before (host view is forced to refresh).
Note that the use of `RefreshView` instead of `Dirty` is _intentional_
here. The `RefreshView` flag is cleared before refreshing the view while
the `Dirty` flag is cleared at the very end. Using the `Dirty` flag
could have consequences because it is a more long-lasting change to the
view flags. Because `detectChangesInView` will immediately clear the
`RefreshView` flag, this change is much more limited and does not
result in a different set of flags during the view refresh.
PR Close#53021
The component fixture dependencies have to be passed in manually. This
is a bit annoying to manage as we expand which dependencies are needed.
Instead, we can run the constructor in the TestBed injection context and
move the dependencies into the component fixture code, as is done with
other constructors in Angular.
PR Close#53400
These patches are no longer necessary with the current state of the
type packages and the code within the repository. The types are now
included in the already required babel.d.ts file for the relevant
babel packages (currently: `@babel/core` and `@babel/generator`).
PR Close#53374
The `@babel/core` package provides the functionality of multiple other babel packages
without the need to directly depend or import the other babel packages. Since the
`@babel/core` package is already used and imported in the locations that previously
used the other babel packages, an overall reduction in both imports and dependencies
is possible. Six babel related packages were able to be removed from the root `package.json`
and one (also present in the aforementioned six) was removed as a dependency from the
`@angular/localize` package. Unfortunately, the functionality used from the `@babel/generator`
package is not provided by `@babel/core` and is still present. Further refactoring may
allow its removal as well in the future.
The following packages were removed:
* @babel/parser
* @babel/template
* @babel/traverse
* @babel/types
* @types/babel__template
* @types/babel__traverse
PR Close#53374
This commit adds a property to the navigation options to allow
developers to provide transient navigation info that is available for
the duration of the navigation. This information can be retrieved at any
time with `Router.getCurrentNavigation()!.extras.info`. Previously,
developers were forced to either create a service to hold information
like this or put it on the `state` object, which gets persisted to the
session history.
This feature was partially motivated by the [Navigation API](https://github.com/WICG/navigation-api#example-using-info)
and would be something we would want/need to have feature parity if/when the
Router supports managing navigations with that instead of `History`.
PR Close#53303
I18n expressions logically have both a target and an owner:
- For i18n text expressions, the owner is the i18nStart instruction. The target is initially the same, but later moves to be the last slot consumer in the i18n block.
- For i18n attribute expressions, the owner is the I18nAttributes config instruction, whereas the target is the ElementCreate that hosts the attribute.
This refactor makes the code clearer in quite a few plases.
Additionally, we now perform a lot of the i18n processing earlier. For example, re-targeting and re-ordering of i18n expressions happens *before* apply instructions are generated. As a result, the re-ordering logic is a lot simpler.
These changes also have consequences on i18n const collection, along with a couple other minor changes.
PR Close#53376
Using more unique characters makes it easier to parse placeholders that may contain JS logic, making it more flexible.
fixes: #53386fixes: #53385fixes: #53384
PR Close#53394
These changes add an option to the `extendedDiagnostics` field that allows the check from #53190 to be disabled. This is a follow-up based on a recent discussion.
PR Close#53311
If a template is passed in as an input, the ng-template will not exist in the same component template. This will leave a template placeholder behind. This fix ensures that template placeholder gets turned into a template outlet.
fixes: #53361
PR Close#53368
When there are ng-templates nested inside other ng-templates, the replacement and removal of the templates gets disrupted. Re-processing the templates in the file along the way resolves this issue.
fixes: #53362
PR Close#53368
Add support for i18n attributes:
- Generate i18n contexts from i18n attributes, and extract the eventual messages into the constant pool.
- Emit I18nAttributes config instructions when needed.
- Use the generated i18n variable in the appropriate places, including extracted attribute instructions, as well as I18nAttributes config arrays.
PR Close#53341
With the deprecation of the configurable errorHandler in the Router, there is a missing
use-case to prevent the navigation promise from rejecting on an error. This rejection
results in unhandled promise rejections. This commit allows developers to instruct
the router to instead resolve the navigation promise with 'false', which matches
the behavior of other failed navigations.
Resolving the Promise would be the ideal default behavior. It is rare
that any code handles the navigation Promise at all and even more rare
that the Promise rejection is caught. Updating the default value for
this option should be considered for an upcoming major version.
fixes#48902
PR Close#48910
Currently we generate the following TCB for a `@for` loop:
```ts
// @for (item of items; track item) {...}
for (const item of this.items) {
var _t1 = item;
// Do things with `_t1`
}
```
This is problematic if the item name is the same as a global variable (e.g. `document`), because when the TCB has references to that variable (e.g. `document.createElement`), it'll find the loop initializer instead of the global variable.
These changes fix the issue by generating the following instead:
```ts
for (const _t1 of this.items) {
// Do things with `_t1`
}
```
Fixes#53293.
PR Close#53319
In certain cases Angular hydration logic can not rely on the order in which elements are present in a template (for example, in content-projection use-cases) and there is a need to serialize a path from one node to another, so that hydration can locate an element on a page. The logic attempts to use an immediate parent element as an anchor and compute the path from it. If it fails - the path is computed starting from the <body> (this is a fallback).
This commit updates the logic to walk up the parents tree if an immediate parent (from a template) is disconnected from the DOM. This helps to shorten the lookup path and make it more stable.
PR Close#53317
Currently, the link to an error guide is only included into an error message in dev mode. This change makes the `Find more at https://angular.io/errors/NG0XYZ` appear in the error message even in prod mode. Note: the rest of the error message is still tree-shaken away in prod mode (as it happens today).
PR Close#53324
This setting was added to prevent comment duplication, since the TS AST printer includes prior line comments as part of a given line with no way to really avoid that.
However in component imports, it is not safe to remove comments as they could be load bearing for some.
PR Close#53350
This commit fixes a memory leak where signal consumers would not be cleaned up for
descendant views when a view is destroyed, because the cleanup logic was only invoked
for the view that is itself being destroyed.
PR Close#53351
Previously we recorded separate param values for a strucural directive
and the element tag it goes on. We then later attempted to combine those
into a single value. However in some cases this merging logic matched
the directive with the wrong tag.
This change implements an alternate approach where we match the
directive to its element tag from the start, while we're traversing the
ops. This should be a more robust solution.
PR Close#53327
We previously failed to populate the attributes property on projection
ops, this commit populates it and later strips out the "select"
attribute.
PR Close#53327
Previously we failed to reset the sub-template index counter when we
exited a root block. This caused following sibling blocks to start
counting at the wrong index.
PR Close#53327
It is possible for ICUs to be nested inside other ICUs. This change
adjusts our ingestion logic to create extra interpolation ops for the
nested ICUs during ingestion.
PR Close#53300
We previously had an assertion that every placeholder in the i18n AST
had a corresponding param in the output. However, there are some cases
such as interpolations nested inside ICUs where this assertion is not
true. This change simply removes the asserion.
PR Close#53300
ICUs may share a placeholder, and in that case they need special
post-processing. This change adds logic to cover this possibility. In
particular, we set the param to a special placeholder value and then
pass an array containing the sub-message variables as a post-processing
param.
PR Close#53300
When we re-assign the slot dependencies for the i18nExprs, we should
move them down below the other ops that target their same slot. This
keeps the behavior consistent with TDB
PR Close#53300
This commit fixes an issue where swapping hydrated views was not possible in the new control flow repeater. The problem was caused by the fact that an internal representation of a view had no indication that hydration is completed and further detaching/attaching should work in a regular (non-hydration) mode. This commit adds a logic that resets a pointer to a dehydrated content and we use this as an indication that the view is swtiched to a regular mode.
Resolves#53163.
PR Close#53274
When the AOT compiler creates a delegated host for a provided TypeScript CompilerHost,
it delegates functionality back to the original via a series of internal method delegations.
However, unlike other members of the CompilerHost, `jsDocParsingMode` is not a method
and cannot be delegated in this way. Attempting to call bind on the property will result
in a runtime error. Instead, `jsDocParsingMode` is now delegated via get/set accessors.
Additionally, the override of `getSourceFile` now has an updated type signature to reflect
the additional of the `jsDocParsingMode` option for the method.
This is a followup to #53126 which updates the other DelegatingCompilerHost.
PR Close#53292
Prior to this fix, the expectation that anytime then was used, else would always be present. That is not a valid assumption.
fixes: #53287
PR Close#53297
i18n template removal expected no other attributes to be present, but if a bound ngIf is present with aliases and i18n, that is more than what was expected. Now it should safely remove them appropriately.
fixes: #53289
PR Close#53299
This commit fixes an issue with hydration, which happens when a content is projected in a certain way, leaving host elements non-projected, but the child content projected.
The fix is to detect such situations and add extra annotations to help runtime logic locate those elements at the right locations.
Resolves#53276.
PR Close#53304
This commit fixes an issue where having an expression with nullish coalescing in styling host bindings leads to JS errors due to the fact that a declaration for a temporary variable was not included into the generated code.
Resolves#53295.
PR Close#53305
The regexp for then and else did not ignore alphanumeric characters prior to the then and else. So if a string contained then, for example Authentication, it would incorrectly match as a then clause.
fixes: #53252
PR Close#53257
This commit updates the logic to handle hydration of multiple nodes projected in a single slot. Currently, in case component nodes are content-projected and their order is changed during the projection, hydration can not find the correct element. With this fix, extra annotation info would be included for such nodes and hydration logic at runtime will use it to locate the right element.
Resolves#53246.
PR Close#53270
When ng-templates are removed, an extra space was being added when it was unnecessary. This resulted in malformed html if there was no space afterwards.
fixes: #53248
PR Close#53255
This should address cases when using ng-containers with ngSwitchCase / ngSwitchDefault
and migrating them safely when they are empty.
fixes: #53235
PR Close#53237
As part of this fix, I realized that child i18n blocks don't need their
own context. Instead, we can just add their params directly to the
context for their root block, and forgo the step of merging the contexts.
PR Close#53209
Fixes a bug in the sub-template index logic that caused it to reuse
indices that had already been assigned to more deeply nested templates
PR Close#53209
Structural directives inside an i18n block previously resulted in a
"list" param value (represented as "[...|...]"). This commit adds a
special case to the template pipeline to collapse the list into a single
compound value like TemplateDefinitionBuilder does.
PR Close#53209
ICU sub-messages should be recorded as belonging to the message for the
root i18n block they are part of. This ensures that they still get
emitted even if they are nested in a child template.
PR Close#53209
This commit updates the logic to preserve previous value of cached TView before applying overrides. This helps ensure that the next tests that uses the same component has correct provider info.
PR Close#52918
This addresses an issue where multiple ng-templates are present with i18n attributes. The offsets would be incorrectly accounted for when being replaced with an ng-container.
fixes: #53149
PR Close#53212
Common module removal would not happen when a component used a templateUrl due to the checks being in separate files. This change passes the removal analysis back to the original source file to safely remove CommonModule.
PR Close#53076
This is a follow-up to the fix from #52414. It adds a diagnostic that will tell users when a control flow is preventing its direct descendants from being projected into a specific component slot.
PR Close#53190
The control flow projection diagnostic will mention `ng-container` as a workaround for projection multiple nodes. These changes add a couple of tests to ensure that the approach works.
PR Close#53190
These changes expose the `ngContentSelectors` and `preserveWhitespaces` metadata to the TCB so they can be used in the next commit to implement a new diagnostic.
PR Close#53190
When doing directive matching in the compiler, we need to be able to create a selector from an AST node. We already have the utility, but these changes simplify the public API and expose it so it can be used in `compiler-cli`.
PR Close#53190
When the AOT compiler creates a delegated host for a provided TypeScript CompilerHost,
it delegates functionality back to the original via a series of internal method delegations.
However, unlike other members of the CompilerHost, `jsDocParsingMode` is not a method
and cannot be delegated in this way. Attempting to call bind on the property will result
in a runtime error. Instead, `jsDocParsingMode` is now delegated via get/set accessors.
Additionally, the override of `getSourceFile` now has an updated type signature to reflect
the additional of the `jsDocParsingMode` option for the method.
PR Close#53126
Currently the way we extract the pathname of a URL is by creating an anchor node, assigning the URL to its `href` and reading the `pathname`. This is inefficient and it triggers an internal security check that doesn't allow the `href` attribute to be set which ends up blocking https://github.com/angular/components/pull/28155.
These changes switch to using the browser's built-in URL parsing instead.
PR Close#53097
Adds support for inheriting host directives from the parent class. This is consistent with how we inherit other features like host bindings.
Fixes#51203.
PR Close#52992
The following commit accidentally broken execution of resolvers when
two resolvers appear in different parts of the tree and do not share a
3278966068
This happens when there are secondary routes. This test ensures that all
routes with resolves are run.
fixes#52892
PR Close#52934
Related to #52928 but `updateAncestorTraversalFlagsOnAttach` is called
on view insertion and _should_ have made that work for views dirty from
signals but it wasn't updated to read the `dirty` flag when we changed
it from sharing the `RefreshView` flag.
For #52928, we've traditionally worked under the assumption that this is working
as expected. The created view is `CheckAlways`. There is a question of whether we
should automatically mark things for check when the attached view has
the `Dirty` flag and/or has the `FirstLViewPass` flag set (or other
flags that indicate it definitely needs to be prefreshed).
PR Close#53001
When blocks were initially implemented, they were represented as containers in the i18n AST. This is problematic, because block affect the structure of the message.
These changes introduce a new `BlockPlaceholder` AST node and integrate it into the i18n pipeline. With the new node blocks are represented with the `START_BLOCK_<name>` and `CLOSE_BLOCK_<name>` placeholders.
PR Close#52958
This commit adds an `error` listener to image elements and removes both
`load` and `error` listeners once the image loads or fails to load. The `load`
listener would never have been removed if the image failed to load.
PR Close#52990
This commit updates the implementation of the `ImagePerformanceWarning` and
runs the image scan even if the page has already been loaded. The `window.load`
event would never fire if the page has already been loaded; that's why we're
checking for the document's ready state.
PR Close#52991
This separates out the NgSwitch migration pass from the NgSwitchCase / Default pass, which makes nested switch migrations work.
fixes: #53009
PR Close#53010
With if then else use cases, we now properly account for the length
of the original element's contents when tracking new offsets.
fixes: #52927
PR Close#53006
This commit cleans up the `loadingPromise` when no `dependenciesFn` is defined,
as it's already cleaned up after the resolution of `Promise.allSettled`. This
occurs with `prefetch on` triggers, such as when `triggerResourceLoading` is called
from `ɵɵdeferPrefetchOnImmediate`, where there are no dependencies to load. The
`loadingPromise` should still be cleaned up because it typically involves the
`ZoneAwarePromise`, which isn't properly garbage collected when referenced elsewhere
(in this case, it would be referenced from the `tView` data).
PR Close#53031
This is a follow-up to the fix from #52414. It adds a diagnostic that will tell users when a control flow is preventing its direct descendants from being projected into a specific component slot.
PR Close#52726
The control flow projection diagnostic will mention `ng-container` as a workaround for projection multiple nodes. These changes add a couple of tests to ensure that the approach works.
PR Close#52726
These changes expose the `ngContentSelectors` and `preserveWhitespaces` metadata to the TCB so they can be used in the next commit to implement a new diagnostic.
PR Close#52726
When doing directive matching in the compiler, we need to be able to create a selector from an AST node. We already have the utility, but these changes simplify the public API and expose it so it can be used in `compiler-cli`.
PR Close#52726
This commit removes the `load` event listener once it has fired within the
`ImagePerformanceWarning`. The `load` event listener prevents the zone stuff from
being garbage collected in development mode when debugging microfrontend applications
that may be destroyed multiple times.
PR Close#52512
The `$first`, `$last`, `$even` and `$odd` variables in `@for` loops aren't defined on the template context of the loop, but are computed based on `$index` and `$count` (e.g. `$first` is defined as `$index === 0`). We do this calculation by looking up `$index` and `$count` when one of the variables is used.
The problem is that all `@for` loop variables are available implicitly which means that when a nested loop tries to rewrite a reference to an outer loop computed variable, it finds its own `$index` and `$count` first and it doesn't look up the ones on the parent at all. This means that the calculated values will be incorrect at runtime.
These changes work around the issue by defining nested-level-specific variable names that can be used for lookups (e.g. `$index` at level `2` will also be available as `ɵ$index_2`). This isn't the most elegant solution, however the `TemplatDefitinionBuilder` wasn't set up to handle shadowed variables like this and it doesn't make sense to refactor it given the upcoming template pipeline.
Fixes#52917.
PR Close#52931
Reworks the `repeater` instruction to go through `advance`, instead of passing in the index directly. This ensures that lifecycle hooks run at the right time and that we don't throw "changed after checked" errors when we shouldn't be.
Fixes#52885.
PR Close#52935
Currently, when a component is overriden using `TestBed.overrideComponent`, Angular retains calculated scope for that component (a set of components and directives used within a component). This may cause stale information to be used in tests in some cases. This commit updates the logic to reset overridden component scope, so it gets re-computed during the next invocation.
Resolves#52817.
PR Close#52916
The call signature of detectChangesInternal requires parameters that can all be
found directly on lView. This commit removes those paramters and instead
grabs them in the function implementation.
PR Close#52866
There are cases where the application's default behavior is 'reload' and
a certain navigation might want to override this to be `ignore` instead.
This commit allows `onSameUrlNavigation` in the `router.navigateByUrl`
to be `ignore` where it was previously restricted to only `reload`.
PR Close#52265
These tests ensure signals can be read in a template after embedded
views are created in the middle of template execution of an update pass.
The embedded view templates are executed in create mode in the middle of
the component template being executed in update mode. This behavior was
found to not work correctly in past implementations of the reactive
template consumers.
PR Close#52495
This should fix the issue where if the same ng-template is used with multiple if / else statements, it replaces all usages properly.
fixes: #52854
PR Close#52863
Previously we had logic for a special case where a root injector in standalone apps would skip the import paths calculation step for the `getEnvironmentInjectorProviders` function.
This commit intends to fix this for two other cases, namely:
- When an injector is created by a route (via the `providers` field and lazy loading).
- When an injector is manually created and attached to the injector tree
It does this by assuming that any environment injector it cannot find a provider imports container for was created without one, and simply returns the raw provider records without the import paths calculation.
PR Close#52774
This fixes a bug where if you have multiple tsconfig files, the migration would not find anything to migrate at the passed in path.
fixes: #52787
PR Close#52796
This update removes imports from component decorators and at the top of the files. It only removes standalone imports though. It does not remove CommonModule if that is the only import.
PR Close#52763
In some cases ICU expression placeholders may have trailing spaces that
need to be trimmed when matching the placeholder to its corresponding
text binding.
PR Close#52698
We were previously counting the i18n expression index and deciding when
to apply i18n expressions based on the i18n context. These should be
done based on the i18n block instead.
PR Close#52698
The previous commit added support for interpolated text in ICUs, but it
made the assumption that the interpolation would be a single variable
read expression.
To properly support all kinds of interpolation expressions, this commit
refactors how ICUs are ingested to allow us to re-use the same logic we
use for bound text outside of ICUs.
To accomplish this, the `IcuOp` creation op has been removed in favor of
a pair of ops: `IcuStartOp` and `IcuEndOp`, that mark the beginning and
end of the ICU. Now, instead of inserting an `IcuUpdateOp` in the update
IR, we call `ingestBoundText` and use the presence of the surrounding
`IcuStartOp` and `IcuEndOp` to match the interpolation with the ICU.
PR Close#52698
Previously ICUs were assumed to only generate a single i18n expression
per ICU. However, it is possible for ICUs to contain text interpolations
which requires additional expressions. This commit adds support for
multiple expressions per ICU.
PR Close#52698
ICUs that contain element tags need extra parameters for the i18n
message. These are in addition to the element slot params that are
already added to the parent i18n block's params. In this commit we add a
new phase to fill in these placeholders.
PR Close#52698
Previously the template pipeline sorted i18n message params before
adding the sub-message placeholders. Now its sorts after all
placeholders are added.
Both the template pipeline and TemplateDefinitionBuilder previously
failed to sort the post-processing params. They both now sort these as
well. This is safe to change in TemplateDefinitionBuilder, as it does
not change anything about the functionality, it simply ensures that
params map in the output has the keys ordered in a way that can be
easily reproduced in the template pipeline.
PR Close#52698
Updates the repo to support TypeScript 5.3 and resolve any issues. Fixes include:
* Updating usages of TS compiler APIs to match their new signatures.
* In TS 5.3 negative numbers are represented as `PrefixUnaryExpression` instead of `NumericExpression`. These changes update all usages to account for it since passing a negative number into the old APIs results in a runtime error.
PR Close#52572
This cleans up a bit of code to make maintenance easier. It also adds comments for all the exported methods so they are clear to anyone in the future.
PR Close#52755
This implementation does most, but not all, of the things the native
Navigation API does. Also adds a spec that tests all the currently
supported behaviors.
PR Close#52363
When a component contains `@defer` blocks, Angular compiler generates the code to apply component metadata (from the `@Component` decorator) after resolving all dynamic dependencies. Currently, this function is invoked eagerly at runtime, which causes dynamic imports to be kicked off earlier than expected. With the change in this commit, Angular will start resolving async metadata when it becomes necessary during testing.
PR Close#52708