This updates the caretaker query for merge queue
to remove status: success, since skipped workflows
are considered failed by Github and omitted from
the query results.
PR Close#59095
Fixes a null pointer error in the unused standalone imports diagnostic. It was caused by an inconsistency in TypeScript's built-in types.
Fixes#58872.
PR Close#59064
Prior to this commit, we were logging the `NOT_USING_FETCH_BACKEND_IN_SSR` error when `provideHttpTestingClient` and `PLATFORM_ID` were provided.
fixes#59028
PR Close#59049
SSR generated component styles used in development environments will add
external styles via link elements to the HTML. However, the runtime would
previously not collect these link elements for reuse with rendered components.
This would result in two copies of the link elements present in the DOM. In
isolation this is not problematic as it is only present in development mode.
Unfortunately, the Vite-based CSS HMR functionality used by the Angular CLI
only updates the first stylesheet it finds and leaves other instances of the
stylesheet in place. This behavior causes the styles to be left in an
inconsistent state. This could be considered a defect within Vite as it should
update all relevant styles to maintain consistency but ideally there should
not be two instances in the Angular SSR case. To avoid the Vite issue, the
runtime will now collect SSR generated external styles and reuse them.
PR Close#59031
Move the members description section below the main content of the page since it is part of the core information about a doc item. The CLI reference details page is affected as well.
PR Close#58610
Fix a typo in an example in Templates page in
Essentials section of Angular Docs.
Instead of "Profile file", the correct would be
"Profile for", according to the example's template.
PR Close#58985
Functions like `linkedSignal` have there `@developerPreview` tags on the overload signature. This commit adds the support for them.
This commit also removes the logic for multiple entries, as now overloads are a single entry.
fixes#58817
PR Close#58994
Some of the devtools commits were merged into v19
(probably shouldn't have) and were missing imports.
This commit adds missing imports to re-enable tests.
PR Close#59000
Fixes that in some cases the internal version of the migration was dropping code when all the statements after the `super` call are deleted.
PR Close#58959
Deletes the `allowInvalidAssignmentEvents` which was added to facilitate a migration away from invalid two-way bindings. Since the migration doesn't exist anymore, we don't need the flag either.
PR Close#58988
fix(docs-infra): do not focus h1 from docs-top-level-banner
Do not focus heading from docs-top-level-banner.
Move the `Skip to main content` button to the top of DOM tree.
PR Close#57698
fix multiple issues with the existing code
1. `shippingOptions` was accessed without `this.` which produces error in realtime
2. the logic in calculating of the item exist or not was not correct since it was comparing the object to the id
3. I'm not sure why, but step 3 fail without stating typing for LinkedSignal, so I added it
PR Close#58756
since the dialogue shows on top of other scrollable elements of the page, then the overscroll behavior should be contain for better UX.
Resloves: #58947
PR Close#58948
For perf reasons, it is more efficient to not rely on creating an `URL` object. Instead we check for the explicit protocol to detect external links.
This will also force us to use relative links, so archived versions & next versions navigate on the current version of the site.
fixes#58954
PR Close#58955
The DOM is cluttered with a lot of nav item UL-s that are not visible to the end user due to the usage of multiple docs-navigation-list instances that render the full navigation tree recursively instead of only the preselected visible levels.
PR Close#58934
The current HMR compiler assumes that there will only be one namespace import in the generated code (`@angular/core`). This is incorrect, because the compiler may need to generate additional imports in some cases (e.g. importing directives through a module). These changes adjust the compiler to capture all the namespaces in an array and pass them along.
Fixes#58915.
PR Close#58924
Provide a callback to the TracingService implementation when a Snapshot can be disposed.
The underlying tracing implementation may use refcounting and needs to release resources
to enable the trace to complete.
While change detection uses the snapshot for exactly one callback, after render runs
multiple hooks in the sequence so we need a more predictable way to indicate that the snapshot
can be finalized.s
PR Close#58929
This cleans up the triggering code base and consolidates it down to one
function that outlines the logic. This also resolves the `hydrate when`
behavior issue.
fixes: #58709
PR Close#58833
The previous warning contained a typo and also somewhat implied that allowSignalWrites did something. However, setting allowSignalWrites to false has no impact at all in Angular 19.
Closes#58790
PR Close#58792
since we are only updating the members margin at the constructing phase,
we should not disable this operation if user hit the page with tabs different than API active,
otherwise if user switched to the API page he won't see the cards since members margin equals zero and docs viewer won't be shown
Resolves#58882
PR Close#58883
Prior to this change, we generated an invalid HTML with nested anchor elements. Those are not valid and are recovered by the browser by closing one early which messed the layout.
fixes#58884
PR Close#58886
Fix a bug where calls to _tick are called without running through the snapshot.
This helps ensure that all snapshots that are requested are resumed.
PR Close#58881
This commit updates the code of the `ɵɵdeferHydrateWhen` function to invoke the `setActiveConsumer` function at the right time (currently, we invoke it in the `finally` block, which is too late).
PR Close#58864
Before this commit, a resource with a previous value wouldn't set the error state correctly.
This commit fixes this. A resource will set its status to error even when there was a previous valid value.
PR Close#58855
Skips the TS version check in tsurge since it's blocking some internal changes and generally isn't necessary since the app will be checked when it's built anyways.
PR Close#58866
Currently host bindings are in a bit of a weird state, because their source spans all point to the root object literal, rather than the individual expression. This is tricky to handle at the moment, because the object is being passed around as a `Record<string, string>` since the compiler needs to support both JIT and non-JIT environments, and because the AOT compiler evaluates the entire literal rather than doing it expression-by-expression. As a result, when we report errors in one of the host bindings, we end up highlighting the entire expression which can be very noisy in an IDE.
These changes aim to report a more accurate error for the most common case where the `host` object is initialized to a `string -> string` object literal by matching the failing expression to one of the property initializers. Note that this isn't 100% reliable, because we can't map cases like `host: SOME_CONST`, but it's still better than the current setup.
PR Close#58870
This commit removes a custom `whenStable` util in favor of standard `ApplicationRef.whenStable` API.
There is also an important different between the custom `whenStable` function and `ApplicationRef.whenStable` implementation: the `whenStable` was caching the "stable" promise on per-ApplicationRef basis, which resulted in unexpected behavior with zoneless, when some code ended up getting a stale resolved promise, when an application was not stable yet, this causing order of operations issues. This commit also has an extra test that covers that case.
PR Close#58834
Updates the sync config to exclude the entire `bazel` package. Previously only some subdirectories were excluded, but in the internal config the entire package is ignored.
PR Close#58837
By API returned type is object, not any, rephrase docs and TIP
Fixes#58273
docs: change type from object to Object
Change the typo from object to Object
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
PR Close#58289
For components with i18n in templates, the `consts` array is generated by the compiler as a function. If client and server bundles were produced with different minification configurations, the serializable contents of the function body would be different on the client and on the server. This might result in different ids generated. To avoid this issue, this commit updates the logic to not take the `consts` contents into account if it's a function.
Resolves#58713.
PR Close#58813
When hydrating a tree of blocks, this prevents cleanup from firing more than once per tree. It also ensures the cleanup happens after hydration has finished.
fixes: #58690
PR Close#58722
Priori to this commit, initializer functions with dependencies were not migrated correctly.
With this commit, the function is executed in a injection context to allow the usage of `inject`.
PR Close#58518
Before, in a situation like shown in the test, all of the initializers
would be dropped, as the code would try to insert it at the hoisted
property which is going to be deleted.
PR Close#58804
Starting from Tablet-landscape siz display the banner on top of all the
elements, and for smaller sizes display it under the nav to make it
accessible to users
PR Close#58775
This fixes an issue where the lazy-routes migration would crash for component classes a
decorator without arguments in front of the `@Component` decorator (in particular, it needed
to be the first decorator).
Fixes#58793
PR Close#58796
This commit introduces a private API, the `TracingService` DI token. By
providing this token, Angular can be configured to capture tracing snapshots
for certain operations such as change detection notifications, and to run
downstream operations within the context of those snapshots.
`TracingService` abstracts this context propagation and makes it pluggable.
PR Close#58771
The error codes that have fixes are present in a Map instance and
can be directly leveraged to determine if an error code can be fixed.
This avoids multiple levels of iteration that would otherwise be needed.
PR Close#58759
Adds some logic to the `inject()` migration that allows is to handle parameter declarations with initializers. This was omitted initially, because we don't officially support such cases, but it came up internally.
PR Close#58769
This change updates the navigation titles for linkedSignal and resource
to follow the pattern of "<accomplish X> with <feature Y>". Also makes a
few minor updates to the body of the resource topic.
PR Close#58761
A note has been added to the application builder documentation regarding
the Vite-based development server and style processing that could
potentially result in initial FOUC due to server processing overhead on startup.
PR Close#58751
Fixes that `getCodeActions` wasn't implemented for the unused imports fixer which meant that it wouldn't show up in the most common cases.
PR Close#58719
Currently the code fixes won't run if the template information can't be resolved on the diagnostic node. This is incorrect for diagnostics that are reported within `.ts` files. These changes make the `templateInfo` nullable and leave the early exit up to the individual fixes.
PR Close#58719
The internal renderer cache within the renderer factory was not being
correctly cleared due to a type-casting error. This prevented template
HMR from correctly updating the component. A more explicity cast has
now been used to mitigate this problem.
Component template HMR is currently considered experimental.
PR Close#58724
* Move the NgModules and Animations guide under "Extended Ecosystem"
* Remove all NgModule topics except for the (newly written) overview.
All of the content in these topics was inherently written on the idea
that your application was organized around NgModules. I went through
all of it, moved the important parts to the overview, and deemed the
rest obsolete (though it will always remain in archived versions).
PR Close#58694
This commit bumps up the stability status of the linkedSignal
to developer preview - clearly expressing our highier confidence
in this API.
PR Close#58684
Fixes#58630
```html
<button (click)="someSubject.next()">Click</button>
```
was migrated to an `.emit` call, even if `someSubject` was not an `EventEmitter`.
The issue was the same in host listeners.
PR Close#58631
fix transformation logic for `:where` and `:is` pseudo-selectors
when these selectors were used in a chain. results were often broken,
the last letter of the selector was incorrectly trimmed.
see tests for examples
Fixes#58226
PR Close#58681
fix several use-cases where `:host` was used in or around pseudo-selectors
- `:host` followed by a comma inside pseudo-selectors
- `:host` outside of pseudo-selectors when another `:host` is present within
see tests for examples
PR Close#58681
If a defer block is nested inside control flow while also being nested
underneath a defer block all using incremental hydration, timing issues
prevented the child nodes from being properly hydrated. This ensures
hydration happens on next render.
PR Close#58644
This commit is only useful to Google. It fixes that some code relies on
`readConfiguration`, but doesn't properly parse Angular compiler options
as those are part of `bazelOptions.angularCompilerOptions` if the
1P-generated tsconfig's are used.
PR Close#58637
A dot was appearing in the middle of the comment for `DerivedIsIncompatible`.
While at it, a dot was missing in `ClassManuallyInstantiated`.
PR Close#58636
* This makes it easier for developers discover SSR docs
* Deletes the original `@defer` guide now that there's a new `@defer` topic in the template guide
* Moves the Image optimization topic to the Directives guide. This isn't my _favorite_ place for this guide and I may revisit in a follow-up PR.
PR Close#58638
This change updates the _Essentials_ topic with the following changes:
* Change the "Managing dynamic data" topic to "Reactivity with signals",
largely replacing the existing content to focus specifically on
signals.
* Replace the "to-do" examples with examples for building a
`UserProfile` component. I made this change because the todo-item
component had an accessibility problem: it was a list item component
that rendered an `li` into its own template. This meant that the
component's host element was in between the `ul` and the `li`, which
is invalid. The "right" way to do this would have been to use a
component with an attribute selector, but this isn't something that
fits into the _Essentials_ guide.
* Reorder some of the concepts in the components topic
* Combine "Rendering dynamic templates", "Conditionals and loops", and
"Handling user interaction" into one topic, "Dynamic interfaces with
templates". Having these as separate topics meant that there was more
preamble/scaffolding around these relatively straightforward ideas.
* Renamed the "Sharing logic" topic to "Modular design with dependency
injection". Aside from this, I have made no meaningful changes to the
DI topic; I may come back for another edit pass here, but this is not
necesary for v19.
* Add a link to the in-depth guide for each essentials topic.
* Add a new introduction to the _Essentials_ overview that explains what
this guide is and what it's trying to accomplish.
PR Close#58603
This is the first commit towards updating the NgModule guide to reflect
the fact that v19+ is standalone by default. This PR focuses on:
* Updating the overview to give an actual overview of the most
important/common uses of `NgModule`
* Add callouts recommending standalone APIs over `NgModule`
* Remove several stale docs that no longer make sense in v19+
This guide (directory) needs additional follow up work; I plan to
address the remaining content in follow-up changes.
PR Close#58606
In #57684 the standalone migration was changed so that it replaces any leftover modules with their `exports`, in an attempt to preserve more working code. These changes expand that logic to also cover tests since it's somewhat common internally to only import a component's module without having any references to the component.
Note that tests are a bit of a special case, because we don't have access to the template type checker, so instead we copy over all of the `exports` of that module.
PR Close#58627
Currently the `getPotentialImportsFor` only accepts a `ClassDeclaration` as the context for generating an import, but that's not necessary because it doesn't require any class-specific information. These changes expand it to any `Node` so that it can be used when generating imports in testing declarations.
PR Close#58627
Running `ng g @angular/core:signals` prompts for the question on which migration to run and offers 3 options (inputs, outputs, queries).
Running with `--defaults` skips the prompts, but only runs 2 of them.
This fixes it by including the `outputs` migration in the default ones.
PR Close#58635
This change updates the docs to show the signal-based APIs for inputs
and queries as the primary way to do things (and also the `output`
function).
Specifically, this means:
* Component guide
* Show `input` and `model` as the main approach, moving `@Input` lower on the same page
* Show signal-based queries as the main approach, moving the
decorator-based queries lower on the same page
* Show `output` as the main approach, moving `@Output` lower on the
same page
* Delete the separate topic for the `output` function
* Signals guide
* Delete the topics for input, model, and queries, as they are not in
the components guide.
* Move all rxjs-interop content to a new guide under "Extended
ecosystem"
I plan to further update the "Essentials" guide and the "Signals" guide
in follow-up PRs.
PR Close#58572
Fixes an edge case where a control flow node that has non-projectable nodes followed by an element node at the end would cause the entire control flow node to be project. For example if we have a projection target of `Main: <ng-content/> Slot: <ng-content select="[foo]"/>`, inserting a node of `@if (true) {Hello <span foo>world</span>}` would project the entire `Hello world` into the `[foo]` slot.
In the process of working on the issue, I also found that `@let` declarations at the root of the control flow node would prevent content projection as well.
PR Close#58607
In this commit, we clean up the event contract once hydration is complete, which removes event
listeners registered through the container manager. If we do not clean up the contract, the listeners
will remain on the `document.body`. When incremental hydration is enabled, we cannot clean up the event
contract immediately; instead, we schedule its cleanup when the app is destroyed. This is because the
event contract is required for deferred blocks, of which we are unaware, that need to be hydrated.
PR Close#58174
This moves all the helpers out of the instructions file, keeping the instructions limited to the actual instruction set. This adds files for defer block rendering functions and triggering functions, respectively.
PR Close#58598
Initially the unused imports check was implemented so that it reports one diagnostic per component with the individual unused imports being highlighted through the `relatedInformation`. This works fine when reporting errors to the command line, but vscode appears to only show `relatedInformation` when the user hovers over a diagnostic which is a sub-par experience.
These changes switch to reporting a diagnostic for each unused import instead.
PR Close#58589
This commit improves the temporary variable generation in signal
migrations, whenever references are "shared" inside property
declarations.
PR Close#58581
Currently whenever we would come across a code snippet like this, where
`maxCellsPerRow` is an input, the control flow analysis would fall apart
because the first occurence of the node points to a control flow node
that is offset-wise "after" the first occurence. This commit makes the
logic more robust.
PR Close#58581
The application builder documentation now contains information about the
`define` option and its usage as well as development server prebundling.
PR Close#58569
This cleans up the memory usage of the defer block registry and jsactionmap when a view is destroyed that contains a defer block that is not yet hydrated.
PR Close#58553
Previously we always ran Tsurge migrations with an Angular program, even
if it's a plain `ts_library` target. This has changed now, so we also
need to properly handle the case where a `ts_library` is analyzed, but
no Angular program is available.
PR Close#58541
Tsurge can run against the full Google3 depot, and will often also deal
with plain `ts_library` targets. Those shouldn't be constructed with the
Angular compiler as this could cause out of memory breakages etc. The
targets are simply not "proven" to be compatible with the Angular
compiler; so we shouldn't use them when not necessary.
PR Close#58541
Previously, `filterMethodOverloads` excluded all members without a body, causing issues with the extraction of functions and members in TypeScript types.
PR Close#58445
This commit introduces a new guide for hybrid rendering APIs, which are currently in developer preview. This documentation provides insights into the usage and features of the APIs, helping developers understand their capabilities and limitations during the preview phase.
PR Close#58445
This commit utilizes the `@angular/ssr` NPM package to generate an API reference for its entry points using the `generate_api_docs` Bazel rule, which will be included in http://angular.dev/api.
PR Close#58445
In TSDoc, we currently handle the `@usageNotes` annotation, but this is not a standard TSDoc tag. Instead, the `@remarks` annotation is the correct standard, which is used in the Angular CLI repo and on the SSR package.
This change ensures that `@remarks` is treated the same as `@usageNotes` during the transform process.
PR Close#58523
The DOM renderer classes perform initialization that captures state from
the component definition during construction. To ensure that the state is
kept synchronized with any newly applied metadata from an HMR `applyMetadata`
call, each renderer is now recreated during the apply process. This also
allows inline component styles to be updated in cases where external component
stylesheets may not be viable.
PR Close#58527
This commit addresses a problem with tests that use the `fit` function to focus on individual test cases. While these tests run successfully in the full suite, they fail when focused individually using `fit`.
The issue lies in the behavior of `withEventReply` and other hydration-related functions (i.e., `provideX`, `withX`). These functions return platform-specific providers based on the `ngServerMode` setting, causing inconsistencies between server and browser environments. As a result, provider instances cannot be reused across server and browser applications.
**Example of problematic code:**
```ts
const hydrationFeatures = [withEventReply()];
const html = await ssr(SimpleComponent, { hydrationFeatures });
// Expected behavior ...
const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
hydrationFeatures,
});
// Expected behavior ...
```
**Solution:**
To address this, we define `hydrationFeatures` as a function instead of a static array. This ensures that a new instance of `withEventReply` is created separately for each environment, eliminating platform-specific mismatches between server and browser contexts:
```typescript
const hydrationFeatures = () => [withEventReply()]; // Define as a function
const html = await ssr(SimpleComponent, { hydrationFeatures: hydrationFeatures() });
// Expected behavior ...
const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
hydrationFeatures: hydrationFeatures(),
});
// Expected behavior ...
```
PR Close#58538
Update the link used to reference algolia as the search provider on our documentation site. Adds a few URL parameters
for algolia to map back to our usage.
PR Close#58542
We were not properly passing around the TCB full program optimization,
so TCB generation was done per individual file. This significantly
slowed down reference resolution.
PR Close#58525
Currently when application source code references e.g. an NgModule that
points to references that aren't available, the compiler will break at
runtime without any actionable/reasonable error.
This could happen for example when a library is referenced in code, but
the library is simply not available in the `node_modules`. Clearly,
TypeScript would issue import diagnostics here, but the Angular compiler
shouldn't break fatally. This is useful for migrations which may run
against projects which aren't fully compilable. The compiler handles
this fine in all cases, except when processing `.d.ts` currently... and
the runtime exception invalides all other information of the program
etc.
This commit fixes this by degrading such unexpected cases for `.d.ts`
metadata reading to be handled gracefully. This matches existing logic
where the `.d.ts` doesn't necessarily match the "expecation"/"expected
format".
The worst case is that the Angular compiler will not have type
information for some directives of e.g. a library that just isn't
installed in local `node_modules`; compared to magical errors and
unexpected runtime behavior.
PR Close#58515
The use of relative imports vs. module imports and the existing mismatch
can cause symbols to be duplicated in migrations. This is problematic as
it breaks migration logic or compiler logic in the worst case.
Long-term we will solve this by having a better Bazel toolchain where
both relative and module imports can point to the same files; but in
practice this is not the case right now.
This commit fixes the fallback template logic in the signal
input/queries migration; in case no type check block information is
available.
PR Close#58515
When we check for duplicates in dev mode, we end up stringifying an `LView` even if we don't report an error. This can be expensive in large views.
These changes work around the issue by only generating the string when we have an error to throw.
Fixes#58509.
PR Close#58521
Angular components that use ShadowDOM view encapsulation have an alternate
execution path for adding component styles to the DOM that does not use the
SharedStylesHost that all other view encapsulation modes leverage. To ensure
that ShadowDOM components receive all defined styles, additional logic has been
added to the ShadowDOM specific renderer to also cover external styles.
PR Close#58482
This updates the prettierrc to reflect how the code seems to already be
formatted. I noticed that without this my IDE seemed to be introducing
formatting changes on save.
PR Close#58266
This update corrects a grammatical error in the "CSS style properties" section of the template binding documentation. The sentence "You must create a new object instance when you modify these values in order to Angular to apply any updates" was updated to read correctly as "You must create a new object instance when you modify these values in order for Angular to apply any updates." This clarification helps improve readability and ensures the documentation communicates instructions accurately for readers.
PR Close#58491
When the compiler generates the `HostDirectivesFeature`, it generates either an eager call (`ɵɵHostDirectivesFeature([])`) or a lazy call (`ɵɵHostDirectivesFeature(() => [])`. The lazy call is necessary when there are forward references within the `hostDirectives` array. Currently we resolve the lazy variant when the component definition is created which has been enough for most cases, however if the host is injected by one of its host directives, we can run into a reference error because DI is synchronous and the host's class hasn't been defined yet.
These changes resolve the issue by pushing the lazy resolution later during directive matching when all classes are guanrateed to exist.
Fixes#58485.
PR Close#58492
There is an unidentified issue causing the Yarn binary to be altered, resulting in packages not installing correctly and leading to failures in the process.
PR Close#58497
Before v19, the default value of the standalone flag was false, this code change flips the logic in the migration to make it true by default.
PR Close#58474
Adjusts the HMR initialization to avoid the edge case where a developer makes change to a non-rendered component that exists in a lazy loaded chunk that has not been loaded yet. The changes include:
* Moving the `import` statement out into a separate function.
* Adding a null check for `d.default` before calling `replaceMEtadata`.
* Triggering the `import` callback eagerly on initialization.
Example of the new generated code:
```js
(() => {
function Cmp_HmrLoad(t) {
import(
/* @vite-ignore */ "/@ng/component?c=test.ts%40Cmp&t=" + encodeURIComponent(t)
).then((m) => m.default && i0.ɵɵreplaceMetadata(Cmp, m.default, [/* Dependencies go here */]));
}
(typeof ngDevMode === "undefined" || ngDevMode) && Cmp_HmrLoad(Date.now());
(typeof ngDevMode === "undefined" || ngDevMode) &&
import.meta.hot &&
import.meta.hot.on("angular:component-update", (d) => {
if (d.id === "test.ts%40Cmp") {
Cmp_HmrLoad(d.timestamp);
}
});
})();
```
PR Close#58465
This change modifies the execution level of `postUpgradeTasks` in Renovate. By setting `executionMode` to `branch`, the task will run once per branch, rather than for each dependency update. This helps streamline tasks across dependencies by consolidating them at the branch level.
PR Close#58470
named as the values of the `TaskType` type.
The Closure Compiler used at Google has a property renaming optimization
that can change the property names when minifying code. Having the
correct type helps the TSJS team that develops a tool to identfy
property renaming issues directly in TypeScript.
Signed-off-by: Costin Sin <sin.costinrobert@gmail.com>
PR Close#51739
Fixes external link for 'Everything you need to know about the "ExpressionChangedAfterItHasBeenCheckedError" error' on the NG0100 error page.
Domain has changed from indepth.dev to angularindepth.com
PR Close#58462
The unused imports diagnostic reports once on the entire initializer and then again once per unused imports. This ends up being a bit hard to follow, because in a lot of cases the code snippet looks identical.
These changes switch to highlighting the `imports:` part of the property declaration and only highlighting the unused imports without a message.
PR Close#58468
This commit updates the code of the incremental hydration feature to make the `DeferBlockRegistry` class tree-shakable. The class is only needed for hydration cases and it should not be included into client bundles for client-only apps.
PR Close#58424
Updates the internal part of the `inject` migration to attempt to correct some cases where the declaration order of properties doesn't match the initialization order.
PR Close#58427
We were repeating the logic that deletes a node together with all its comments in a few different places. These changes consolidate the logic under `ChangeTracker.removeNode`.
PR Close#58427
We were filtering out abstract classes pretty late in the migration which led to the internal part of it to make some changes that aren't finalized later. These changes fix the issue by filtering out abstract classes during analysis.
PR Close#58427
With this commit the explicit standalone migration uses the presents of imports to make sure that we can safely remove the standalone prop
and not adding it again when re-run.
PR Close#58418
This commit adds the `ngServerMode` as global, which allows for the tree-shaking of server-only code from the bundles. When this flag is unset at runtime, server-specific code will be excluded by Closure, optimizing bundle size.
**Internal Angular Flag:** This is an internal Angular flag (not a public API), avoid relying on it in application code.
PR Close#58386
Before this fix the output migration was incorrectly assuming
that the @Output decorator takes its params as an object.
What happens in reality is that the @Output decorator is taking
alias as the only argument, without any object literal wrapper.
PR Close#58411
This change fixes a bug where the output migration was interacting
with the InputManager utility in the way that was resulting in
incorrect import replacements.
The fix consists of making sure that a new ImportManager instance
is created for each and every file containing @Output declarations.
PR Close#58414
In 1P, we saw that a type of a target wasn't resolvable, referenced in a
`hostBindings#directive` field. This breaks the entire pipeline; so we
should handle gracefully but report an error.
Worst case scenario here is that we would miss some references to the
given directive/component. This is acceptable and we can continue
investigation why that given target was broken; especially since the
file was part of the target inputs- but seemingly not in the `tsconfig`.
PR Close#58413
Fixes that the migrations weren't properly determing the highest block
of multiple shared references. The logic was flawed by checking the
`start` indices; because we also need to respect that the blocks
should enclose all references; and the block practically is a common
ancestor. This is not guaranteed without this commit.
Note: The logic assumes that all references are part of the same control
flow container; this is verified.
PR Close#58413
Disables the standalone by default behavior in the compiler when running against and older version of Angular. This is necessary, because the language service may be using the latest version of the compiler against and older version of core in a particular workspace.
PR Close#58405
hydrate triggers were firing in CSR cases and attempting to find parent defer blocks. This prevents that from happening. In these cases, the defer block id will be empty.
fixes: #58359
PR Close#58366
Remove an unnecessary whitespace between an opening parenthesis and a
word in the documentation on lifecycle.
Closes#58380
PR Close#58388
PR Close#58388
Fixes that if a class has a `super` call, the `inject` migration would always insert the generated variable before it, even if there's other code before the `super` call.
PR Close#58393
Fixes that when the `inject` migration in internal mode was starting to visit the nodes one level down from the root when considering whether an expression contains local references. This lead it to skip over top-level identifiers and migrate some code incorrectly.
PR Close#58393
Fixes an issue where the `inject` migration was generating and attempting to insert code after a `super` call, but the string buffering implementation was dropping it if the statement right after the `super` call was deleted as a result of the migration.
PR Close#58393
When the internal mode for the `inject` migration is enabled, we find properties without initializers, we add their initializers and we prepend the `inject` calls before them. The remaining properties that couldn't be combined are left in place. This appears to break some internal cases.
These changes work around the issue by hoisting all the non-combined members above the `inject()` calls. This should be safe, because they don't have initializers and as such can't have dependencies.
PR Close#58393
Top-level property access was causing dead code elimination (DCE) and tree-shaking issues. This commit modifies `ɵɵNgOnChangesFeature` to prevent these bailouts.
PR Close#58297
Marked the PHASES constant within AfterRenderImpl as @__PURE__ to enable better tree-shaking during bundling. This optimization ensures that unused code is more effectively eliminated, improving overall bundle size and performance.
Closes#58296
PR Close#58297
Added the `@__PURE__` annotation alongside `@pureOrBreakMyCode` to improve compatibility with third-party bundlers. This refactor follows optimization best practices, ensuring broader support across different tools, as `@pureOrBreakMyCode` was only supported by Closure Compiler.
PR Close#58297
When setting `"useDefineForClassFields": false`, static fields are compiled within a block that relies on the `this` context. This output makes it more difficult for bundlers to treeshake and eliminate unused code.
PR Close#58297
This is necessary given the previous Tsurge refactorings. It should
speed up migrations in the merge phase signficiantly and reduce memory
pressure. In 1P, we already have workers from analyze phase anyway— so
those can be re-used for parallel metadata merging.
PR Close#58280
This is helpful and important for large scale migrations where a single
call for merging _all_ unit data's can be subject to memory / disk
resource constraints. Consider a compilation unit data for every target
in Google3, and those being merged in a single program.
PR Close#58280
For scroll-blocking events like 'touchstart', 'touchmove', 'wheel' and 'mousewheel',
if passive option is not specified when adding the event listener, browser may give
a violation warning.
This PR allows us to set the passive option when calling event lib's addEvent().
PR Close#58316
For scroll-blocking events like 'touchstart', 'touchmove', 'wheel' and 'mousewheel',
if passive option is not specified when adding the event listener, browser may give
a violation warning.
This PR allows us to set the passive option when calling event lib's addEvent().
PR Close#58316
Fix initializer of instance members that reference identifiers declared in
the constructor.
When public class fields are enabled, such cases throw TS2729: property used
before its initialization.
PR Close#58349
By removing the standalone feature, we reduce the amount of code generated for components but at the cost of including the `StandaloneService` in the main bundle even if no standalone components are included in it.
PR Close#58288
The `rxResource` was using `firstValueFrom` which isn't supported in rxjs 6.x. `@angular/core` currently supports rxjs 6 so we need this to be backwards compatible. This came up when trying to deploy the Material docs site which is still on rxjs 6 ([see](https://github.com/angular/components/actions/runs/11487971079/job/31973721563)).
PR Close#58341
The runtime default is now `standalone: true`.
`ɵɵdefineComponent`, `ɵɵdefineDirective` and `ɵɵdefinePipe` now set `standalone` as `true` by default in the definitions.
PR Close#58238
This change captures different statistics from the run of the
output migration:
- total number of outputs detected
- number of problematic outputs that can't be migrated
- overall success rate
PR Close#58321
Currently, the cloudinary image loader doesn't support rounded transform.
Add a new prop called `rounded` to the existing `ImageLoaderConfig.loaderParams`
test(common): add test case for cloudinary loader rounded option
add test case for the rounded transform option of cloudinary loader
PR Close#55364
This commit adds an operator to help rxjs observables important for rendering
keep the application unstable (and prevent serialization) until there is
an event (observable emits, completes, or errors, or the subscription is
unsubscribed). This helps with SSR for zoneless and also helps for when
operations are intentionally executed outside the Angular Zone but are
still important for SSR (i.e. angularfire and the zoneWrap helper hacks).
PR Close#56533
This is necessary given the previous Tsurge refactorings. It should
speed up migrations in the merge phase signficiantly and reduce memory
pressure. In 1P, we already have workers from analyze phase anyway— so
those can be re-used for parallel metadata merging.
PR Close#58280
This is helpful and important for large scale migrations where a single
call for merging _all_ unit data's can be subject to memory / disk
resource constraints. Consider a compilation unit data for every target
in Google3, and those being merged in a single program.
PR Close#58280
Angular DevTools is working on developing signal debugging support. This commit is a step in the direction of making available debug information to the framework that will allow Angular DevTools to provide users with more accurate information regarding the usage of signals in their applications.
Follow up PRs that will use this arg will:
- Develop a typescript transform that will detect usages of signal functions and attempt to add a debugName without the user needing to specify one directly
- Develop debug APIs for discovering signal graphs within Angular applications (using debugName as a way to label nodes on the graph)
PR Close#57073
Angular DevTools uses globally available functions to provide debugging information to the framework. This commit exports `getLoadedRoutes` function using the `ɵpublishExternalGlobalUtil` function added in PR: https://github.com/angular/angular/commit/f5cd8f7ab498f35dc2ec3c6662d4443135989720.
Follow-up PRs that will:
- Add a new router example in the Angulat DevTools demo application.
- Implement the router graph in the Angular DevTools to view the routes that are loaded in the application
PR Close#58199
add helper functions provideAppInitializer, provideEnvironmentInitializer & providePlatformInitializer
to respectively simplify and replace the use of APP_INITIALIZER, ENVIRONMENT_INITIALIZER, PLATFORM_INITIALIZER
add a migration for the three initialiers
PR Close#53152
This commit adds an `applicationMaxAge` to the service worker configuration. When set, it will only assign a cached version to clients within the `maxAge`. Afterwards, it will ignored any expired application versions and fetch exclusively from the network. The default is `undefined`, for which the behaviour is the same as it currently is.
PR Close#49601
Remove the usage of MagicString and the generation of intermediate sourcemaps,
as sourcemaps are never included in the schematic bundles. Peparing source maps
is a CPU / memory intensive and was causing OoO errors in rollup.
PR Close#58299
This change introduces a new configuration parameter to the
output as function migration - it is now possible to restrict
a set of migrated paths.
PR Close#58299
Implementations of two rxjs-interop APIs which produce `Resource`s from
RxJS Observables. `rxResource()` is a flavor of `resource()` which uses a
projection to an `Observable` as its loader (like `switchMap`).
PR Close#58255
Implement a new experimental API, called `resource()`. Resources are
asynchronous dependencies that are managed and delivered through the signal
graph. Resources are defined by their reactive request function and their
asynchronous loader, which retrieves the value of the resource for a given
request value. For example, a "current user" resource may retrieve data for
the current user, where the request function derives the API call to make
from a signal of the current user id.
Resources are represented by the `Resource<T>` type, which includes signals
for the resource's current value as well as its state. `WritableResource<T>`
extends that type to allow for local mutations of the resource through its
`value` signal (which is therefore two-way bindable).
PR Close#58255
Currently, `AFTER_RENDER_PHASE_EFFECT_NODE` is not tree-shakable. By wrapping it in an IIFE, it will be annotated as pure, allowing unused code to be removed during the tree-shaking process.
This issue was discovered while investigating: https://github.com/angular/angular-cli/issues/28676.
PR Close#58283
* Improves handling of the query migration is `strict = false` w/
`strictNullChecks` is configured in the project. There is a special
case that needs to be handled; similar to the input migration.
* Improves readability of the code for normal type generic insertion.
The current logic was a little confusing.
PR Close#58265
Adds a combined `@angular/core:signals` migration that combines all of the signals-related migrations into one for the apps that want to do it all in one go.
All of the heavy-lifting was already done by the individual migrations, these changes only chain them together for a more convenient developer experience.
PR Close#58259
Removed two typos in the withHttpTransferCacheOptions function description.
- Corrected spelling of "whether"
- Changed spelling from "a an" to "an"
PR Close#58244
Reports a diagnostic if an NgModule refers to itself in its `imports` or `exports`. Previously the compiler would go into an infinite loop.
Fixes#58224.
PR Close#58231
xterm was not resizing correctly when terminal/console component was resized.
- Load fitAddon for each terminal instance to enable resize.
- Use `ResizeObserver` to detect changes to the component size changes (window resize does not catch `as-split` events).
- Move padding from `.xterm-screen` to `.xterm` ancestor to fix text alignment.
Fixes#52645
PR Close#58257
This change introduces the new reactive primitive: linkedSignal.
A linkedSignal represents state (hence the signal in the name)
that is reset based on the provided computation. Conceptually
it is a state that is maintained / valid only in the context of
another source signal (context is deteremined by a computation).
Closes#55673
PR Close#58189
This commit exposes the new producerMarkClean utility that
makes it possible to mark a reactive node as clean following
changes to the node's value. In practice it resets the dirty
flag and all other internal flags as need. Prior to this change
the cleanup code was duplicated.
The new utility will be used in the linkedSignal implementation.
PR Close#58228
The `@HostBinding` decorator may be currently applied to inputs
directly, or queries. This is not great and should be replaced with
`host: {}` usages that are more close to template expressions anyway.
Migrating the inputs or queries to signals would break with
`@HostBinding`, because the signals need to be invoked to access their
underlying values. The `@HostBinding` does not do this automatically,
expectedly.
PR Close#58243
A unit test has been added to check that `EventEmitter` properly completes upon component/directive destrouction when used with `outputToObservable`.
It explains why `destroyRef` has to be injected in `EventEmitter` in the first place.
PR Close#58239
Introduced back in v15 by #47502, its usage with fix with #55652 for the `FetchBackend` which will become the default `HttpBackend` with #58212
PR Close#58221
The keyvalue pipe sorts the entries of the input by key. This has been the subject of debate in the past (https://github.com/angular/angular/issues/42490). The core of the discussions is that it is often desirable (and perhaps expected) that they natural ordering of the input is respected. There are at least two workarounds to restore natural ordering, such as a `compareFn` that simply returns `1` or a custom pipe. However, both of these require code for pipe consumers to maintain or copy around to many places.
Allowing `null` as `compareFn` and treating it as "natural order" is fairly simple to understand, backward compatible and was suggested a few times on https://github.com/angular/angular/issues/42490 where it seemed to be received well. Using `null` is also possible in templates without any component code changes.
PR Close#57487
Change diagram colors to:
- Better match the overall site theme.
- Improve dark theme.
- Make the diagram easier to understand. "Unchecked" nodes have no color and "Checked" nodes match the color of the "Event" node that triggered the change detection.
Fixes#56314
PR Close#58223
BREAKING CHANGE: Angular directives, components and pipes are now standalone by default. Specify for declarations that are currently declared in s. for v19 will take care of this automatically.
Cleans up the logic that was marking a decorator as standalone after some of the recent changes by:
* Reusing some of the existing logic instead of duplicating it.
* Ensuring that we don't drop cases like an explicit `standalone: true`.
PR Close#58216
Fixes some tests that started failing, because #58154 made it so placeholder-only messages are extracted while #58176 added some tests that only contain placeholders.
PR Close#58217
Prior to this commit, each abstract method that was overloaded was extracted. With this commit it will be extracted only once. Every overload was and still will be supported by the signatures.
fixes#57693
PR Close#57707
Adds the ability to generate the function that replaces the component's metadata during HMR. The HMR update module is a function that is loaded dynamically and as such it has some special considerations:
* It isn't bundled, because doing so will result in multiple version of core.
* Since it isn't bundled, all dependencies have to be passed in as parameters. These changes include some special logic to determine and output those dependencies.
* While HMR is enabled, we have to disable the functionality that generates dynamic imports and drop the dependencies inside `@defer` blocks, because we need to retain the ability to refer to them in case they're needed inside the HMR update function.
* The function is returned by the `NgCompiler` as a string for the CLI's sake.
PR Close#58205
Currently only the prefix of namespace imports is configurable, but for HMR we need to know ahead of time what the name of `@angular/core` will be. These changes allow us to rewrite it.
PR Close#58205
Fixes that the output AST's `RecursiveVisitor` wasn't visiting all the nodes when an arrow function has an implicit return. The problem was that we were calling the `visitExpression` method directly, instead of `.visitExpression`. This doesn't affect existing code since the `RecursiveVisitor` isn't used anywhere, but it will affect future HMR code.
PR Close#58205
Updates the runtime code to account for the upcoming changes to `ɵɵreplaceMetadata`.
I also had to reorganize how the `angularCoreEnv` was set up, because `ɵɵreplaceMetadata` needs access to it without triggering a circular dependency.
PR Close#58205
While effective, `preservePlaceholders` unfortunately is not viable in google3 at the moment due to some complexities with how TC extracts messages. Therefore this feature is being removed in favor of whitespace trimming of expressions, which is viable for TC and provides most of the same benefit.
This is a partial revert of dab722f9c8.
PR Close#58176
This parses and reserializes expressions to normalize their whitespace formatting and make them more durable to insignificant changes in whitespace which might otherwise alter message IDs despite no translator-meaningful change being made.
PR Close#58176
This serializes the expression AST back into a string. This is useful to normalize whitespace in expressions so i18n messages are not affected by insignificant changes (such as going from `{{ foo }}` to `{{\n foo\n}}`).
PR Close#58176
Previously, effect() would handle errors differently depending on the effect
type. Root effects had a try/catch that would execute them independently and
report errors to `ErrorHandler`, while component effects would "crash" CD.
This commit switches all effects to use the same error handling (errors
always reach the CD error handler).
An additional unrelated refactoring is thrown in which removes the
`pendingTask` machinery from root effects, since they make `ApplicationRef`
dirty and thus trigger the scheduler.
PR Close#57952
With this commit, the standalone migration will only migrate code with `standalone: false` to standalone by default (without the standalone attribute)
PR Close#58169
With this commit directives, components & pipes are standalone by default.
To be declared in an `NgModule`, those require now `standalone: false`.
PR Close#58169
When dealing with union types of queries, we should be conservative in
the default mode and skip migration. That is because `viewChild()`
always includes `undefined`, but we cannot trivially emulate the
behavior where it was initially set to `null` (as an alternative to
`undefined`). Those queries can still be migrated via best effort
mode.
PR Close#58190
This will improve cross-target problematic pattern detection, with
batch execution.
Notably, unfortunately, the inheritance checking is still suboptimal for
the queries migration, simply because we don't know what fields are
queries during analyze stage. Theoretically we could track all edges of
classes/fields and filter out irrelevant edges during merge phase, but
this seems out of scope for now.
Signal inputs has the fully working checks. Only issue I can see is that
we don't properly propagate incompatibilities from derived to base
classes. This hasn't come up much though, so may be a follow-up based on
need.
PR Close#58190
We currently extend `.componentInstance` accesses (which are `any` for
`DebugElement`). We are doing this for `By.directive(T)` invocations,
but can expand this for other common expressions like with harnesses.
E.g.
`harness.query(T).componentInstance`.
PR Close#58191
Unfortunately mouseenter is a synthetic event, meaning it does not bubble in the same ways. So mouseover needs to be included in this list in order to get proper browser replayability of the mouse hovering events.
PR Close#58197
This re-organizes the hydration tests to make it easier to add new tests. Incremental hydration can have tests in a separate file after this groundwork is landed.
PR Close#58196
This commit is part of the migration to standalone by default and sets up 2 files with a default value for standalone. They are still `false` in this case to land the change into G3 first. The switch to `true` will be executed in a follow-up PR.
PR Close#58175
For the HMR initializer block to support being used in a Vite setup with
import analysis, the import call expression needs to be a runtime generated
value and include the `@vite-ignore` special comment. Without the first,
Vite will error prior to loading the application. Without the second, a
warning will be shown for each import which is effectively each component
within the application when HMR is enabled.
PR Close#58173
The compiler's AST factories now support generating a dynamic import call
expression with either a string literal or an expression. The later is useful
for cases where the URL is dynamically created at runtime. Also, a leading
comment can now be added to the URL for cases where bundler behavior
needs to be included via special comments.
PR Close#58173
Message which only contain a single placeholder cannot be translated, there is no static text to be translated. Therefore these messages can be skipped and shouldn't be extracted at all.
Ideally, Angular would throw an error if a message is only a placeholder, since it should not contain an `i18n` attribute at all. However this would be a breaking change and require a migration which isn't in scope right now. We can explore converting this to a hard error sometime in the future.
PR Close#58154
In rare cases, there may be queries that fail Angular compiler-cli
extraction. This should not prevent migration of other queries and
instead be a graceful error.
PR Close#58168
This is a follow-up to the VSCode queries code refactoring feature. This
commit adds support for running the refactoring with
`--best-effort-mode`.
PR Close#58168
Currently the migration does not detect queries declared on accessors.
This is fine as we cannot migrate them anyway.
We should still try to detect them and mark them as incompatible so that
we could insert TODOs.
PR Close#58168
Disables the `bazel-saucelabs` job in `main`, and re-uses the PR legacy
saucelabs job to run on `main` instead (which is much more stable and
reliable).
PR Close#58162
Instead of skipping queries without any reasoning, we should categorize
fields that couldn't be migrated. This is also important for the VSCode
integration— similar to how it's done with the inputs migration.
We are fully sharing the problematic pattern detection etc. This means
we are also sharing the enum. Not super ideal, but enables the best
sharing of code.
PR Close#58152
We're using `path.relative` to compute a relative path between a `SourceFile` and the one of the `rootDirs`. The problem is that the `rootDirs` get passed through `getCanonicalFileName` which lowercases the path in some platforms, while `SourceFile.fileName` is always case-insensitive. This yields a path outside of the project which we were ignoring.
This change passes the `SourceFile.fileName` before passing it through `path.relative` to ensure that we get a valid result.
PR Close#58150
This commit updates the table of contents functionality to clean up correctly whenever the user
navigates to other pages and nodes are removed from the DOM.
Currently, calling `renderComponent` with the `TableOfContents` keeps creating a new table of contents
component without removing the previous one, as they are created manually.
This leads to memory leaks because the components cannot be collected properly, even if the user
navigates to the home page where there is no TOC component.
PR Close#58034
parse constructions like `:where(:host-context(.foo))` correctly
revert logic which lead to decreased specificity if `:where` was applied
to another selector, for example `div` is transformed to `div[contenta]`
with specificity of (0,1,1) so `div:where(.foo)` should not decrease it
leading to `div[contenta]:where(.foo)` with the same specificity (0,1,1)
instead of `div:where(.foo[contenta])` with specificity equal to (0,0,1)
PR Close#57796
add support for nested and deeply nested (up to three levels) selectors,
parse multiple :host selectors, scope selectors within pseudo functions
PR Close#57796
allow css combinators within pseudo selector functions, parsing those
correctly. Similarly to previous version, don't break selectors
into part if combinators are within parenthesis, for example
`:where(.one > .two)`
PR Close#57796
fix scoping and transforming logic of the `shimCssText` for the
components with encapsulated view:
- add support for pseudo selector functions
- apply content scoping for inner selectors of `:is()` and `:where()`
- allow multiple comma separated selectors inside pseudo selectors
Fixes#45686
PR Close#57796
We should skip inputs/queries that are part of ternary narrowing
expressions. Those would break builds and we can quickly avoid this in
the safe mode as detection is rather easy with the existing analysis
data we have.
PR Close#58136
Copy and document the refreshAhead option that allows to refresh cache entries before they expire.
This allows to mark cached entries as stale while still retruning them until maxAge in case of service outage.
Closes#46729
PR Close#53356
This commit moves the incompatibility categorization into a more common
place, and renames it from Input incompatibilities to "field
incompatibilities". This construct can then be used in the queries
migration as well to give insight into why certain fields weren't
migrated.
PR Close#58139
The Angular CLI devkit and Tsurge, as well as TypeScript only deal with
Posix paths. We also normalize paths into posix paths, and try to
implement a devkit compatible virtual file system for the compiler-cli.
This commit fixes an issue where we accidentally resolved `/` to the
system root on Windows. e.g. `C:/`. This broke the posix and devkit
paths throughout tsconfig parsing.
This commit fixes this.
Fixes#58132.
PR Close#58137
The `bootstrap()` phase might fail e.g. due to an rejected promise in some `APP_INIIALIZER`.
If `PlatformRef` is not destroyed, then the main app's injector is not destroyed and therefore `ngOnDestroy` hooks of singleton services is not called on the end (failure) of SSR.
This could lead to possible memory leaks in custom SSR apps, if their singleton services' `ngOnDestroy` hooks contained an important teardown logic (e.g. unsubscribing from RxJS observable).
Note: I needed to fix by the way another thing too: now we destroy `moduleRef` when `platformInjector` is destroyed - by setting a `PLATFORM_DESTROY_LISTENER`
fixes#58111
PR Close#58112
The unique name generator did not properly work to avoid collisions with
previously generated unique names. This commit fixes this and also
improves type safety of the logic.
PR Close#58126
We stop tracking `afterRender` hooks as soon as they execute, but their on destroy callbacks stay registered until either the injector is destroyed or the user calls `destroy` manually. This was leading to memory leaks in the `@defer` triggers based on top of `afterRender` when placed inside long-lived views, because the callback would execute, but its destroy logic was waiting for the view to be destroyed.
These changes resolve the issue by destroying the `AfterRenderRef` once it is executed.
PR Close#58119
Angular DevTools uses globally available functions to provide debugging information to the framework. This commit adds a new function to the framework that will allow Angular DevTools to publish these functions to the global namespace.
Follow up PRs that will use this arg will:
- Add a new function in the router package to publish `getLoadedRoutes` function to the global namespace
- Implement the router graph in the Angular DevTools to view the routes that are loaded in the application
PR Close#58086
Make it so that encapsulation for empty styles, styles containing only whitespace and comments, etc.
is handled the same way as with no styles at all.
Components without styles already have view encapsulation set to `None`
to avoid generating unnecessary attributes for style scoping, like `_ngcontent-ng-c1` (#27175)
If the component has an empty external styles file instead, the compiler would generate
a component definition without the `styles` field, but still using the default encapsulation.
This can result in runtime overhead if the developer forgets to delete the empty styles file
generated automatically for new components by Angular CLI.
Closes#16602
PR Close#57130
with latest signal apis there are duplicates dependencies are shown in injected services, this PR filters the depdencies by token and value
PR Close#57564
Consider a template with a context variable `a`:
```
<ng-template let-a>{{this.a}}</ng-template>
```
t push -fAn interpolation inside that template to `this.a` should intuitively read the class variable `a`. However, today, it refers to the context variable `a`, both in the TCB and the generated code.
In this commit, the above interpolation now refers to the class field `a`.
BREAKING CHANGE: `this.foo` property reads no longer refer to template context variables. If you intended to read the template variable, do not use `this.`.
Fixes#55115
PR Close#55183
This commit adds support for converting decorator queries to signal queries
via the VSCode extension.
Note that this is not fully finished as we still need to add better
messaging when certain fields could not be migrated.
In addition, it's worth noting that the migration is not as safe as the
input migration because commonly query lists are passed around— this
quickly can break the build— but is an acceptable trade-off for the work
saved. A migration cannot be 100% correct in general; there are always
edge-cases.
PR Close#58106
Instead of inspecting all types of property accesses, we can use a
similar optimization we did for TS references— leveraging the list of
known field names to minimize type checker calls.
PR Close#58106
Whenever information is requested from the template checker right now,
the shim is only ensured to be generated for the single file/component.
This is slow in migrations where we don't want to collect diagnostics,
but rather request information from the component state.
This commit supports `OptimizeFor` in `checker#getTemplate`.
PR Close#58106
This allows us to return extra properties along with `#migrate`
replacements. Useful for language service integration or other
integrations of Tsurge migrations in special runners.
PR Close#58106
This commit updates the `fetch` patch for zone.js. Currently, we're attaching an
`abort` event listener on the signal (when it's provided) and never removing it.
We should be good citizens and remove event listeners whenever objects need to be
properly collected. In Firefox, when saving a heap snapshot and running it through
`fxsnapshot`, querying `AbortSignal` will print a so-called "CaptureMap" with a list
of "lambdas," indicating that the signal is not garbage collected because of the event
listener lambda function.
PR Close#57882
Currently we don't defer any symbols that have references outside of the `import` statement and the `imports` array. This is a bit too aggressive, because it's possible that the symbol is only used for types (e.g. `viewChild<SomeCmp>('ref')`) which will be stripped when emitting to JS.
These changes expand the logic so that references inside type nodes aren't considered.
**Note:** one special case is when the symbol used in constructor-based DI (e.g. `constructor(someCmp: SomeCmp)`, because these constructors will be compiled to `directiveInject` calls. We don't need to worry about them, because the compiler introduces an addition `import * as i1 from './some-cmp';` import that it uses to refer to the symbol.
Fixes#55991.
PR Close#58104
BREAKING CHANGE: The deprecated `BrowserModule.withServerTransition` method has been removed. Please use the `APP_ID` DI token to set the application id instead.
PR Close#58062
To ensure that the external runtime style component feature is correctly
emitted by the Angular compiler, compliance tests have been added for
file-based component styles. Additionally, the partial golden generator
has been updated to work with file-based component styles.
PR Close#57613
To provide support for HMR of inline component styles (`styles` decorator field), the AOT
compiler will now use the resource host transformation API with the Angular CLI to provide
external runtime stylesheet URLs when the `externalRuntimeStyles` compiler option is enabled.
This allows both a component's file-based and inline styles to be available for HMR when used
with a compatible development server such as with the Angular CLI. No behavioral change is
present if the `externalRuntimeStyles` option is not enabled or the resource host transformation
API is not used.
An `order` numeric field is also added to the transformation API which allows consumers such as
the Angular CLI to create identifiers for each inline style in a specific containing file.
PR Close#57613
The AOT compiler now has the capability to handle component stylesheet files as
external runtime files. External runtime files are stylesheets that are not embedded
within the component code at build time. Instead a URL path is emitted within a component's
metadata. When combined with separate updates to the shared style host and DOM renderer,
this will allow these stylesheet files to be fetched and processed by a development
server on-demand. This behavior is controlled by an internal compiler option `externalRuntimeStyles`.
The Angular CLI development server will also be updated to provide the serving functionality
once this capability is enabled. This capability enables upcoming features such as automatic
component style hot module replacement (HMR) and development server deferred stylesheet processing.
The current implementation does not affect the behavior of inline styles. Only the
behavior of stylesheet files referenced via component properties `styleUrl`/`styleUrls`
and relative template `link` elements are changed by enabling the internal option.
PR Close#57613
In this commit, we update the documentation to reflect the property that allows
enabling the default browser `beforeunload` handling, which was added in a
previous commit.
Additionally, some cosmetic grammar changes have been made in this documentation,
as the previous text had some issues.
Closes#52256
PR Close#57881
In order to investigate the performances of SSR, this commit introduces a benchmark suite which will measure several step of the rendering.
PR Close#57647
Added a new section in the documentation explaining how to lazy load a standalone component using `loadComponent`. This includes a code example demonstrating the setup in Angular routes.
PR Close#57620
Now that effects allow to write to signals (see https://github.com/angular/angular/commit/4e890cc5ac6eaa04a6f7ca988908812a65991c14),
the SIGNAL_WRITE_FROM_ILLEGAL_CONTEXT error is only thrown in `computed` functions.
This commit updates the error message to remove the mention of effects and of the deprecated `allowSignalWrites` option.
PR Close#57973
Fixes that the signal input and queries migration detects code like
`fixture = bla.componentInstance.field` as an incompatible write because
it's part of a binary expression, but we didn't check whether it's part
of the left side.
PR Close#58054
Apply the min() function for set the smallest height
fix(docs-infra): move height into editor-wrapper
Move the calculation rule of height edit into editor-wrapper selector
fix(docs-infra): change has selector
Change the has selector
fix(docs-infra): change selector's for child
Changing the selector for test this solution
Fix
PR Close#54128
Remove max-height: 200px in ul child inline-errors-box, add the overflow & max-height in percentages to the parent for correct visualization
Fixes#52760
refactor(docs-infra): correct typo
Correct typo in comment
feat(docs-infra): modify the height of the editor
If error box are displayed, modify the height of the editor
PR Close#54128
In this commit, we're replacing the provided injector in `afterNextRender` with a node injector
because it was previously mistakenly passing an `EnvironmentInjector`. The `EnvironmentInjector`
resolves `DestroyRef` to itself, meaning that `AfterRenderSequence` is essentially never destroyed
(since the environment injector is not destroyed either).
PR Close#58030
Instead of only migrating `Partial<T>` references to unwrap signal
inputs when all members are migrated, we should do this, even if just a
subset of inputs of the class are migrated.
This is something we saw required manual fixups in google3— so this
commit fixes this.
PR Close#58049
I’ve noticed that there was a loop inside a loop. Since we’re already iterating through
`images` using `forEach`, it was running a `for` loop through `images` again. This was
probably a mistake made when the functionality was initially added. The test actually
verified that `logs.length` is `1`, but in the real environment, it logs twice
(which is quite obvious due to the code).
I’ve also added the missing file to the Bazel target.
PR Close#58021
With the newly-added `RenderMode` config for routes, some of the routes may have the `RenderMode.Client` mode enabled, while also having `provideClientHydration()` function in provider list at bootstrap. As a result, there was a false-positive warning in a console, notifying developers about hydration misconfiguration.
This commit adds extra logic to handle this situation and avoid such warnings.
Note: there is a change required on the CLI side to add an extra marker, which would activate the logic added in this commit.
PR Close#58004
This commit adds an automated `ng generate` schematic/migration for
converting decorator queries to signal queries, as good as possible.
PR Close#58032
Currently if inputs are marked as optional via the question mark syntax,
we add `undefined` only if there is an explicit type. This is wrong as
we should do the same if there is just an initializer.
This commit fixes this.
PR Close#58031
This commit updates the tutorial component's functionality to unsubscribe from the route
data observable and stop monitoring the resizer element when the component is destroyed.
This is necessary because `monitor` adds event listeners that prevent the element and
component from being garbage collected.
PR Close#58028
when initialized from a `Headers` object containing multiple values for the same header, `HttpHeaders` now contains all the header values instead of only having one of them.
Fixes#57798
PR Close#57802
We should support tracking statistics in Tsurge migrations. This allows
us to print them after migration, or run migrations periodically as
large scale changes to track to progress.
TODO is an internal implementation that eventually runs periodcally
in LSC modes.
PR Close#58019
This commit removes event listeners from the `script` element once loading is
complete. If the element is not garbage collected properly, in Firefox, the script
element still appears in the memory tree view, captured by
`__zone_symbol__loadfalse -> HTMLScriptElement -> GC Roots`. We should always be good
citizens and clean up event listeners when we no longer need them, as browser's garbage
collectors work differently. Calling `remove()` on the node doesn't guarantee that the
node can be collected.
PR Close#57877
Instead of leaving incorrect `.first` and `.last` accesses for migrated
queries, we can migrate them to an equivalent using `at()`.
Notably, we need to use an non-null assertion to be on the safe side,
given that the current `first` and `last` types are not typed to include
a potential `undefined`.
We may add a TODO in the future.
PR Close#57992
If we see a reference to e.g. `QueryList#changes`, we should skip
migration to be on the safe side. Similar for other fields of query
lists.
PR Close#57992
This commit updates PullApprove config:
- Removes Dylan
- Adds Alex to the `fw-forms` group
- Adds Charles to the `fw-language-service` group
PR Close#57985
This commit expands the VScode integration of the signal input migration
to allow migration of full classes and all their inputs. This enables a
faster workflow than just migrating every member individually.
In addition, we now properly support migrating classes that are
unexported and no actual metadata is available in `ngtsc` (but this is
fine for the migration).
PR Close#57975
Prior to this commit, the `ImagePerformanceWarning` class was checking all `img`
elements in the DOM to determine whether they were oversized after the DOM loading
was complete. We should not check SVGs because they are vector-based and can scale
infinitely without losing quality.
Closes#57941
PR Close#57966
Some apps follow a pattern where they have an array of common declarations which is imported in most standalone components, but only some of the declarations are used. Such cases will currently raise the unused imports diagnostic but can be hard to fix, because it would require either removing declarations from the common array which can break other components, or copying only the necessary declarations from the array. Since neither of these solutions is great, this commit tweaks the logic for the diagnostic so that unused imports coming from _exported_ arrays are not reported (either from the same file or another one).
PR Close#57940
The shared style host now has the capability to add component styles as
link elements with external style references. This is currently unused
within the runtime but is an enabling feature for upcoming features such
as automatic component style HMR and development server deferred
stylesheet processing. Instead of inline style content that is then
added to a `style` element for each host node, a `link` element with a
stylesheet `rel` attribute and a `href` attribute can now be created.
The development server must be configured to provide the relevant
component stylesheet upon request. The Angular CLI development server
will provide this functionality once this capability is enabled.
Since the primary use of this capability is development mode and will
not be used for production code, server (SSR) style reuse is currently
not yet implemented but may be implemented in the future.
A component feature is used to provide the DOM renderer access to any
external styles that were emitted at compile time. When external styles
are present, the `getExternalStyles` function will be present on the
runtime component metadata object. The DOM render will use this function
to access and encapsulate the external style URLs as required by the
component.
PR Close#57922
This commit updates a golden file with payload sizes for integration apps. One of the sizes got dropped below the threshold (but not significantly), most likely due to changes merged earlier (dependency updates, CLI changes, etc).
PR Close#57986
This update modifies the `getAnswerFiles` function to support file systems that do not adhere to POSIX standards.
Prior to this change this method will always fail with the below:
```
Error: Invalid state: could not find start of answers path
```
PR Close#57970
The batch test was failing (it doesn't run on CI for resource reasons)
because incompatibilities were not properly "incorporated" in batch
execution mode (due to enum values of 0 being incorrectly checked via
truthy).
This is only visible in batch scenarios in two cases:
- when a class was manually instantiated, between targets
- when a class was overridden by a derived class, between targets
PR Close#57961
Instead of printing the full diff, which may be a super large file or
golden, we only print context around lines with diff. This makes the
diffs much more actionable and readable.
PR Close#57961
Adds the new `ɵɵreplaceMedata` function that can be used to replace the metadata of a component class and re-render all instances in place without refreshing the page. The function isn't used anywhere at the moment, but it will be necessary for future functionality.
PR Close#57953
The `SharedStylesHost` class has been refactored to further reduce
the runtime code size. SSR generated component styles are now added directly
into the usage records to avoid the need for additional data structures and
lookups when adding a component style. The code reduction in a prerelease
newly generated Angular CLI application for production is ~190 bytes.
Before:
```
Initial chunk files | Names | Raw size | Estimated transfer size
main-3X2VHGTM.js | main | 208.26 kB | 56.30 kB
polyfills-FFHMD2TL.js | polyfills | 34.52 kB | 11.28 kB
styles-5INURTSO.css | styles | 0 bytes | 0 bytes
| Initial total | 242.78 kB | 67.58 kB
```
After:
```
Initial chunk files | Names | Raw size | Estimated transfer size
main-MGOZ6Q4F.js | main | 208.07 kB | 56.26 kB
polyfills-FFHMD2TL.js | polyfills | 34.52 kB | 11.28 kB
styles-5INURTSO.css | styles | 0 bytes | 0 bytes
| Initial total | 242.59 kB | 67.54 kB
```
PR Close#57951
Add the `strictStandalone` flag to `angularCompilerOptions`. When set to
true, the compiler will require that all declarations of components,
directive, and pipes be standalone. When `standalone: false` is provided,
an error is raised.
Note that until the default value of the standalone flag is flipped, this
does not catch the case where a declaration does not specify a value for
`standalone`.
The default value of the `strictStandalone` flag is `false`.
PR Close#57935
Adds a `manualCleanup` flag to `afterRender` and `afterNextRender`, similarly to `effect`. The reason is that currently if the hook is created outside of an injection context, it requires an injector to be passed in. In some cases that injector might be an injector that is never destroyed (e.g. `EnvironmentInjector`) which can give a false sense of security users thinking that the hook will be cleaned up automatically. We fell into this in the CDK which caused a memory leak (see https://github.com/angular/components/pull/29709). With the `manualCleanup` option users explicitly opt into cleaning the hook up themselves.
PR Close#57917
`@angular/upgrade` writes to inputs when downgrading an Angular 2+ component
into an Angular.JS adapter. Previously, it wrote directly to the input
property, which isn't compatible with input signals. It also handles
`ngOnChanges` directly.
The correct way to support input signals would be to refactor upgrade to use
`ComponentRef.setInput`, which also handles `ngOnChanges` internally.
However, this refactoring might be more breaking since it would change the
timing of certain operations. Instead, this commit updates the code to
recognize `InputSignal` and write it through the `InputSignalNode`. This
avoids the above breaking changes for now, until a bigger refactoring can be
tested.
Fixes#56860.
PR Close#57020
With this commit, we're now able to perform checks even when the image has already
been loaded (e.g., from the browser cache), and its `load` event would never be triggered.
We use the [complete](https://html.spec.whatwg.org/#dom-img-complete) property, as specified,
which indicates that the image state is fully available when the user agent has retrieved all
the image data. This approach effectively triggers checks, as we no longer solely rely on the
`load` event and consider that the image may already be loaded.
This will not remove the placeholder until the `load` event fires (and it won't fire if the
image is already "there").
This prevents memory leaks in development mode, as `load` and `error` event listeners are
still attached to the image element.
PR Close#55444
Whenever the insert TODO option is enabled, we should not insert a TODO
for inputs that were explicitly skipped via config.
This currently causes TODOs to be inserted for inputs outside of the
given `--path`, if the analysis directory is still including files from
outside of the directory.
PR Close#57957
If an input is already skipped from the migration for e.g. being an
accessor, then the fact that it may be incompatible due inheritance is
not relevant. This commit assigns signficance/priority to input
incompatibilities.
This is also important for not accidentally overriding "explicit config
filter" incompatibilities with e.g. accessor incompatibility (which may
be recognized later or visible from another compilation unit).
PR Close#57957
This commit migrates `toArray` and `get` methods of `QueryList`. The
`toArray` method is no longer needed for multi-queries, and `get` can be
replaced with native array `at`.
PR Close#57947
This allows us to detect usages in templates and figure out if they are
e.g. invoking a problematic method like `.pipe` for the output
migration, or in queries `.toArray` etc.
PR Close#57947
According to Choosing event names for Outputs and this line
`Always use camelCase output names. Avoid prefixing output names with "on".`
So I made updates for Function-based outputs chapter in all examples from onNameChange functions to nameChange function
PR Close#57930
This commit marks the contentChild, contentChildren, viewChild
and viewChildren APIs (along with any associated APIs) as stable
and thus exits the dev preview
phase for those APIs.
PR Close#57921
Nothing of concern arose during the time this feature was in the
experimental phase. There are no plans to change the shape of the API.
This change also updates the route animations documentation to use the
view transitions feature instead of the old and difficult to follow
guide that used the animations package. The content was taken from the
blog post: https://blog.angular.io/check-out-angulars-support-for-the-view-transitions-api-3937376cfc19
PR Close#55600
This update addresses a build failure on Windows caused by the previous method, which was incompatible with the Windows environment.
Closes#57920
PR Close#57924
We've been seeing some reports about Angular DevTools being unable to detect applications running in dev mode.
This commit adds more context to the error message displayed when development mode is not detected and offers some possible resolutions.
Displays 3 common reasons why DevTools fails to detect an application running in dev mode. Links directly to angular.dev for relevant configurations.
Links to the Angular DevTools issue template if none of the suggestions work.
PR Close#57861
The `SharedStylesHost` class has been refactored to both reduce the runtime
code size and also modernize some of the code structures. The class is also
adjusted to better support reuse via subclassing or other reuses in the future.
Additional comments have been added to improve readability as well.
The code reduction in a prerelease newly generated Angular CLI application
for production is ~410 bytes.
Before:
```
Initial chunk files | Names | Raw size | Estimated transfer size
main-GOQKBZBZ.js | main | 208.67 kB | 56.41 kB
polyfills-FFHMD2TL.js | polyfills | 34.52 kB | 11.28 kB
styles-5INURTSO.css | styles | 0 bytes | 0 bytes
| Initial total | 243.19 kB | 67.69 kB
```
After:
```
Initial chunk files | Names | Raw size | Estimated transfer size
main-CRTDDKPH.js | main | 208.26 kB | 56.32 kB
polyfills-FFHMD2TL.js | polyfills | 34.52 kB | 11.28 kB
styles-5INURTSO.css | styles | 0 bytes | 0 bytes
| Initial total | 242.78 kB | 67.61 kB
```
PR Close#57834
When running a migration, tsurge creates a TS program from the tsconfig files found.
This can result in a 18003 error when no files are found (based on the includes/files of the config).
For example, the signal input migration throws in a CLI project that has no spec files:
```
ng g @angular/core:signal-inputs --defaults
Tsconfig could not be parsed or is invalid:
No inputs were found in config file '/tsconfig.spec.json'. Specified 'include' paths were '["src/**/*.spec.ts","src/**/*.d.ts"]' and 'exclude' paths were '["/out-tsc/spec"]'.
```
A similar issue has already been raised in the CDK migration (see https://github.com/angular/components/issues/27055).
This was solved in the CDK (credits to @crisbeto) by ignoring the 18003 error (see 9c1112d408361a47c98dfd470b8e990cbd1753db).
This PR does the same in tsurge.
PR Close#57899
This commit drops the `@developerPreview` annotation from the `withEventReplay()` function, which effectively makes the Event Replay feature stable.
PR Close#57895
This commit promotes the `ExperimentalPendingTasks` service from
experimental to developer preview and includes a migration schematic for
the rename.
BREAKING CHANGE: `ExperimentalPendingTasks` has been renamed to
`PendingTasks`.
PR Close#57533
The compiler and its file system implementation expects `fs.exists` to
return `true` even for directories. This caused issues with the TSConfig
resolution as `/` was looked up.
We fix this by making use of `stat` which is equally expensive to
`tree.exists`. The devkit tree's don't expose directory existance checks
out of the box.
Fixes#57887.
PR Close#57897
The batch test (not running on CI due to memory/resource constraints) currently fails
after refactorings we did recently. This commit fixes that there were
two different instances of `sourceFiles string[]`.
PR Close#57883
Instead of running inheritance checking for analyze and migration phases
(in batch mode), we can run once and create a mini-graph in the
compilation unit data. This can then improve lookups and propagation of
incompatibilities.
This commit fixes an issue where a class is chained between three
isolated units and members are overriden. Currently this pattern would
not be checked properly and e.g. an incompatibility of the superclass
would not propagate to derived class, or deeper.
PR Close#57883
This reduces the bytes of the merged compilation unit data, so that we
don't have to transer gigabytes of data to every batch worker. This
reduces quota and helps with reliablity of the migration in 1P.
The references metadata was never needed across units, but an initial
idea to e.g. allow for issuing of CLs based on a graph that we build
after changes computation
PR Close#57883
Currently we support filtering files outside of the project, or source
files via `shouldMigrateInput` option. This works well, but we can
smartly skip inputs in batch migrations if we never saw a source
declaration.
This is an improvement in G3 where we cannot simply limit the migration
to a given directory, because we may include build targets from various
places. E.g. via reverse dependency tracking— so this fixes the issue
naturally.
Notably, an explicit filter would improve reference lookups because we
wouldn't consider the input when determining potential references. That
is because we would know beforehand that those inputs in the `.d.ts`
cannot be migrated inputs— and therefore references with names of the
input would never be verified via expensive type checking.
This is fine for G3 though, and there is no way around this. This is a
slow performance overhead; mostly releveant for VSCode integration.
PR Close#57883
This commit flips the flag that was added in 4e890cc, putting the new effect
timing into... effect :)
BREAKING CHANGE:
Generally this PR has two implications:
* effects which are triggered outside of change detection run as part of
the change detection process instead of as a microtask. Depending on the
specifics of application/test setup, this can result in them executing
earlier or later (or requiring additional test steps to trigger; see below
examples).
* effects which are triggered during change detection (e.g. by input
signals) run _earlier_, before the component's template.
We've seen a few common failure cases:
* Tests which used to rely on the `Promise` timing of effects now need to
`await whenStable()` or call `.detectChanges()` in order for effects to
run.
* Tests which use faked clocks may need to fast-forward/flush the clock to
cause effects to run.
* `effect()`s triggered during CD could rely on the application being fully
rendered (for example, they could easily read computed styles, etc). With
the change, they run before the component's updates and can get incorrect
answers. The recent `afterRenderEffect()` API is a natural replacement for
this style of effect.
* `effect()`s which synchronize with the forms system are particularly
timing-sensitive and might need to adjust their initialization timing.
Fixes#55311Fixes#55808Fixes#55644Fixes#56863
PR Close#57874
The Angular build system recently introduced an opt-in chunk optimizer
for application builds. This is now enabled for adev production builds.
It reduces the initial chunk count from 14 to 1 JavaScript file. While
the raw initial total file size does increase by 0.75% (7.3kB), the total
estimated transfer size decreases by 8% (17.8kB). Not only does this
reduce the amount of data that must be sent over the network but it also
reduces the amount of HTTP requests that must be made by the browser.
While the injected HTML module preloads mitigate request cascades, not
needing to make the requests is even better.
PR Close#56830
In Bazel, the `CI` environment variable is not set due to its hermetic nature. As a result, caching is enabled by default, which includes Vite pre-bundling. This is unnecessary in CI environments.
In some cases, this leads to errors during CI runs when the Vite build is closed or canceled prematurely, resulting in the following errors:
```
Error: R] The build was canceled
Error: R] Terminating worker thread [plugin angular-vite-optimize-deps]
```
PR Close#57863
The original effect design for Angular had one "bucket" of effects, which
are scheduled on the microtask queue. This approach got us pretty far, but
as developers have built more complex reactive systems, we've hit the
limitations of this design.
This commit changes the nature of effects significantly. In particular,
effects created in components have a completely new scheduling system, which
executes them as a part of the change detection cycle. This results in
behavior similar to that of nested effects in other reactive frameworks. The
scheduling behavior here uses the "mark for traversal" flag
(`HasChildViewsToRefresh`). This has really nice behavior:
* if the component is dirty already, effects run following preorder hooks
(ngOnInit, etc).
* if the component isn't dirty, it doesn't get change detected only because
of the dirty effect.
This is not a breaking change, since `effect()` is in developer preview (and
it remains so).
As a part of this redesigned `effect()` behavior, the `allowSignalWrites`
flag was removed. Effects no longer prohibit writing to signals at all. This
decision was taken in response to feedback / observations of usage patterns,
which showed the benefit of the restriction did not justify the DX cost.
The new effect timing is not yet enabled - a future PR will flip the flag.
PR Close#56501
The visitor that all extended diagnostics are based on hadn't implemented the `visitIcu` method which meant that it wasn't detecting any code inside of them.
Fixes#57838.
PR Close#57845
Notably the inheritance checking is less complete as the one in the
input migration. That is because we can't efficiently determine query
fields in the analyze phase of compilation units. Unless we aggresively
consider every field of decorated classes as queries and complexify
the merged metadata significantly, we can't reliably check for cases
where a class is incompatible for migration because it overrides a
member from a class that is in a different compilation unit.
This is an acceptable limitation though (maybe for now), as worst case,
we would migrate the class and the other compilation unit would simply
break. Not ideal, but migrations are impossible to be 100% correct in
general— so not a surprise.
In the future, we may find ways to identify queries more reliably in
analyze phase already. e.g. if the compiler were to include this
metadata in the `.d.ts`, or if we decide to simply add this to the
metadata, accepting potential significant HDD increase.
PR Close#57854
Before this commit, `@let` decleration with an array where mistaken for a component in the lView and throwing an unexpected error.
This commit fixes this.
PR Close#57816
Optional operations that don't run in the actual application compilation
would then cause fatal diagnostic errors breaking the compiler
initialization at runtime.
We should try to keep the migration as close as possible to the
application build.
PR Close#57835
This commit prepares us for sharing the problematic pattern detection,
or inheritance checking. E.g. if a class is manually instantiated, using
certain APIs may not be considered safe. This logic will be shared in
the following commit.
PR Close#57835
Finalizes compiler implementation of the new `hydrate` triggers by:
* Reworking the logic that was depending on the `hydrateSpan` to distinguish hydrate triggers from non-hydrate triggers.
* Fixing that the `hydrate when` trigger didn't have a `hydrateSpan`.
* Adding an error if a parameter is passed into a `hydrate` trigger.
* Add an error if other `hydrate` triggers are used with `hydrate never`.
* Replacing the `prefetch` and `hydrate` flags in the template pipeline with a `modifiers` field.
* Fixing an error that was being thrown when reifying `hydrate` triggers in the pipeline.
* Adding quick info support for the `hydrate` keyword in the language service.
* Adding some tests for the new logic.
PR Close#57831
Introduces a new `ng generate` schematic for migration `@Input()`
declarations to signal inputs.
This migration is the same that is also integrated into the
VSCode extension.
Note: In a follow-up the documentation for this will be improved, and a
flag to report reasons on why certain inputs weren't migrated, is added.
PR Close#57805
Whenever the `ngc` binary is used directly to parse configurations, we
should try to respect the configured file system like we do in all other
places. Right now one spot where we escape the FS is for reading
directories to e.g. support tsconfig#includes.
This commit fixes this, implementing TypeScript's read directory method
leveraging the configured FS. The approach taken here was used for a
couple of months/years for Angular Material migrations and no issues
were found.
PR Close#57805
For component stylesheet hot module replacement scenarios, it will be necessarily to directly
encapsulate a component's stylesheet in a single operation. This currently requires the
consumer of the `encapsulateStyle` helper to use the internal Angular attribute values combined
with a find/replace over the entire stylesheet. To avoid both of these, the helper function now
has an optional second parameter which allows direct and full encapsulation of a style for a given
component when the component identifier is known.
PR Close#57809
This commit marks the input, output and model APIs as stable
(along with the associated APIs) and thus exits the dev preview
phase for those APIs.
PR Close#57804
This helper method is simply a convenience function that reduces some
boilerplate with manually adding and removing a task around some
asynchronous function.
PR Close#56546
The query migration will now fully re-use the reference resolution and
migration logic from the input migration to reliably migrate references
to the new signal properties, supporing control flow outsourcing etc.
PR Close#57777
Commonly when testing Tsurge migrations, we need to diff text content of
files. This commit adds a colored diff helper that makes writing tests
much easier.
PR Close#57777
Dedenting the smallest leading whitespace is useful for conveniently
testing the output of a migration. This commit includes the helper in
Tsurge.
PR Close#57777
This commit introduces an overload for `input` to accept `undefined` as initial value if only
options are needed to be provided, inferring an input of type `T|undefined`. Prior to this change,
the type argument as specified needed to include `|undefined` explicitly even though that isn't
necessary when passing options isn't needed.
Relates to #53909
PR Close#57621
The reference migration code of the signal input migration should be
re-usable as the queries migration needs the exact same.
This builds on top of the shared reference resolution logic from
previous commits. Similarly this commit introduces a small "host" for
providing necessary configurable information about what references
should be migrated; supporting e.g. "input incompatibilities".
This is important as e.g. queries may also be incompatible for migration
and references to such, should not be migrated.
PR Close#57766
Allows us to re-use the reference resolution that works within TS code,
Angular templates, or host bindings. This is helpful for queries
migration which also needs to migrate many references, or allows use in
the output migration.
This is achieved by introducing an abstraction of the "known inputs"
registry we have already, but making it more generic to work with _any_
class fields. Known inputs can then implement/extend this. Queries
similarly.
The "known fields" construct gives insight on field unique IDs etc. This
is then used by the reference resolution to determine if it's a
reference that needs to be captured.
We may move all of this code to Tsurge eventually; depending on how
useful it is. We'll discuss.
PR Close#57766
This change uses the outputToObservable utility function to
convert migrated outputs to Observables. This happens only
in test files as it is a common practice to use RxJS to listen
to events raised by the component under test.
PR Close#57691
Currently several parsing errors in the new control flow (e.g. missing `track` expression) produce errors whose span targets the entire block. This can be really noisy in the IDE where the error can span many lines in the template.
These changes switch to highlighting just the start of the block.
PR Close#57711
Instead of traversing the same paths multiple times, we should avoid
this extra work and optimize. This solves some issues in super large
files with extremely complex flow graphs. E.g. large `ngOnChanges`
functions in Pantheon.
For an example of a flow graph where it doesn't make sense to re-visit
nodes that have multiple incoming edges, see this internal screenshot:
https://screenshot.googleplex.com/6ub4e5e5gbzJAvH
PR Close#57719
Migrations may resolve files in e.g. `blaze-out` and try to compute a
path for the file that is "recognizable" across workers. E.g. in one
worker, it may be the actual `.ts` file inside the source tree, while in
the other, the file may be inside `blaze-out`.
Tsurge currently expects project relative paths to be passed around.
Those project relative paths are currently only based on the single root
directory. Hence paths inside `blaze-out` would actually not be
recognizable.
The fix idea here is that we introduce a structure for Project files.
This structure will contain two fields:
- an ID of a file. This is similar to a module ID in the project. Those
are resolved with respect to all root directories. This matches the
conceptual virtual roots of `tsconfig#rootDirs`. The IDs can be used
for matching files across workers, assuming those are executing using
the same root directories, and handle the same overall project (e.g.
google3).
- a path relative to the primary project root. Multiple roots may be
configured, but the primary project root, is the directory that
contains all others. See: `tsconfig.rootDir`. This path is NOT
necessarily useful for matching files between stages etc, but it's
useful for writing replacements for a given file to disk.
Note that those two things cannot be combind into one conceptual
"project relative path" because a path relative to the most appropriate
root directory cannot be used for safe replacements. E.g. consider a
replacement matches a file from a root directory like `/sub/`. The path
inside `/sub/` would then omit the `/sub/` and later on when writing
replacements, we wouldn't know which root directory it actually was part
of. Hence the concept of a "project root relative path" and the "ID".
ds
PR Close#57677
With the framework enabling `standalone` by default (making module based an opt-in), the migration will migrate none-standalone existing components and add `standalone: false` to the decorator.
PR Close#57643
Currently during the module pruning stage of the standalone migration we assume that any leftover modules which only have `imports` and `exports` can safely be removed. That can be incorrect for the cases where some parts of the app were converted to standalone outside of the migration.
These changes update the logic so that such modules are replaced with the `exports` which are used within the specific component.
Fixes#51420.
PR Close#57684
Add a check to the language service that ignores specified diagnostic codes. This will be useful in g3.
The codes to ignore are exposed as part of the PluginConfig.
Fixes github.com/angular/vscode-ng-language-service/issues/1243
PR Close#57675
Currently the import manager always add a space after the import clause
brace. We should only do this if the existing import did the same.
PR Close#57672
Currently whenever we apply the import manager changes in migations, we
leave the decision of multi-line or single-line to the TS printer.
This works, but in practice can cause signficiant file jumps/changes if
there are large imports that aren't wrapped for example, or the other
way around. We should try to be minimal here and preserve the existing
formatting, assuming that a multi-line import remains multi-line, while
a single-line import remains single-line if it already had many items in
a single line, intentionally.
PR Close#57672
Whenever the signal input migration runs in VSCode, other inputs are
marked as incompatible via the config. Best effort mode currently skips
those incompatibilities and still migrates them. This is incorrect as
the config intends to skip those inputs, regardless of best effort mode.
PR Close#57672
The migration took a type from the directive handler metadata, and
inserted it into a synthetic node for the new input() call. This works
perfectly fine, but in some cases, I saw some `T:VAE` comments attached
🤯 These are from the type checker which attached
synthetic comments to the exact same node.
PR Close#57672
Whenever we migrate object expansion patterns, we may need a temporary
variable to generate a construct like:
```ts
const {bla: blaValue} = this;
const bla = blaValue();
```
We should instead use `blaInput` as the name for the temporary
variable. For narrowing constants, `blaValue` is correct, but here
it's an actual reference to the input / signal.
PR Close#57659
With the preparation work from previous commits, we are able to reduce
analysis time of the migration from e.g. whole Material repo 7seconds to
0.1seconds when the migration is invoked via the VSCode extension.
This is possible because we can avoid many expensive type checking
lookups if we know what inputs are actually migrated. We do this by
adding some naive pre-check to see if identifiers are possibly pointing
to a migrated input.
This is possible now because we no longer migrate aliased identifiers
for object expansion, but instead migrate directly at object
expansion declaration. This allows us to assume that all possible
references to inputs must go through identifiers that are named like
the original input class field name.
PR Close#57659
Instead of printing the enum name as the reason why migration did not
complete, we should print some human-readable descriptions.
This commit implements this. This logic may also be useful for the
devkit comment generation, or CLI usage.
In addition, we expose another VSCode refactoring to try via best effort
mode. There is no way for prompting, or adding multiple actions for the
same refactoring, so we expose a new refactoring.
PR Close#57659
Whenever the signal migration discovers multiple references in the same
control flow container, it assumes narrowing and wants to preserve this
functionality. It does this by introducing temporary variables.
This works fine, but currently there is an edge case with arrow
functions, as those can also turn into blocks, but aren't considered as
such in the current code. This commit fixes this, so that arrow
functions will be converted to be block-based if necessary.
PR Close#57659
This commits extends the decorator-based output migration
to replace .next usage (not supported with the output function)
with .emit (supported in both decorator-based and function based
outputs).
PR Close#57654
Angular 18 introduced fallback content for <ng-content>. This commit updates the docs of content projection guide to contain fallback content for <ng-content>.
PR Close angular#57083
PR Close#57513
Adds a new diagnostic that will report cases where a declaration is in the `imports` array, but isn't being used anywhere. The diagnostic is reported as a warning by default and can be controlled using the following option in the tsconfig:
```
{
"angularCompilerOptions": {
"extendedDiagnostics": {
"checks": {
"unusedStandaloneImports": "suppress"
}
}
}
}
```
**Note:** I'll look into a codefix for the language service in a follow-up.
Fixes#46766.
PR Close#57605
Currently we detect element bindings as normal references and inside
usages we simply unwrap its usages. This works, but breaks in situations
like the following:
- When the expressions are narrowed. Narrowing analysis does not support
aliased inputs. E.g. `const {myInput: alias} = this`. We could add
this, but it would complexify the logic.
- When binding patterns deeply access value properties directly. E.g.
`const {myInput: {value}} = this;`
In addition, the current approach requires us to understand that aliases
may point to inputs. This means we need to check all identifiers if they
point to Angular inputs. We could optimize this, but it's much easier if
we can simply assume that we only need to "verify" identifiers that have
names of "known inputs". This would significantly speed up turnaround in
the language service integration.
In addition, it would be more _correct_, semantically to directly access
the value of the input at object expansion, versus later.
PR Close#57645
Adds logic to capture performance timings when resolving input
references. This is useful for debugging and improving integration in
the VSCode extension.
PR Close#57645
Moves the rather complicated reference migration logic for the input
migration into a separate method. This cleans up the logic and makes way
for an additional complexity with regards to element bindings.
PR Close#57645
This commit shares the logic for looking up a property access, using
`ts.Type` information. This is helpful in case where no linked TS
symbols are available; e.g. templates in test files without TCB.
This helper will be useful for handling object expansion in the signal
input migration; resolving references like `const {x} = this`.
PR Close#57645
Instead of creating instances of refactoring whenever the language
service loads, we should lazily create these upon first "application".
This will speed up loading of the language service, while it also gives
us the ability to implement caching in code refactorings to speed up
subsequent applications; leveraging e.g. the `script versions` from the
TS server project.
PR Close#57645
Implement the `afterRenderEffect` primitive, which creates effect(s) that
run as part of Angular's `afterRender` sequence. `afterRenderEffect` is a
useful primitive for expressing DOM operations in a declarative, reactive
way.
The API itself mirrors `afterRender` and `afterNextRender` with one big
difference: values are propagated from phase to phase as signals instead of
as plain values. As a result, later phases may not need to execute if the
values returned by earlier phases do not change.
PR Close#57549
Previously Elements was assuming that every output was an RxJS `Subject` and
supports `.pipe()`. This is not true for `output()`-based outputs which
have `.subscribe()` but not `.pipe()`. This commit fixes such outputs by
using a `new Observable` instead of `map` to forward outputs.
PR Close#57535
Replaces esbuild with Rollup for bundling schematics to support code splitting, as esbuild does not handle code splitting when targeting CommonJS modules.
**Before:**
```
du -sh dist/bin/packages/core/npm_package/schematics
7.7M dist/bin/packages/core/npm_package/schematics
```
**After:**
```
du -sh dist/bin/packages/core/npm_package/schematics
3.1M dist/bin/packages/core/npm_package/schematics
```
PR Close#57602
This commit updates the public API for pending tasks to schedule an
application tick, effectively making the stability async when the last
task is removed.
PR Close#57570
Instead of some special hook that relies on mutation to filter inputs in
the signal input migration, we are now introducing a new configuration
interface where the language-service can pass a filter method.
This makes the code more readable. We also need the filter method to
support filtering based on directories. E.g. when the migration runs
against sub-folders, all inputs outside of the folder should be
considered incompatible; to not migrate incorrectly.
PR Close#57606
Sometimes `--strictPropertyInitialization` is not enabled, while strict
null checks is enabled. In those cases, `undefined` cannot be used as
initial value with `input()`, nor can we expand the type of the input.
We can migrate those instances to `undefined!` to preserve the original
semantics and behavior. In addition, in the future we may leave a TODO
or we may consider skipping migration of such inputs.
PR Close#57629
Remove specific reference to "Tour of Heroes" tutorial and add sample route for use in the example for reference.
Co-authored-by: Andrew Scott <atscott01@gmail.com>
PR Close#57590
This allows for the replacements to be conveniently passed between
migration stages. This is especially relevant in 1P where stages may
have different root directories.
Tsunami attempts to relativize paths in general, similar to how we do
here, but this doesn't work with e.g. Funnel-based migrations where
replacements are serialized in between stages; and where the migration
stage at the end doesn't know about the previous root directory anymore.
PR Close#57584
This commit changes the structure of the API extraction files to include all symbols used inside a package.
The structure is a `Map`, Symbol => package
eg: 'ApplicationRef' => '@angular/core'
PR Close#57346
This allows us to bundle e.g. the signal input migration into
language-service without duplicating code. Rollup with Bazel may end up
duplicating because it isn't able to associate the local sources with
the linked modules from `node_modules/@angular/compiler-cli`.
PR Close#57214
(experimental at this point)
Language service refactoring action that can convert `@Input()`
declarations to signal inputs.
The user can click on an `@Input` property declaration in e.g. the VSCode
extension and ask for the input to be migrated. All references, imports and
the declaration are updated automatically.
PR Close#57214
VSCode explicitly split code actions into two stages:
- what actions are active?
- what are the edits, if the user presses the button.
The latter stage may take longer to compute complex edits, perform
analysis. This stage is currently implemented via our non-LSP standard
`applyRefactoring` method. We should make it asynchronous, so that it
can easily integrate with migrations that aren't synchronous/or compute
in parallel.
Long-term we may want to revisit this given integration in 1P with the
language service as an actual TS server plugin; but it's not necessary
right now and we shouldn't block the effort on this for now.
PR Close#57214
This allows us to split up the BUILD rules a bit further, so that
refactorings can be their own BUILD target. This is beneficial as
e.g. refactorings may rely on migration code from Angular core etc.
and this allows for more fine-grained visibility and a better conceptual
split.
PR Close#57214
in order for the docs to process function entry, this commit refactor function extraction by keeping the implementation as a the default entry and adds all the overloads into a separate array of entries.
PR Close#56489
Remove hash in link for correct view
Fixes#57349
docs(docs-infra): change the link
Change the link with name of class and method
docs: fix the link name
PR Close#57351
Previously, when "Hide injectors with no providers" was toggled, it is possible for the injector tree visualizer to have no Element injectors to visualize. This caused a bug in the slicing logic that splits apart the environment and element injectors from DI resolution paths within the injector tree component in Angular DevTools.
Now, this logic is correctly handled when there are no element injectors to visualize.
PR Close#57442
We have removed the `esm2022` directory from the generated package, as it was unused and contributed 7.7 MB to `@angular/core`. The `ng_package` rule still passes `esm2022` to the packager to perform `analyzeFileAndEnsureNoCrossImports`.
A moment of reflection:
You've always been there, full of potential, yet never called upon. Now, we bid you farewell.
PR Close#57559
Adds initial migration logic to convert decorator query declarations to
signal queries.
We will re-use more part of the signal input migration in follow-ups, to
properly migrate, and e.g. even handle control flow
PR Close#57556
This change updates the timers used in the coalescing and hybrid mode
schedulers to run in the zone above Angular rather than the root zone.
Running the timers in the root zone makes them impossible to flush when
using `fakeAsync` and also may make them invisible to other zones in the
hierarchy that might have desirable behaviors such as task/perf tracking.
fixes#56767
BREAKING CHANGE: The timers that are used for zone coalescing and hybrid
mode scheduling (which schedules an application state synchronization
when changes happen outside the Angular zone) will now run in the zone
above Angular rather than the root zone. This will mostly affect tests
which use `fakeAsync`: these timers will now be visible to `fakeAsync`
and can be affected by `tick` or `flush`.
PR Close#57553
We had some tests that were leaking LViews, because we were testing things like `createComponent`, but not destroying them afterwards. These changes clean up most of them, although there are a handful still left that I didn't have time to fully track down.
PR Close#57546
When we create the LView for a component, we track it in the `TRACKED_LVIEWS` map. It gets untracked when it is destroy, but if it throws during creation, the user won't have access to a `ComponentRef` in order to clean it up.
These changes automatically untrack the related LViews if the component couldn't be created.
PR Close#57546
This commit reduces the bundle size of `@angular/core` by 19.5 MB by excluding sourcemaps from the schematics.
Since the `esbuild` rule doesn't allow disabling sourcemaps directly, we work around this by setting the sourcemaps to `external`. Afterward, we filter the output to include only the `.js` files.
PR Close#57545
This commit updates a directive mock instance to include an extra field that a compiler code was expecting, which caused issues while processing elements with local refs and exported directives.
PR Close#57537
Adds initial migration logic to convert decorator query declarations to
signal queries.
We will re-use more part of the signal input migration in follow-ups, to
properly migrate, and e.g. even handle control flow
PR Close#57525
Previously, if an application had DOM Nodes injected into it from other frames, DevTools would fail to parse component trees with the render tree strategy properly because of an instanceof Node check that the framework performs.
Now we check for instanceof Node before even calling framework debug APIs on DOM nodes so that we can skip nodes that come from other frames entirely.
PR Close#57518
In some cases apps need to schedule a bit later the loading of the animation module. This private token will allow to investigate which other strategy could be useful.
PR Close#57493
BREAKING CHANGE: Render default fallback with empty `projectableNodes`.
When passing an empty array to `projectableNodes` in the `createComponent` API, the default fallback content of the `ng-content` will be rendered if present. To prevent rendering the default content, pass `document.createTextNode('')` as a `projectableNode`.
For example:
```ts
// The first ng-content will render the default fallback content if present
createComponent(MyComponent. { projectableNodes: [[], [secondNode]] });
// To prevent projecting the default fallback content:
createComponent(MyComponent. { projectableNodes: [[document.createTextNode('')], [secondNode]] });
```
Fixes#57471
PR Close#57480
When disabling `i18nPreserveSignificantWhitespaceForLegacyExtraction` I was looking at a test case with ICU messages containing leading and trailing whitespace:
```angular
<div i18n>
{apples, plural, =other {I have many apples.}}
</div>
```
This would historically generate two messages:
```javascript
const MSG_TMP = goog.getMsg('{apples, plural, =other {I have many apples.}}');
const MSG_FOO = goog.getMsg(' {$ICU} ', { 'ICU': MSG_TMP });
```
But I found that I was getting just one message:
```javascript
const MSG_TMP = goog.getMsg(' {apples, plural, =other {I have many apples.}} ');
```
This is arguably an improvement, but changed the messages and message IDs, which isn't desirable with this option. I eventually traced this back to the `isIcu` initialization in [`i18n_parser.ts`](/packages/compiler/src/i18n/i18n_parser.ts):
```typescript
const context: I18nMessageVisitorContext = {
isIcu: nodes.length == 1 && nodes[0] instanceof html.Expansion,
// ...
};
```
[`_I18nVisitor.prototype.visitExpansion`](/packages/compiler/src/i18n/i18n_parser.ts) uses this to decide whether or not to generate a sub-message for a given ICU expansion:
```typescript
if (context.isIcu || context.icuDepth > 0) {
// Returns an ICU node when:
// - the message (vs a part of the message) is an ICU message, or
// - the ICU message is nested.
const expPh = context.placeholderRegistry.getUniquePlaceholder(`VAR_${icu.type}`);
i18nIcu.expressionPlaceholder = expPh;
context.placeholderToContent[expPh] = {
text: icu.switchValue,
sourceSpan: icu.switchValueSourceSpan,
};
return context.visitNodeFn(icu, i18nIcu);
}
// Else returns a placeholder
// ICU placeholders should not be replaced with their original content but with the their
// translations.
// TODO(vicb): add a html.Node -> i18n.Message cache to avoid having to re-create the msg
const phName = context.placeholderRegistry.getPlaceholderName('ICU', icu.sourceSpan.toString());
context.placeholderToMessage[phName] = this.toI18nMessage([icu], '', '', '', undefined);
const node = new i18n.IcuPlaceholder(i18nIcu, phName, icu.sourceSpan);
return context.visitNodeFn(icu, node);
```
Note that `isIcu` is the key condition between these two cases and depends on whether or not the ICU expansion has any siblings. The introduction of `WhitespaceVisitor` to `I18nMetaVisitor` trims insignificant whitespace, including empty text nodes not adjacent to an ICU expansion (from [`WhitespaceVisitor.prototype.visitText`](/packages/compiler/src/ml_parser/html_whitespaces.ts)):
```typescript
const isNotBlank = text.value.match(NO_WS_REGEXP);
const hasExpansionSibling =
context && (context.prev instanceof html.Expansion || context.next instanceof html.Expansion);
if (isNotBlank || hasExpansionSibling) {
// Transform node by trimming it...
return trimmedNode;
}
return null; // Drop node which is empty and has no ICU expansion sibling.
```
`hasExpansionSibling` was intended to retain empty text nodes leading or trailing an ICU expansion, however `context` was `undefined`, so this check failed and the leading / trailing text nodes were dropped. This resulted in trimming the ICU text by dropping the leading / trailing whitespace nodes. Having only a single ICU expansion with no leading / trailing text nodes caused `_I18nVisitor` to initialize `isIcu` incorrectly and caused it to generate one message instead of two.
`WhitespaceVisitor` is supposed to get this context from `visitAllWithSiblings`. So the fix here is to make sure `WhitespaceVisitor` is always visited via this function which provides the required context. I updated all usage sites to make sure this context is use consistently and implemented the `WhitespaceVisitor.prototype.visit` method to throw when the context is missing to make sure we don't encounter a similar mistake in the future.
Unfortunately this broke one compliance test. Specifically the [`icu_logic/icu_only.js`](/home/douglasparker/Source/ng/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/icu_logic/icu_only.js) test which changed from generating:
```javascript
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
i0.ɵɵi18n(0, 0);
}
// ...
}
```
To now generating:
```javascript
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
i0.ɵɵtext(0, " ");
i0.ɵɵi18n(1, 0);
i0.ɵɵtext(2, "\n");
}
// ...
}
```
This test uses the default value `preserveWhitespaces: false` (`i18nPreserveSignificantWhitespaceForLegacyExtraction` should not affect compiled JS output, we already retain significant whitespace there). So what this indicates to me is that ICU logic is already broken because it's not preserving significant whitespace in this case. My change is probably a bug fix, but one which would affect the compiled runtime, which is not in scope here. The root cause is because using `visitAllWithSiblings` everywhere means the context is retained correctly in this case and the whitespace is leading/trailing an ICU message, therefore it is retained per the logic of `WhitespaceVisitor.prototype.visitText` I mentioned eariler.
To address this, I left one usage of `WhitespaceVisitor` using `html.visitAll` instead of `visitAllWithSiblings` to retain this bug. I has to lossen the assertion I put in `WhitespaceVisitor.prototype.visit` to make this possible, but it should still throw by default when misused, which is the important part.
PR Close#56507
This configures whether or not to preserve whitespace content when extracting messages from Angular templates in the legacy (View Engine) extraction pipeline.
This includes several bug fixes which unfortunately cannot be landed without changing message IDs in a breaking fashion and are necessary to properly trim whitespace. Instead these bug fixes are included only when the new flag is disabled.
PR Close#56507
When disabling autodetect (not recommeneded) with zoneless,
`fixture.detectChanges` would previously not refresh the fixture's component.
PR Close#57416
Disabling `checkNoChanges` in `ComponentFixture.detectChanges` was an
error for the zoneless fixture since it was not yet working. This now
allows checkNoChanges to be disabled. This option isn't really
used/shouldn't be used by anyone except the FW so marked as a refactor.
PR Close#57416
This commit removes the abstract base class and two separate
implementations of `ComponentFixture` for zone vs zoneless. Now that the
behaviors have gotten close enough to the same, the diverged concrete
implementations serve less value. Instead, the different behaviors can
be easily handled in if/else branches. The difference is now limited to
the default for `autoDetect` and how `detectChanges` functions.
PR Close#57416
This commit moves the ngZone onError subscription to the base fixture
implementation. While this subscription isn't necessary for zoneless, it does
no harm because the observable never emits.
PR Close#57416
This commit updates the implementations of `autoDetectChanges` to be
shared between the zone-based and zoneless fixtures. This now allows
`autoDetect` to be turned off for zoneless fixtures after it was
previously on because the host view is no longer directly attached to
`ApplicationRef`.
PR Close#57416
When a browser extension is updated it becomes invalidated on currently open pages. If that extension then tries to send a message to those pages through `chrome.runtime.sendMessage(..)` then an error is thrown in the console
For Angular DevTools, this results in spamming the console with "Uncaught Error: Extension context invalidated." errors.
This commit catches that error and removes the event listener that triggers the `chrome.runtime.sendMessage(...)` call.
PR Close#55697
Previously, the component handler was processing and resolving stylesheets
referenced via `styleUrl`/`styleUrls` multiple times when generating the
compiler metadata for components. The style resource information collection
for such styles has been further consolidated to avoid repeat resource loader
resolve calls which potentially could be expensive. Further optimization is
possible for the inline style case. However, inline styles here only require
AST traversal and no potentially expensive external resolve calls.
PR Close#57502
Angular applications that are AngularJS hybrids are currently unable to
adopt Trusted Types due to violations eminating from an innerHTML
assignment in the @angular/upgrade package. This commit allows
developers of such applications to optionally ignore this class of
violations by configuring the Trusted Types header to allow the new
angular#unsafe-upgrade policy.
Note that the policy is explicitly labeled as unsafe as it does not in
any way mitigate the security risk of using AngularJS in an Angular
application, but does unblock Trusted Types adoption enabling XSS
protection for other parts of the application.
The implementation follows the approach taken in @angular/core;
see packages/core/src/util/security.
PR Close#57454
These should only fire if the target is the same as the targetElement. Also, delete an out of date test since capture/non-capture tests are separately covered.
PR Close#57476
The custom element implementation previously used a custom code path for
setting inputs, which contained bespoke code for writing input properties,
detecting whether inputs actually change, marking the component dirty,
scheduling and running CD, invoking `ngOnChanges`, etc. This custom logic
had several downsides:
* Its behavior different from how Angular components behave in a normal
template.
For example, inputs setters were invoked in `NgZone.run`, which (when
called from outside the zone) would trigger synchronous CD in the
component, _without_ calling `ngOnChanges`. Only when the custom rAF-
scheduled `detectChanges()` call triggered would `ngOnChanges` be called.
* CD always ran multiple times, because of the above. `NgZone.run` would
trigger CD, and then separately the scheduler would trigger CD.
* Signal inputs were not supported, since inputs were set via direct
property writes.
This change refactors the custom element implementation with two changes:
1. `ComponentRef.setInput` is used instead of a custom code path for
writing inputs.
This allows us to drop all the custom logic related to managing
`ngOnChanges`, since `setInput` does that under the hood. `ngOnChanges`
behavior now matches how the component would behave when _not_ rendered
as a custom element.
2. The custom rAF-based CD scheduler is removed in favor of the main Angular
scheduler, which now handles custom elements as necessary.
Running `NgZone.run` is sufficient to trigger CD when zones are used, and
the hybrid zoneless scheduler now ensures CD is scheduled when `setInput` is
called even with no ZoneJS enabled. As a result, the dedicated elements
scheduler is now only used when Angular's built-in scheduler is disabled.
As a concession to backwards compatibility, the element's view is also
marked for refresh when an input changes. Doing this allows CD to revisit
the element even if it becomes dirty during CD, mimicking how it would be
detected by the former elements scheduler unconditionally refreshing the
view a second time.
As a part of this change, the elements tests have been significantly
refactored. Previously all of Angular was faked/spied, which had a number
of downsides. For example, there were tests which asserted that change
detection only happens once when setting multiple inputs. This wasn't
actually the case (because of `NgZone.run` - see logic above) but the test
didn't catch the issue because it was only spying on `detectChanges()` which
isn't called from `ApplicationRef.tick()`. Even the components were fake.
Now, the tests use real Angular components and factories. They've also been
updated to not use `fakeAsync`.
A number of tests have been disabled, which were previously asserting
behavior that wasn't matching what was actually happening (as above). Other
tests were disabled due to real differences with `ngOnChanges` behavior,
where the current behavior could be seen as a bug.
Fixes#53981
BREAKING CHANGE: as part of switching away from custom CD behavior to the
hybrid scheduler, timing of change detection around custom elements has
changed subtly. These changes make elements more efficient, but can cause
tests which encoded assumptions about how or when elements would be checked
to require updating.
PR Close#56728
This removes an unnecessary type wrapping that can be removed because
`Replacements` is expected to be serializable by default.
Similar to how it's done in `TsurgeComplexMigration`.
PR Close#57501
The `afterRender` infrastructure was first implemented around the idea of
independent, singular hooks. It was later updated to support a spec of
multiple hooks that pass values from one to another as they execute, but the
implementation still worked in terms of singular hooks under the hood. This
creates a number of maintenance issues, and a few bugs. For example, when
one hook fails, further hooks in the pipeline should no longer execute, but
this was hard to ensure under the old design.
This refactoring restructures `afterRender` infrastructure significantly to
introduce the concept of a "sequence", a collection of hooks of different
phases that execute together. Overall, the implementation is simplified
while making it more resilient to issues and future use cases, such as the
upcoming `afterRenderEffect`.
As part of this refactoring, the `internalAfterNextRender` concept is
removed, as well as the unused `queueStateUpdate` concept which used it.
PR Close#57453
Previously the zoneless scheduler had a concept of whether views needed to
be refreshed or not, based on the notification type that was received. It
tracked this information as a boolean.
This commit refactors things to track dirtiness in `ApplicationRef` itself,
as a `dirtyFlags` field with bits corresponding to either view tree
dirtiness or after-render hooks.
PR Close#57453
Introduces a simpler, smaller variant of the current `Tsurge` migration
class. The difference is simply that for the migration phase (the third
stage), some migrations do not need a full set of workers re-analyzing
every compilation unit again to compute the "final migration
replacements".
This can be the case, for example, if a migration eagerly computes all
replacements in the analyze stage, visiting every unit, and then after
deriving the global metadata, problematic replacements are simply
filtered (e.g. via some unique IDs again).
PR Close#57484
This commit adds indentations to the file tree section in `app-shell.md`, it makes the tree easier to read. The indentation is now two spaces instead of no spaces.
PR Close#57436
docs(docs-infra): add top level banner component
- create top level banner component
- write unit tests
- close banner and keep state in the local storage
- fix: support screens of tablets and phones
PR Close#57458
This commit adds an internal util method that allows to detect:
* which selectors are matching nodes in a template
* which pipes are present in a template
Both directives and pipes are split into 2 buckets: eagerly used and the ones that might potentially be defer-loaded.
PR Close#57466
Previously, style elements within a template were used directly and not provided
to the optional transformation step that may be present on the resource host interface.
This causes such styles to not be processed by the Angular CLI's stylesheet pipeline
and could cause the styles to not work properly on all browsers. The style elements
are now processed in the same manner as inline styles within a component's metadata.
Link elements within a stylesheet were already being processed as `styleUrls`
equivalent and there is no behavior change in that regard.
PR Close#57429
This commit simplifies the batching support for the signal input
migration by using the new tsurge framework we've built.
This allows for consistent setup across all possible entry-points and
also simplifies the 1P setup given that we can simply use the Tsurge
macros, instead of having to maintain our own Go-based runner.
PR Close#57451
* Improves some of the generic assignability for tsurge. Anything is
allowed to be returned from an overridden `prepareProgram` method.
This is useful for the signal input migration.
* Passes the absolute root paths to migrations. This is helpful for the
signal input migration and there is no other way to access it. It's
better to pass specifically, compared to passing the whole unsafe
`ParsedConfiguration` object.
PR Close#57451
Introduces a migration framework to build batchable migrations that
can run in Large Scale mode against e.g. all of Google, using workers.
This is the original signal input migration infrastructure extracted
into a more generic framework that we can use for writing additional
ones for output, signal queries etc, while making sure those are not
scoped to a single `ts.Program` that limits them to per-directory
execution in very large projects (e.g. G3).
The migration will be updated to use this, and in 1P we will add
helpers to easily integrate such migrations into a Go-based pipeline
runner.
PR Close#57396
This commit updates the CHANGELOG to remove an entry about a breaking change in Zone.js, since the change was not actually released. It will be released separately in Zone.js package.
PR Close#57419
The migration was migrating all files in a project (like most migrations).
As there is no gain in migrating components used in test files. Excluding the test files reduces the migration noise.
PR Close#57317
This commit fully integrates the `autoDetect` feature into
`ApplicationRef.tick` without special handling for errors.
This commit also shares the method of autoDetect for change detection between
the zoneless and zone component fixture implementations. The difference
is now limited to:
* autoDetect is defaulted to true with zoneless
* detectChanges with zoneless is AppRef.tick while it is
ChangeDetectorRef.detectChanges with zones. This should likely
converge more in the future. Not going through AppRef.tick means that
the zone fixture does not get guaranteed `afterRender` executions and
does not get the rerunning behavior if the fixture is marked dirty by
a render hook.
BREAKING CHANGE: The `autoDetect` feature of `ComponentFixture` will now
attach the fixture to the `ApplicationRef`. As a result, errors during
automatic change detection of the fixture be reported to the `ErrorHandler`.
This change may cause custom error handlers to observe new failures that were previously unreported.
PR Close#55228
The zoneless scheduler callback was executed in the root zone rather
than simply in `runOutsideAngular` to allow us to land the hybrid mode
change detection (scheduler always enabled, even for zones) without
breaking a ton of existing `fakeAsync` tests that could/would fail with
the "timer(s) still in queue" error. However, this caused another
problem: when a test executes inside `fakeAsync`, it cannot flush the
scheduled time. A similar problem exists with event and run coalescing (#56767).
This change would allow `fakeAsync` to flush the zoneless-scheduled
change detections and minimize breaking existing tests
by flushing pending timers at the end of the test, which actually now
matches what's done internally.
PR Close#56932
Updates the migration so that it passes the type as a generic in the case of `@Inject(SOME_TOKEN) foo: SomeType`. This is done for two reasons:
1. It's a fairly common pattern and it ensures that the code can still be compiled.
2. It avoids leaving behind unused imports.
PR Close#57389
This commit fixes an issue when hydration serialization tries to calculate DOM path to a content projection node (`<ng-content>`), but such nodes do not have DOM representation.
Resolves#56750.
PR Close#57383
This commit updates the search results to query for the content as well
as a snippet of the content for display when it's the content that
matches the query rather than any of the headers.
PR Close#57298
Makes it so the inject migration preserves the optional token when declaring a parameter. This came up in some testing as something that can be potentially breaking for classes that implement interfaces.
PR Close#57367
This commit fixes an issue that happens when an i18n block is defined as a projectable content, but a parent component doesn't project it. With an extra check added in this commit, the code will be taking a regular "creation" pass instead of attempting hydration.
Resolves#57301.
PR Close#57356
Signal inputs are no longer updated by assignment, unlike `@Input()`, so
a good practice is adding `readonly` for the `InputSignal`— which should
never be swapped out.
This is a safe operation because the migration skips all inputs that are
being written anyway.
PR Close#57368
In some cases, the migration can detect when `input()` as a shorthand
may be usable. This commit adds such detection and migrates inputs to
this form when possible.
PR Close#57368
Components with `jit: true` are not processed by the Angular compiler,
so we cannot ask the template checker for the parsed template; simply
because the template wasn't attempted to be parsed.
We still can migrate simple cases of such components, commonly seen in
unit tests. We do this by manually parsing the template and making use
of the reference fallback resolution that is also used for host bindings
(where we don't have any type check block information).
PR Close#57347
Instead of exposing just the `ts.CompilerOptions`, we should expose the
actual Angular compiler options throuhgout the signal input migration.
This will be useful for parsing templates, in cases of JIT-opted
components.
PR Close#57347
As of this commit, the migration will also inspect safe property reads
and migrate them, if they reference an input that is being migrated.
PR Close#57318
Instead of revisiting each source file, and each of its child nodes
twice, we now visit them together using a grouped AST visitor that only
traverses each source file once.
This seemed to speed up migration by 6-8% locally, but is likely
noticable better with large compilation scopes.
PR Close#57318
Instead of fiddling manually with the imports, which worked well, but
comes at a cost of complexity— we are now using the canonical import
manager. This simplifies deletion, insertion and updating of imports.
Notably, our import manager is not super great at preserving whitespaces
right now, but we assume a formatter runs over migrated code anyway.
PR Close#57318
Introduces a best effort mode for the signal input migration. This mode
can be used to aggresively migrate as much as possible, ignoring most
of the incompatibility reasons, like "writes to the input".
PR Close#57318
Errors during change detection from `ApplicationRef.tick` are only
reported to the `ErrorHandler`. By default, this only logs the error to
console. As a result, these errors can be missed/ignored and allow tests
to pass when they should not. This change ensures that the errors are
surfaced. Note that this is already the behavior when zoneless is
enabled.
BREAKING CHANGE: Errors that are thrown during `ApplicationRef.tick`
will now be rethrown when using `TestBed`. These errors should be
resolved by ensuring the test environment is set up correctly to
complete change detection successfully. There are two alternatives to
catch the errors:
* Instead of waiting for automatic change detection to happen, trigger
it synchronously and expect the error. For example, a jasmine test
could write `expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()`
* `TestBed` will reject any outstanding `ComponentFixture.whenStable` promises. A jasmine test,
for example, could write `expectAsync(fixture.whenStable()).toBeRejected()`.
As a last resort, you can configure errors to _not_ be rethrown by
setting `rethrowApplicationErrors` to `false` in `TestBed.configureTestingModule`.
PR Close#57200
This change aligns the behavior of the error handler in the
`ExtraOptions` of `RouterModule.forRoot` with the error handler in
`withNavigationErrorHandler`. The changes are:
* Slightly different timing: The handler is called before the
`NavigationError` emits
* Runs in the injection context, meaning it is more configurable at the
config location rather than needing to assign the value to the
`Router.errorHandler` later to get access to injectables
* Can now return `RedirectCommand` to recover from the error and
redirect without emitting `NavigationError`
* No longer allows arbitrarily overriding return value of the navigation
promise
BREAKING CHANGE: The `Router.errorHandler` property has been removed.
Adding an error handler should be configured in either
`withNavigationErrorHandler` with `provideRouter` or the `errorHandler`
property in the extra options of `RouterModule.forRoot`. In addition,
the error handler cannot be used to change the return value of the
router navigation promise or prevent it from rejecting. Instead, if you
want to prevent the promise from rejecting, use `resolveNavigationPromiseOnError`.
PR Close#57050
This commit updates the interface of `Resolve` to allow for
`RedirectCommand`, as was done with `ResolveFn` in v18.
fixes#57131
BREAKING CHANGE: The return type of the `Resolve` interface now includes
`RedirectCommand`.
PR Close#57309
This commit adds an input to `RouterOutlet` that allows developers to
pass data from a parent component to the outlet components.
Setting the `routerOutletData` input on `RouterOutlet` makes the value
available to the child component injectors via the `ROUTER_OUTLET_DATA`
token. This token uses a `Signal` type to allow updating the input value
and propogating it to the token rather than needing to make the value
static.
resolves#46283
PR Close#57051
This commit updates serialization and hydration i18n logic to take into account situations when i18n blocks are located within "skip hydration" blocks.
Resolves#57105.
PR Close#57299
Previously, if a component injects a `ViewContainerRef`, the post-hydration cleanup process doesn't visit inner views to cleanup dehydrated views in nested LContainers. This commit updates the logic to recognize this situation and enter host LView to complete cleanup.
Resolves#56989.
PR Close#57300
By default, we don't migrate inputs if they are part of e.g. `@if` for
now. That is because we don't have the template narrowing feature
available yet.
To improve impact of the migration until we have the narrowing, we add
some additional checks that allow us to migrate instances of inputs that
are part of e.g. `@if` but are actually not used inside (and hence are
guaranteed to be _not_ narrowed).
PR Close#57308
This commit updates the inside/outside NgZone detection of the hybrid CD
scheduling to track the actual instance of the NgZone being used rather
than the name "Angular" (how `isInsideAngularZone` works). This allows
the scheduling to work correctly when there are multiple versions of
Angular running on the page.
fixes#57261
PR Close#57267
Currently in some scenarios the compiler generates code like `null as any ? foo : bar` which will be invalid with [an upcoming TypeScript change](https://devblogs.microsoft.com/typescript/announcing-typescript-5-6-beta/#disallowed-nullish-and-truthy-checks). These changes switch to generating `0 as any` which is exempt from the change.
**Note:** I'm not starting the work to fully get us on TS 5.6 until the 18.2 release comes out, but this change is necessary to unblock an internal team.
PR Close#57303
This changes the migration so that we don't generate `_1` suffixes when
a temporary variable wouldn't conflict with any variables in the lexical
scope.
In addition, if we discover conflicts, we try alternative suffixes that
seem more natural and follow style guides. E.g. `Value`, `Val` or
`Input`.
PR Close#57292
Currently we use some short variable names like `t` and `r` in the generated factory functions. They can conflict with local symbols with the same names, if they're used for DI.
These changes rename the parameters to reduce the change for conflicts.
Fixes#57168.
PR Close#57181
This commit addresses a performance bottleneck in the `interpolatedSignalNotInvoked` extended
diagnostic by querying directive metadata instead of consulting the type-checker to determine if
a property binding corresponds with an input.
Fixes#57287
PR Close#57291
These changes replace most usages of `removeChild` with `remove`. The latter has the advantage of not having to look up the `parentNode` and ensure that the child being removed actually belongs to the specific parent.
The refactor should be fairly safe since all the browsers we cover support `remove`. [Something similar was done in Components](https://github.com/angular/components/pull/23592) some time ago and there haven't been any bug reports as a result.
PR Close#57203
From the internal issue on the matter:
> When using the standard Jasmine version of it promises returned by the body function are automatically awaited. The Catalyst version of it is fake-async, so awaiting the promise does not make sense; however it would be nice if Catalyst automatically flushed the promise to replicate the experience of using standard it. This would allow users to do the following:
```
it('should fail later', async () => {
await new Promise(r => setTimeout(r));
fail('failure');
});
```
> In Catalyst today the above test will pass. If this proposal to automatically flush the resulting promise were implemented it would fail.
Flushing after the tests complete has been the default behavior inside
Google since 2020. Very few tests remain that use the old behavior of
only flushing microtasks. The example above would actually fail with
`fakeAsync` due to the pending timer, but the argument still remains the
same. We might as well just flush if we're going to fail the test
anyways by throwing if there's no flush at the end.
BREAKING CHANGE: `fakeAsync` will now flush pending timers at the end of
the given function by default. To opt-out of this, you can use `{flush:
false}` in options parameter of `fakeAsync`
PR Close#57240
From the internal issue on the matter:
> When using the standard Jasmine version of it promises returned by the body function are automatically awaited. The Catalyst version of it is fake-async, so awaiting the promise does not make sense; however it would be nice if Catalyst automatically flushed the promise to replicate the experience of using standard it. This would allow users to do the following:
```
it('should fail later', async () => {
await new Promise(r => setTimeout(r));
fail('failure');
});
```
> In Catalyst today the above test will pass. If this proposal to automatically flush the resulting promise were implemented it would fail.
Flushing after the tests complete has been the default behavior inside
Google since 2020. Very few tests remain that use the old behavior of
only flushing microtasks. The example above would actually fail with
`fakeAsync` due to the pending timer, but the argument still remains the
same. We might as well just flush if we're going to fail the test
anyways by throwing if there's no flush at the end.
PR Close#57239
Similar to a previous fix that intended to make the JIT transforms
compatible with pre-transforms like e.g. Tsickle, we need to solve
an additional issue where the class properties are synthetic and result
in an `getSourceFile() => undefined` invocation that breaks the import
insertion, causing errors like:
```
TypeError: Cannot read properties of undefined (reading 'fileName')
```
PR Close#57262
From the internal issue on the matter:
> When using the standard Jasmine version of it promises returned by the body function are automatically awaited. The Catalyst version of it is fake-async, so awaiting the promise does not make sense; however it would be nice if Catalyst automatically flushed the promise to replicate the experience of using standard it. This would allow users to do the following:
```
it('should fail later', async () => {
await new Promise(r => setTimeout(r));
fail('failure');
});
```
> In Catalyst today the above test will pass. If this proposal to automatically flush the resulting promise were implemented it would fail.
Flushing after the tests complete has been the default behavior inside
Google since 2020. Very few tests remain that use the old behavior of
only flushing microtasks. The example above would actually fail with
`fakeAsync` due to the pending timer, but the argument still remains the
same. We might as well just flush if we're going to fail the test
anyways by throwing if there's no flush at the end.
PR Close#57137
Angular's template files are not valid TypeScript. Attempting to get suggestion
diagnostics from the underlying TypeScript language service will result in
a large amount of false positives. Only actual TypeScript files should
be analyzed by the underlying TypeScript language service for suggestions.
PR Close#56241
This commit adds an option to specify the default value for
`queryParamsHandling` in `Router.createUrlTree` when another option is
not specified (or is `null|undefined`).
resolves#12664
PR Close#57198
This was an old feature that mapped shift + click (et al) to "clickmod". This doesn't really make sense to add to Angular, so let's remove it.
PR Close#57201
This change is a proof of concept of how the new Chrome DevTools
Performance extension API (https://bit.ly/rpp-e11y) can be used to
surface Angular runtime data directly in the Chrome DevTools Performance
panel.
Specifically, it implements the following changes:
1. Use the profiling status notification API to toggle the Timing API:
The notification API is implemented under the
chrome.devtools.performance extension namespace and consits of two
events: ProfilingStarted and ProfilingStopped, dispatched when the
Performance panel has started and stopped recording, respectively. This
API is used to enable the Timings API when the recording has started in
the Performance panel and disable it when recording has stopped.
2. Use the User Timings `detail` field format specification of the
Performance extension API
(https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/User_timing)
to inject data collected by the Angular Profiler into the
Performance panel timeline. Angular Profiler uses several hooks to
measure framework tasks like change detection. With this change, this
measurements are visible in the same context as the runtime data
collected by the browser in the Performance Panel timeline.
Note: to enable the user timings to be collected in the first place, one
needs to open the Angular DevTools panel so that the related artifacts
are loaded in the page. This shortcoming can be fixed in a follow up so
that the extra step isn't necessary.
PR Close#55805
Lock file maintenance updated Terser, which impacts the bundle
optimizations being tested via the symbol golden tests.
There was a small noticable change in the symbol golden where
`withDomHydration` is now preserved, and the underlying function
that was previously detected is gone. Seemingly Terser now inlines
this function and had to preserve `withDomHydration` as the entry point.
PR Close#57205
The new package comes with types by default, and also has a nicer
API.
The old package had broken types and couldn't be used anymore; and
it's deprecated/unmaintained. We did a similar switch in
angular/dev-infra.
PR Close#57205
This commit is similar to 98ed5b609e, and
makes use of the preparation work implemented there.
Similar to directives and components marked via `jit: true`, we also
need to do the same for JIT marked `@NgModule` classes. This is mostly
important for downleveling of decorators to support dependency injection
of such classes.
Inside Google3, migrating from `ts_library` to `ng_module` turns of
decorator downleveling, so the `jit: true` for NgModule's is implicitly
requesting/reliant on this transform— as expected.
PR Close#57212
Rather than leaving the timers around as no-ops, this commit updates the
logic to also attempt to clear or cancel the timers. This is helpful for
the eventual goal of running the scheduler in the `fakeAsync` zone (if
the test is running in `fakeAsync`) rather than scheduling in the root
zone and making it impossible to flush.
PR Close#57186
This creates a private option that can be used internally while we
migrate this to the default and only behavior. ~200 tests in TGP have errors
that are being swallowed (console.log) and not causing the test to fail.
We can first explicitly opt those out, flip the default internally, then
"fix" them by adding expect...toThrow.
PR Close#57153
This commit adds the `ImagePerformanceWarning` to the common bootstrap
code rather than only starting it when using `bootstrapApplication`.
PR Close#57060
This commit de-duplicates the code for bootstrapping between
`bootstrapApplication` and `bootstrapModule`. A majority of the
bootstrap code was identical between the two, with some minor
differences that can be handled with a function overload.
PR Close#57060
This commit allows configuring `NgZone` through the providers for
`bootstrapModule`. Prior to this change, developers had to configure
`NgZone` in the `BootstrapOptions`.
PR Close#57060
fix(docs-infra): skip navigation to card if user clicks on anchor
If user clicks on anchor inside member card (Reference) then skip navigation to card section and allow to navigate to anchor link.
Use correct RxJs operator.
Fix DI: destroy ReferenceScrollHandler when navigate outside of reference pages.
fix: scroll to the of the card only after click on card header
fix: remove import of filter operator
PR Close#57081
Fixes that we were throwing an assertion error during hydration if a `@let` declaration is used before and immediately inside of a container.
Fixes#57160.
PR Close#57173
To increase the ease of development we are moving @angular/docs into the adev directory within this repo. While
we are doing this to improve our development experience in the short term, efforts are also in place
to maintain a division between this @angular/docs (shared) code and adev itself, so that it can be extracted
back out in the future when components is ready to leverage it as well.
PR Close#57132
The behavior of `ComponentFixture` for zoneless tests was decided somewhat through guesswork, trial, and error. In addition, working on the zoneless fixture revealed oddities in the behavior of the zone-based fixture, or behaviors that we felt were counterintuitive. The most consequential difference is how change detection works: `detectChanges` goes through ApplicationRef.tick in zoneless while it is `changeDetectorRef.detectChanges` in the zone fixture.
We felt that running change detection through `ApplicationRef.tick` was important for several reasons:
* Aligning application behavior more closely with the test behavior (almost all views are attached to application ref in reality)
* Ensuring that afterRender* hooks are executed when calling `fixture.detectChanges`
* Ensuring that the change detection runs again if render hooks update state
This change, however, has some noticeable consequences that will break some tests, mostly around how errors are handled. `ApplicationRef.tick` catches errors that happen during change detection and reports them to the ErrorHandler from DI. The default error handler only logs the error to the console. This will break tests which have `expect(() => fixture.detectChanges()).toThrow()`. In addition, it allows tests to pass when there are real errors encountered during change detection.
This change ensures that errors from `ApplicationRef.tick` are rethrown
and will fail the test. We should also do a follow-up investigation to
determine whether we can/should also do this for the zone-based
`ComponentFixture`.
fixes#56977
PR Close#56993
When on a certain width, the tab-bar width glitch back-and-forth and forcing the 2 other buttons to reduce their width. This glitches appeared when we introduced that 2nd button.
fixes#57143
PR Close#57172
The `inject` migration can leave some unused imports behind when it removes decorators like `@Inject`. These changes add some logic to remove them.
PR Close#57179
Makes a few optimizations in the utilities we use for dealing with imports in migrations. I didn't end up using these in the inject migration, but they should still come in handy. Includes:
1. Exiting `isReferenceToImport` early when the node being checked is an identifier and it doesn't match the identifier of the import. This saves us some type checker calls.
2. Adds the ability to pass a single string to `getImportSpecifiers`. This saves us unnecessary arrays and for loops.
PR Close#57179
Currently we use some short variable names like `t` and `r` in the generated factory functions. They can conflict with local symbols with the same names, if they're used for DI.
These changes add a `ɵ` to the generated variables to reduce the chance of conflicts.
Fixes#57168.
PR Close#57181
Dev-infra recently upgraded to Renovate version 38. This update causes `matchDepPatterns` to only accept RegExp. Since we require a glob pattern, we will now use `matchPackageNames`, which supports glob patterns and is already used in the configuration.
Updates the inject migration to unwrap the `forwardRef` call in cases like `constructor(@Inject(forwardRef(() => Foo)) foo: Foo);`, because the `forwardRef` will type the initializer to `any` and it shouldn't be necessary.
PR Close#57127
This can up in Material where we had a `constructor(@Optiona() foo: Foo | null)` which ended up producing incorrect code, because the union type was preserved.
These changes resolve the issue by picking out the first non-literal type from the union for the `inject` call.
PR Close#57127
Currently if an injected type has type arguments, we copy it over together with the type arguments to inject, because `inject()` isn't able to infer the generic properly otherwise. E.g. if there's `constructor(el: ElementRef<HTMLElement>)` we produce `inject<ElementRef<HTMLElement>>(ElementRef<HTMLElement>);`.
These changes drop the generics from the `inject()` parameter since we're overwriting the type anyway. The example from above would become `inject<ElementRef<HTMLElement>>(ElementRef);`.
PR Close#57127
Follow-up to #56961 which doesn't appear to have caught all the cases. This change moves the pre-emit untagging to `NgCompiler.prepareEmit` which seems to cover a bit more comared to `NgtscProgram.emit`.
Fixes#57135.
PR Close#57138
This reverts commit 66ffeca2de.
It looks like nuxt encountered the same issue with scrolling when
waiting for Vue's `nextTick`, which is a microtask. This would have
similar timing to ZoneJS's rendering in the microtask queue. This
reverts to a `setTimeout` alone, though recreates the problem in #53985.
This was also mentioned in one of the comments in the Nuxt issue and the
solution would be `rAF`.
In order to address #53985, we'd likely want to use the `race(rAF, setTimeout)`
that we use in the zoneless and coalescing schedulers. This would have effectively the same timing as
the `afterNextRender` implementation here with zoneless, but quite
different timing to `afterNextRender` with ZoneJS.
fixes#57109
PR Close#57115
The test was broken because multiple errors happen and the last error would be the displayed message.
However, in this case, those errors happen because the initial one already terminated the container
so the follow-up errors are a result of the service being in an unexpected state
PR Close#57104
Updates the import manager to allow for a specific alias to be passed in. This is a prerequisite for switching schematics to the new import manager.
Note that passing in an alias disables identifier conflict resolution in order to avoid rewriting the alias that was passed in explicitly. For now this is fine since we have a very narrow use case for it, but we may want to revisit it in the future.
PR Close#57096
This commit adds golden tests for the signal input migration, along with
a tool to execute and automatically test the migration via the batch
mode, treating a single file as compilation unit.
PR Close#57082
This commit adds the batching logic helpers for running the signal
migration as a sharded/parallel action in Google3 and potentially
externally. The helpers are the main entry points for go/tsunami.
PR Close#57082
Adds the migration phase for migrating inputs and references. Thise
phase may execute as the third step when batching.
The migration is intentionally split into three phases:
1. Extract and analyze
2. Inheritance merge / merge of metadata
3. Migrate
This allows us to batch the migration in Google3, or for large projects,
merge metadata, and then batch-execute migration for computation of
replacements. This is compatible with Google's LSC tsunami tool.
PR Close#57082
E.g. detects `spyOn(myComp, 'input')`. This is problematic
as `input` no longer provides access to the raw value via property
access, but via a getter. The `spyOn` would be effictively a noop,
causing tests to fail. We skip such inputs for safety right now.
Similarly, we have an advisor for correcting type safety loss
with `.componentInstance` in unit tests. This is a common pattern
but is typed in Angular core as `any`. This breaks resolution of
references and we accidentally miss those. This advisor mitigates that.
PR Close#57082
This commit adds the logic for detecting and capturing references to
Angular `@Input`s. Those references may be migrated to unwrap signals
as part of the migration; or are refactored into temporary variables.
This commit detects and captures:
- host bindings references
- template references
- TypeScript references
PR Close#57082
This commit adds logic for AST traversing Angular HTML templates and
detecting references to Angular `@Input`s that may be migrated.
In addition, the expression visitor logic is built in a generic way so
that it can also be used for finding references in host binding
expressions— where no type check block information is available.
PR Close#57082
This commit includes the initial logic for converting `@Input()` to
`input`. The logic is not fully polished in terms of what use-cases
and patterns we want to generate, but it's working pretty stable
with testing in Angular Material and some g3 targets.
We may improve this and e.g. generate the `input()` shorthand in a
couple of cases.
The commit also includes some related helpers/parts that are needed
for the migration phases.
Notably the conversion phase is split up into preparation and migration.
That is necessary because as part of analysing we already try to
prepare to see if it's "possible". This is necessary for the global
metadata analysis, so that we can know that certain references are
incompatible across compilation units (e.g. when running as a batch).
PR Close#57082
This commit adds the initial set of helpers and registries for tracking
inputs discovered in the signal input migration.
A few short summary notes:
- Every input has an unique key. This key is used for global analysis
that may be performed when the migration is executed on a per
individual unit basis in Google3 via e.g. go/tsunami — The keys allow
us to build a combined global metadata for e.g. references or figuring
out which inputs are incompatible or not.
- A known input may be _any_ input in an compilation unit/ the program.
E.g. even inputs from `d.ts`. We keep track of these inputs so that we
can later figure out if a reference `ts.Identifier` points to any of
those. In addition it allows us to attach incompatibility metadata to
those. I.e. incompatible for migration because "something writes to
the input".
PR Close#57082
This commit introduces the initial flow analysis logic for the input
migration. The flow analysis will allow us to determine which references
inside a flow container participate potentially in narrowing.
We can then use this information and the proposed restructred accesses
to refactor the accesses to use temporary variables where needed. E.g.
```
if (this.input) {
this.input.charAt(0);
}
```
```
const input_1 = this.input();
if (input_1) {
input_1.charAt(0);
}
```
Notably we could easily, naively figure out similar references in a flow
container and always use temporary variables, but this approach allows
us to minimally introduce such variables and this commonly leaves code
very readable when no narrowing was involved (noticable in g3 tests)
E.g. simple cases like:
```
this.input.bla();
this.input.bla();
```
would otherwise result in refactored expressions, leveraging a temporary
variable.
PR Close#57082
This allows use of poisoned data for migrations. Right now, migrations
often enable this flag by creating some deeper structures of the
Angular compiler, but with this change it's easier to enable as a
private compiler option.
This is helpful for migrations, specifically the signal input migration
as it allows us to generate as much TCB code as possible, for reference
resolution.
PR Close#57082
This commit exposes metadata about inputs that are defined inside
the `inputs` field of `@Directive` or `@Component` class decorators
This is useful and necessary information for migrations, like the
signal inputs migration.
PR Close#57082
This option was introduced out of caution as a way for developers to opt out of the new behavior in v18 which schedule change detection for the above events when they occur outside the Zone. After monitoring the results post-release, we have determined that this feature is working as desired and do not believe it should ever be disabled by setting this option to `true`.
PR Close#57029
Adds a new extended diagnostic that will flag `@let` declarations that aren't used within the template. The diagnostic can be turned off through the `extendedDiagnostics` compiler option.
PR Close#57033
Adds the new `ng generate @angular/core:inject-migration` schematic that will convert existing code from constructor-based injection to injection using the `inject` function. The migration also has a few options that should help reduce compilation errors.
This migration is slightly different than our usual ones in that it may have to update entire class or constructor declarations. We don't go through the `ts.factory.update*` APIs for this, because it can cause the entire declaration to be re-formatted. Instead, this migration tries to insert strings in a way that won't affect the user's formatting.
PR Close#57056
Some Angular template instructions that follow each other may be chained
together in a single expressions statement, containing a deeply nested
AST of call expressions. The number of chained instructions wasn't previously
limited, so this could result in very deep ASTs that cause stack overflow
errors during TypeScript emit.
This commit introduces a limit to the number of chained instructions to
avoid these problems.
Closes#57066
PR Close#57069
There are existing usages that inject the renderer to manualy listen (often for event
delegation purposes). These should contribute as well.
PR Close#56799
Adds a new extended diagnostic that will flag `@let` declarations that aren't used within the template. The diagnostic can be turned off through the `extendedDiagnostics` compiler option.
PR Close#57033
The `Timeout` object in Node.js has a `refresh` method, used to restart `setTimeout`/`setInterval` timers. Before this commit, `Timeout.refresh` was not handled, leading to memory leaks when using `fetch` in Node.js. This issue arose because `undici` (the Node.js fetch implementation) uses a refreshed `setTimeout` for cleanup operations.
For reference, see: https://github.com/nodejs/undici/blob/1dff4fd9b1b2cee97c5f8cf44041521a62d3f133/lib/util/timers.js#L45Fixes: #56586
PR Close#56852
The `window` global is patched by domino on the server but the value of `window.location.href` isn't a valid base.
Before this change `getUrl()` would throw when running in devmode on the server.
Fixes#56207
PR Close#56213
Fixes that only the first callback was firing when multiple are registered in the same call to `afterNextRender`, e.g. `afterNextRender({earlyRead: fn, read: fn});`
Fixes#56979.
PR Close#56981
This is a performance optimization that would exit early when
code actions are requested, but we know Angular cannot provide fixes
based on the error codes.
Previously, we would unnecessarily compute and analyze the application
for semantic diagnostics.
This will be helpful for: https://github.com/angular/vscode-ng-language-service/pull/2050
PR Close#57000
Fixes that the runtime implementation of `ɵɵngDeclareDirective` was interpreting the `hostDirectives` mapping incorrectly. Instead of treating the inputs/outputs as `['binding', 'alias']` arrays, it was parsing them as `['binding: alias']`. This was leading to runtime errors if a user is consuming a partially-compiled library in JIT mode.
Fixes#54096.
PR Close#57002
In addition to quick fixes, this commit adds the ability to write
code refactoring actions that can be applied by users.
For example, we may implement a migration as a code refactoring action.
Notably the quick fix support, existing already, is insufficient as it
only allows for edits to be applied based on diagnostics shwon in e.g.
VSCode.
PR Close#56895
In #56358 we removed most of the places that untag the references to typecheck files, because it was causing the compiler to throw error when it produces diagnostics. This appears to have caused a regression in TS 5.4 which now emits the synthetic references.
These changes add tagging right before the program emits.
Fixes#56945.
PR Close#56961
This fixes the case that common module is removed on a second run of the migration. We were not looking at block parameters for common module usage.
PR Close#56968
This commit fixes that the angular.dev deployment is subject
to GitHub API rate limiting due to lack of an access token.
This commit fixes this, similar to how we fixed it in
`angular/components`. The token is pure read-only.
PR Close#56929
Replace loose equality (==) with strict equality (===) for the 'code' variable.
This change ensures type safety and prevents unintended type coercion.
PR Close#56944
This is the first step towards combining `EarlyEventContract` and `EventContract`. It contains a few refactors, such as making names more consistent.
The goal of this refactor is to remove the `EarlyEventContract` class altogether, as well as `EventContract`.
To install the early event contract with the default events in early script tag, users will call:
`bootstrapGlobalEarlyEventContract()`
And for boostraping:
`registerGlobalDispatcher(dispatcher)`
PR Close#56900
This commit moves the JIT transforms into the ngtsc folder. They existed
outside of ngtsc mostly as an historic artifact— and now with compiler
relying on them even more deeply, it makes sense to move them into
`ngtsc/transform`.
PR Close#56892
Currently when compiling code with the Angular compiler, all classes
with Angular decorators are compiled with AOT. This includes type
checking, scope collection etc.
This may not be desirable for all components, e.g. dynamic components,
or test components w/ `TestBed.configureTestingModule` (if compiled with ngtsc).
Those components can opt out of AOT on a per component-basis via `jit:
true`. This is helpful as it allows incremental migrations/refactorings
to AOT. Whether we want to keep this capability long-term is something
to be discussed separately.
For now though, we should fix that components compiled with `jit: true`
actually work as expected. Currently this **not the case** as soon as
the new initializer APIs are used— as those do no longer declare class
metadata with decorators.
This commit runs the JIT transform on JIT-opted classes.
Related: https://docs.google.com/document/d/1ox4atCJldWWDXlaYgwM-hU8BNsTpKNW7gx8OfZ0HtRY/edit?resourcekey=0-G1haTNYtD-dN0vNRkQ8_OQ&tab=t.0
PR Close#56892
This update goes through half of the component-scenarios guide and makes
relevant updates to examples.
Updates include:
* Use signals in examples
* Advise and use `await fixture.whenStable` more frequently than
`detectChanges`
* Use and advise mocks and spies more sparingly
* Remove `waitForAsync` and jasmine `done` guidance - The ecosystem has evolved
and these aren't needed
* Remove marble testing for rxjs - this belongs in rxjs documentation,
not in Angular
* Remove class-only component testing. This approach is not advisable
for components.
related to #48510
PR Close#56388
It is valid CSS to list keyframe names in an animation declaration only
separating the names with a comma and no whitespace. This is typical of
production builds. Updated a couple of regexes and added a couple of
tests to account for this scenario.
Fixes#53038
PR Close#56800
This commit updates one of the `@defer`-based test to use the `on immediate` trigger to make a test mor
e stable without the need to add mocks for the `on idle` (default) condition.
PR Close#56904
The option introduced in 5df3e78c99 has been named `equals` whereas the existing option in `signal` is named `equal`.
This commit renames the new option to `equal` as well to keep the naming coherent across these APIs.
PR Close#56769
The `@angular/schematic` package has a `utility` export path which can be
used to access common utility rules and helpers. The previous deep imports
into the `@angular/schematic` package have been switched to the actual
export path where possible. This lowers the potential for breakage from
internal package changes.
PR Close#56839
When we process `@if` and `@for` blocks, we create a scope around their expressions in order to encapsulate the aliases to them. The problem is that this doesn't represent the actual structure since the expression is part of the outer scope. This surfaces by not raising the "used before declared" diagnostic for `@let` declarations.
These changes resolve the issue by processing the expression as a part of the parent scope.
Fixes#56842.
PR Close#56843
In this update, the fetch backend now executes fetch operations outside of the Angular zone. This adjustment primarily aims to decrease Continuous Delivery (CD) cycles on Node.js. The decision was influenced by Undici, the Node.js fetch implementation, which relies on `setTimeouts` to manage response timeouts.
PR Close#56820
This commit updates the logic that create an injector for defer blocks (when it's needed) to account for a situation when a component is instantiated without a connection to the current component tree. This can happen if a component is created using its factory function or via `createComponent()` call.
Resolves#56372.
PR Close#56763
This change is the final cleanup after removing NgSwitch's equality patch
that was used in G3 to allow == matching for a certain period of time. This
code is no longer needed as both the external ecosystem and G3 are using
=== equality for matching NgSwitch cases.
PR Close#56806
This should make things somewhat faster, since setAttribute can be slower than addEventListener. Jsaction attribute is still needed for SSR though.
PR Close#56747
Export `producerIncrementEpoch` which was missing before, as well as a new
`runPostSignalSetFn` helper. These changes make it easier to write `signal`-
like utilities which don't use the `createSignal` abstraction.
PR Close#56759
Currently the logic that maps a name to a variable looks at the variables in their definition order. This means that `@let` declarations from parent views will always come before local ones, because the local ones are declared inline whereas the parent ones are hoisted to the top of the function.
These changes resolve the issue by giving precedence to the local variables.
Fixes#56737.
PR Close#56752
Now that all `Dispatcher` implementations use `ActionResolver`, `EventContract` no longer needs to. Additionally, all a11y click support has been removed. `EventContract` will not specifically listen for `keydown` automatically, as all `EventContract` instances already have `keydown` listeners. This removes the need for the `A11Y_CLICK_SUPPORT` define, which will be removed in a future PR.
PR Close#56723
These values are inlined in ActionFlow internally in google3, and are no longer used.
Do some additional cleanup to only define the properties once.
PR Close#56590
This commit adds more team members into the `public-api` group, so that they can approve public API changes, but they would not be requested for reviews by PullApprove (to avoid requests for unrelated changes).
PR Close#56743
When running the JIT transforms in 1P w/ tsickle, tsickle will
transform source files before our custom transforms can run. This is
also impacting the Ivy transform and hence we use `ts.getOriginalNode`
in various places to inspect the source AST for detecting Angular.
For the JIT transform we need to do a similar change so that the
transform could run in 1P.
PR Close#56520
The `window` global is patched by domino on the server but the value of `window.location.href` isn't a valid base.
Before this change `getUrl()` would throw when running in devmode on the server.
Fixes#56207
PR Close#56213
In #56558 it was raised that we used an devMode function in a prod scope.
This commit adds a test when an defer error block is missing in devMode and prodMode
PR Close#56561
In Angular v17 we've alligned NgSwitch equality check with the build in control
flow to be ===. At the same time we've left the ability to use ==. This ability was
controlled by the NG_SWITCH_USE_STRICT_EQUALS const targetted by the G3 patch.
This commits removes the infrastructure to swap equality operator in preparation
for the G3 patch removal.
PR Close#56426
This replaces all addEventListener calls with a stashing function,
and installs an event listener on the document body to retrieve
the stashed function;
PR Close#56247
When the DOM content is loaded, Angular will log a warning message if the `priority` attribute is applied to often on `NgOptimizedImage` directive instances.
PR Close#56669
Enables the new `@let` syntax by default.
`@let` declarations are defined as:
1. The `@let` keyword.
2. Followed by one or more whitespaces.
3. Followed by a valid JavaScript name and zero or more whitespaces.
4. Followed by the `=` symbol and zero or more whitespaces.
5. Followed by an Angular expression which can be multi-line.
6. Terminated by the `;` symbol.
Example usage:
```
@let user = user$ | async;
@let greeting = user ? 'Hello, ' + user.name : 'Loading';
<h1>{{greeting}}</h1>
```
Fixes#15280.
PR Close#56715
`EventContract` usages in Angular now use `false` for
`useActionResolver`. Tests have been updated, with functionality that
depends on `ActionResolver` moving to dispatcher_test.ts.
PR Close#56369
PR Close#56369
Adds the implementation of the following new instructions:
* `declareLet` - creation-time instruction that initializes the slot for a let declaration.
* `storeLet` - update-time instruction that stores the current value of a let declaration.
* `readContextLet` - instruction that reads the stored value of a let declaration from a different view.
On top of the instructions, it also introduces a new `LetDeclaration` TNode type.
The new TNode is nececessary for DI to work correctly in pipes inside the let expression,
as well as for proper hydration support.
PR Close#56527
Prior to this change, is the `Content-Type` passed to the `FetchBackend` was lowercase it was overwritten with the default one.
fixes#56539
PR Close#56541
`getTemplateLocationDetails()` is a devMode only function and should guarded by `ngDevMode` or calling it will throw an error.
fixes#56558
PR Close#56559
When collecting nodes from the DOM for hydration, we need to treat nodes with paths (e.g. content projection) as the new root for all subsequent elements, not just the next one.
Additionally, when using content projection it's possible for translated content to become disconnected, e.g. when it doesn't match a selector and there isn't a default. We need to handle such cases by manipulating the disconnected node data associated with hydration as usual.
PR Close#56192
This commit delays makes two changes:
* Use the `read` phase for `afterNextRender` hook. We really want to
wait for any write hooks to complete before starting the animation
* In addition, wait a macrotask before resolve (really, this makes the
above change unnecessary but it's still conceptually the right
thing). This ensures any follow-up rendering in the microtask queue
is flushed before the animation starts.
Important note: This only affects the timing of the animation start,
delaying it longer to allow additional rendering/change detections to
flush. This promise already resolves in an `afterNextRender` hook and is
only used directly by the browser's view transition machinery.
PR Close#56494
This commit adds extra checks to handle a situation when an application has no events configured, but the Event Replay feature was enabled. This situation can happen when some routes in an application are mostly static, when other routes are more interactive.
Resolves#56423.
PR Close#56509
This commit fixes a typo in the `AfterRenderPhase` deprecation warning and improves the documentation of the options parameter of the afterRender hooks (which are now all named `options` instead of being called `opts` in some functions and `options` in others).
PR Close#56522
Before this commit, the migration was removing the `AfterRenderPhase` enum from the imports but not the comma, resulting in invalid code:
ts
```
import { , Directive, afterRender } from '@angular/core';
```
This commit fixes this by using `updateNamedImports` and `replaceNode` instead of `removeNode`.
After:
ts
```
import { Directive, afterRender } from '@angular/core';
```
PR Close#56524
These changes integrate let declarations into the template pipeline. This involves a few operations:
* Producing a `declareLet` instruction call at creation time to initialize the declaration.
* Producing a `storeLet` instruction call in the place of the let declaration, including the necessary `advance` calls beforehand.
* For let declarations used within their declaration view, moving the `const` to be placed right after the `storeLet` call to ensure the their value has been computed.
* For let declarations that are _only_ used in their declaration view, removing the `storeLet` call and inlining the expression into the constant statement.
PR Close#56299
This commit makes the host bindings of `NgControlStatus[Group]`
compatible with `OnPush` components. Note that this intentionally _does not_
expose any new APIs in the forms module. The goal is only to remove
unpreventable `ExpressionChangedAfterItHasBeenCheckedError` in the forms
code that developers do not have control over.
PR Close#55720
This contains follow-up fixes to 2a2439712a.
This commit updates scrolling on references page to scroll to the top
when there is no anchor in the URL. The behavior after the above commit would
be that the position doesn't change from whatever the previous page was
(potentially scrolled to the bottom). In addition, this restores the
previous scroll position when traversing through browser history rather
than always scrolling to the fragment.
PR Close#56478
When importing a component exported by default, the `default` can't be
used as the component name.
For example:
This is the export declarations:
```ts
export default class TestComponent {}
```
Previously, the output generated by LS looked like this:
```ts
import { default } from "./test.component";
```
Now the output looks like this:
```ts
import TestComponent from "./test.component";
```
Fixes#48689
PR Close#56432
`DOCUMENT` instances retrieved from DI may not contain a necessary function to complete the cleanup. In tests that don't interact with DOM, the `DOCUMENT` might be mocked and some functions might be missing. For such tests, DOM cleanup is not required and we can skip DOM cleanup logic if there are missing functions. For tests that use DOM, TestBed would behave the same as before and rely on more complete `DOCUMENT` instances.
PR Close#56422
Router's `OutletInjector` required a special handling in cases when `@defer` is used, see https://github.com/angular/angular/pull/55374 for additional info. As a result, the `ChainedInjector` that represents an `OutletInjector` instance is currently exposed via `getInjectorResolutionPath` function. This creates a problem, because other debug APIs used by DevTools can not interact with `ChainedInjector`s. This commit updates the logic around `getInjectorResolutionPath` utility to avoid exposing `OutletInjector`in the resolution path.
Resolves#56331.
PR Close#56394
Many developers find these interfaces useful for various reasons. Beyond
that, the deprecation of the interfaces has incorrectly implied that
existing class-based guard implementations need to be migrated to
functions. Class injectables are _not_ deprecated and choosing to
implement a guard's state and logic as a class that is injectable in the
functions run inside the injection context is valid.
resolves#50234
PR Close#56408
This allows for helpers like the following to work intuitively for all
types of "input fields". It also establishes the intended mental
philosophy that a model is both an input and an output.
```ts
/** Unwraps all signal input properties. */
export type UnwrapSignalInputs<T> = {
[K in keyof T]: T[K] extends InputSignalWithTransform<any, infer WriteT>
? WriteT
: T[K];
};
```
PR Close#56452
`toSignal` predates the decision to allow a more flexible equality check in
signals, and thus doesn't support a custom equality function. This commit
adds the ability to pass a custom value equality function. As a side effect,
it now adds the default equality check where it wasn't used before.
Fixes#55573
PR Close#56447
* Create custom scroller to manage scroll behavior more directly. There
are two many special and weird behaviors in the site to use the
built-in scrolling.
* Update scrolling to wait for application stability. This waits a bit
longer than the current `Scroll` event, which happens in
`afterNextRender` after the `NavigationEnd`. fixes#56446
* Disable scrolling on the API references page. It just never worked
well with all the custom scroll locations
* Update card clicks on API references page to change the fragment of
the URL (this allows docs viewers to link directly to an item). Also update
API reference page to listen to fragment changes and use that as the
scroll trigger rather than the click. This takes care of the initial
scroll when the page loads as well.
fixes#56446
PR Close#56464
The saucelabs connect tunnel utility is now downloaded via bazel as needed.
For the directly invoked case the utility is downloaded via the local shell script.
Previously it was part of the root `package.json` and downloaded whenever
a package install was executed. The utility archive was also not an actual
package which incidentally worked with npm but does not work with newer versions
of yarn.
PR Close#56456
We don't have any docs yet for that error, so I'm removing the minus sign which indicate that there is a dedicated error doc.
Fixes#56424
PR Close#56441
This feature adds a property to the `NavigationBehaviorOptions` that
allows developers to define a different path for the browser's address
bar than the one used to match routes. This is useful for redirects
where you want to keep the browser bar the same as the original
attempted navigation but redirect to a different page, such as a 404 or
error page.
fixes#17004
PR Close#53318
The linker inserts the constant statements that are needed to support compiled templates
after the import statements of an ESM file, but it failed to account for import statements
that are not at the top of the file. This is typically seen in FESM files where multiple
individual ESMs have been concatenated into a single ESM file, with imports in various places.
The linker would then find the very last import statement to insert the constant statements
after, but this may result in TDZ errors for component templates that have been emitted
earlier in the file.
This commit updates the Babel linker plugin to insert constant statements after the last
import of the first import group, therefore avoiding the TDZ error.
Fixes#56403
PR Close#56431
The import manager ensures generation of unique identifiers when
inserting imports. This is done by inspecting existing identifiers
within the original source file, while also checking if a similar
identifier was generated at an earlier time. This is correct behavior.
We can improve the detection so that the same identifier can be
generated in different files. This is beneficial for schematic/migration
use-cases where we wouldn't want to generate import aliases in multiple
files just because we generated an import to e.g. `input` previously.
E.g. it's fine to generate
```ts
// a.ts
import {input} from '@angular/core';
// b.ts
import {input} from `@angular/core';
// instead of `input as input_1`.
```
PR Close#56406
Whenever we parse object property assignment shorthands in expression
ASTs, the AST will have no information about whether the property read
for the `LiteralMap` is built based on the shorthand or not.
Exposing this information in the AST is useful for migrations as those
might need to decompose the shorthand into its longer form to e.g.
invoke a signal read.
PR Close#56405
This commit starts exposing `isSignal` for inputs in the
`ComponentMirror`. We initially had this as a draft when rolling out
signal inputs, but there were no good use-cases, so we skipped it.
Now, inside G3, for the testing infrastructure and rolling out
advancements for signal inputs, having this information is necessary and
allows identifying signal inputs without "accessing fields" on the class
that may cause side-effects (like triggering setters).
PR Close#56402
`EventContract` usages in Angular now use `false` for
`useActionResolver`. Tests have been updated, with functionality that
depends on `ActionResolver` moving to dispatcher_test.ts.
PR Close#56369
Prior to this commit, when zone.js was included, it wasn't possible to handle `beforeunload`
events correctly if event handlers returned strings to prompt the user.
With this change, we introduce a global configuration flag,
`__zone_symbol__enable_beforeunload`, to allow consumers to enable the default
`beforeunload` handling behavior.
This flag is necessary to prevent any breaking changes resulting from this modification.
The previous attempt to fix it caused a large number of failures in G3. Hence, we're
hiding that fix behind the configuration flag.
Closes#47579
PR Close#55875
This PR allows the language service to suggest imports for all directives returned from the
compiler, and generate the TypeScript module import and the decorator import when the component
is selected by the user.
PR Close#55595
Use depth 100 to allow for some history in the artifact repos, without the entire history being necessary
which caused us to run out of space on the CI runner.
PR Close#56414
Nested block elements in a `p` element are not valid.
The p block automatically closes if another block-level element is parsed before the closing.
PR Close#56390
This commit updates the payload size for a couple integration apps. Those apps were likely close to a threshold already and the most recent commit added a few extra bytes to go over the limit.
PR Close#56391
This commit also performs lock file maintenance on all integration
tests, fixing some ambigous ESM/CJS dependency graph issues.
e.g.
```
Unknown error: Error [ERR_REQUIRE_ESM]: require() of ES Module /tmp/ng-integration-test-aTpQOT/test-sandbox/node_modules/string-width/index.js from /tmp/ng-integration-test-aTpQOT/test-sandbox/node_modules/cliui/build/index.cjs not supported.
Instead change the require of index.js in /tmp/ng-integration-test-aTpQOT/test-sandbox/node_modules/cliui/build/index.cjs to a dynamic import() which is available in all CommonJS modules.
------------------------------------------
```
Closes#56261.
PR Close#56364
This commit fixes an issue where signals in embedded views are not
tracked if they are refreshed with `EmbeddedViewRef.detectChanges`
directly. We had previously assumed that embedded views were always
refreshed along with their hosts.
PR Close#55719
Use full depth repositories for artifact publishing to prevent the commits from not being able to find the path between commits during push.
PR Close#56383
This parameter was removed in a recent change but is being added back to
avoid breaking code in a minor version.
While the changes parameter is not used, some code relies on it, mostly
through API misuse (extending `RouterLink`, manually calling `ngOnChanges`, etc.).
PR Close#56371
The chrome version controlled by selenium reports chrome-headless-shell in the
current setup. This fix accounts for the updated browser name.
PR Close#56360
* Move from `docs/` to `contributing-docs/`
* Updated file names to better communicate their content
* Consolidated content into fewer docs
* Updated and/or deleted obsolete info
PR Close#56141
This commit updates the event binding part, where all `scroll` listeners are marked
as passive using the special zone.js configuration flag. The configuration has been
moved from the `polyfills` file to `index.html`. Since new apps no longer include a
`polyfills.ts` file but instead have a `polyfills` property in the builder, setting
the flag in `index.html` ensures compatibility with both configurations.
PR Close#56322
Adds an `ng update` migration to move users from using the phase flag
with `afterRender` / `afterNextRender` to passing a spec object instead.
PR Close#55648
Adds back the ability to set the phase of an `afterRender` /
`afterNextRender` callback using the `phase` option. However, this API
is now deprecated, and the phase should instead be specified by passing
a spec object rather than a callback function.
PR Close#55648
Previously `afterRender` and `afterNextRender` allowed the user to pass
a phase to run the callback in as part of the `AfterRenderOptions`. This
worked, but made it cumbersome to coordinate work between phases.
```ts
let size: DOMRect|null = null;
afterRender(() => {
size = nativeEl.getBoundingClientRect();
}, {phase: AfterRenderPhase.EarlyRead});
afterRender(() => {
otherNativeEl.style.width = size!.width + 'px';
}, {phase: AfterRenderPhase.Write});
```
This PR replaces the old phases API with a new one that allows passing a
callback per phase in a single `afterRender` / `afterNextRender` call.
The return value of each phase's callback is passed to the subsequent
callbacks that were part of that `afterRender` call.
```ts
afterRender({
earlyRead: () => nativeEl.getBoundingClientRect(),
write: (rect) => {
otherNativeEl.style.width = rect.width + 'px';
}
});
```
This API also retains the ability to pass a single callback, which will
be run in the `mixedReadWrite` phase.
```ts
afterRender(() => {
// read some stuff ...
// write some stuff ...
});
```
PR Close#55648
This is related to an issue that was reported internally. We were assuming that `hasNgModuleMetadataElements` will return true only for property assignments initialized to arrays, but that's not the case.
These changes update the type and our assertions to more accurately reflect the AST and to avoid the error.
PR Close#56302
This commit adds `UrlTree` as a valid input to `routerLink`. It
disallows using this together with any inputs that come from
`UrlCreationOptions`, such as `queryParams` or `fragment`.
We could, in the future, decide on a different approach for these, like merging or
replacing those in `urlTree` input. We cannot, however, go the other way
(decide to prevent those inputs if we've already decided to allow it and
using a merging/replacing strategy). For this reason, an error seems the
most reasonable approach to start and we can re-evaluate if there's a
compelling reason to.
fixes#34468
PR Close#56265
Provide a thorough explanation of why an application may remain unstable and
why developers should consider not running asynchronous code on the server outside
of the Angular zone, as this may lead to memory leaks.
PR Close#55973
This commit addresses an issue where the `@angular/localize/init` polyfill is not included when there are no polyfills specified in the `angular.json` file.
PR Close#56300
Move tests from `eventcontract_test.ts` to `dispatcher_test.ts` for
functionality that lives in `Dispatcher`.
Add an extra test for `preventDefault` behavior for `CLICKMOD` that
covers a previous bug case.
PR Close#56193
Prior to this commit, a memory leak occurred when the `abort` listener was
not removed from the `AbortSignal`. We introduced a fix to remove the event
listener, but it was erroneously stored on the `taskData`, which is a shared
global object. Consequently, when something attempted to remove an event listener,
it immediately removed the last stored abort listener. As a result, events would
never be canceled.
We have now rectified this by storing the remove abort listener function directly on
the task itself. This adjustment ensures that the abort listener is tied only to the
specific task. When the `abort` function is called, it cancels the task. Therefore, it
is safe to associate the cleanup function directly with the task.
Closes: #56148
PR Close#56160
Updates the check that prevent writes to template variables in two-way bindings to account for let declarations.
Also fixes some old tests that weren't properly setting up two-way bindings.
PR Close#56199
Integrates let declarations into the template type checker by producing corresponding constants in the TCB.
This also includes a couple of custom diagnostics to flag usages of let before they're declared and illegal writes to let declarations. We can't rely on TS for these checks, because it includes the variable name in the diagnostic.
PR Close#56199
fix(docs-infra): remove config release from test scripts
As we discussed in one of the previous PRs we should remove `--config=release` from test scripts on CI
fix(docs-infra): use DI to inject current VERSION.major
PR Close#56062
After inspecting and testing the adev-root component is seems like
it could be marked as OnPush.
This change gets us closer to enabling zoneless for adev.
PR Close#56254
After inspecting and testing the embedded-editor and adev-code-editor
components it
seems like those could be marked as OnPush.
This change gets us closer to enabling zoneless for adev.
PR Close#56254
After inspecting and testing the adev-update-guide component it
seems like it could be marked as OnPush. This change gets us closer
to enabling zoneless for adev.
PR Close#56254
As of this commit, there is a visual discrepancy between the height of the content on the left compared to the separator and editors on the right. It appears that the cause of this is an additional computation of layout padding which is unnecessary for these particular elements.
PR Close#54828
This PR replaces all links available within the devtools to point
to the new docs.
The links to Input/Output (decorators) have been replaced with
their function (signal) counterparts: input, output.
PR Close#56138
Currently the template syntax errors are extracted in the template type check phase. But in local compilation mode we skip the type check phase. As a result template syntax errors are not displayed. With this change we show the template syntax diagnostics in local mode.
PR Close#55855
This commit updates hydration serialization logic to handle a case when the `withI18nSupport()` call is not present for an application that has a component that uses i18n blocks. Note: the issue is only reproducible for components that also inject `ViewContainerRef`, since it triggers a special serialization code path.
Resolves#56074.
PR Close#56175
This removes the explicit 1 review required for the primitives and primitives-shared groups so that PR creators can serve as their own approval for that group.
PR Close#56191
When a consumer switches its liveness state, it gets added to / removed from
the consumer list of all of its producers. This operation is transitive, so
if its producer is *also* a consumer and *its* liveness state is switched,
then the change is applied recursively.
Note that this only matters *if* the producer is also a consumer. However,
the logic in `producerAddLiveConsumer` / `producerRemoveLiveConsumerAtIndex`
coerced the producer node into a producer & consumer node, which allocated
extra arrays into the node structure that are never used. This didn't affect
correctness, but increased the memory usage of plain signal nodes (which are
just producers, never consumers).
This fix changes the logic in those operations to simply check if a producer
is also a consumer instead of coercing it into one.
PR Close#56140
Introduces a new `LetDeclaration` into the Render3 AST, simiarly to the HTML AST, and adds an initial integration into the various visitors.
PR Close#55848
Previously, the `@angular/docs` package had `xterm` as dependency but wasn't referencing it. It only had dedicated styles. This commit moves back the styles to the FW repo as it is only used here.
PR Close#55642
empty ngSwitchCase generate `case ()` which isn't valid syntax therefore adding quotes will help prevent us migrate empty case if no condition was provided
fix angular#56030
PR Close#56105
This makes events bubble! This change also contains changes to
dispatcher and event_dispatcher to make replay synchronous,
so that we avoid odd timing issues. This can be split out though.
Lastly, we have one cleanup change to move the mapping from
event type to functions on the element itself.
PR Close#56036
Fixes an issue in the update guide found at https://angular.dev/update-guide?v=14.0-15.0&l=3 which has links that redirect to v17 documentation. This is because the links were missing the v15 reference within the a tag links.
Fixes#56101
PR Close#56116
Previously, the event replay serialization logic was located before we verify that a `TNode` exists. `TNode`s may not exist in `tView.data` array in several cases, including cases when there is a local ref used on an element: in this case an extra slot in `LView` contains a reference to the same element and `TNode` is not needed. This commit moves the event replay serialization logic a bit lower, after we check for TNode presence.
Resolves#56073.
PR Close#56076
All documentation tutorials will now use the recently released version 18
of Angular. Additionaly, the tutorials have been migrated to use the new
`@angular/build` package which does not contain the Webpack related dependencies.
The `first-app` tutorial was not moved to `@angular/build` due to it having
karma related dependencies present which currently requires the Webpack-based
build system during test execution.
PR Close#56043
Currently we optimize methods that pass both `$index` and the item into a method. We can take this a step further by also optimizing calls that only pass `$index` into the first parameter.
PR Close#55872
Prior to this commit, event listener options were mutated directly, for example,
`options.signal = undefined` or `options.once = false`.
This issue arises in apps using third-party libraries where the responsibility lies
with the library provider. Some libraries, like WalletConnect, pass an abort controller
as `addEventListener` options. Because the abort controller has the `signal` property,
this is a valid case. Thus, mutating options would throw an error since `signal`
is a readonly property.
Even though zone.js is being deprecated as Angular moves towards zoneless change detection,
this fix is necessary for apps that still use zone.js and cannot migrate to zoneless change
detection because they rely on third-party libraries and are not responsible for the code
used in them.
Closes#54142
PR Close#55796
`EventDispatcher` emulates the browser's event dispatch (mostly).
It supports:
- Bubbling and `stopPropagation`/`stopImmediatePropagation`.
- `currentTarget` during dispatch.
- Throwing errors for `preventDefault` if the event is being dispatched
in replay.
- Throwing errors for `composedPath()` if event is being dispatched in
replay.
PR Close#55837
fix(docs-infra): calculate the list of Angular Docs versions based on VERSION, append --config=release to docs build and serve the script. Support displaying the right color of navigation for the deprecated state.
fix(docs-infra): add scrollbar to version picker
fix(docs-infra): set initial adev docs version to 18
fix(docs-infra): remove --config=release from scripts for local development, write unit tests
fix(docs-infra): update CI tests step
fix(docs-infra): remove rc from the list
fix(docs-infra): update unit test to check count of versions
PR Close#55977
This commit updates the `ngswAppInitializer` implementation and removes the `controllerchange`
listener upon the destruction of the `ApplicationRef`. This adjustment aims to prevent memory
leaks. In a zone.js environment, neglecting to do so could lead to the perpetual creation of
a zone task, which captures the zone and obstructs proper garbage collection.
PR Close#55365
This will prevent running `ActionResolver` logic multiple times while
migrating to use `Dispatcher` to resolve actions rather than
`EventContract`.
PR Close#55864
The compiler now checks if a signal is properly called on dom property bindings.
The ideal solution would be for the compiler to check if dom property bindings in general are properly typed,
but this is currently not the case, and it is a bigger task to land this change.
In the meantime, the signal diagnostic is augmented to catch cases like the following:
```
<div [id]="mySignal"></div>
```
PR Close#54324
Users may be using zoneless, but are still loading Zone.js in which case they won't get the full benefits like reduced bundle size. These changes detect such a case and log a warning.
PR Close#55769
The SecondaryNavigation component was updating state outside of an event handler
without notifying about this change. Modeling state as signal should take
care of proper UI updates (note that I did just a mechanical change here, maybe
there are better ways of dealing with this animations case).
PR Close#55830
Provide a thorough explanation of why third-party libraries should be created outside
of the Angular zone. Using a statement like "authored with Zone.js in mind" may seem
unusual because third-party libraries typically do not have knowledge of Zone.js, nor
should they be developed with it in mind. Therefore, we revise this explanation accordingly.
Additionally, include a section on handling events originating from third-party APIs.
PR Close#55876
This reverts commit 6d95131d84.
This change was created by a security researcher and is being reverted as it is a noop.
We intend to follow up with more information in a future blog. Please refer to the pull
request description for the link to this blog.
PR Close#55896
Because exhaustive checks traverse the whole tree regardless of the
dirty state, it breaks some expectations around how change detection
should be running. When a view has transplanted views, it
unconditionally marks all ancestors for traversal, assuming this is fine
because the loop will just traverse them and find nothing dirty.
However, exhaustive checkNoChanages actually refreshes everything during
traversal.
This update ensures the exhaustive check only does a single pass and
also prevents some unnecessary marking of transplanted views for
refresh since we know they're going to be reached.
PR Close#55839
When an `@if` expression has an alias, only the type of the alias is
currently narrowed. So for example, suppose `value` is `string|undefined`:
```
@if (value; as alias) {
{{ value.length }} <!-- error, value may be undefined -->
{{ alias.length }} <!-- no error, alias is narrowed -->
}
```
This is especially noticeable when the expression contains guards which are
preconditions for the aliased expression:
```
@if (a && b; as alias) {...}
```
In this case, `a` would not be narrowed within the body, even though the
`@if` condition forces it to be truthy. This is a bug.
The reason is that aliased expressions were previously type-checked as:
```
var alias = a && b;
if (alias) {
// nothing other than alias is narrowed
...
}
```
One option considered was to emit `const alias` instead of `var alias`.
TypeScript _does_ trace `const` expressions and narrow their individual
components when the overall expression is guarded:
```
const alias = a && b;
if (alias) {
// a, b are also narrowed
}
```
However, this narrowing has different semantics than if `a && b` appeared
directly in the guard expression. For example, object properties aren't
narrowed with this approach, so component properties (which are referenced
as e.g. `this.a`) would not be narrowed.
Instead, we amend the guard expression to include both the expression _and_ the
alias variable, enforcing that both are narrowed.
```
var alias = a && b;
if ((a && b) && alias) {
// a, b, and alias all narrowed correctly.
}
```
This form ensures all conditions within the guard expression get narrowed
while also narrowing the alias variable type.
Fixes#52855
PR Close#55835
Currently when attempting to retrieve a TCB symbol for an input binding
that refers to a signal input with e.g. `protected`, while the
`honorAccessModifiersForInputBindings` flag is `false`, Angular will
throw a runtime exception because the symbol retrieval code always
expects a proper field access in the TCB.
This is not the case with `honorAccessModifiersForInputBindings =
false`, as TCB will allocate a temporary variable when ignoring the
field access. This will then trigger the runtime exception (which we
added to flag such "unexpected" cases). This commit handles it
gracefully, as it's valid TCB, but we simply cannot generate a proper
TCB symbol (yet). This is similar to `@Input` decorator inputs.
In the future we may implement logic to build up TCB symbols for
non-property access bindings, for both signal inputs or `@Input`
inputs. This commit just avoids a build exception.
Related to: #54324.
PR Close#55774
The Angular CLI documentation topic for migrating to the new build system
now has a navigation label of "Migrating to new build system" instead of
"esbuild". This new label better reflects the action a user may want to
take rather than one of the tools used by the new build system.
PR Close#55782
Developers may want to enable zoneless for all tests by default by
adding the zoneless provider to `initTestEnvironment` and then
temporarily disabling it for individual tests with the zone provider
until they can be made zoneless compatible.
PR Close#55813
With this change, If an async validator that should have emitted was cancelled by a non-emitting validator, the status change will be reported on the `AbstractControl.events` observable.
This issue can happen when a `FormControl` is added to a `FormGroup` and a FormGroupDirective/FormControlDirective trigger a non-emitting validation (which cancels the initial validator execution).
Note: The behavior remains the same of the existing `statusChanges` observable as the change was too breaking to land in G3.
fixes: angular#41519
PR Close#55134
This was mistakenly implemented automatically by the override without
filling in the default value of `true` like it is for the zone-based
fixture.
PR Close#55800
The migration was breaking tests with test modules that imported `HttpClientTestingModule`,
as it removed the JS imports without migrating the module imports.
The migration now handles the case where `HttpClientTestingModule` is used in test modules,
by replacing the module import with the `provideHttpClient` and `provideHttpClientTesting` providers.
Before:
```ts
import { HttpClientTestingModule } from '@angular/common/http/testing';
@NgModule({
declarations: [AppComponent],
imports: [HttpClientTestingModule],
})
export class TestModule {}
```
After:
```ts
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
@NgModule({
declarations: [AppComponent],
imports: [],
providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()]
})
export class TestModule {}
```
PR Close#55803
Angular has long had the ability to use different interpolation delimiters
(by default `{{` and `}}`). This concept was copied over from AngularJS,
where AngularJS syntax is included in HTML sent over the network to the
browser. Occasionally developers would use SSR frameworks which _also_ have
interpolation syntaxes of their own, so there was a need to change the
delimiters used by AngularJS to avoid conflicts.
Since Angular templates are always processed by our compiler and the
interpolation characters are never processed by other systems first, this
option is vestigial in Angular and only increases the complexity of our
parser.
DEPRECATED: `@Component.interpolation` is deprecated. Use Angular's
delimiters instead.
PR Close#55778
The `HttpClientModule` migration was dropping the existing properties other than imports and providers when updating an `@NgModule`, `@Component` or `configureTestingModule`.
PR Close#55777
This reuses information already recorded during hydration to
remove jsaction attributes to also stash event handlers. This avoids
a tree walk and looku.
PR Close#55747
The first test asserts that bubbling does not work right now.
The second asserts that stopPropagation works, which should pass when test #1 passes too.
The third test asserts properties about the events passed to the event handler.
THe fourth test asserts that mouse events do not translate to jsaction nor help emit the jsaction binary. This required a change in code to make this pass.
PR Close#55747
This commit implements the replacement of rollup and terser with esbuild for generating the contract_bundle binary. The transition is facilitated by optimizations aimed at reducing the bundle size.
PR Close#55705
Rename `BaseDispatcher` to `Dispatcher` and `Dispatcher` to
`LegacyDispatcher`. The `GlobalHandler` type and `stopPropagation`
function needs to be left for now in dispatcher.ts as it was not
exported previously from legacy_dispatcher.ts.
PR Close#55721
This commit deprecates the aliases for the control events to ease the changes in G3
A follow-up commit will remove those deprecated entries.
PR Close#55698
Since we aren't using clang anymore, we can remove the comments and the workarounds that were in place to prevent it from doing the wrong thing.
PR Close#55750
Currently the variable optimization phase happens somewhat late in the process which is okay since the variables are generally static (e.g. `reference()` instruction calls). In some upcoming work we'll have variables that consume slots and require `advance` instructions. To allow for them to be optimized correctly, we need to move the variable optimization phase earlier, at least before we allocate the slots.
PR Close#55771
The application migration instructions and information page now contains
updated information related to the v18 release. This includes a reordering
of the migration section to mention the automatic migration first as well
as mention that `ng update` will now ask to perform the migration for v18.
PR Close#55699
The payload size of the `event-dispatch-contract.min.js` script was reduced by more than 5%, which triggered CI checks. This commit updates a golden file to match the actual size.
PR Close#55748
This changes include
- Using multi line comments to write JSDoc comments which improves DX
- Use `this.container` instead of `window.document.documentElement`
PR Close#55704
We removed display of the Git SHA in Angular DevTools in https://github.com/angular/angular/pull/55694, so there is no longer a need to stamp release builds in Chrome or Firefox.
I opted to leave a `--config snapshot-build-firefox` option as a no-op which a reader could follow to a comment explaining exactly _why_ we can't stamp Firefox releases. This should hopefully make it less likely that we forget and attempt to re-add this feature in the future only to encounter the same release problems.
PR Close#55717
Trigger an error when attempting to enable size-tracking for a project not listed in the integration-payload.json file.
Before this update, size-checks would succeed even if the project wasn't included in the file size limit.
PR Close#55708
This commit introduces integration tests for hydration and event reply functionalities. Additionally, it implements a payload size check for the `event-dispatch-contract.min.js`.
PR Close#55708
This commit adds a feature that is useful for determining if an
application is zoneless-ready. The way this works is generally only
useful right now when zoneless is enabled. Some version of this may be useful in
the future as a general configuration option to change detection to make
`checkNoChanges` pass always exhaustive as an opt-in to address #45612.
Because this is an experimental, debug-only feature, it is okay to merge
during the RC period.
PR Close#55663
This behavior is now implemented by calling `dispatch` whether or not
the `action` is populated. The `Dispatcher` then does global dispatch
and early returns if there's no action.
PR Close#55692
This commit updates the implementation of the `addEventListener` patcher.
We're currently creating an abort event listener on the signal (when it's provided)
and never remove it. The abort event listener creates a closure which captures `task`
(tasks capture zones and other stuff too) and prevent `task`, zones and signals from
being garbage collected.
We now store the function which removes the abort event listener when the actual event
listener is being removed. The function is stored on task data since task data is already
being used to store different types of information that's necessary to be shared between
`addEventListener` and `removeEventListener`.
Closes#54739
PR Close#55339
This stamping is interfering with publishing to the Firefox addons store by brining in the entirety of the `.git` directory as part of the source code necessary for a reproducible build, which Firefox requires as part of it's approval process.
In it's place, we are now using the extension version pulled from the manifest.
PR Close#55694
Related to #51131, this change ensures that the router navigation exits
the current event loop before rendering the route when the view transition
feature is enabled, when the browser does not support view transitions.
PR Close#55327
Prior to this change, `NgZone` was provided by default in TestBed in a
location that would override anything configured in
`TestBed.initTestEnvironment`. This change moves the default `NgZone`
provider to the `RootScopeModule` and these providers can be overridden
by the ones in `additionalModuleTypes`, which are assigned from the
first argument of `initTestEnvironment`. This makes it possible to
configure Zone globally for all tests as opposed to needing to repeat it
in `configureTestingModule` of each suite.
PR Close#55226
Previously, multiline selectors were being converted into single lines, resulting in sourcemap disruptions due to shifts in line numbers.
Closes#55508
PR Close#55509
Closure compiler optimizations in g3 require `.then` to be present for a dynamic import (or an import should be `await`ed) to detect the set of imported symbols. Currently, the `.then` is located at a later stage in the file, which confuses static code analysis. This change adds the `.then((m) => m)` workaround to satisfy Closure compiler constraints.
PR Close#55686
This commit addresses a warning in Renovate regarding a deprecated behavior that will be phased out in the future.
```
WARNING: To prevent future issues, replace the usage of matchPackagePatterns with matchDepPatterns (repository=angular/angular, baseBranch=main)
"packageRule": {
"matchPackagePatterns": ["^@bazel/.*", "^build_bazel.*"],
"groupName": "bazel setup",
"schedule": ["at any time"]
},
"packageName": "bazelbuild/rules_nodejs",
"depName": "build_bazel_rules_nodejs"
```
PR Close#55683
This commit removes the 'stopUpdatingLabel' option from Renovate settings. This option caused pull requests to not automatically rebase when conflicting.
PR Close#55683
This commit addresses dependency injection defects when using the `withFetch` API. Formerly, utilizing `withFetch` led to the automatic setting of `HttpBackend` to `FetchBackend`, which proved problematic in certain scenarios. Notably, conflicts arose when integrating `withRequestsMadeViaParent` and manually overriding tokens, as observed in instances like `InMemoryWebApiModule`.
PR Close#55652
This commit handles two cases that were breaking applications when using the new migration:
- tests using `HttpClientModule` in `TestBed.configureTestingModule` were broken as the import was removed, but the module is still present in the test configuration. It now properly adds `provideHttpClient(withInterceptorsFromDi())` and related imports to the test.
- tests using `HttpClientTestingModule` were migrated to use `provideHttpClient(withInterceptorsFromDi())` but the necessary imports were not added. They are now added by the migration.
PR Close#55640
This will allow a multi-app application to listen to early events from different elements and place them
on a separate field on the window.
PR Close#55586
Prior to this change, MathML element were created with the wrong namespace resulting in regular DOM `Element`.
This commit fixes this.
Related to #55608 (but doesn't fix it entirely).
PR Close#55622
This commit updates the list of Node.js `fs` APIs to be patched because
they haven't been updated for a long time. It adds `opendir,lutimes,writev`.
For example, the `opendir` method was added to Node.js in version 12.12.0 in
2019, causing some of the APIs to potentially be always called within the
`<root>` context.
**Note:** There are missing unit tests for these changes because in unit tests,
`fs` is patched by Bazel's Node.js rules and its `node_patches.cjs`. However,
the APIs are successfully patched in the real production code and are called
with the correct context.
PR Close#54396
This key comes from the release build of the Chrome extension. Setting it here configures the extension ID of a local build to match the extension ID of the public release. This makes Chrome recognize that local builds are the same extension leading to more intuitive behavior. It's also useful for allowlists of extension IDs to keep the local ID consistent.
PR Close#55639
Rather than attempting to use the native timing functions, this commit
simplifies the logic significantly by using the global timer functions
as they are, either patched or unpatched. When Zone is defined, we run
the timers in the root zone. This has more predictable behavior and
timing than (a) using both patched and unpatched versions of timers in
different places (b) trying to get an unpatched timer and failing due to
environment specifics and patches that aren't ZoneJS.
PR Close#55366
This commit removes the `@developerPreview` annotation from the `@defer` APIs, effectively promoting them (and the entire feature!) to stable.
PR Close#55625
All usages in google3 have been deleted so this should be a no-op. Next I'll clean up all the configurations turning this off and then delete the option entirely.
PR Close#55598
Fixes that we didn't have the MathML elements in the schema. Note that we can't discover which tag names are available by looking at globally-available classes, because all MathML elements are `MathMLElement` rather than something like `SVGCircleElement`. As such, I ended up having to hardcode the currently-available tags.
Fixes#55608.
PR Close#55631
This also adds a test to make sure that the event contract is still listening to other events, especially in the case where we may want partial hydration in the future.
PR Close#55549
This reverts commit 7e89753eef.
Running render hooks inside the zone is specifically problematic for
`afterRender` hooks. If the callback has async task, it would cause an
infinite change detection. In addition, updating state in render hooks
is generally discourages and certainly should update state in a way that
notifies Angular of the change (either via signal or with `markForCheck`) rather
than relying on ZoneJS to pick it up (which would only work if the
change is done inside an async task).
PR Close#55624
This commit fixes an error in the looping logic of `ApplicationRef.tick`
when the tick skips straight to render hooks. In this case, if a render
hook makes a state update that requires a view refresh, we would never
actually refresh the view and just loop until we hit the loop limit.
PR Close#55623
Currently we add global extra imports to all the files in the compilation unit. However not all the files need extra imports. For example non-Angular files definitely do not need such extra imports, and in some cases these extra imports causes problems as the file is meant to be run the Node but it has Angular dependencies which are not compatible with Node. This change tries to limit extra import generation to a subset of files. Wit hthis change we create extra imports only for the files that contain at least one component whose NgModule is in a different file. This is because all other files do not need extra imports since they are either not Angular files or they already have all the imports that the components need.
PR Close#55548
Fixes that even though we weren't rendering the deferred block the server, we were still triggering the timeout which can delay the response.
Fixes#55475.
PR Close#55605
This define has been removed at head, and now legacy stop propagation
behavior can be opted into at the LegacyDispatcher level, if necessary.
PR Close#55582
This commit ensures we flush animations by calling renderFactory
begin/end in cases where the ApplicationRef._tick happens in a mode that
skips straight to the render hooks.
PR Close#55564
These lines were not tree shakable by Closure Compiler because `.toString()` is special cased as a "pure" function eligible to eliminated if it's return value is unused. However `.toString.call` circumvents this and makes Closure Compiler think the function may have side effects. Switching to `.toString()` should be fine here as `process.toString()` in Node outputs `[object process]` so this should be safe. Presumably the original motivation for this roundabout approach was for type safety reasons which no longer apply as `_global` is `any`.
PR Close#55412
The docs-viewer loads asynchronously and can happen after the scroll
event has happened and the Router has attempted to scroll to the
requested position/anchor. This commit saves the scroll event and
handles it again if the cards are loaded after scrolling happens.
PR Close#55566
Currently whenever a compliance test case TS file is modified, all
compliance tests in repository are rebuilt in partial compilation mode.
This is inefficient and also slows down local development where one may
use a wildcard to run all test targets inside `/test/compliance/...`.
This commit fixes this.
PR Close#55594
This commit adds detailed description for the errors NG0955 and NG0956.
Those errors correspond to the check introduced in the built-in for loop.
PR Close#55591
Using `setTimeout` to delay scrolling can result in scrolling in the
next frame and cause noticeable flicker. This commit scrolls as soon as
the next render happens (or in `setTimeout` if a render does not happen
before then).
fixes#53985
PR Close#55105
The caveat here is that this needs to be done before creating the
fixture. There are some technical issues to overcome with disabling it
after it was already enabled, related to detaching from `ApplicationRef`
without other side effects.
PR Close#55494
Fixes several issues with the `HttpClient` migration that showed up after I tried updating the Material docs site to the latest v18 release. Includes:
* The migration was assuming that all Angular decorators have at least one argument. This led to a null pointer error that broke the v18 update process when I was testing it.
* The migration incorrectly reimplemented the detection of classes with Angular decorators. This can cause code to be migrated incorrectly and doesn't handle cases like import aliases. I've switched it to use the existing tooling for detecting decorated classes.
* The migration was trying to migrate directives, even though they don't support the `imports` field.
* The migration was detecting `TestBed.configureTestingModule` calls using a raw string match which is very fragile and can be broken by the user's formatting.
* There were syntax errors in the unit tests.
* There were type checking errors in the unit tests, for example none of them were importing the Angular decorators that they were migrating.
There's more room for improvement, but this should resolve the most glaring issues without having to rewrite too much.
PR Close#55557
In some cases the height of the viewport wasn't calculated correctly because of extension tabs quirks. This commit fixes this issue.
Fixes#53704
PR Close#54912
This commit prevents doubling change detections when the zoneless
scheduler is notified first, followed by the zone becomeing unstable
(effectively "scheduling" zone-based change detection). When run
coalescing is enabled, this would otherwise result in the zoneless
scheduler running change detection first and then change detection
running again because of the run coalescing since both scheduler use the
same timing function (and then it would be FIFO).
PR Close#55403
In Angular today, a bound listener automatically marks the view for
check. When using ZoneJS, these listeners are most often executed in the
Angular Zone as well, so synchronization (`ApplicationRef.tick`) will
eventually happen. _However_, developers can opt out of zone-patching
for events in several ways, and often do this for very frequent
listeners like `mousemove`, `resize`, and `scroll`. We do not want to
break existing expectations that these are now "safe" events to have
listeners for by automatically scheduling change detection regardless of
whether the listener executed inside or outside the Angular zone.
In contrast, in order for developers to more easily transition to zoneless,
we need to be able to ensure that components which are using `OnPush`
are, for the most part, compatible with zoneless as well. Because listeners
automatically mark the component for check, developers using `OnPush`
did not/do not need to also call `ChangeDetectorRef.markForCheck` or a
similar API. Unfortunately, this means that we need to consider the
listener callbacks as a notification to schedule a `tick` when Zoneless
is enabled. In the future, we would like to have an opt-out for this
(i.e. signal components) since it's not really how we _want_ things to work.
Also includes the fix for #54919 that got reverted only because it was
easier to revert the set of conflicting commits
PR Close#55525
This commit modifies the setup of the injector profiler to occur solely when the application is running in a browser context. This adjustment is made because the injector profile serves no purpose when the application is running on the server.
PR Close#55530
The timing of render hook execution is almost entirely identical to
`ngZone.onMicrotaskEmpty`. Developers working towards zoneless
compatibility will need to migrate `onMicrotaskEmpty` calls to use
`afterNextRender`/`afterRender` instead. This, however, would lead to
confusing issues if there are promises in the callbacks because
`onMicrotaskEmpty` emits inside the Angular zone while render hooks
execute outside today. This is problematic because it's not documented
and does not produce any notification or error message when async work
is done inside the hooks that requires change detection. Instead, change detection
simply does not run, and this behavior has proven to be surprising to
developers who are used to ZoneJS change detection behavior.
fixes#55299
PR Close#55399
Currently fallback content for `ng-content` gets declared and rendered out in one go. This breaks down if multiple instances of the same component are used where one doesn't render the fallback content while the other one does, because the `TNode` for the content has to be created during the first creation pass.
These changes resolve the issue by always _declaring_ the template, but only rendering it if the slot is empty.
Fixes#55466.
PR Close#55478
This PR sets a default state for cookie consent of 'denied'. The other part of the PR exists in the angular/dev-infra repo which will grant permission when the user accepts the cookie banner.
PR Close#54574
The ExperimentalPendingTasks service was accidently exposing one of its
internal fields as a public one. This commit fixes this by marking the
field in question as private.
PR Close#55516
In Angular today, a bound listener automatically marks the view for
check. When using ZoneJS, these listeners are most often executed in the
Angular Zone as well, so synchronization (`ApplicationRef.tick`) will
eventually happen. _However_, developers can opt out of zone-patching
for events in several ways, and often do this for very frequent
listeners like `mousemove`, `resize`, and `scroll`. We do not want to
break existing expectations that these are now "safe" events to have
listeners for by automatically scheduling change detection regardless of
whether the listener executed inside or outside the Angular zone.
In contrast, in order for developers to more easily transition to zoneless,
we need to be able to ensure that components which are using `OnPush`
are, for the most part, compatible with zoneless as well. Because listeners
automatically mark the component for check, developers using `OnPush`
did not/do not need to also call `ChangeDetectorRef.markForCheck` or a
similar API. Unfortunately, this means that we need to consider the
listener callbacks as a notification to schedule a `tick` when Zoneless
is enabled. In the future, we would like to have an opt-out for this
(i.e. signal components) since it's not really how we _want_ things to work.
PR Close#55492
The new ExperimentalPendingTasks API lets developers to add and remove
tasks that control applications stability: a pending task prevents
application from being stable.
This API is important for all the use-cases that depend on the concept
of stability and SSR serialization is a notable example.
Closes#53381
PR Close#55487
This change ensures that `ApplicationRef.tick` flushes animations by
calling `rendererFactory2.end`. This might not have happened before if
there were no views that needed to be refreshed.
This is also likely to fix a potential regression caused by #53718 even
in zone apps where animations don't get flushed when no views attached
to ApplicationRef are dirty.
PR Close#55132
This commit fixes an issue where event contract init script was injected into the page before the inlined event dispatch script. That resulted in runtime exceptions, since event contract relies on some code being present on a page already.
PR Close#55502
This commit updates the logic to take into account a situation when Event Replay feature is enabled (using `withEventReplay()` method), but there were no events configured in an application. In this case, there is no need to setup an event dispatcher and trigger event replay.
PR Close#55502
This commit updates Terser config to disable property renaming for the event delegation script (that we later inline into the HTML during SSR). The problem is that event dispatcher relies on some functions on the EventContract class to have original names after after minification, we loose an ability to call those functions.
PR Close#55502
This will enable refactoring existing usages of the Dispatcher that use
APIs that we do not intend to support, like registerGlobalHandler and
registerEventInfoHandlers to use the LegacyDispatcher.
PR Close#55372
When a formControlName is used without a parent formGroup, an error is
logged in the console. Before this commit, there was no information
about which control had the issue. Now, it's reported and the
troubleshoot is much faster.
PR Close#55397
The `DeferBlockFixture.render` function should not await the
`whenStable` promise of the fixture. This does not allow developers to
test any intermediate states that might occur between rendering the
initial content and the full app stability.
fixes#55235
PR Close#55271
Remove the `async` function in favor of using `waitForAsync` instead.
BREAKING CHANGE: `async` has been removed, use `waitForAsync` instead.
PR Close#55491
The previous example had an incomplete code snippet that would not work if copied and pasted as is. There were two missing closing parentheses, one for the `inject` function, and the other for the `waitForAsync` function.
PR Close#55407
Adds a check that disables the timer scheduling for `placeholder` and `loading` blocks on the server since the underlying timer will delay the server response.
Fixes#55475.
PR Close#55480
BREAKING CHANGE: Deprecated `StateKey`, `TransferState` and `makeStateKey` have been removed from `@angular/platform-browser`, use the same APIs from `@angular/core`.
PR Close#55474
Mozilla requires add-ons to have reproducible builds and this is managed directly by human reviewers and need to understand how to build Angular DevTools correctly. This commit defines a reproducible way of building Angular DevTools which is useful for reviewers and contributers.
The actual changes I made include:
1. Moving local development content into `devtools/README` (deleting `devtools/DEVELOPING.md`) and explicitly stating the Node version as well as global Yarn install to be clear about the correct way to build the extension. This should make it easier for reviewers to understand and reproduce builds.
2. Moving release instructions to a separate doc to reduce noise as well as making some minor clean ups there.
I briefly considered pointing reviewers at a new `devtools/docs/reviewers.md` doc, but decided against it because I want these instructions to be maintained in a single location where contributors and reviewers use the same content. This way any changes don't miss one of these sets of users. If reviewers have trouble with this format (dev builds isn't useful to reviewers and some content is repeated from other docs for contributors) then we can consider splitting out to a separate `reviewers.md` file. But until then, I'd like to try sharing this content and see how it works out in practice.
PR Close#55406
Partial revert of #54891. Webcontainers do not support node ^18.19.1 which is required by the v18 CLI.
Until this is solved by the stackblitz team, we're stucked with v17 based tutorials
PR Close#55437
Ahead of delegating the i18n subsystem to the `Intl` API, this commit introduce the intention to remove those functions from the public API.
DEPRECATED: `getCurrencySymbol`, `getLocaleCurrencyCode`, `getLocaleCurrencyName`, `getLocaleCurrencySymbol`, `getLocaleDateFormat`, `getLocaleDateTimeFormat`, `getLocaleDayNames`, `getLocaleDayPeriods`, `getLocaleDirection`, `getLocaleEraNames`, `getLocaleExtraDayPeriodRules`, `getLocaleExtraDayPeriods`, `getLocaleFirstDayOfWeek`, `getLocaleId`, `getLocaleMonthNames`, `getLocaleNumberFormat`, `getLocaleNumberSymbol`, `getLocalePluralCase`, `getLocaleTimeFormat`, `getLocaleWeekEndRange`, `getNumberOfCurrencyDigits`
PR Close#54483
This migration will allow developers to migrate the deprecated `HttpClientModule`, `HttpClientJsonpModule` & `HttpClientXsrfModule` to their respective provider functions.
PR Close#54020
This commit deprecates the `HttpClientModule` and other related http modules. Those can be replaced by provider function only.
Angular is an opinionated framework, feature guidance will help developer choose the recommended way to enable feature (like Http requests here).
Note: This is not an indication of deprecation for `NgModule`. The deprecated module's only purpose here was to define providers. This can be done directly by the provide function pattern.
DEPRECATED: `HttpClientModule`, `HttpClientXsrfModule` and `HttpClientJsonpModule`
As mentionned, those modules can be replaced by provider function only.
PR Close#54020
The change in the index is to allow the framework to add a type to the object that is passed from the contract to the dispatcher. ie
registerDispatcher(contract, (eventInfo: EventInfoWrapper) => ...).
The latter is to return the event contract so that tests can clean it up.
PR Close#55411
`RouterOutlet` uses a unique injector logic that returns a value that correspond to the `ActivatedRoute` token dynamically. This logic breaks when a component/directive/pipe that injects the `ActivatedRoute` is located within a `@defer` block, because defer creates an `EnvironmentInjector` instance, which doesn't have that dynamic logic.
We've added some special handling of the `OutletInjector` in one of the previous commits, but it was incomplete and it was not covering cases when different routes use the same component. This commit updates defer logic to re-establish this dynamic behavior for `ActivatedRoute` by creating an instance of the `OutletInjector` when a parent injector was also an instance of `OutletInjector`.
This fix is a short-term solution and longer term we should find a way to achieve the dynamic behavior that Router relies on, but without adding a special case logic into defer.
Resolves#54864.
PR Close#55374
Removes the warning about performance from the directive composition API docs since some recent benchmarks have snown that their effect is negligible.
PR Close#55448
This breaks renovate
```
### ⚠ Artifact update problem
Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.
♻ Renovate will retry this branch, including artifacts, only when one of the following happens:
- any of the package files in this branch needs updating, or
- the branch becomes conflicted, or
- you click the rebase/retry checkbox if found above, or
- you rename this PR's title to start with "rebase!" to trigger it manually
The artifact failure details are included below:
##### File name: packages/zone.js/test/typings/yarn.lock
```
error Package "zone.js" refers to a non-existing file '"/tmp/renovate/repos/github/angular/angular/dist/bin/packages/zone.js/npm_package"'.
```
PR Close#55433
PR #51670 removed the usage of `const enum`. As a consequence HttpStatusCode that were previously inlined now pull and retains the (fairly large) `HttpStatusCode` enum.
By intermediate constants, we prevent the framework from pulling this big enum by default.
PR Close#55434
JSAction script is inlined into the HTML by the build process to avoid extra blocking request. The script looks like this:
```
<script type="text/javascript" id="ng-event-dispatch-contract">...</script>
```
This commit updates the logic to remove JSAction if event replay feature is disabled or if there are no events to replay.
PR Close#55428
Expose `HTTP_TRANSFER_CACHE_ORIGIN_MAP` injection token in public api. This is useful when different origins are used to access the same APIs between server and browser.
Fixes#53702
PR Close#55274
Angular DevTools depends on many modern Angular features in order to function. As a result, at present the last officially supported version is v12. Angular DevTools may function for some Angular 9, 10 and 11 applications, but they are not officially supported.
This commit fixes an issue where DevTools would not inject a backend script into an Angular application if it detected it was below version 12. This backend script is important because it's used to inform the DevTools panel that the inspected application is in fact Angular, but that it is not on a supported version.
Angular 9, 10 and 11 applications that successfully have Angular DevTools initialize will now have a red highlight and tooltip on their version number, informing the user that they are using Angular DevTools on a version of Angular that is no longer supported.
Angular DevTools for applications that are below version 9 will continue to display the "Angular Devtools supports Angular versions 12 and above" message.
PR Close#55233
This commit introduces a check plus an associated warning for situations where
the combination of the collection change and the tracking expression resulted
in the entire view structure managed by @for to be re-created.
The check uses the following conditions before raising a warning:
- the entire collection was re-created and there were no other operations (ex.: move);
- views in a collection are considered "expensive" to re-create;
- a developer is using tracking by identity.
The last condition tries to capture cases where changes to immutable data
collections can cause significent performance and / or corectness problems.
Note that this warning might be "overreacting" and report cases where
the collection re-creation is the intended behavior. Still, the assumption is that
most of the time it is undesired.
PR Close#55314
This commit fixes an error in a previous commit which attempted to read
`data` from the first item in the apply args array, even if it was not
defined.
PR Close#55465
This commit removes of migrations introduced in version 17, along with the relocation of a migration from 17.3 to version 18. This ensures that this is ran for users who may have updated from one minor to another without executing `ng update`
PR Close#55391
Angular only checks the contents of template nodes in full type checking mode. After v17, the new control flow always had its body checked, even in basic mode, which started revealing compilation errors for apps that were using the schematic to automatically switch to the new syntax.
These changes mimic the old behavior by not checking the bodies of `if`, `switch` and `for` blocks in basic mode. Note that the expressions of the blocks are still going to be checked.
Fixes#52969.
PR Close#55360
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
This commit adds helpful stack information for the case when change
detection continues to be triggered in the event loop and would cause
the browser to freeze.
PR Close#55231
There is an existing pattern that zone-based applications use to avoid
`ExpressionChangedAfterItHasBeenCheckedError` which is also used in
`NgModel`: update the state in a microtask instead of doing it
synchronously. This defers the state update to another round of change
detection, and with ZoneJS, also still executes in the same event loop.
These types of changes across multiple rounds of change detection were
still executed before the browser paint.
This update allows the `NgModel` workaround to continue working in
Zoneless. This may not be permanent and is certainly still not
advisable. Render hooks (`afterNextRender`/`afterRender`) will execute between these
rounds of change detection when they are intended to be run after all
DOM updates completed.
PR Close#55231
This update modifies the transfer cache logic to prevent caching of HTTP requests that require authorization. To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`
BREAKING CHANGE: By default we now prevent caching of HTTP requests that require authorization . To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`.
Example:
```ts
withHttpTransferCache({
includeRequestsWithAuthHeaders: true,
})
```
Closes: #54745
PR Close#55034
This commit adds the ability to return `RedirectCommand` from the error
handler provided by `withNavigationErrorHandler`. This will prevent the
error from being surfaced in the `events` observable of the Router and
instead convert the error to a redirect. This allows developers to
have more control over how the Router handles navigation errors. There
are some cases when the application _does not_ want the URL to be reset
when an error occurs.
resolves#42915
PR Close#55370
This commit ensures we correctly handle the exit from the zone.run in
the zoneless scheduler. Run coalescing would delay the `onMicrotaskEmpty` event
until after we have exited the change detection triggered by the
zoneless scheduler and mean that the subscription cannot determine if
`ApplicationRef.tick` should be skipped.
PR Close#55352
For ideal DOM usage, you would not unwrap an ElementRef outside of the browser. However, it's reasonable to want to find the tag name of the host node on the server, and so this introduces a HOST_TAG_NAME token that can be injected to read this value.
PR Close#54751
Flip `stopPropagation` constructor parameter default to `false` for
`EventContract` and `EventContractMultiContainer`. Change type for
`EventContract` to `false` to indicate that no values besides `false`
should be passed. This enables removing all usages of `stopPropagation`
in `EventContract` and leaving only usages of `stopPropagation = true`
for `EventContractMultiContainer`.
PR Close#55351
When `cleanUp` is called `containerManager` is set to null. Currently
the `EventContract` API assumes that users know not to call further
methods on `EventContract`, but this lead to a bug in a downstream app,
b/333750059. So instead, this makes a defensive check to make sure it's
not null.
PR Close#55353
This commit integrates the JSA contract binary into the NPM package and ensures its accessibility by including it in the package exports. This adjustment is essential for enabling Angular CLI to effectively access and inject the script. Additionally, sourcemaps are removed from the minified bundle to prevent their inclusion in the HTML page.
PR Close#55361
This commit loosens the restrictions on calling `ComponentFixture.detectChanges`
when using the zoneless scheduler. While we don't necessarily think it's
a good idea, the thought is that it's unnecessary mental overhead to
diverge behaviors in the API when zoneless is enabled versus when it is
not. Instead, these opinionated restrictions can be considered when we
look at new testing APIs.
PR Close#55325
BREAKING CHANGE: The deprecated `isPlatformWorkerUi` and `isPlatformWorkerApp` have been removed without replacement, as they serve no purpose since the removal of the WebWorker platform.
PR Close#55302
When Angular receives a clear indication that change detection should
run again, this should not be ignored, regardless of what Zone it
happened in. This change updates the default change detection scheduling
approach of Zone-based applications to ensure a change detection will
run when these events happen outside the Angular zone (which includes,
for example, updating a signal that's read in a template, setting an
input of a `ComponentRef`, attaching a view marked for check, calling
`ChangeDetectorRef.markForCheck`, etc.).
This does not apply to applications using `NoopNgZone` or those which
have a custom `NgZone` implementation without ZoneJS.
The impact of this change will most often be seen in existing unit tests. Tests
execute outside the Angular Zone and this can mean that state in the
test is not fully recognized by Angular. Now that Angular will ensure
change detection _does_ run, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior. Often, this should be seen
as more correct and the test should be updated, but in cases where it is
too much effort to debug, the test can revert to the old behavior by adding
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the `TestBed` providers.
fixes#55238fixes#53844fixes#53841fixes#52610fixes#53566fixes#52940fixes#51970fixes#51768fixes#50702fixes#50259fixes#50266fixes#50160fixes#49940fixes#49398fixes#48890fixes#48608fixes#45105fixes#42241fixes#41553fixes#37223fixes#37062fixes#35579fixes#31695fixes#24728fixes#23697fixes#19814fixes#13957fixes#11565fixes#15770fixes#15946fixes#18254fixes#19731fixes#20112fixes#22472fixes#23697fixes#24727fixes#47236
BREAKING CHANGE:
Angular will ensure change detection runs, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior.
This change will be more likely to impact existing unit tests.
This should usually be seen as more correct and the test should be updated,
but in cases where it is too much effort to debug, the test can revert to the old behavior by adding
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the `TestBed` providers.
Similarly, applications which may want to update state outside the zone
and _not_ trigger change detection can add
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the providers in `bootstrapApplication` or add
`schedulingMode: NgZoneSchedulingMode.NgZoneOnly` to the
`BootstrapOptions` of `bootstrapModule`.
PR Close#55102
Rather than attempting to use the native timing functions, this commit
simplifies the logic significantly by using the global timer functions
as they are, either patched or unpatched. When Zone is defined, we run
the timers in the root zone. This has more predictable behavior and
timing than (a) using both patched and unpatched versions of timers in
different places (b) trying to get an unpatched timer and failing due to
environment specifics and patches that aren't ZoneJS.
We will try to update the coalescing behavior of ZoneJS in a future PR
to also just use the patched version of the timers instead of the
"fakeTopEvent" workaround with the native timers.
PR Close#55367
This commit ensures that manually calling ApplicationRef.tick will
result in any scheduled change detections being canceled. There is no
need for the scheduled one to run because it was manually done by the
`tick` already.
PR Close#55290
This commit updates the implementation of `ngswAppInitializer` to configure
the `controllerchange` event listener outside of the Angular zone. This adjustment
is made to prevent unnecessary change detections, as the `controllerchange` event
is unrelated to view updates.
**NOTE**: This change may result in breaking unit tests that implicitly rely on a
specific number and sequence of change detections for their assertions to pass.
PR Close#54222
Two-way bindings are meant to represent a property binding to an input and an event binding to an output, e.g. `[(ngModel)]="foo"` represents `[ngModel]="foo" (ngModelChange)="foo = $event"`. Previously due to a quirk in the template parser, we accidentally supported unassignable expressions in two-way bindings.
In #54154 the quirk was fixed, but we kept support or some common expression because of internal usages. Now the internal usages have been cleaned up so the backwards-compatibility code can be deleted.
Externally a migration was added in #54630 that will automatically fix any places that depended on the old behavior.
BREAKING CHANGE:
Angular only supports writable expressions inside of two-way bindings.
PR Close#55342
Right now this binary sits at 9.5kb. Additional changes to the library will
be done to reduce the binary size, such as converting event_type from
an enum to an object, and other code size reductions.
PR Close#55319
When we started fixing the version mismatch with local 1st-party
packages, we also re-routed all dependencies like `@lezer/javascript`
into `adev/node_modules`. This works fine, but results in a different
version mismatch because the codemirror dependencies may resolve the
Angular version from `/node_modules`- causing some subtle complex
runtime error.
This commit fixes this by only re-routing dependencies that have
dependency on e.g. `@angular/core` into `adev/node_modules`.
Fixes#55298.
PR Close#55349
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
This commit removes the long-deprecated Testability methods that track
pending tasks. This is done by NgZone today and will be done by other
APIs in zoneless.
BREAKING CHANGE: Testability methods `increasePendingRequestCount`,
`decreasePendingRequestCount` and `getPendingRequestCount` have been
removed. This information is tracked with zones.
PR Close#53768
This commit adds a configuration option to zone-based change detection
which allows applications to enable/disable the zoneless scheduler.
When the zoneless scheduler is enabled in zone-based applications,
updates that happen outside the Angular zone will still result in a
change detection being scheduled. Previously, Angular change detection
was solely based on the state of the Angular Zone.
PR Close#55252
An implementation of a TypeScript server plugin module factory has
been added to the main plugin code which minimizes the amount of
infrastructure code necessary to directly setup the Angular plugin.
This is not yet used externally but can be integrated in the future.
PR Close#55264
Expect that the number of template executions is `===` to a number, rather than expect that it
does not contain a number. As they were, these expectations would pass regardless of the expected
value.
PR Close#55294
1: Remove USE_EVENT_PATH, which has no users.
2: Create a new `EventActionInfo` object to represent actions, update all `EventInfoWrapper` users.
3: Fix `stopPropagation` behavior in JSAction Dispatcher - it should only `stopPropagation` if an action is found, which is only known during normal dispatch rather than global.
PR Close#55182
Similar to what we did for aio, we should not clear the architect CLI
output in Bazel. This messes up with the output and makes debugging
hard.
PR Close#55282
There is quite some trickery going on with the adev build related to
local packages:
- Adev builds using npm packages from `/node_modules`
- At runtime, we are adding `HEAD` packages for e.g. `@angular/core` to
the bundles.
- At build time, the CLI, or Angular devkit may accidentally resolve to
`@angular/core` from `/node_modules/`— which is the core version from
npm, transitively installed via `@angular/docs`.
This causes a version mismatch, leading to issues like:
- CLI throwing because of a mismatch. https://github.com/angular/angular/issues/54858#issuecomment-2047188739
- Compiler changes not being picked up. https://github.com/angular/angular/issues/54858#issuecomment-2041322427
This commit attempts to fix this by:
- Linking all Angular `HEAD` packages into `adev/node_modules`. The
current logic attempts to link into `/node_modules`, but this does not
override existing `@angular/core`!
- Linking all direct external NPM packages, like
`@angular_devkit/build-angular` into `adev/node_modules` without their
transitive deps. This allows proper resolution of e.g. compiler as
node looks in `adev/node_modules` first, and falls back for the rest
to the execroot `node_modules`, or symlink target destination (if
`preserveSymlinks=false`).
Note: This is still not 100% ideal because a direct external NPM
dependency may have a transitive dependency that has another transitive
dependency on `@angular/core`. In those cases, the may be a conflict
that is not resolvable until we switch to a Bazel toolchain with better
first party resolution support.
PR Close#55282
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests (https://github.com/angular/angular/commit/28c68f709cdc930e12bac51a266e7bf790656034).
Today, `PendingTasks` contribute to `ApplicationRef.isStable` but do not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended and we plan to make these two
stability indicators the same again, like they were when it was solely
based on the state of the Zone.
By aligning the two behaviors again, this would include all pending
tasks in the stability of fixtures. After investigation, this seems
likely to be a pretty large breaking change. Tests appear to quite often use
`await fixture.whenStable` when there are unfinished requests that have
not been mocked or flushed.
This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` automatically but only when using
`HttpClientTesting`. In this scenario, requests need to be expected and
flushed manually for them to resolve. When the test backend and controllers
aren't used, requests should resolve on their own so `await fixture.whenStable`
shouldn't be particularly affected or problematic.
PR Close#54974
The `getDefinitionAtPosition` function may be called by consumers instead
of `getDefinitionAndBoundSpan` with the later of which already implemented.
The `getDefinitionAtPosition` result is a subset of what `getDefinitionAndBoundSpan`
returns and currently delegates to that function.
PR Close#55269
Within the language service, the Angular compiler instance can provide
access to the current TypeScript program via `getCurrentProgram`. By
using the compiler, the need to pass around the program driver is no longer
required and can also be removed as an instance field of the Angular language
service class. This change also provides a higher assurance that the correct
program is being used throughout each language service request.
PR Close#55097
Keep theme constants in sync betwee index.html file and theme manager. Move versions config static data to their own file, and replace the deprecated toPromise() api with the new firstValueFrom() api
PR Close#55234
Previously located in the `aio` directory, the commit moves the docs file into `adev` and also moves the `script` used to generated them from the `angular-cli` repo.
PR Close#55242
Prior to this change, `NgZone` was provided by default in TestBed in a
location that would override anything configured in
`TestBed.initTestEnvironment`. This change moves the default `NgZone`
provider to the `RootScopeModule` and these providers can be overridden
by the ones in `additionalModuleTypes`, which are assigned from the
first argument of `initTestEnvironment`. This makes it possible to
configure Zone globally for all tests as opposed to needing to repeat it
in `configureTestingModule` of each suite.
PR Close#55226
Now that #55092 has merged, we now consistently get the `setTimeout` and
`rAF` implementations that are not patched by zone. There's no longer a
need to run them in the root zone.
PR Close#55230
PR #55099 updated zoneless behavior to treat all views attached to
`ApplicationRef` as `OnPush`. Put another way, Zoneless change detection
will only refresh view trees that notified Angular of a change. This
generally works as expected but there was one situation where it did
not.
Some views are logically linked to their declaration locations and
should refresh when the declaration refreshes. These views are called
"transplanted views" and work correctly when inserted into another view
container. This change updates the logic to also work when they are
attached directly to `ApplicationRef`.
PR Close#55154
Previously the input flags were being generated as a reference to an enum member for better readability and under the assumption that minifiers would inline the values. That doesn't appear to be the case so these changes switch to using the literal values instead.
PR Close#55215
This commit introduces a new method to subscribe to on every `AbstractControl` subclass.
It allows to track value, pristine, touched and status changes on a given control.
Fixes#10887
PR Close#54579
The fix from PR #55079 introduced a configuration of the injector chain, which wasn't properly handled by the injector debug utils, thus resulting in JS exceptions in DevTools. This commit updates injector debug utils logic that calculates injector resolution path to also handle `ChainedInjector`s.
Resolves#55137.
PR Close#55144
In #52110 we had to use `if` statements to represent `switch` blocks, because TypeScript had a bug when narrowing the type of parenthesized `switch` statements. Now that it has been fixed by TypeScript and we don't support any version that has the broken behavior, we can go back to generating `switch` statements in the TCB which are simpler and better represent the user's code.
PR Close#55168
Grabbing and saving the references to global `setTimeout` and `rAF`
implementations at a certain point in time can be problematic, espcially
in tests. Tests might call something like `jasmine.clock().install();`
and `jasmine.clock().uninstall();`. If the install happens before we
grab the implementation and then the uninstall happens after, our
scheduling function will be broken because it would have saved a reference to
the jasmine `setTimeout` implementation, which would have since been
cleaned up and will throw an error when attempting to access `delayedFunctionScheduler`.
There are other scenarios that may apply, not even just for tests, when
patches are applied and removed to the globals.
PR Close#55124
This commit ensures components in the route config predictably always
get their providers from the hierarchy available to routes rather than
sometimes being dependent on where they are inserted.
fixes#53369
BREAKING CHANGE: Providers available to the routed components always
come from the injector heirarchy of the routes and never inherit from
the `RouterOutlet`. This means that providers available only to the
component that defines the `RouterOutlet` will no longer be available to
route components in any circumstances. This was already the case
whenever routes defined providers, either through lazy loading an
`NgModule` or through explicit `providers` on the route config.
PR Close#54265
Returning a `RedirectCommand` from a resolver can be interpreted as
distinctly different from regular resolved data. When a resolver returns
`RedirectCommand` we can interperet this as an intention to redirect in
the same way as other guards.
resolves#29089
PR Close#54556
Fix scrolling experience in API Reference:
- set correct margin top for members container (right side) which is aligned with tabs (left side)
- prevent scroll on focus
- remove redundant blur calls
PR Close#55133
The control flow migration was using a couple of Greek letters as placeholders. This ended up conflicting with templates authored in Greek.
These changes use a more obscure placeholder to make conflicts less likely. It also moves the placeholder generation to a centralized function so it's easier to make changes if we decide to update the pattern again.
Fixes#55085.
PR Close#55113
To display the image correctly, swap the image from the folders
Fixes #54778
feat(docs-infra): change path for correct ADEV
Changing path for correctly displaying in adev
PR Close#54795
This reverts commit 367b3ee6e9.
The search element is not a void element but existing components may use
the same selector and be used as a void element.
PR Close#55127
This change treats all views attached to `ApplicationRef` as `OnPush`,
meaning that they have to be explicitly marked for check in order to be
refreshed when a tick happens. This prevents "accidentally" refreshing
views which have `Default` change detection as a side effect of running
change detection from an unrelated notification.
In addition, this change helps us achieve one of the big goals of the
project: that we can provide a testing experience which gives developers
more confidence that a component is zoneless-compatible. Because
`ComponentFixture` change detection is run through `ApplicationRef`
instead of `ChangeDetectorRef` when zoneless is enabled, this ensures
that the component under test has correctly been marked for check in
order to be updated. Without this, calling
`ComponentFixture.detectChanges` would allow a test to _force_ change
detection on a view when Angular would have otherwise not known that it
needed to be updated. Calling `ComponentFixture.detectChanges` on a component
which is not marked for check will now omit refreshing component view.
PR Close#55099
It is not enough to use provideHttpClientTesting() for HTTP Client Testing, it will throw a dependency injection error. Update the docs to include both provideHttpClient() and provideHttpClientTesting()
Fixes#53390
PR Close#53716
Rework the i18n cleanup behavior to more closely match that of containers. Specifically, we assume that nodes are going to be claimed unless they are part of a branching ICU block.
During hydration, we then track which ICU case was active at serialization time, and which was active during hydration. Any remaining cases that weren't used during hydration are then cleaned up.
PR Close#54823
Add support for hydrating i18n blocks. This is accomplished by serializing information about selected ICU cases for a block during server-side rendering.
During hydration, this data is read and is used to traverse both an AST of the translated message and the DOM, in parallel, to map each LView with an RNode.
Finally, this mapping is used while nodes are being created (either via i18n or their respective instructions) to locate existing nodes.
PR Close#54823
This commit updates the internal resolve value of the navigation promise
to use `false` instead of `null` when a navigation is skipped. The
navigation promise type requires `boolean` so the correct resolution to
match the truthy/falsiness of the currently resolved value, `null`, is
`false` instead.
PR Close#55068
This commit moves the call to the error handler to the location where
the error event emits instead of having it indirectly work through the
events subscription. This change would also allow the handler to return
a value which can be handled by the navigation transition.
PR Close#55068
This commit fixes the types on the error handler resolve and reject
functions and also ensures that the resolve value matches the API type
(`boolean`, not "any random value returned from `errorHandler`"). This
could be considered a breaking change but I would argue instead that
relying on the return value of the error handler is API misuse because
the promise returned by the router navigation _does not_ include `any`
in its type.
PR Close#55068
This commit fixes the internal types for the resolve and reject
functions used for the router navigation Promise. These are currently
typed as `any`.
PR Close#55068
Angular recently gained a local compilation mode (see commit 345dd6d).
This is intended to be used with the TypeScript compiler option isolatedModules, which bans imports of const enums.
PR Close#55103
While we do want to discourage `fixture.detectChanges`, it is yet to be
determined how this should be accomplished (warning, documentation, etc.). At
the moment, not being able to disable the error at all is entirely
prohibitive for existing test suites to use zoneless change detection in
tests. We would much rather allow existing test suites to disable the
error and use the zoneless change detection than prevent them from using
it entirely until all the `detectChanges` calls have been fixed.
Calling `detectChanges` manually can hide errors related to change
detection timing, but it is even worse when the "PseudoApplication"
fixture used (since it runs change detection _only_ on the component
rather than through `ApplicationRef`).
PR Close#55098
Angular's template files are not valid TypeScript. Attempting to get syntactic
diagnostics from the underlying TypeScript language service will result in
a large amount of false positive errors. Only actual TypeScript files should
be analyzed by the underlying TypeScript language service for syntactic errors.
PR Close#55091
Fixes that the control flow migration was throwing an error if the `imports` of a component are initialized to an identifier.
Fixes#55080.
PR Close#55081
This commit updates the `@defer` logic to establish proper injector resolution order. More specifically:
- Makes node injectors to be inspected first, similar to how it happens when `@defer` block is not used.
- Adds extra handling for the Router's `OutletInjector`, until we replace it with an `EnvironmentInjector`.
Resolves#54864.
Resolves#55028.
Resolves#55036.
PR Close#55079
Allows for `SourceFileValidatorRule.checkNode` to produce a single diagnostic. The most common case should be one diagnostic per node so this allows us to save some array allocations.
PR Close#54993
Adds the new `SourceFileValidator` that will be used to check for file-level issues that may prevent Angular from working, like invoking the `input()` function outside of an initializer. Currently only one check is planned, but this setup will allow us to easily add more in the future.
PR Close#54993
`Object.getPrototypeOf(obj)` returns `null` if `obj` is an empty object. `Object.getOwnPropertyDescriptors` throws on `null`/`undefined`
PR Close#55061
This commit makes the zoneless scheduler (privately) available to applications that
have ZoneJS-based change detection. This would catch any changes of
interest (signal updates, `markForCheck` calls, attaching `Dirty` views)
that happen outside the Angular Zone.
See #53844 for additional information about why this is important.
More details to come in the a future commit that makes this a public option.
PR Close#54952
Add a sentence to the `@loading` block documentation that emphasizes more that the `@loading` block will replace the `@placeholder` block once the deferred view starts loading.
PR Close#54779
This change aligns the stability of `ComponentFixture` with that of
`ApplicationRef`, preventing confusing differences between the two as
more APIs start using the `PendingTasks` that may not be tracked by
`NgZone`.
BREAKING CHANGE: `ComponentFixture.whenStable` now matches the
`ApplicationRef.isStable` observable. Prior to this change, stability
of the fixture did not include everything that was considered in
`ApplicationRef`. `whenStable` of the fixture will now include unfinished
router navigations and unfinished `HttpClient` requests. This will cause
tests that `await` the `whenStable` promise to time out when there are
incomplete requests. To fix this, remove the `whenStable`,
instead wait for another condition, or ensure `HttpTestingController`
mocks responses for all requests. Try adding `HttpTestingController.verify()`
before your `await fixture.whenStable` to identify the open requests.
Also, make sure your tests wait for the stability promise. We found many
examples of tests that did not, meaning the expectations did not execute
within the test body.
In addition, `ComponentFixture.isStable` would synchronously switch to
true in some scenarios but will now always be asynchronous.
PR Close#54949
This commit will fix the issue of the setting of NavigationExtras.replaceUrl being lost when
returning a urlTree from a CanActivateFn.
Fixes#53503
BREAKING CHANGE: When a a guard returns a `UrlTree` as a redirect, the
redirecting navigation will now use `replaceUrl` if the initial
navigation was also using the `replaceUrl` option. If this is not
desirable, the redirect can configure new `NavigationBehaviorOptions` by
returning a `RedirectCommand` with the desired options instead of `UrlTree`.
PR Close#54042
Previously, `RouterLinkActive` would only add or remove the active classes when
its active state changed. This means that if you accidentally add one of
the active classes to the static class attribute, it won't get removed
until the link becomes active and then deactives (because the class is
added at creation time and never removed until the `RouterLinkActive`
state changes from active to inactive).
fixes#54978
PR Close#54982
The custom flatMap implementation can now be removed as Array contains a
native implementation that is available for all supported Node.js versions.
PR Close#55011
When the `angularOnly` option is disabled, the underlying TypeScript language service
was previously used for all files including `.html` template files. This can result in
incorrect responses including a large amount of invalid diagnostics for a template file.
Checks have now been added to only use the Angular Language service for template files
which can properly handle template files. Additionally, the check for a TypeScript file
name has now been expanded to encompass all current file extension forms.
PR Close#55003
For `FatalDiagnosticError` we are currently hiding the `message` string
field in favor of the actual TS `diagnosticMessage`.
This works as expected, but makes these errors hard to debug in certain
environments (e.g. Jasmine). That is because `null` is the value of
`message` at runtime. We fix this by just overriding the type, like we
originally intended to do.
In addition, we properly render message chains in the `Error#message`
field— so that these errors, when uncaught, are somewhat reasonable and
can be useful.
PR Close#54981
This commit ensures that the new APIs like `input`, `model`, `output`,
or signal-based queries are not accidentally used on fields that have a
problematic visibility/access level that won't work.
For example, queries defined using a private identifier (e.g. `#bla`)
will not be accessible by the Angular runtime and therefore _dont_ work.
This commit ensures:
- `input` is only declared via public and protected fields.
- `output` is only declared via public and protected fields.
- `model` is only declared via public and protected fields.
- signal queries are only declared via public, protected and TS private
fields (`private` works, while `#bla` does not).
Fixes#54863.
PR Close#54981
An initializer API like `input`, `output`, or signal queries may not be
compatible with certain access levels. E.g. queries cannot work with ES
private class fields.
This commit introduces a check for access levels into the initializer
API recognition— enforcing that every initializer API *clearly*
specifies what type of access is allowed.
PR Close#54981
This commit changes the TypeScript reflection host to:
* inspect / process ES private fields. e.g. `#someField` — those are
ignored right now and we would want to check them to issue
diagnostics.
* determine an access level of a class member. E.g. a member may be
public, may be private, may be ES private, or public readonly. This
can then be used in various checks later.
PR Close#54981
Updates the function that parses initializer APIs to check any `Expression`, instead of expecting a class member. This will be useful for the upcoming changes.
PR Close#54981
This commit fixes various issues that seem to cause the 17.3.x patch
to be red for weeks:
- Eslint checking a file for aio/tools that is not part of a tsconfig—
hence an error is being reported.
- Audit-web-app importing some Lighthouse APIs that aren't available
under the given path.
PR Close#55064
Previously, a race condition could cause DevTools to enter a state where it can't detect an application on reload. This was caused by a sequencing issue between the content script connection, the devtools panel connection and an event "backendReady" that lets DevTools know when a particular frame is ready to be inspected.
This commit replaces the previously stored backendReady boolean with a promise, so that the devtools panel can eventually run a callback to connect to a content script when that content script emits it's backendReady message.
PR Close#54805
Passes the attributes of the `ng-content` element to the container that is created for the fallback content so that it can be re-projected into the same slot.
PR Close#54854
Moves the logic that declares a template out into a separate function so that it can be reused in other places like control flow and defer, without having to call directly into the `template` instruction.
PR Close#54854
Adds the ability to specify content that Angular should fall back to if nothing is projected into an `ng-content` slot. For example, if we have the following setup
```
@Component({
selector: 'my-comp',
template: `
<ng-content select="header">Default header</ng-content>
<ng-content select="footer">Default footer</ng-content>
`
})
class MyComp {}
@Component({
template: `
<my-comp>
<footer>New footer</footer>
</my-comp>
`
})
class MyApp {}
```
The instance of `my-comp` in the app will have the default header and the new footer.
**Note:** Angular's content projection happens during creation time. This means that dynamically changing the contents of the slot will not cause the default content to show up, e.g. if a `if` block goes from `true` to `false`.
Fixes#12530.
PR Close#54854
Adds logic to ingest the content of an `ng-content` element in the template type checker. We treat `ng-content` as a `ScopedNode`, because its content is inserted conditionally.
PR Close#54854
This commit adds support for ignoring specific doc entries when
extracting doc entries. This allows us to drop e.g. `InputFunction` from
the API docs, given that the `input` API entry holds all the relevant
information.
`InputFunction` only exists for type purposes in the `.d.ts`.
PR Close#54925
Similar to `input`, `model`, `output`, the query initializer APIs are
also explicitly denoted as such. This allows angular.dev to display them
more readable and compactly.
PR Close#54925
This improves the API documentatino for `output` in angular.dev,
similar to how we improved the API for `input`.
Angular.dev can now show these documentation entries more
readable if annotated explicitly as initializer API.
Note: output API is short enough that we want to include
the types in the code snippet previews.
PR Close#54925
This commit improves the API documentation for `input` after
we added support for initializer APIs in angular.dev docs generation.
Changes:
- Rename `ReadT` to `T`. This conceptually makes it easy to talk about
inputs of type `T` if there is no transform involved. The common case.
- Rename `WriteT` to `TransformT`. This makes it clear that this is the
type that the "transform" needs to handle.
- Improves the "overall" description of the input function so that it
can be shown as a general overview for the API site.
- Improves usage notes to be a little more helpful, yielding more useful
content in the API docs usage notes section.
- Add short JSDoc description for each individual overload.
PR Close#54925
This commit adds support for extracting initializer API functions.
Initialixer API functions are functions conceptually that can are
intended to be used as class member initializers.
Angular started introducing a few of these for the new signal
APIs, like `input`, `model` or signal-based queries.
These APIs are currently confusingly represented in the API docs because
the API extraction:
- does not properly account for call signatures of interfaces
- does not expose information about sub-property objects and call
signatures (e.g. `input.required`)
- the docs rendering syntax highlighting is too bloated and confusing
with all types being included.
This commit adds support for initializer API functions, namely two
variants:
- interface-based initializer APIs. e.g. `export const input:
InputFunction`- which is a pattern for `input` and `input.required`.
- function-based simpler initializer APIs with overloads. e.g.
`contentChildren` has many signatures but doesn't need to be an
interface as there are no sub-property call signatures.
PR Close#54925
When creating the Angular Language Service instance, attempts to read
configuration files are now only attempted if the project is considered
a `Configured` project. Such a project has been analyzed by TypeScript
and one or more configuration files (tsconfig/jsconfig) files have been
found for the project.
PR Close#55035
Based on some internal feedback, these changes add validations to prevent cases where the `@for` loop variable name is the same as one of the built-in context variables, or when one of the context variables is aliased to the same name as the item.
PR Close#55045
This update enhances the encoding handling of request bodies to generate the necessary cache key for transfer cache functionality.
Closes#54956
PR Close#54980
Builds on top of the previous changes to add support for deferred blocks during partial compilation. To do this, the following changes had to be made:
* The metadata passed into `ɵɵngDeclareComponent` has an additional field called `deferBlockDependencies` which has an array of the dependency loading functions for each defer block in the template. During linking, the dependency functions are loaded by matching their template index to the index in the `deferBlockDependencies` array.
* There's a new `ɵɵngDeclareClassMetadataAsync` function that is created for components that have deferred dependencies. It gets transpiled to `setClassMetadataAsync` and works in the same way by capturing a dependency loading function and setting the metadata after the dependencies are resolved. It also has some extra fields for capturing the version which are standard in linker-generated code.
* Deferred import statements are now stripped in partial compilation mode, similar to full compilation.
PR Close#54908
Adds the `ɵɵngDeclareClassMetadataAsync` function that will be produced during partial compilation for component classes that have deferred dependencies. At runtime the dependencies will be resolved before setting the metadata.
PR Close#54908
Updates the type of the resolver function to be any `Expression` since JIT may receive a function reference rather than a `ArrowFunctionExpr`.
PR Close#54908
Switches to tracking the deferred blocks in a flat array in the binder to ensure that their template order is maintained. This will be relevant in the next commits where we'll match deferred blocks by their index.
Note that the current map we have technically guarantees the insertion order in the spec, but the array is a bit more explicit.
PR Close#54908
Updates the logic that detects if a node should be checked for control flow content projection to exit as soon as it detects a second root node, instead of counting the total and then checking if it's more than one.
PR Close#54921
Previously only the first branch of an `if` block was captured for content projection. This was done because of some planned refactors in the future. Since we've decided not to apply those refactors to conditionals, these changes update the compiler to capture each branch individually for content projection purposes.
PR Close#54921
This commit changes the way we use containers to insert conditional content.
Previously if and switch conditional would always use the first content as the
insertion container. This strategy interfered with content projection that
projects entire containers - as the consequence content for _all_ cases would
end up in slot matched by the first container. This could be very surprising
as desicribed in https://github.com/angular/angular/issues/54840
After the change each conditional content is projected into its own container.
This means that content projection can match more than one container and
result in correct display.
Fixes#54840
PR Close#54921
Currently when aliasing a `for` loop variable with `let`, we replace the variable's old name with the new one. Since users have found this to be confusing, these changes switch to a model where the variable is available both under the original name and the new one.
Fixes#52528.
PR Close#54942
Since the PR is always expected to be ready to merge as renovate won't make changes in response to any sort of comment, it should already be marked as merge ready
PR Close#54947
Previously we assumed that if a `for` loop tracking function is in the form of `someMethod($index, $item)`, it will be pure so we didn't pass the parameter to bind the context to it. This appears to be risky, because we don't know if the method is trying to access `this`.
These changes play it safe by always binding method-based tracking functions.
Fixes#53628.
PR Close#54960
This commit adds `declare` to each interface in the `zone-impl` to
prevent renaming of any interface properties by compiler optimizations.
This would otherwise cause issues if multiple applications depend on ZoneJS and
compile the interface properties to different names.
PR Close#54966
This commit refactors the router module to enhance performance by substituting the startsWith method with direct access `[0]` when verifying the value of a single character. This optimization improves efficiency, as direct access retrieves the character's value stored at a specific index in the string, resulting in slightly faster execution.
PR Close#54940
This change updates the approach to the loop in `ApplicationRef.tick`
for allowing state updates in `afterRender` hooks. It is valid to update
state in render hooks and we need to ensure we refresh views that may be
marked for check in these hooks (this can happen simply as a result of
focusing an element). This change ensures that the behavior of `markForCheck`
with respect to this loop does not change while we are actively running
change detection on a view tree.
This approach also has the benefit of preventing a regression for #18917,
where updating state in animation listeners can cause `ExpressionChanged...Error`
This should be allowed - there is nothing wrong with respect to unidirectional
data flow in this case.
There may be other cases in the future where it is valid to update
state. Rather than wrapping the render hooks and the animation flushing
in something which flips a global state flag, the idea here is that
`markForCheck` is safe and valid in all cases whenever change detection
is not actively running.
PR Close#54900
In some cases the hydration mismatch is nested within a component.
As the devTool only reports issues on the component level, we need to mark the component node rather than the actual mismatched node.
PR Close#54671
This commit updates the name of an internal function argument that represents an embedded view injector. Also it introduces a new config option that allows passing an environment injector to be used in the underlying LView. There are no changes to the behavior, just some initial cleanup for upcoming changes.
PR Close#54903
BREAKING CHANGE:
Legacy handling or Node.js URL parsing has been removed from `ServerPlatformLocation`.
The main differences are;
- `pathname` is always suffixed with a `/`.
- `port` is empty when `http:` protocol and port in url is `80`
- `port` is empty when `https:` protocol and port in url is `443`
PR Close#54874
BREAKING CHANGE: deprecated `platformDynamicServer` has been removed. Add an `import @angular/compiler` and replace the usage with `platformServer`
PR Close#54874
I initially tried switching to use public entry points under `zone.js/plugins/*`, however this file is both manually compiled for Saucelabs and also built with Bazel for a number of tests. The Bazel integration doesn't work well with depending on real NPM packages, so importing `zone.js/plugins/*` in that context doesn't really work. Instead we need to depend on the internals and manually call the `patch*` functions.
PR Close#53443
This was a bit complicated, but the typings test (`packages/zone.js/test/typings/...`) was failing due to an unresolved import on `./zone-impl`.
The main cause is that `//packages/zone.js:zone_js_d_ts` was generating the output `zone.d.ts` file by _concatenating_ `zone.d.ts` with `zone.api.extensions.d.ts` and `zone.configurations.api.d.ts`. Now that `zone.d.ts` imports `zone-impl.d.ts`, concatenation is no longer a viable means of bundling this content.
To fix this, I created a new `packages/zone.js/zone.ts` entry point and imported the underlying `zone.ts` file as well as the two extensions. I added `extract_types` to pull the `*.d.ts` files out of the target (because all the JS is bundled separately) and used those files in the final NPM package. This is sufficient to pass the typings test and should be equivalent to what exists today.
PR Close#53443
The `rxjs|electron` regex was causing `import { /* ... */ } from './electron';` to be treated as external and not bundled, which is an issue for the Electron entry point which just happens to be named `electron.ts`. Now only the actual `electron` package should be treated as external, while internal files of any name should not.
I actually tried updating to `^rxjs` as well, however this appears to break some tests and isn't necessary to fix the failing Electron test, so I'm leaving it alone.
PR Close#53443
Not sure why this becomes a problem now. These errors appear to be preexisting. Most likely the file wasn't loaded previously and now it is.
PR Close#53443
As this was, `__symbol__` was being called as a static field initializer, which runs during module evaluation, meaning it happened at import time. However for tests, the Zone prefix is overridden which changes the result of `__symbol__`. This change happens too late to be picked up by `__symbol__` at top-level execution, so instead we defer it until `symbolParentUnresolved` is actually read.
PR Close#53443
This moves timer patching from a top-level side effect into the `patchFakeAsyncTest` function. Top-level statements are evaluated before the Node patches run and have a chance to patch them with the Zone versions of these timers, meaning `FakeAsyncTestZoneSpec` was repatching the native versions between tests. The fix here is to grab the patched versions of these timers during the `patchFakeAsyncTest` function where we can be confident Node patches have already run.
PR Close#53443
This moves the internals of `fake-async-test.ts` outside `patchFakeAsyncTest` and exports them. This way they can be imported without depending on the top-level side effects of loading Zone.
PR Close#53443
For some reason the `_global` name appears to conflict with another `_global` name. Not entirely sure how or why, but the easiest fix seems to be to just give the variable a unique name.
PR Close#53443
While reading this is not a top-level side effect, it does _depend_ on a top-level side effect. Specifically, `node-env-setup.ts` set this value. Now that its side effect is moved into a function, we can't read it as the top-level of `zone-impl.ts` and need to wait until `__symbol__` is actually called outside of top-level scope.
PR Close#53443
While `TaskTrackingZoneSpec` was implicitly global previously, it does not need to be exposed in a `declare global {}` block. This is because classic scripts in TypeScript are only implicitly global within the same compilation. `TaskTrackingZoneSpec` was not exposed in the existing `.d.ts` files shipped with the `zone.js` package. Within google3, this is also a separate compilation and was not accessible. As a result, `TaskTrackingZoneSpec` was always private and we do not need a global to maintain compatibility.
PR Close#53443
While `ProxyZoneSpec` was implicitly global previously, it does not need to be exposed in a `declare global {}` block. This is because classic scripts in TypeScript are only implicitly global within the same compilation. `ProxyZoneSpec` was not exposed in the existing `.d.ts` files shipped with the `zone.js` package. Within google3, this is also a separate compilation and was not accessible. As a result, `ProxyZoneSpec` was always private and we do not need a global to maintain compatibility.
PR Close#53443
Since each patch no longer contains top-level side effects, each bundled entry point needs to import and call its associated patch. For the most part this just means that each entry point imports the associated patch and invokes it at the top-level scope.
Note that many of these entry points did not actually have a dependency on `Zone` and had no guarantee that it was loaded prior to execution. To maintain consistency, the missing dependencies on `Zone` are left as-is. They will use the global instance of `Zone` and if users fail to load it prior to importing a specific patch, then the patch will fail just as it did previously.
PR Close#53443
This drop the top-level side effects in `zone.ts` and allows the initialization to be reused across the various entry points in the package.
PR Close#53443
This particular is slightly different from the others because it does not have a hard dependency on `Zone`. It doesn't actually use `Zone` directly during the patch because the patch just sets a `legacyPatch` global. To maintain consistency, this continues to use global `Zone` and does _not_ accept `Zone` as a parameter. While it's using a global in an inconvenient way, this isn't a problem right now because it doesn't cause or require a dependency on a top-level side effect.
PR Close#53443
This removes top-level side effects from each of these files and drops the dependency on global `Zone`, instead allowing it to be provided to each patch as a parameter.
Most of these are pure mechanical transformations. A couple notable files which were somewhat unique:
* `async-test.ts`, `fake-async-test.ts`, and `wtf.ts` had unique IIFE usage and patch `Zone` itself. This removes the IIFE and exports the function instead.
* `jest.ts` and `jasmine.ts` have a unique `jest` global usage which needs to be declared.
PR Close#53443
These are all the symbols originally under `declare global {}` with the same names. Unfortunatley TypeScript treats a `declare global {}` scope as the parent scope, so we need to import with a different name than the global, meaning everything gets an `_` prefix.
PR Close#53443
This removes a name collision on `Zone` with the interface. Otherwise putting the `interface Zone {}` and `class Zone {}` in the same scope when the IIFE is removed will cause a conflict.
PR Close#53443
This drops global declarations from this file (as they will be limited to `zone.ts`. It also deletes the `/** @internal */` annotation on `AmbientZone` which is no longer necessary since it isn't in the `declare global` and deletes the global Zone declaration which is also unnecessary.
PR Close#53443
This is just a straight copy, no code is altered. The new `zone-impl.ts` file will contain the actual definitions exported directly without any global declarations or top-level side effects. The existing `zone.ts` will remain as an entry point with those globals and side-effects.
PR Close#53443
We are already testing the JIT transforms via integration tests, but
this commit adds dedicated unit tests for the transform behavior for
proper test coverage (planned follow-up).
PR Close#54841
Move the initialization of class field `DelegatingPerfRecorder` into the constructor.
This fixes the error : `TypeError: Cannot read properties of undefined (reading 'eventCount')`
This is blocking the roll-out of public class.
PR Close#54834
This commit updates the logic for preserving file overview comments
to be more reliable and less dependent on previous transforms.
Previously, with the old import manager, we had a utility called
`addImport` that always separated import statements and non-import
statements. This meant that the non-emitted statement from Tsickle
for the synthetic file-overview comments no longer lived at the
beginning of the file.
`addImports` tried to overcome this by adding another new non-emitted
statement *before* all imports. This then was later used by the
transform (or was assumed!) to attach the synthetic file overview
comments if the original tsickle AST Node is no longer at the top.
This logic can be improved, because the import manager shouldn't need to
bother about this fileoverview non-emitted statement, and the logic for
re-attaching the fileoverview comment should be local. This commit fixes
this and makes it a local transform.
PR Close#54819
This commit adds some unit tests verifying the import generation in TCB
files and inline blocks. We don't seem to have any unit tests for these
in general. This commit adds some, verifying some characteristics we
would like to guarantee.
PR Close#54819
To ease review and to allow for both instances to co-exist, `ImportManagerV2`
was introduced. This commit renames it to `ImportManager` now that we
deleted the older one.
PR Close#54819
Enables the incremental type-checking test that we never enabled when we
landed signal inputs. Now that we fixed incremental re-use by re-using
the existing user imports for inline type check blocks, the test is
passing and can be enabled.
PR Close#54819
Updates the type-check block generation code (also for inline type check
blocks) to use the new import manager.
This is now a requirement because the translator utilities from the
reference emit environment expect an import manager that follows the
new contract established via `ImportGenerator<TFile, TExpression>`.
For type check files, we can simply print new imports as we don't expect
existing imports to be updated. That is because type check files do not
have any _original_ source files (or in practice— those are empty).
For type check blocks inline, or constructors, imports _may_ be re-used.
This is great as it helps fixing some incrementality bugs that we were
seeing in the type check code. That is, sometimes the type check block
code may generate imports conditionally for e.g. `TemplateRef`, or
animations. Those then **prevent** incremental re-use if TCB code
switches between those continously. We tried to account for that with
signal inputs by always pre-generating such imports. This fixed the
issue for type-check files, but for inline type check blocks this is
different as we would introduce new imports in user code that would then
be changed back in subsequential edit iterations. See:
https://github.com/angular/angular/pull/53521#pullrequestreview-1778130879.
In practice, the assumption was that we would be fine since user code is
most likely containing imports to `@angular/core` already. That is a
true assumption, but unfortunately it doesn't help with incremental
re-use because TypeScript's structural change detection does not dedupe
and expects 1:1 exact imports from their old source files.
https://github.com/microsoft/TypeScript/pull/56845
To improve incremental re-use for the type check integration, we should
re-use original source file imports when possible. This commit enables
this.
To update imports and execute inline operations, we are now uisng
`magic-string` (which is then bundled) as it simplifies the string
manipulatuons.
PR Close#54819
This commit switches ngtsc's JS and DTS transform to use the new import
manager. This is a drop-in replacement as we've updated the translator
helpers in the previous commit to align with the new API suggested by
the `ImportManagerV2` (to be renamed then).
PR Close#54819
`ImportGenerator` is the abstraction used by the translator functions to
insert imports for `ExternalExpr` in an AST-agnostic way.
This was built specifically for the linker which does not use any of the
complex import managers- but rather re-uses `ngImport` or uses
`ngImport.Bla`.
This commit also switches the linker AST-agnostic generator to follow
the new signatures. This was rather trivial.
PR Close#54819
This commit introduces a new implementation of `ImportManager` that has
numerous benefits:
- It allows efficient re-use of original source file imports.
* either fully re-using original imports if matching
* updating existing import declarations to include new symbols.
- It allows efficient re-use of previous generated imports.
- The manager can be used for schematics and migrations.
The implementation is a rework of the import manager that we originally
built for schematics in Angular Material, but this commit improved it
to be more flexible, more readable, and "correct".
In follow-ups we can use this for schematics/migrations.
PR Close#54819
This commit ensures components in the route config predictably always
get their providers from the hierarchy available to routes rather than
sometimes being dependent on where they are inserted.
fixes#53369
BREAKING CHANGE: Providers available to the routed components always
come from the injector heirarchy of the routes and never inherit from
the `RouterOutlet`. This means that providers available only to the
component that defines the `RouterOutlet` will no longer be available to
route components in any circumstances. This was already the case
whenever routes defined providers, either through lazy loading an
`NgModule` or through explicit `providers` on the route config.
PR Close#54265
This commit updates the logic around `Route.redirectTo` to enable using a
function to create the redirect. This function can return a string,
ands acts the same as previous string redirects, or a `UrlTree`, which
will act as an absolute redirect.
To be useful, the redirect function needs access to the params and data.
Today, developers can access these in their redirect strings, for
example `{path: ':id', redirectTo: '/user/:id'}`. Unfortunately,
developers only have access to params and data on the _current route_
today in the redirect strings. The params and data in the `RedirectFn`
give developers access to anything from the matched parent routes as
well. This is done as the same way as param and data aggregation later
on (https://github.com/angular/angular/blob/897f014785578d87bc655ea6ae9e113653960f50/packages/router/src/router_state.ts#L236-L278).
In order to accomplish this, we inherit params and data while
matching, after the `ActivatedRouteSnapshot` is created for the matched
route rather than waiting until the end.
The `RedirectFunction` does not return the full
`ActivatedRouteSnapshot` interface. Some things are not accurately known
at the route matching phase. For example, resolvers are not run until
later, so any resolved title would not be populated. The same goes for lazy
loaded components. The is also true for all the snapshots up to the
root, so properties that include parents (root, parent, pathFromRoot)
are also excluded. And naturally, the full route matching hasn't yet
happened so firstChild and children are not available either.
fixes#13373resolves#28661 (though not for the redirect string - you would return a
`UrlTree` from the function)
BREAKING CHANGE: This change allows `Route.redirectTo` to be a function
in addition to the previous string. Code which expects `redirectTo` to
only be a string on `Route` objects will need to be adjusted.
PR Close#52606
This commit updates the loop in ApplicationRef.tick to only throw in dev
mode. In addition, it reduces the reruns to 10 from 100 in order to
reduce the impact on production applications that encounter this error.
That is, the loop will bail out much earlier and prevent prolonged
unresponsiveness.
PR Close#54848
Zone event and run coalescing now races `requestAnimationFrame` and
`setTimeout`. There are tradeoffs to both functions and racing the two
gives us the benefits of both. This is explained in more detail in the
jsdoc comment. This change also aligns the timing of zone coalescing
with what will be used for zoneless.
BREAKING CHANGE: The exact timing of change detection execution when
using event or run coalescing with `NgZone` is now the first of either
`setTimeout` or `requestAnimationFrame`. Code which relies on this
timing (usually by accident) will need to be adjusted. If a callback
needs to execute after change detection, we recommend `afterNextRender`
instead of something like `setTimeout`.
fixes#54544fixes#44314fixes#39854 (unverified but seems likely)
PR Close#54578
This is a follow-up to #53718 that applies the same logic to the
`autoDetect` feature of the fixture's host view. This now unifies the
logic between `ApplicationRef` and `ComponentFixture` autodetect.
BREAKING CHANGE: The `ComponentFixture` `autoDetect` feature will no
longer refresh the component's host view when the component is `OnPush`
and not marked dirty. This exposes existing issues in components which
claim to be `OnPush` but do not correctly call `markForCheck` when they
need to be refreshed. If this change causes test failures, the easiest
fix is to change the component to `ChangeDetectionStrategy.Default`.
PR Close#54824
The logic in `isCssClassMatching` is only interested in two areas in the attributes:
implicit attributes and the `AttributeMarker.Classes` area, with the first area only
of interest for projection matching, not directive matching. This commit splits these
two searches to make this more apparent.
PR Close#54800
This commit resolves a regression that was introduced when the compiler switched from
`TemplateDefinitionBuilder` (TDB) to the template pipeline (TP) compiler. The TP compiler
has changed the output of
```html
if (false) { <div class="test"></div> }
```
from
```ts
defineComponent({
consts: [['class', 'test'], [AttributeMarker.Classes, 'test']],
template: function(rf) {
if (rf & 1) {
ɵɵtemplate(0, App_Conditional_0_Template, 2, 0, "div", 0)
}
}
});
```
to
```ts
defineComponent({
consts: [[AttributeMarker.Classes, 'test']],
template: function(rf) {
if (rf & 1) {
ɵɵtemplate(0, App_Conditional_0_Template, 2, 0, "div", 0)
}
}
});
```
The last argument to the `ɵɵtemplate` instruction (0 in both compilation outputs) corresponds with
the index in `consts` of the element's attribute's, and we observe how TP has allocated only a single
attribute array for the `div`, where there used to be two `consts` entries with TDB. Consequently,
the `ɵɵtemplate` instruction is now effectively referencing a different attributes array, where the
distinction between the `"class"` attribute vs. the `AttributeMarker.Classes` distinction affects
the behavior: TP's emit causes the runtime to incorrectly match a directive with `selector: '.foo'` to
be instantiated on the `ɵɵtemplate` instruction as if it corresponds with a structural directive!
Instead of changing TP to align with TDB's emit, this commit updates the runtime instead. This uncovered
an inconsistency in selector matching for class names, where there used to be two paths dealing with
class matching:
1. The first check was commented to be a special-case for class matching, implemented in `isCssClassMatching`.
2. The second path was part of the main selector matching algorithm, where `findAttrIndexInNode` was being used
to find the start position in `tNode.attrs` to match the selector's value against.
The second path only considers `AttributeMarker.Classes` values if matching for content projection, OR of the
`TNode` is not an inline template. The special-case in path 1 however does not make that distinction, so it
would consider the `AttributeMarker.Classes` binding as a selector match, incorrectly causing a directive to
match on the `ɵɵtemplate` itself.
The second path was also buggy for class bindings, as the return value of `classIndexOf` was incorrectly
negated: it considered a matching class attribute as non-matching and vice-versa. This bug was not observable
because of another issue, where the class-handling in part 2 was never relevant because of the special-case
in part 1.
This commit separates path 1 entirely from path 2 and removes the buggy class-matching logic in part 2, as
that is entirely handled by path 1 anyway. `isCssClassMatching` is updated to exclude class bindings from
being matched for inline templates.
Fixes#54798
PR Close#54800
The paths for the security guide were flipped in the original PR. As a result, it looked for a markdown file in the best-practices directory when it should have looked for it in the guide directory instead.
PR Close#54830
Add an internal API to enable and use i18n hydration for testing and development. This helps ensure that we don't accidentally break the current behavior until we are completely ready to roll out i18n support.
PR Close#54784
Currently if an `(output)` listener fails, it will be handled gracefully
by Angular and reported to the `ErrorHandler`.
For programmatic subscriptions with `OutputEmitterRef`, this is not the case.
Instead, as soon as any subscription is failing, all other subsequent
subscription callbacks are not firing anymore.
This commit intends to make this more consistent by gracefully
reporting errors from `OutputEmitterRef#emit` to `ErrorHandler`,
allowing for listener execution to continue.
PR Close#54821
Returning `UrlTree` from a guard was a convenient new feature added to
the `Router`. However, it does not have feature-parity with the old
`router.navigate(...); return false;` pattern. The most common use-case
for this feature is to redirect to a new page _without_ updating the URL
from the initially attempted navigation. For example, rendering a 404
page when the user does not have access privelages to a route.
Fixes#17004Fixes#27148
BREAKING CHANGE: Guards can now return `RedirectCommand` for redirects
in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree`
values in `Route` types will need to be adjusted.
PR Close#45023
Ensures that all of the functions intended to be run in initializers are in an injection context. This is a stop-gap until we have a compiler diagnostic for it.
PR Close#54761
This commits assert that the repeater instruction gets a reference
to a tracking function. This change will allow us to better track
occurences of https://github.com/angular/angular/issues/53628 -
in certain situations a reference to a tracking function might be
undefiened.
We are not fixing the underlying issue here, just getting better
visibility.
PR Close#54814
Speeds up the retrieval of `DestroyRef` in `EventEmitter` because
`try/catch` is expensive if there is no injection context.
We saw a script time regression in Cloud.
The goldens had to be updated because `getInjectImplementation` is now
referenced. `inject` also references the underlying field, but directly.
This is super minimal overhead of a function exposing the internal
field.
PR Close#54748
Moves the logic that creates the defer resolver function into `@angular/compiler` for consistency with the rest of the compilation APIs. Also renames some of the symbols to make it clearer what they're used for.
PR Close#54759
Fixes an issue where we were outputting the reference to non-deferrable dependencies as strings, rather than going through the reference emitter. This caused some issues internally because the reference wasn't maintained in the generated JS.
PR Close#54759
Currently we have the `deferrableDeclToImportDecl`, `deferBlocks`, `deferrableTypes` and `deferBlockDepsEmitMode` fields on the `R3ComponentMetadata` which is incorrect, because the interface is used both for JIT and AOT mode even though the information for those fields is AOT-specific. It will be problematic for partial compilation since the runtime will have a reference to the dependency loading function, but will not be able to provide any of the other information.
These changes make the following refactors:
1. It changes the defer-related information in `R3ComponentMetadata` to include only references to dependency functions which can be provided both in JIT and AOT.
2. Moves the AOT-specific defer analysis into the `ComponentResolutionData`.
3. Moves the construction the defer dependency function into the compilation phase of the `ComponentDecoratorHandler`.
4. Drops support for defer blocks from the `TemplateDefinitionBuilder`. This allows us to clean up some TDB-specific code and shouldn't have an effect on users since the TDB isn't used anymore.
PR Close#54759
This commit updates `ApplicationRef.tick` to use `detectChangesInternal` for root
views rather than go through the `ChangeDetectorRef.detectChanges` API
which refreshes the host view without first looking at whether the view
is `OnPush` and not dirty. The current behavior would hide errors in
`OnPush` components that do not correctly get marked for check and would
break when migrating to zoneless change detection because `markForCheck`
was never called so change detection was never scheduled.
The error would be surprising and blamed on switching to zoneless when in
reality the issue already exists and is a problem with the component not
calling `markForCheck`. However, this error is hidden today because
`ApplicationRef.tick` refresh host bindings unconditionally.
BREAKING CHANGE: `OnPush` views at the root of the application need to
be marked dirty for their host bindings to refresh. Previously, the host
bindings were refreshed for all root views without respecting the
`OnPush` change detection strategy.
PR Close#53718
PR Close#53718
This commit updates HTML sanitization logic to avoid infinite loops in case clobbered elements contain fields like `nextSibling` or `parentNode`. Those fields are used for DOM traversal and this update makes sure that those calls return valid results.
Also this commit fixes an issue when clobbering `nodeName` causes JS exceptions.
PR Close#54425
An i18n message effectively acts as a dynamic template: two elements with contiguous instruction indices won't necessarily be contiguous in the DOM.
For that reason, we need to maintain a mapping from instruction index to a physical DOM node in order to hydrate views with i18n, pointing to where hydration for that view should begin.
PR Close#54750
Updates the instruction generation for two-way bindings to only emit the `twoWayBindingSet` call when writing to template variables. Since template variables are constants, it's only allowed to write to them when they're signals. Non-signal values are flagged during template type checking.
Fixes#54670.
PR Close#54714
We have a diagnostic that reports writes to template variables which worked both for regular event bindings and two-way bindings, however the latter was broken by #54154 because two-way bindings no longer had a `PropertyWrite` AST.
These changes fix the diagnostic and expand it to allow two-way bindings to template variables that are signals.
PR Close#54714
Moves the check which ensures that there are no writes to template variables into the `TemplateSemanticsChecker` to prepare for the upcoming changes.
PR Close#54714
Introduces a new `TemplateSemanticsChecker` that will be used to flag semantic errors in the user's template. Currently we do some of this in the type check block, but the problem is that it doesn't have access to the template type checker which prevents us from properly checking cases like #54670. This pass is also distinct from the extended template checks, because we don't want users to be able to turn the checks off and we want them to run even if `strictTemplates` are disabled.
PR Close#54714
The `runCallbackOnce` closure is declared not to have any parameters itself, so it is
compatible as `queueMicrotask` callback without the extra closure. This reduces the call
stack by a frame and avoids the extra closure allocation.
PR Close#54801
This commit addresses a typing mismatch, where these functions were declared to return whichever
value their callback returned, but this was inaccurate: it's always a test callback function
with `done` argument.
PR Close#54801
The assertion in `packages/core/test/acceptance/after_render_hook_spec.ts:165` was prone to flakes,
where Jasmine could frequently report an error:
```
Error: 'expect' was used when there was no current spec, this could be because an asynchronous test timed out
at Env.expect (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1945:15)
at expect (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8267:18)
at file:///packages/core/test/acceptance/after_render_hook_spec.ts:165:12
```
This happens because `wrapTestFn` checks for an exact type of `Promise`, which may have been patched by zone.js
such that the `instanceof` condition is dependent on whether zone.js has patched the `Promise` constructor.
PR Close#54801
Many acceptance tests define goldens for both `TemplateDefinitionBuilder` and Template Pipeline. All such tests have had the TDB golden files removed, and the corresponding expectations adjusted.
PR Close#54757
`TemplateDefinitionBuilder` is the legacy template compiler, and was replaced by Template Pipeline as the default in v17.3.
This PR attempts to delete `TemplateDefinitionBuilder`, `ExpressionConverter`, and various helpers (i18n context, style builder, property visitors, etc).
Consider this a first pass: a lot of code has not yet been deleted (e.g. old TDB-specific test cases), and I'm sure I have missed additional helper code.
PR Close#54757
There is an edge case where synchronous navigations caused in
response to navigation events can result in a previous navigation not
being unsubscribed from. b/328219996
PR Close#54710
This commit ensures that render hooks are rerun when a node is attached
or detached. We do not necessarily need to run change detection but DOM
did change so render hooks should execute.
PR Close#54083
This commit updates the `afterRender` and `afterNextRender` hooks to
notify the scheduler (which subsequently schedules change detection)
when created. This makes the hooks similar to `requestAnimationFrame`,
which requests that the browser schedule a rendering operation. This
reqeust is not conditional. Even if there was nothing to repaint, the
`requestAnimationFrame` callback will execute.
In Angular, this is useful because callers of `afterNextRender` don't
necessarily have any way of knowing whether a change detection is even
scheduled. For example, the anchor scrolling with the Angular Router
needs to wait for rendering to complete before attempting to scroll
because rendering can affect the size of the page. However, if the user
is already on the page that the navigation is targeting, such as
navigating to an anchor on the page, there is nothing new for the Router
to render so a render might not even be scheduled.
Related to https://github.com/angular/angular/issues/53985, which
could use `afterNextRender` instead of `setTimeout` to ensure the
scrolling happens in the same frame as the page rendering, but would not
necessarily work without this change (as described above). Note that the
scrolling _cannot_ use a microtask to ensure scrolling happens in the
same frame because `NgZone` will ensure microtasks flush before
change detection, so it would cause the scroll to happen before rendering.
PR Close#54083
Currently we have the `deferrableDeclToImportDecl`, `deferBlocks`, `deferrableTypes` and `deferBlockDepsEmitMode` fields on the `R3ComponentMetadata` which is incorrect, because the interface is used both for JIT and AOT mode even though the information for those fields is AOT-specific. It will be problematic for partial compilation since the runtime will have a reference to the dependency loading function, but will not be able to provide any of the other information.
These changes make the following refactors:
1. It changes the defer-related information in `R3ComponentMetadata` to include only references to dependency functions which can be provided both in JIT and AOT.
2. Moves the AOT-specific defer analysis into the `ComponentResolutionData`.
3. Moves the construction the defer dependency function into the compilation phase of the `ComponentDecoratorHandler`.
4. Drops support for defer blocks from the `TemplateDefinitionBuilder`. This allows us to clean up some TDB-specific code and shouldn't have an effect on users since the TDB isn't used anymore.
PR Close#54700
This commit updates `ApplicationRef.tick` to use `detectChangesInternal` for root
views rather than go through the `ChangeDetectorRef.detectChanges` API
which refreshes the host view without first looking at whether the view
is `OnPush` and not dirty. The current behavior would hide errors in
`OnPush` components that do not correctly get marked for check and would
break when migrating to zoneless change detection because `markForCheck`
was never called so change detection was never scheduled.
The error would be surprising and blamed on switching to zoneless when in
reality the issue already exists and is a problem with the component not
calling `markForCheck`. However, this error is hidden today because
`ApplicationRef.tick` refresh host bindings unconditionally.
BREAKING CHANGE: `OnPush` views at the root of the application need to
be marked dirty for their host bindings to refresh. Previously, the host
bindings were refreshed for all root views without respecting the
`OnPush` change detection strategy.
PR Close#53718
In order to serialize and hydrate i18n blocks, we need to be able to walk an AST for the translated message. This AST is generated during normal parsing of the message.
PR Close#54724
The following changes help the language service code build in g3:
* `Omit<T>` produces an index signature, so we must access the resulting properties with square bracket (because `noPropertyAccessFromIndexSignature` is on in g3).
* Explicitly export `absoluteFrom` from `packages/compiler-cli/index.ts`, since the `*` re-export is patched out in g3.
* Remove const from a few const enums, since accessing const enums across modules is not compatible with `isolatedModules` (which is on in g3).
PR Close#54726
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.
fixes#52928fixes#15634
BREAKING CHANGE: Newly created and views marked for check and reattached
during change detection are now guaranteed to be refreshed in that same
change detection cycle. Previously, if they were attached at a location
in the view tree that was already checked, they would either throw
`ExpressionChangedAfterItHasBeenCheckedError` or not be refreshed until
some future round of change detection. In rare circumstances, this
correction can cause issues. We identified one instance that relied on
the previous behavior by reading a value on initialization which was
queued to be updated in a microtask instead of being available in the
current change detection round. The component only read this value during
initialization and did not read it again after the microtask updated it.
PR Close#54735
When the `ApplicationRef` refreshes attached views, it will continue to
do so while there is still one marked for check after the refresh
completes.
BREAKING CHANGE: When Angular runs change detection, it will continue to
refresh any views attached to `ApplicationRef` that are still marked for
check after one round completes. In rare cases, this can result in infinite
loops when certain patterns continue to mark views for check using
`ChangeDetectorRef.detectChanges`. This will be surfaced as a runtime
error with the `NG0103` code.
PR Close#54734
The current behavior of `autoDetect` in `ComponentFixture` does not
match production very well. It has several flaws that make it an
insufficient change detection mechanism:
* It runs change detection for the component under test _after_ views
attached to the `ApplicationRef`. This can cause real behavior
differences that break in production, because tests can observe view
refreshes in the incorrect order (for example, a dialog refreshing
before the component which opened it).
* Because of the above ordering, render hooks registered during change
detection of the fixture views _will not execute at all_ because
`ApplicationRef.tick` already happen.
* It does not rerun change detection on the view tree if there are more
dirty views to refresh after the render hooks complete.
* It effectively hides/swallows errors from change detection inside the
`onMicrotaskEmpty` subscription by not reporting them to the error
handler. Instead, this error ends up being unhandled in the
subscription and rxjs throws these in a `setTimeout`.
All of the above are problematic but this commit _does not_ fix the
final point. Ideally, we can land this in a future change but this
requires additional internal fixes. In the meantime, we have to juggle
special-case handling of the component fixture views within
`ApplicationRef.tick` using some special events to retain current
behavior and avoid errors from the fixture propagating to the `ErrorHandler`.
BREAKING CHANGE: The `ComponentFixture.autoDetect` feature now executes
change detection for the fixture within `ApplicationRef.tick`. This more
closely matches the behavior of how a component would refresh in
production. The order of component refresh in tests may be slightly
affected as a result, especially when dealing with additional components
attached to the application, such as dialogs. Tests sensitive to this
type of change (such as screenshot tests) may need to be updated.
Concretely, this change means that the component will refresh _before_
additional views attached to `ApplicationRef` (i.e. dialog components).
Prior to this change, the fixture component would refresh _after_ other
views attached to the application.
PR Close#54733
For model signals we introduced some sniffing on the return type of a
`.subscribe` invocation- allowing for subscribe to _just_ return a
callback directly to unsubscribe.
This works in practice, but the positive `tCleanup` indices have more
meaning, especially in the context of `DebugElement`. A positive index
indicates a DOM event- so we need to revert this change. This now
surfaced as we made `EventEmitter` return a function + the subscription
via a proxy that ended up `typeof function` --> and broke some tests
where debug element incorrectly invoked non-dom outputs as dom
listeners. We don't need this change with current unsubscribe function
concept.
PR Close#54650
Currently the `makeProgram` utility from `ngtsc/testing` does not use
the test host by default- optimizing for source file caching.
Additionally, the host can be updated to attempt caching of the `.d.ts`
files from `@angular/core`— whether that's fake core, or the real core-
is irrelevant. We are never caching if these changes between tests, so
correctness is guaranteed.
This commit reduces the type check test times form 80s to just 11
seconds, faster than what it was before with `fake_core`. The ngtsc
tests also run significantly faster. From 40s to 30s
PR Close#54650
The `inject` global augmentation from upgrade tests, leak into
all source files for IDEs, making it easy to run into issues
when actually trying to deal with `inject` from Angular core for DI.
PR Close#54650
Technically `model()` and `output()` already need to be defined in an
injection context- because `OutputRef` requires this.
To improve the error messaging, this commit asserts this as part of the
top-level entry functions for `model()` and `output()`. Without this
change, the error would mention the `_createOutputRef` internal
function.
PR Close#54650
An `EventEmitter` is a construct owned by Angular that should be
used for outputs as of right now.
As we are introducing the new `OutputRef` interface for the new output
function APIs, we also think `EventEmitter` should implement
`OutputRef`— ensuring all "known" outputs follow the same contract.
This commit ensures `EventEmitter` implements an `OutputRef`
Note: An output ref captures the destroy ref from the current injection
context for clean-up purposes. This is also done for `EventEmitter` in a
backwards compatible way:
- not requiring an injection context. EventEmitter may be used
elsewhere.
- not cleaning up subscriptions/completing the emitter when the
directive/component is destroyed. This would be a change in behavior.
Note 2: The dependency on `DestroyRef` causes it to be retained in all
bundling examples because ironically `NgZone` uses `EventEmitter`- not
for outputs. The code is pretty minimal though, so that should be
acceptable.
`EventEmitter` will now always retain `NgZone. This increases the
payload size slightly around 800b for AIO. Note that the other increases
were coming from previous changes. This commit just pushed it over the
threshold.
PR Close#54650
A model signal is technically an output, at runtime and conceptually.
This commit re-uses the shared output ref logic and ensures the
interfaces match.
PR Close#54650
This commit introduces an addition to `output()` and
`outputFromObservable`()` —called `outputToObservable()`.
The helper lives in the RxJS interop package and allows agnostic
programmatic subscriptions to `OutputRef`s by converting the output
to an observable with `.pipe` etc.
The function is ideally used in all places where you subscribe to an
output programmatically. Those outputs in the future, with the new APIs,
may not be actual RxJS constructs, but abstract `OutputRef`'s that
simply expose a `.subscribe` method. The helper allows you to
agnostically convert outputs to RxJS observables that you can safely
interact with.
The observables are also completed automatically, if possible, when the
owning directive/component is destroyed— Something that is not
guaranteed right now.
PR Close#54650
Introduces a second API in addition to the new `output()` function.
The new function `outputFromObservable()` can be used to declare outputs
using the new `OutputRef` API and `output()` API, while using a custom
RxJS observable as data source.
This is something that is currently possible in Angular and we would
like to keep possible- even though we never intended to support custom
observables aside from RxJS-based `EventEmitter`.
The interop bridges the gap and allows you to continue using
`Subject`, `ReplaySubject`, `BehaivorSubjct,` - or cold custom
observables for outputs. You can still trigger logic only when
the output is subscribed- unlike with imperative `emit`s of
`EventEmitter` or the new `OutputEmitterRef`.
A notable difference is that you need two class members where you
previously could access the `Subject` directly. This is an intentional
trade-off we've made to ensure that all new outputs implement the
`OutputRef` interface and we are exposing a minimal API surface to
consumers of components that currently access the output
programmatically.
PR Close#54650
This commit allows us to detect initializer APIs like
`outputFromObservable` that are declared in different modules- not
necessarily `@angular/core`.
PR Close#54650
This commit exposes the new `output()` API with numerous benefits:
- Symmetrical API to `input()`, `model()` etc.
- Fixed types for `EventEmitter.emit`— current `emit` method of
`EventEmitter` is broken and accepts `undefined` via `emit(value?: T)`
- Removal of RxJS specific concepts from outputs. error channels,
completion channels etc. We now have a simple consistent
interface.
- Automatic clean-up of subscribers upon directive/component destory-
when subscribed programmatically.
```ts
@Directive({..})
export class MyDir {
nameChange = output<string>(); // OutputEmitterRef<string>
onClick = output(); // OutputEmitterRef<void>
}
```
Note: RxJS custom observable cases will be handled in future commits via
explicit helpers from the interop.
PR Close#54650
This commit creates the proposed `OutputRef` interface along
with `OutputEmitterRef`:
- `OutputRef` is the consistent interface for all Angular outputs.
- `OutputEmitterRef` is an extension for emitting values. Like
`EventEmitter`.
- subscriptions are cleaned up automatically upon directive/component
destroy.
- emitting is an error when destroyed
- subscribing programmatically is an error when already destroyed.
This commit will also implement the shared output ref runtime construct,
that can be used by `output()`, `outputFromObservable()` and `model()`.
We will manage subscriptions in a simple way, manually, without RxJS.
PR Close#54650
This commit replaces `fake_core` with the real `@angular/core`
output. See previous commit for reasons.
Overall, this commit:
* Replaces references of `fake_core`
* Fixes tests that were testing Angular compiler detection that _would_
already be flagged by type-checking of TS directly. We keep these
tests for now, and add `@ts-ignore` to verify the Angular checks, in
case type checking is disabled in user applications- but it's worth
considering to remove these tests. Follow-up question/non-priority.
* Adds `@ts-ignore` to the tests for `defer` 1P because the property is
marked as `@internal` and now is (correctly) causing failures in the
compiler test environment.
* Fixes a couple of tests with typos, wrong properties etc that
previously weren't detected! A good sign.
PR Close#54650
As part of improving test safety of the compiler, I've noticed that
we have a special pass for detecting external `ModuleWithProviders`
where we detect the module type from an object literal.
This literal is structured like the following: `{ngModule: T}`. The
detection currently takes `T` directly, but in practice it should be
`typeof T` to satisfy the `ModuleWithProviders` type that is accepted
as part of `Component#imports`.
This commit adds support for this, so that we can fix the unit test
in preparation for using the real Angular core types in ngtsc tests.
PR Close#54650
This adds documentation regarding the latest changes to framework merge tools. It specifically covers the requires: TGP label and separate sync for primitives.
PR Close#54664
Previously, the language service relied on deep imports such as `@angular/compiler/render3/...`. This is bad form, because that creates a dependency on the package's internal structure. Additionally, this is not compatible with google3.
In this PR, I replace all the deep imports with shallow imports, in some cases adding the missing symbol to the `compiler.ts` exports.
PR Close#54695
This commit updates TestBed logic to take into account situations when dependencies loaded within `@defer` blocks may import NgModules with providers. For such components, we invoke provider override function, which recursively inspects and applies the necessary changes.
PR Close#54667
In zone-full applications, this is already true because effects are
scheduled inside a microtask and tracked by ZoneJS. When not using
zones, this should stay consistent on principle and for testability
reasons. A general pattern with zoneless testing will be to update state
and `await` some promise (i.e. `fixture.whenStable`, which will be
linked to `ApplicationRef.isStable`).
PR Close#53835
The current behavior of `autoDetect` in `ComponentFixture` does not
match production very well. It has several flaws that make it an
insufficient change detection mechanism:
* It runs change detection for the component under test _after_ views
attached to the `ApplicationRef`. This can cause real behavior
differences that break in production, because tests can observe view
refreshes in the incorrect order (for example, a dialog refreshing
before the component which opened it).
* Because of the above ordering, render hooks registered during change
detection of the fixture views _will not execute at all_ because
`ApplicationRef.tick` already happen.
* It does not rerun change detection on the view tree if there are more
dirty views to refresh after the render hooks complete.
* It effectively hides/swallows errors from change detection inside the
`onMicrotaskEmpty` subscription by not reporting them to the error
handler. Instead, this error ends up being unhandled in the
subscription and rxjs throws these in a `setTimeout`.
All of the above are problematic but this commit _does not_ fix the
final point. Ideally, we can land this in a future change but this
requires additional internal fixes. In the meantime, we have to juggle
special-case handling of the component fixture views within
`ApplicationRef.tick` using some special events to retain current
behavior and avoid errors from the fixture propagating to the `ErrorHandler`.
breaking note for future when isG3 flag condition is removed for v18:
The `ComponentFixture.autoDetect` feature now executes
change detection for the fixture within `ApplicationRef.tick`. This more
closely matches the behavior of how a component would refresh in
production. The order of component refresh in tests may be slightly
affected as a result, especially when dealing with additional components
attached to the application, such as dialogs. Tests sensitive to this
type of change (such as screenshot tests) may need to be updated.
PR Close#54354
One downside of implicit dependency tracking in `effect()`s is that it's easy
to for downstream code to end up running inside the effect context by accident.
For example, if an effect raises an event (e.g. by `next()`ing a `Subject`), the
subscribers to that `Observable` will run inside the effect's reactive context,
and any signals read within the subscriber will end up as dependencies of the
effect. This is why the `untracked` function is useful, to run certain
operations without incidental signal reads ending up tracked.
However, knowing when this is necessary is non-trivial. For example, injecting
a dependency might cause it to be instantiated, which would run the constructor
in the effect context unless the injection operation is untracked.
Therefore, Angular will automatically drop the reactive context within a number
of framework APIs. This commit addresses these use cases:
* creating and destroying views
* creating and destroying DI injectors
* injecting dependencies
* emitting outputs
Fixes#54548
There are likely other APIs which would benefit from this approach, but this
is a start.
PR Close#54614
This refactor makes it easier to update the return types of guards.
Rather than having to track what types guards can return, which may
change with new features over time, `MaybeAsync<GuardResult>` can be
used instead.
PR Close#54580
As a part of #54154, an old parser behavior came up where two-way bindings were parsed by appending `= $event` to the event side. This was problematic, because it allowed some non-writable expressions to be passed into two-way bindings.
These changes introduce a migration that will change the two-way bindings into two separate input/output bindings that represent the old behavior so that in a future version we can throw a parser error for the invalid expressions.
```ts
// Before
@Component({
template: `<input [(ngModel)]="a && b"/>`
})
export class MyComp {}
// After
@Component({
template: `<input [ngModel]="a && b" (ngModelChange)="a && (b = $event)"/>`
})
export class MyComp {}
```
PR Close#54630
Fixes that a query like `viewChild('locator', {read: ElementRef<HTMLElement>})` would throw because we didn't account for expressions with type parameters.
I've also included support for parenthesized expressions and `as` expressions since it's pretty easy to support them.
Fixes#54645.
PR Close#54647
Updated the "Setting up Zone.js" instructions to the latest convention from
how the Angular CLI configures it.
Include adding zone-flats.ts to the tsconfig.app.json file step.
Added src/ to zone-flag.ts in the code example.
PR Close#52409
Add more details around:
- What we consider a breaking change
- What is a deprecation
- How do we guarantee Angular stays stable
- Update invalid links
PR Close#51423
Angular has the `@Attribute` decorator that allows for attributes to be injected from the host node, but we don't have an equivalent for the `inject` function. These changes introduce the new `HostAttributeToken` class that can be used to inject attributes similarly to `@Attribute`. It can be used as follows:
```typescript
import {HostAttributeToken, inject} from '@angular/core';
class MyDir {
someAttr = inject(new HostAttributeToken('some-attr'));
}
```
The new API works similarly to `@Attribute` with one key exception: it will throw a DI error when the attribute doesn't exist, instead of returning `null` like `@Attribute`. We made this change to align its behavior closer to other injection tokens.
PR Close#54604
This commit ensures that any internal render hooks that cause views to
become dirty again first refresh those dirty views before running user
render hooks. This ensures that user render hooks have the most complete
render state possible and stops them from needlessly executing multiple
times. This is important to maintain the goal of the public render
hooks, which is to provide the safest place to place code that depends
on DOM state, especially in ways that may force a browser paint.
PR Close#54224
This adds a helper function to defer application state updates to the
first possible "safe" moment. If application-wide change detection
(ApplicationRef.tick) is currently executing when this function is used,
the callback will execute as soon as all views attached to the
`ApplicationRef` have been refreshed. Refreshing the application views
will happen again before `checkNoChanges` executes.
When a change detection is _not_ running, this state update will execute
in the microtask queue.
This function is necessary as a replacement for current
`Promise.resolve().then(() => stateUpdate())` to be zoneless compatible
while ensuring those state updates are synchronized to the DOM before
the browser repaint. Without this, updates done in `Promise.resolve(...)` would
queue another round of change detection in zoneless applications, and
this change detection could happen in the next browser frame, and cause
noticeable flicker for the user.
Additionally, this function provides a way to perform state updates that
will run on the server as well as in the browser.
Last, current applications using `ngZone: 'noop'` may not be
calling `ApplicationRef.tick` at all so this function provides a
mechanism to ensure the state update still happens by racing
a microtask with `afterNextRender` (which might never execute).
PR Close#54224
Fixes that initializer functions weren't being recognized if they are aliased (e.g. `import {model as alias} from '@angular/core';`).
To do this efficiently, I had to introduce the `ImportedSymbolsTracker` which scans the top-level imports of a file and allows them to be checked quickly, without having to go through the type checker. It will be useful in the future when verifying that that initializer APIs aren't used in unexpected places.
I've also introduced tests specifically for the `tryParseInitializerApiMember` function so that we can test it in isolation instead of going through the various functions that call into it.
PR Close#54609
Currently, when a `@defer` block contains standalone components that import NgModules with providers, those providers are not available to components declared within the same NgModule. The problem is that the standalone injector is not created for the host component (that hosts this `@defer` block), since dependencies become defer-loaded, thus no information is available at host component creation time.
This commit updates the logic to collect all providers from all NgModules used as a dependency for standalone components used within a `@defer` block. When an instance of a defer block is created, a new environment injector instance with those providers is created.
Resolves#52876.
PR Close#52881
This PR enhances the Angular documentation by replacing the placeholder `<component-name>` with the actual `PageNotFoundComponent` in the wildcard route configuration. This update ensures that the documentation accurately reflects the recommended practice for handling page-not-found scenarios. Additionally, it addresses the issue where HTML entities like `<` were being displayed instead of the desired `<` symbol, resulting in clearer and more readable documentation for users.
PR Close#54570
Fixes that initializer functions weren't being recognized if they are aliased (e.g. `import {model as alias} from '@angular/core';`).
To do this efficiently, I had to introduce the `ImportedSymbolsTracker` which scans the top-level imports of a file and allows them to be checked quickly, without having to go through the type checker. It will be useful in the future when verifying that that initializer APIs aren't used in unexpected places.
I've also introduced tests specifically for the `tryParseInitializerApiMember` function so that we can test it in isolation instead of going through the various functions that call into it.
PR Close#54480
The diagnostic for signals that haven't been invoked wasn't working internally, because the path to `@angular/core` is different. These changes resolve the issue and do some general cleanup.
PR Close#54585
Fixes an edge case where a single-line elemnt with a long tag name a closing bracket on a new line was putting the control flow migration into an infinite loop.
Fixes#54587.
PR Close#54588
Template pipeline is now the default template compiler.
A pair of source map tests is failing, related to DI in JIT mode; I will fix and re-enable these during the preview period.
PR Close#54571
ApplicationRef.tick has a loop that will refresh views again that have
an updated signal. This change ensures views marked with the `Dirty`
flag are also considered in this loop, but only inside g3 for now
because this may be considered a breaking change and we need to wait for
v18 to land externally.
PR Close#54572
This commit prevents `AsyncPipe` from calling `markForCheck` when values
are synchronously emit during subscription to an observable. This
prevents subscriptions to `Replay` observables from needlessly walking
up to the root of the view tree during template execution for each
new replay observable in the template.
PR Close#54554
Use no-remote-exec to allow for building and serving to occur locally but still allow remote caching. Because of the number of
files involved in being passed to and from the RBE server, it is actually a bit faster to perform these actions locally.
PR Close#54549
In rare cases people may use an underscore in their component names, which was not accounted for in the formatting portion of the migration.
fixes: #54532
PR Close#54533
This provides some more information on how to release and notably includes commands for zipping extension code and source code, which can otherwise be tricky to get exactly right.
PR Close#54525
This is based on an internal issue report.
An earlier change introduced a diagnostic to report cases where a symbol is in the `deferredImports` array, but is used eagerly. The check worked by looking through the deferred blocks in a scope, resolving the scope for each and checking if the element is within the scope. The problem is that resolving the scope won't work across scoped node boundaries. For example, if there's a control flow statement around the block or within the block but around the deferred dependency, it won't be able to resolve the scope since it isn't a direct child, e.g.
```
@if (true) {
@defer {
<deferred-dep/>
}
}
```
To fix this the case where the deferred block is inside a scoped node, I've changed the `R3BoundTarget.deferBlocks` to be a `Map` holding both the deferred block and its corresponding scope. Then to resolve the case where the dependency is within a scoped node inside the deferred block, I've added a depth-first traversal through the scopes within the deferred block.
PR Close#54499
We have a couple of cases now (#53753 and #54414) where we're forced to redefine enums as object literals. These literals aren't rendered in the best way in the docs so these changes introduce a new `object-literal-as-enum` tag that we can use to mark them so they're treated for documentation purposes.
PR Close#54487
This change allows template binding "inert" attribute with the following syntax: [inert]="isInert"
Fixes#51879
fixup! fix(compiler): adding the inert property to the "SCHEMA" array
revert: "fixup! fix(compiler): adding the inert property to the "SCHEMA" array"
This reverts commit b637b7ce646e8bab2f585339028a84018e8ea982.
This commit is being reverted because the inert property is safe as a boolean attribute
PR Close#53148
This commit addresses a problem with PR #53695 that introduced support for default imports,
where the actual dynamic import used in the defer loading function continued to use the
symbol name, instead of `.default` for the dynamic import. This issue went unnoticed in the
testcase because a proper instance was being generated for the `ɵsetClassMetadataAsync` function,
but not the generated dependency loader function.
Fixes#54491
PR Close#54495
Prior to this fix an incorrect view instance (a dynamically created component
one instead of the root view) was passed to the content query function. Having
incorrect view instance meant that a component instance could not be found.
This is a pre-existing bug, introduction of signal-based queries just surfaced it.
Fixes#54450
PR Close#54457
The documentation on angular.dev mentions build-angular:browser as default
application builder. This is not correct. Recent applications are setup
with build-angular:application by default.
PR Close#54386
In the Angular DevTools Chrome DevTools page:
- Angular DevTools is able to ask the background script to list each frame that has been registered on a page.
- Angular Devtools is able to ask the background script to "enable" the connection on a particular frame. This enables the messaging between the content script <-> background script <-> devtools page
- Implements detection of non unique urls on the inspected page
Limitations:
- The `inspectedWindow.eval` API is only able to target frames by frameURL. This means some features that integrate with Chrome DevTools like inspect element and open source will not be available when inspecting frames that do not have a unique url on the page.
PR Close#53934
Modifies the messaging layer of devtools to allow for switching communication between frames on a page. When served as a browser extension.
Design:
- When a page renders, DevTools installs a content script onto it through it's manifest file. The all_frames option is used here to install this script onto every frame in a page.
- When Angular is detected, the content script will install a backend script into it's frame.
- Each content script / backend script pairing is kept track of in the background script. This pairing represents an angular devtools context in a particular frame.
- Angular DevTools is able to ask the background script to list each frame that has been registered on a page.
- Angular Devtools is able to ask the background script to "enable" the connection on a particular frame. This enables the messaging between the content script <-> background script <-> devtools page
Limitations:
- The `inspectedWindow.eval` API is only able to target frames by frameURL. This means some features that integrate with Chrome DevTools like inspect element and open source will not be available when inspecting frames that do not have a unique url on the page.
PR Close#53934
When the linker is running using an unpublished version of angular, locally built, the version will be `0.0.0`.
When encountering this situation, the range that for the linker map support is considered to be `*.*.*` allowing
for the linker to work at build time with packages built with versioned angular.
Most notably this allows for us to properly use the linker in building our documentation site with the locally
built version of angular.
PR Close#54439
The version detection condition for signal two-way bindings used an OR
instead of an AND, resulting in every `.0` patch version being considered
as supporting two-way bindings to signals.
This commit fixes the logic and adds additional parentheses to ensure the
meaning of the condition is more clear. Long term, we should switch to
semver version parsing instead.
PR Close#54443
In order to allow both signals and non-signals in two-way bindings, we have to pass the expression through `ɵunwrapWritableSignal`. The problem is that the language service uses a bundled compiler that is fairly new, but it may be compiling an older version of Angular that doesn't expose `ɵunwrapWritableSignal` (see https://github.com/angular/vscode-ng-language-service/issues/2001).
These changes add a `_angularCoreVersion` flag to the compiler which the language service can use to pass the parsed Angular version to the compiler which can then decide whether to emit the function.
PR Close#54423
Currently all triggers are set up to show the placeholder block on the server, except for `on immediate` which is basically a noop. These changes update `on immediate` to match the rest of the triggers.
Fixes#54385.
PR Close#54394
Getting the typing for `ɵunwrapWritableSignal` just right was tricky so these changes add some tests to ensure that we don't regress.
Also reworks the type tester a bit to make it easier to find where to add new test files.
PR Close#54387
This commit updates the implementation of the `customElements` patch and also
patches FACE callbacks (`formAssociatedCallback`, `formDisabledCallback`, `formResetCallback`
and `formStateRestoreCallback`). This now allows invoking those callbacks in the same zone
where the custom element has been defined.
PR Close#50686
Assure that the same readonly array corresponding to the children query results
is returned for cases where a query is marked as dirty but there were no actual
changes to the content of the results array (this can happen if a view is added
and removed thus marking queries as dirty but not influencing final results).
Fixes#54376
PR Close#54392
Creates a "fast mode" for building the adev site, currently only disabling prerender during fast build.
This is intended to be used for local development.
PR Close#54364
The newly introduced signal queries would error if no match exists, due to an
invalid read within the query internals.
This commit addresses the crash by allowing there to be no matches.
PR Close#54353
Currently we have two fake copies of `@angular/core` in the compiler tests which can be out of sync and cause inconsistent tests. These changes reuse a single copy instead.
PR Close#54344
This updates some tests to use the public imports from `@angular/core` now that they are available,
and cleans up useless imports and inaccurate names.
PR Close#54334
In some situations, calling `markForCheck` can result in an infinite
loop in seemingly valid scenarios. When a transplanted view is inserted
before its declaration, it gets refreshed in the retry loop of
`detectChanges`. At this point, the `Dirty` flag has been cleared from
all parents. Calling `markForCheck` marks the insertion tree up to the
root `Dirty`. If the declaration is checked again as a result (i.e.
because it has default change detection) and is reachable because its
parent was marked `Dirty`, this can cause an infinite loop. The
declaration is refreshed again, so the insertion is marked for refresh
(again). We enter an infinite loop if the insertion tree always calls
`markForCheck` for some reason (i.e. `{{createReplayObservable() | async}}`).
While the case above does fall into an infinite loop, it also truly is a
problem in the application. While it's not an infinite synchronous loop,
the declaration and insertion are infinitely dirty and will be refreshed
on every change detection round.
Usually `markForCheck` does not have this problem because the `Dirty`
flag is not cleared until the very end of change detection. However, if
the view did not already have the `Dirty` flag set, it is never cleared
because we never entered view refresh. One solution to this problem
could be to clear the `Dirty` flag even after skipping view refresh but
traversing to children.
PR Close#54329
The `subscribe` methods on `ModelSignal` and `OutputEmitter` were marked as `@internal` which will break when the TCB needs to reference them. These changes make them `@deprecated` temporarily so we can address the properly later.
PR Close#54342
The new `model()` signal introduces a `ModelSignal` type that needs to be handled by the interpolatedSignalNotInvoked diagnostic to catch issues like:
```
<div>{{ myModel }}</div>
```
PR Close#54338
Add an image loader for Netlify Image CDN. It is slightly different in implementation from existing loaders, because it allows absolute URLs
Fixes#54303
PR Close#54311
The import of `module` can conflict with the native global variable called `module` and can break some internal tests. These switch to only importing the function we need.
PR Close#54333
Adds usages of signal-based queries into the signal integration test to
verify queries can be used in production, and testing environments as
expected (i.e. the transform works as expected).
PR Close#54314
This helps with the Angular CLI currently swallowing fatal diagnostic
errors in ways that are extremely difficult to debug due to workers
executing Angular compiler logic.
The worker logic, via piscina, is currently not forwarding such Angular
errors because those don't extend `Error.`
https://github.com/piscinajs/piscina/blob/a7042ea27d129f3cad75c422f5aa92f0663854ee/src/worker.ts#L175
Even with access to these errors by manually forwarding errors, via
patching of the Angular CLI, there is no stack trace due to us not using
`Error` as base class for fatal diagnostic errors. This commit improves
this for future debugging and also better reporting of such errors to
our users- if we would accidentally leak one.
PR Close#54309
An identical addition to: 760b1f3d0b.
This commit expands the `try/catch`-es:
- to properly NOT throw and just convert the diagnostic.
- to be in place for all top-level instances. Notably, this logic cannot
reside in the template type checker directly as otherwise we would
risk multiple duplicate diagnostics.
PR Close#54309
Fixes that `ɵunwrapWritableSignal` inferring getter functions as not matching the interface of `WritableSignal` instead of preserving them.
PR Close#54252
In a previous commit the TCB was changed to cast the assignment to an input in order to widen its type to allow `WritableSignal`. This ended up breaking existing inputs whose setter has a wider type than its getter. These changes switch to unwrapping the value on the binding side.
PR Close#54252
Reworks the TCB for two-way bindings to make them simpler and to avoid regressions for two-way bindings to generic inputs. The new TCB looks as follows:
```
var _t1: Dir;
var _t2 = _t1.input;
(_t1 as typeof _t2 | WritableSignal<typeof _t2>) = expression;
```
PR Close#54252
Adds support for model inputs in the framework. `model()` returns a writable signal that implicitly defines a input/output pair that can be used either in two-way bindings to keep two values in sync or by binding individually to the input and output. When the value of the `model` changes, it will emit an event with the current value.
Furthermore, these changes expand two-way bindings to accept `WritableSignal`. This will make it easier to transition existing code to signals in a backwards-compatible way.
Example:
```ts
@Directive({
selector: 'counter',
standalone: true,
host: {
'(click)': 'increment()',
}
})
export class Counter {
value = model(0);
increment(): void {
this.value.update(current => current + 1);
}
}
@Component({
template: `<counter [(value)]="count"/> The current count is: {{count()}}`,
})
class App {
count = signal(0);
}
```
PR Close#54252
This commit improves IDE completion of the `read` option for
signal-based queries.
Currently, TS only matches the first overload when starting out with
defining a query. TS doesn't build up the combination of possible
options from the second overload- so in practice users will only see
IDE completions for the `descendants` option.
This is not a problem for view queries as the only option is `read`, so
TS will always match the overload with the `read` option.
```
class X {
query = contentChild('', {^^ <--
here we should completion for `read` an `descendants`
}
```
PR Close#54280
Currently the error is a generic error "exportAs must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the error is a generic error "selector must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the error is a generic error "selector must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the correct error message is shown only if @Component.styles is an array with some unresolved element. This change supports the new case of string type for the @Component.styles field.
PR Close#54230
A helper `validateLocalCompilationUnresolvedConst` is added to encapsulate a common pattern which leads to the error `LOCAL_COMPILATION_UNRESOLVED_CONST`.
PR Close#54230
The trailing error message comes from tracing the chain of DymaicValue which leads to a mostly useless error that highlights the same symbol as the original message and emits the error message "Unknown reference". This error message is removed in the favour of the original message which suffices.
PR Close#54230
A single error code is created to unify the common error pattern in local compilation mode where an imported const cannot be resolved, but needs to be resolved. This mainly happens for Angular decorator fields such as @Component.template.
The error messages are also upgraded to be more centered around this unifying theme.
PR Close#54230
Currently, when two components are named `TestComponent`, and both would
use e.g. control flow. Templates would be generated by the compiler and
those would conflict at runtime because the names for the template
functions are not ensured to be unique.
This seems like a more general problem that could be tackled in the
future in the template pipeline by always using the `ConstantPool`, but
for now, we should be good already, given us ensuring the `baseName`'s are
always unique.
PR Close#54273
This commit updates the implementation of the zone.js `fs` patch to
restore the implementation of `realpath.native` and patches it as a macrotask,
along with other functions of the `fs` package. This is the only nested function
that must be patched.
Closes: #45546
PR Close#54208
The `read` option for queries can rely on lexical variables inside the
class. These constructs are fine from a technical perspective in
TypeScript, but in practice, when the component/directive definition is
being created, the read value is extracted into the definition,
**outside** of the class. This breaks `this` references.
To fix this, we are restricting the `read` option to literal values.
Similar to `descendants`. Literal references are in practice constructs
like:
- `read: bla.X`
- `read: X`
where `bla` or `X` is never a `ThisKeywoord`- hence fixing the issue
and also simplifying the patterns for easier single file compilation.
PR Close#54257
This commit adds a JIT transform for signal-based queries, so that
queries are working as expected in JIT environments like `ng test` where
decorator metadata is needed as a prerequisite for the component
definition creation.
This is similar to the JIT transforms for signal inputs etc.
PR Close#54257
Extracts common JIT transform helper into the transform API, so that
those helpers can be re-used for output, model, queries and inputs.
PR Close#54257
Adding debug information for failing firebase deploy, hoping
to yield information about the missing resource. The next
multi-site seems to be failing, but is available.
PR Close#54275
The compileNgModuleFactory dont need to be in the application_ref file (in fact
the whole logic has little to do with ApplicationRef and it is not even called
from the application_ref). Performing this move to avoid circular dependencies
when the new query as signals authoring functions are exported.
PR Close#54103
This commit changes the approach to the reactive node representing query
results: instead of creating a custom node type we can use a computed -
the main change to get there is representing dirty change notification as
a signal (a counter updated every time a query changes its dirty status).
This change is dictated by simplification (we can avoid creation of a custom
signal type) as well as fixes to the multiple issues not covered by the
initial implementation:
- assuring referential stability of results (ex.: the same array instance
returned from child queries until results change);
- per-view results collection to avoid a situation where accessing query
results during view creation would return partial / inconsistent results;
- proper refresh of query results for both live and non-connected consumers.
All the above cases are covered by the additional tests in this commit.
PR Close#54103
This commit adds tests for content queries and fixes the arguments
order in the contentQuerySignal instruction, thus fixing a bug
discovered while adding tests.
PR Close#54103
This commits converts the hand-written tests into their usual,
compiled form. We can perform this change now since the compiler
bits of the queries-as-signal story landed.
PR Close#54103
This commit updates the logic of defer blocks to create an internal pending task to indicate that an application is not yet stable. This change would be helpful for zoneless applications.
PR Close#54239
Updates the acceptance authoring test compiler targets to support
multiple spec files. This will be useful for output, model, inputs
and queries.
PR Close#54253
Adds `output()` to the signal inputs integration test to verify
full integration with the Angular CLI. In the future we may
consider renaming the test to something less specific to signal inputs,
but for now this serves the purpose and `output()` is a closely related
part to signal-based inputs.
it doesn't warrant creating another new integration test, as those are
quite expensive to maintain and run.
PR Close#54217
The `listener` instruction currently always assumes RxJS subscribables,
and verifies this via `isSubscribable`. The type narrowing is not
ignored and the type remains `any` given the `ngDevMode` check.
This commit improves type safety, and actually switches to a dedicated
interface for "output subscribable" values. This is needed because
`Subscribable` from `RxJS` is typed to expect an observer in object
literal form- which is not correct and doesn't apply to `EventEmitter`
and matches the form of `.subscribe` we are using in the `listener`
instruction.
PR Close#54217
Similar to `input()`, initializer-based `output()`'s need to be
transformed in JIT to be annotated with an `@Output()` decorator.
This is necessary so that Angular can statically collect all defined
outputs without instantiating the class (which would not be possible
upon directive definition computation).
This commit introduces a transform next to the input transform that
automatically runs with the Angular CLI and `ng test`.
PR Close#54217
Adds type check diagnostic tests for the `output()` API. This
is necessary because we are maintaining a separate emitter
for `output()` as with the current design (still discussed - but this is
a starting foundation).
Note: `OutputEmitter` currently does not publicly expose `.subscribe`,
while the testing infrastructure exposes it for now. That is because we
are still discussing this before making changes in the TCB to account
for the case where `.subscribe` might be `@internal` ultimately.
PR Close#54217
Generalizes the type check table scenario testing infrastructure
so that it can also be used for testing outputs in a table-scheme
without a lot of TS code repetition.
PR Close#54217
Adds an ngtsc diagnostic and compilation output test for `output()`. The
test will verify certain recognition restrictions and ensures that
diagnostics are raised, in addition to proper full compilation output
being generated (aside from the compliance tests verifying output more
closely).
PR Close#54217
Adds compliance output tests for `output()` to verify that
we are emitting proper full compilation output, as well as proper
partial compilation output that can be linked to match the full output.
PR Close#54217
This commit introduces the `output()` function and corresponding
runtime code.
In practice, `output()` will defer to `EventEmitter` as outlined in the
RFC, but we are considering limiting the type to a minimal version that
is not coupled with RxJS, less complex, and also has better type safety
around emitting of values.
E.g. currently `EventEmitter.emit` can always be called without
any value, even though the output may be typed to always pass around
values of type `T`. This could cause subtle and confusing bugs.
PR Close#54217
As we are introducing the new `output()` function as an inituive
alternative to `@Output()` that matches with signal-based inputs,
this commit prepares the compiler to detect such initializer-based
outputs.
PR Close#54217
The deps tracker which is responsible to track orphan components does not work for classes mutated by custom decorator. Some work needed to make this happen (tracked in b/320536434). As a result, with option `forbidOrphanComponents` being true the deps tracker will falsely report any component as orphan if it or its NgModule have custom/duplicate decorators. So it is unsafe to use this option in the presence of custom/duplicate decorator and we disable it until it is made compatible. Note that applying custom/duplicate decorators to `@Injectable` classes is ok since these classes never make it into the deps tracker. So we excempt them.
PR Close#54139
Custom/duplicate decorators break the deps tracker in local mode. But deps tracker only deals with non-injectable classes. So applying custom/duplicate decorators to `@Injectable` only classes does not disturb deps tracker and local compilation in general. There are also ~ 100 such cases in g3 which cannot be cleaned up.
PR Close#54139
For cases like this:
```
@Component({...})
@Component({...})
export class SomeComp {
}
```
The `DecoratorHandler.detect` apparantly matches only one of the `@Component` decorator, leaving the other undetected which will be transformed by TS decorator helper and that breaks local compilation runtimes. But the error message only mentioned "custom" decorator, while in this case it is a "duplicate Angular" decorator. The respective error message is updated thus.
PR Close#54139
Consider the following very quirky Angular template, which has both an i18n attribute binding and a property binding to `in`:
```
<cmp [in]="foo" in="bar" i18n-in />
```
What would you expect the above template to do? `TemplateDefinitionBuilder` will emit the following Ivy instructions:
```
// Element constant attributes
consts: () => {
__i18nMsg__('bar', [], {}, {})
return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
// Create mode
i0.ɵɵelement(0, "cmp", 0);
}
}
```
This makes some sense -- we create a single element, and attach an i18n message to the `in` attribute. But is this actually correct? Notice that the property binding is completely missing!
Indeed, Template Pipeline actually produces this code:
```
// Element constant attributes
consts: () => {
__i18nMsg__('bar', [], {}, {})
return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
// Create mode
i0.ɵɵelement(0, "cmp", 0);
} else if (rf & 2) {
// Update mode
i0.ɵɵproperty("in", ctx.foo);
}
}
```
Aha! There's the property binding! Arguably, this is a bug in `TemplateDefinitionBuilder`, but after some discussion on Slack, we have decided to ban this practice in a future Angular version.
For now, we allow Template Pipeline to have slightly different output, but print an error to warn the user of the issue.
PR Close#54063
This test ensures that the `ExpressionChanged...` error does not happen
when signals are updated in a view that is attached to `ApplicationRef`
but was already checked. This was fixed in 432afd1ef4
which actually consequently fixes it for regular `markForCheck` as well.
PR Close#54206
* Renames the `input_signals` directory to `signals` so it can be reused for other tests.
* Reworks the build file to allow multiple test files.
PR Close#54213
Instead of maintaining individual transforms for `input`, `output`,
`model` etc. we are grouping them directly and the first one matching,
will execute.
This reduces needed traversal through AST and also makes it a little
more clean to write new initializer API metadata transforms.
Note: The Angular JIT transform is now also moving from `tooling.ts`
directly into `/transformers` for more local placement of transformer
logic.
PR Close#54200
Fixes that `@defer` blocks weren't recognizing default imports and generating the proper code for them. Default symbols need to be accessed through the `default` property in the `import` statement, rather than by their name.
PR Close#53695
One of the earlier commits separated one-way and two-way bindings which ended up breaking some internal targets, because it changed the assignment order. These changes bring back the old order.
PR Close#54154
In one of the earlier commits, the logic that appends `=$event` before parsing two-way bindings was removed and some validation was added to prevent unassignable expressions from being used. This ended up being problematic, because previously the parser was incorrectly allowing some invalid expressions which users came to depend on. For example, it transformed `[(value)]="a && a.b"` to `a && (a.b = $event)`.
These changes add some special cases for the common breakages that came up during the TGP.
PR Close#54154
Updates the template definition builder to emit the new format for the listener side of two-way bindings.
```js
// Before
listener("ngModelChange", function($event) {
return ctx.name = $event;
});
// After
ɵɵtwoWayListener("ngModelChange", function($event) {
ɵɵtwoWayBindingSet(ctx.name, $event) || (ctx.name = $event);
return $event;
});
```
PR Close#54154
Currently the listener side two-way listeners are parsed by appending `=$event` to the raw expression. This is problematic, because:
1. It can interfere with other expressions (see #37809).
2. It can lead to confusing error messages because users will see code that they didn't write.
3. It doesn't allow us to further manipulate the expression.
These changes remove the logic that appends `=$event` to resolve the issue. There's also some new logic that checks the expression after it has been parsed to ensure that the result is an assignable expression.
Subsequent commits will update the code that emits the expression to add back the `$event` assignment where it's needed.
PR Close#54154
Adds the following new instructions:
* `twoWayBindingSet` - used to assign values inside of the listener side of a two-way binding. Currently a noop, but will come into play later.
* `twoWayListener` - used to bind a two-way listener. Currently calls directly into `listener`, but it may be useful in the future.
PR Close#54154
Currently all the members of `_ParseAST` are public, even though they're all used only within the class. This change marks them as private so that it's explicit which ones are intended to be used outside the class.
PR Close#54154
Reworks the compiler so that it generates a `twoWayProperty` instruction, instead of `property`, for the property side of a two-way binding. Currently the new instruction passes through to `property`, but it'll have some two-way-binding-specific logic in subsequent PRs.
PR Close#54154
It was always the intent to have `afterRender` hooks allow updating
state, as long as those state updates specifically mark views for
(re)check. This commit delivers that behavior. Developers can now use
`afterRender` hooks to perform further updates within the same change
detection cycle rather than needing to defer this work to another round
(i.e. `queueMicrotask(() => <<updateState>>)`). This is an important
change to support migrating from the `queueMicrotask`-style deferred
updates, which are not entirely compatible with zoneless or event `NgZone` run
coalescing.
When using a microtask to update state after a render, it
doesn't work with coalescing because the render may not have happened
yet (coalescing and zoneless use `requestAnimationFrame` while the
default for `NgZone` is effectively a microtask-based change detection
scheduler). Second, when using a `microtask` _during_ change detection to defer
updates to the next cycle, this can cause updates to be split across
multiple frames with run coalescing and with zoneless (again, because of
`requestAnimationFrame`/`macrotask` change detection scheduling).
PR Close#54074
This change updates the `checkNoChanges` pass to only run once after
both view refresh and `afterRender` hooks execute rather than both
before and after the hooks. The original motivation was to specifically
ensure that the application was in a "clean state" before running the
`afterRender` hooks and ensure that `afterRender` hooks don't "fix"
`ExpressionChanged...` errors. This, however, adds to the complexity and
cost of running change detection in dev mode. Instead, the
`checkNoChanges` pass runs once we have done all render-related work and
want to ensure that the application state has been synced to the DOM
(without additional changes).
PR Close#54074
Errors during change detection are terminal and we do not generally
attempt to continue processing or recover after one occurs. This helps clean
up the `tick` implementation with respect to running `afterRender` hooks.
PR Close#54074
ISO 8601 defines
* Monday as the first day of the week.
* week 01 is the week with the first Thursday
Therefore:
Sunday Dec 31st 2023 is the last day of the last week of the year : W52 2023.
PR Close#53879
This commit updates the implementation of the `fetch` patch and additionally
patches `Response` methods which return promises. These are `arrayBuffer`, `blob`,
`formData`, `json` and `text`. This fixes the issue when zone becomes stable too early
before all of the `fetch` tasks complete. Given the following code:
```ts
appRef.isStable.subscribe(console.log);
fetch(...).then(response => response.json()).then(console.log);
```
The `isStable` observer would log `false, true, false, true`. This was happening because
`json()` was returning a native promise (and not a `ZoneAwarePromise`). But calling `then`
on the native promise returns a `ZoneAwarePromise` which notifies Angular about the task
being scheduled and forces to re-calculate the `isStable` state.
Issue: #50327
PR Close#50653
This commit updates the signature of the `ZoneGlobalConfigurations` interface and adds
missing `__Zone_ignore_on_properties` property, which may be setup to ignore specific `on`
properties from being patched.
PR Close#50737
`isNavigationCancelingError` & `isRedirectingNavigationCancelingError` had duplicate implementations. This commit also cleans-up those functions.
PR Close#53762
This commit adds hydration informations to the devtools.
* List of hydrated/hydrated components
* Shows hydration overlays
* Shows hydration errors for NG0500, 501 & 502
PR Close#53910
At the moment the extra import generation in local compilation mode fails if these extra imports produce a cycle. To handle this, the cycle handling strategy is updated for local compilation, and following the behaviour in the full compilation mode, the compiler does not generate extra import if it leads to cycle and instead leave things to the runtime.
PR Close#53543
With option `generateExtraImportsInLocalMode` set, in local mode the compiler generates extra imports for each component local dependencies. Here local dependencies means all component's dependencies within the same compilation unit.
To achieve this, the compiler performs a "local version" of its regular static analysis to find each component's deps, and these deps are used to generate extra side effect imports.
PR Close#53543
In this commit the resolve method for components is run fully when the option `generateExtraImportsInLocalMode` is set. This is because we need local component depedencies in order to generate extra imports causing by them. This requires cutting some resolve phase logics that are unnecessary in local mode, such as diagnostics.
PR Close#53543
When option `generateExtraImportsInLocalMode` is set, we need to compute component local depednecies in order to generate extra imports related to them. At the same time running the register phase in general is harmless in local compilation. So we run it anyway.
PR Close#53543
With option `generateExtraImportsInLocalMode` set in local compilation mode, the compiler generates extra side effect imports using this rule: any external module from which an identifier is imported into an NgModule will be added as side effect import to every file in the compilation unit. To illustrate this better assume the compilation unit has source files `a.ts` and `b.ts`, and:
```
// a.ts
import {SomeExternalStuff} from 'path/to/some_where';
import {SomeExternalStuff2} from 'path/to/some_where2';
...
@NgModule({imports: [SomeExternalStuff]})
```
then the extra import `import "path/to/some_where"` will be added to both `a.js` and `b.js`. Note that this is not the case for `import "path/to/some_where2"` though, since the symbol `SomeExternalStuff2` is not imported into any NgModule.
The math behind this mechanism is, in local compilation mode we cannot resolve component external dependencies fully. For example if a component in `a.ts` uses an external component defined in an external file `some_external_comp.ts` then we can generate the import to this file in `a.js`. Instead, we want to generate an import to a file that "gurantees" that `a.js` is placed after `some_external_comp.js` in the bundle. Now since the component in `some_external_comp.ts` is used in `a.ts`, then there must be a chain of imports starting from the NgModule that declares the component in `a.ts` to the component in `some_external_comp.ts`. This chain means some file in the same compilation unit as `a.ts` should import some external NgModule which includes `some_external_comp.ts` in its transitive closure and import it to some NgModule. So by adding this import to `a.js` we ensure that the bundling will have the right order.
PR Close#53543
As the first step, the import manager's `generateSideEffectImport` method is implemented to enable it to store info for side effect imports. Next, the helper `addImports` is modified to be able to generate correct statement for side effect imports.
These changes will be tested in the subsequent commits when these tools are used to generate an actual extra import for the generated file.
PR Close#53543
This commit includes a skeleton of how the tool `LocalCompilationExtraImportsTracker` is used in the overall compilation workflow end-to-end.
First of all, a new option `generateExtraImportsInLocalMode` is added, whose presence will make `LocalCompilationExtraImportsTracker` part of the compilation process. When this option is set an instance of `LocalCompilationExtraImportsTracker` is created within the NgCompiler. Then it is passed to the Ivy transformer and plumbed all the way down and the extra imports registered in it are added to the `ImportManager` instances before the imports are added from `ImportManager` to the generated file. This required adding a new method `generateSideEffectImport` to the `ImportManager`, which is an empty method and will be implemented in the subsequent commits.
This commit expected to make no change in the compilation behavior as the methods are not implemented yet.
PR Close#53543
The tracker is responsible for registering the extra imports during the analysis and resolve compiler phases, and later to be used by the transformer to get a list of extra imports to be generated for each source file.
This commit only contains the API, and the actual implementation for each method will be done in subsequent commits where an application of that method is available and so tests can be written for the implementation.
PR Close#53543
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
When the zoneless scheduler is provided, we want to update the behavior
of `ComponentFixture` to address common issues and painpoints in testing.
Developers should never have to call `detectChanges` on a fixture
manually. Instead of calling `detectChanges` after performing an
action that updates state and requies a template refresh, developers
should wait for change detection to run because the update needs to also have
notified the scheduler. If this was not the case, the component would
not work correctly in the application. Calling `detectChanges` to force
an update could hide real bugs.
This commit also updates the zoneless tests to uses `ComponentFixture`
instead of manually attaching to the `ApplicationRef` and rewriting a
lot of the helpers (`getDebugNode`, `isStable` as a value, `whenStable` as a
Promise).
PR Close#54024
Clarify the range of TypeScript versions supported in Angular v15 and v16 upgrade guides. The previous documentation's phrasing led to potential misunderstandings, as it suggested broader compatibility than actually supported. This change prevents errors by explicitly stating the maximum TypeScript version for each Angular version, ensuring developers have clear guidance during upgrades.
PR Close#54131
Adds some logic to skip over `TestBed.configureTestingModule` calls where the `declarations` aren't initialized to an array. We can't migrate these cases, because test migrations don't have access to the Angular compiler. Previously the migration would throw a runtime error.
PR Close#54122
At the moment local compilation mode does not support custom decorators, and it leads to unhandled errors. In this change a compile time diagnostic is produced in local mode for custom decorators. This is a temporary solution since there are few custom decorators are in use in g3. Custom decorators will be eventually supported in local mode.
PR Close#53983
I've been working on framework parts and compiler since pre-Ivy, and
helped with Ivy, runtime and compiler. Adding myself as a reviewer to
ease future work and to help with review load.
PR Close#54053
This enables us to show overloads of methods in the API overview. This
is useful for e.g. showing the various signatures of the signal input
function, or for signal-based queris.
There seems to be some issues with the length of the `InputFunction`
overloads. There is some line wrapping that doesn't make it _super_
readable but this is an unrelated problem to this change, but rather
a question of UI / API representation in the angular.io site.
PR Close#54053
clang-format seems to have problems with the call signature for
`input.required`. This commit works around the formatting issues that
obfuscate the signature. Users will actually see similar output when
they are looking for the `input` function definition of `@angular/core`.
PR Close#54053
This adds initial support for extracting and rendering call and construct
signatures of classes, like within the new `InputFunction` for signal
inputs.
For now, signatures are a rare occasion and represented as class member
entries. In the future we might consider exposing this via its own entry
type, and field on the class/interface entry.
PR Close#54053
This fixes the definitions for signal-based inputs in the language
service and type checking symbol builder.
Signal inputs emit a slightly different output. The output works well
for comppletion and was designed to affect language service minimally.
Turns out there is a small adjustment needed for the definition symbols.
PR Close#54053
This commit separates `InputSignal` for input signals with transforms.
The reason being that most of the time, signal inputs are not using
transforms and the generics are rather confusing.
Especially for users with inferred types displayed in their IDEs, the
input signal types are seemingly complex, even if no transform is used.
For this reason, we are introducing a new type called
`InputSignalWithTransform`. This type will be used for inputs with
transforms, while non-transform inputs just use `InputSignal`.
A notable fact is that `InputSignal` extends `InputSignalWithTransform`,
with the "identity transform". i.e. there is no transform. This allows
us to share the code for input signals. In practice, we don't expect
users to pass around `InputSignal`'s anyway.
PR Close#54053
Fix case of not wanted internal properties displayed in the documentation by adding if blocks in the concerned templates. So if the option is marked as internal the template won't create an entry in the documentation table for the concerned property of method
Fixes#52018
PR Close#52020
docs: testing-components-basics.md and components-basics.md links to css selector documentation are dead
As MDN's documentation link to the "css selector" topic is dead, this commit makes the angular documentation use the new valid link.
PR Close#53586
The "Providing HttpClient through dependency injection" documentation now shows that in case of a standalone boostraped app, the provideHttpClient is to include in the app.config.ts file.
Also updated the http setup server communication example to align the new doc (adev) with the old one (aio).
PR Close#52806
Follow-up to #54002 that:
* Remove the `toString` implementation from the `primitives`.
* Guards the `toString` with `ngDevMode` and prints out the value.
PR Close#54079
Since signals are function, currently stringifying them reveals the implementation of the function. This can lead to confusion since it contains internal implementation details. These changes add static `toString` function to address the issue.
**Note:** it's tempting to have `toString` output the actual value of the signal, but that would encourage users not to call the function which will be problematic in the long run. That's why these changes are using a static string instead.
PR Close#54002
Currently, when using `provideAnimationsAsync`, Angular uses `AnimationRenderer`
as the renderer. When the root view is removed, the `AnimationRenderer` defers the actual
work to the `TransitionAnimationEngine` to do this, and the `TransitionAnimationEngine`
doesn't actually remove the DOM node, but just calls `markElementAsRemoved()`.
The actual DOM node is not removed until `TransitionAnimationEngine` "flushes".
Unfortunately, though, that "flush" will never happen, since the root view is being
destroyed and there will be no more flushes.
This commit adds `flush()` call when the root view is being destroyed.
PR Close#53033
During the template parsing stage two-way bindings are split up into a property and event binding. All the downstream code treats these binding the same as their one-way equivalents. For some future work we'll have to distinguish between the two so these changes update the `BoundElementProperty.type` and `ParsedEvent.type` to include a `TwoWay` type. All existing call-sites have been updated to treat `TwoWay` the same as `Property`/`Regular`, but more specialized logic will be added in the future.
PR Close#54065
Previously, defer deps fns names were only prefixed with the component name, meaning that distinct deps fns in the same component would produce a name collision. Now, we take into account the entire template function name when naming inner deps fns.
PR Close#54060
This refactoring expands the QueryList such that we can add onDirty
callback to be invoked when a given query gets marked as dirty during
view insertion / removal. This mechanism is needed for signal-based
queries.
PR Close#54017
This is a refactor commit that moves more query construction / refresh
logic from the body of instructions into dedicated functions. This is
in preparation for the signal-based query instructions.
PR Close#54017
In some bundling scenarios, there may be local references to `ngDevMode` that need to be kept in sync with the global variable. This becomes hard to impossible if the global is reassigned. This allows setting the global to an empty object instead of `true` and preserve identity during `initNgDevMode`.
PR Close#53862
The Template Pipeline is a brand new backend for the Angular compiler, replacing `TemplateDefinitionBuilder`. It generates the Ivy instructions corresponding to an input template (or host binding). The Template Pipeline has an all-new design based on an intermediate representation compiled over many phases, which will allow us to experiment with compiler changes more easily in the future.
With this commit, the template pipeline can now be enabled in any project via the `useTemplatePipeline` TSConfig option. However, it is still disabled by default.
PR Close#54057
In #53591, Andrew added local compliation support for defer blocks. However, this requires the ability to emit pre-generated static defer deps functions. We now also support that feature in Template Pipeline.
PR Close#54043
Similar to signal-based inputs, we support signal-based queries in JIT
by expecting a decorator to be added. This is a consequence of the
design, given that JIT requires query declaration information before
the class is initialized- but ironically there is no way to collect this
information without instantiating the class.
A JIT transform in the Angular CLI will automatically generate these
decorators for testing.
PR Close#54019
This commit introduces three additional diagnostics for queries:
- If a query (either using decorator or signal-based) is declared on a
static class member, a diagnostic is raised.
- If a signal-based query is mixed with a query decorator, a diagnostic
is raised. Similar to signal inputs.
- If a singal-based query is also declared in the directive/component
class decorator metadata, a diagnostic is raised.
PR Close#54019
Due to some refactorings, we were only checking the function name
and whether it originates from an import. We should also verify the
module. This seems like logic we lost in the refactorings.
PR Close#54019
Collapses multiple sibling query advance statements into single
query advance invocations. This will help reducing generated code
for directives/components with many queries.
PR Close#54019
Currently the ZoneJS typing tests executes outside of Bazel, as a legacy
artifact of the monorepo merging (as it seems - not ideal at all).
Looks like this test relies on its own node modules, that were NOT
locked using a yarn lock file. This commit adds one, and specifically
locks it to a `@types/node` version that does not include the most
recent patch release (which seemingly introduced a breaking change)
that causes issues with TypeScript's lib checking.
Whenever we perform lock file maintenance in the future, we have the
following options:
- Consider disabling lib checking via `skipLibCheck` for this test. This
may be acceptable.
- Continue locking the node version,
- Waiting for chokidar to comply with the new signature
- Waiting for the breaking change to be rolled back.
Culprit change:
https://github.com/DefinitelyTyped/DefinitelyTyped/pull/68300
PR Close#54048
While `Array.at` is technically supported in all browsers we officially
support, the change was needlessly breaking without any real benefit.
PR Close#54021
@@ -32,7 +32,7 @@ Stack Overflow is a much better place to ask questions since:
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
If you would like to chat about the question in real-time, you can reach out via [our Discord server][discord].
If you would like to chat about the question in real-time, you can reach out via [the Angular community Discord server][discord].
## <a name="issue"></a> Found a Bug?
@@ -89,7 +89,7 @@ Before you submit your Pull Request (PR) consider the following guidelines:
We cannot accept code without a signed CLA.
Make sure you author all contributed Git commits with email address associated with your CLA signature.
4. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the angular/angular repo.
4. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the [angular/angular](https://github.com/angular/angular/fork) repo.
5. In your forked repository, make your changes in a new git branch:
@@ -138,7 +138,7 @@ If we ask for changes via code reviews then:
git push
```
For more info on working with fixup commits see [here](docs/FIXUP_COMMITS.md).
For more info on working with fixup commits see [here](./contributing-docs/using-fixup-commits.md).
That's it! Thank you for your contribution!
@@ -207,7 +207,7 @@ To ensure consistency throughout the source code, keep these rules in mind as yo
* All public API methods **must be documented**.
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
An automated formatter is available, see [DEVELOPER.md](contributing-docs/building-and-testing-angular.md#formatting-your-source-code).
## <a name="commit"></a> Commit Message Format
@@ -260,7 +260,7 @@ The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is opti
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (examples: CircleCi, SauceLabs)
* **ci**: Changes to our CI configuration files and scripts (examples: Github Actions, SauceLabs)
* **docs**: Documentation only changes
* **feat**: A new feature
* **fix**: A bug fix
@@ -302,7 +302,7 @@ There are currently a few exceptions to the "use package name" rule:
* `dev-infra`: used for dev-infra related changes within the directories /scripts and /tools
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
* `docs-infra`: used for docs-app (angular.dev) related changes within the /adev directory of the repo
* `migrations`: used for changes to the `ng update` migrations.
@@ -353,9 +353,9 @@ DEPRECATED: <what is deprecated>
Closes #<pr number>
```
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
Breaking Change section should start with the phrase `BREAKING CHANGE: ` followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
Similarly, a Deprecation section should start with "DEPRECATED: " followed by a short description of what is deprecated, a blank line, and a detailed description of the deprecation that also mentions the recommended update path.
Similarly, a Deprecation section should start with `DEPRECATED: ` followed by a short description of what is deprecated, a blank line, and a detailed description of the deprecation that also mentions the recommended update path.
### Revert commits
@@ -389,16 +389,11 @@ The following documents can help you sort out issues with GitHub accounts and mu
Angular is part of Google [Open Source Software Vulnerability Reward Program](https://bughunters.google.com/about/rules/6521337925468160/google-open-source-software-vulnerability-reward-program-rules). For vulnerabilities in Angular, please submit your report [here](https://bughunters.google.com/report).
For more information, check out [Angular's security policy](https://angular.io/guide/security).
For more information, check out [Angular's security policy](https://angular.dev/best-practices/security).
The content is written primarily in Markdown format located in `src/content`. For simple edits, you can directly edit the file on GitHub and generate a Pull Request.
## Local Development
For local development, [yarn](https://yarnpkg.com/) is the preferred package manager. You can setup a local environment with the following commands
:
```bash
# Clone Angular repo
git clone https://github.com/angular/angular.git
# Navigate to project directory
cd angular
# Install dependencies
yarn
# Build and run local dev server
# Note: Initial build will take some time
yarn docs
```
If you are having issues with the docs building, see the [FAQs](#faqs) section.
## Contributing
Want to report a bug, contribute some code, or improve the documentation? Excellent!
Read through our [contributing guidelines](/CONTRIBUTING.md) to learn about our submission process, coding rules, and more.
And if you're new, check out one of our issues labeled as <kbd>[help wanted](https://github.com/angular/angular/labels/help%20wanted)</kbd> or <kbd>[good first issue](https://github.com/angular/angular/labels/good%20first%20issue)</kbd>.
### Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
## FAQs
### The build is failing and I'm seeing `bazel:bazel failed: missing input file` messages.
This is most likely due to a bazel dependency / caching issue. To resolve this, run the following command:
```
# Try this first
yarn bazel clean
# If that doesn't work, try it with the expunge flag
* Map of the previews components, values are functions which returns the promise of the component type, which will be displayed as preview in the ExampleViewer component.
* Keys has to be equal to paths written down in the docs markdown files.
This script updates the Angular CLI help JSON files stored in `adev/src/content/cli/help`. This files are used to generate the [angular.dev CLI](https://angular.dev/cli) pages.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.