add a link to the community-driven Turkish translation of Angular
documentation to make it easier for Turkish-speaking developers to
discover localized docs.
The translation project is maintained by the community and hosted at:
https://github.com/erkamyaman/angular-tr
Providing documentation in developers' native languages helps lower
the barrier to entry and supports wider Angular adoption in the
Turkish-speaking developer community.
(cherry picked from commit 03465360bd)
Fix browser-specific styles infrastructure. PR #62786 cleans up part of the code, but there are still services that attempt to load these stylesheets on `main`.
(cherry picked from commit ed3dc10fea)
This is a follow-up to #67381 which introduced a subtle bug where depending on the type checking configuration, we may put an object literal directly in the TCB body which the TS compiler ends up interpreting as a block. These changes resolve the issue by always wrapping the literal in parentheses.
TypeScript has functionality that automatically escapes quotes in string literals. These changes update the places where we may need to do the same ourselves.
Expands the `debounce` rule configuration to accept `'blur'`. When this option
is provided, the rule will delay model synchronization until the field loses
focus (is touched). This introduces a debouncer that defers resolution
until the framework automatically aborts pending debounces upon touch events.
(cherry picked from commit c767d678cf)
This commit updates the github.mjs configuration to set requireReleaseModeForRelease to false, removing the requirement to use release mode for releases in the angular/angular repository.
(cherry picked from commit a6941adce8)
The Angular compiler unconditionally adds a debug name transform for signals
which generates a conditional on `ngDevMode` (e.g., `ngDevMode ? { debugName: "xyz" } : []`).
During testing, `ngDevMode` is true, so the true branch executes but the
false branch is never executed. Consequently, coverage tools report the
false branch as an untested line/branch, preventing 100% test coverage.
This commit adds a synthetic `/* istanbul ignore next */` comment to the
generated false branch so that Istanbul ignores it. We only include the
istanbul comment (instead of additionally including c8) to focus on the
established standard for Angular CLI/Karma coverage while maintaining
compatibility with modern Vitest setups, since @vitest/coverage-v8 now
natively respects the fallback istanbul comment.
Fixes#64583
(cherry picked from commit dc4cf649b6)
RecursiveVisitor.visitIfBlockBranch was permanently mutating the children array by pushing the expressionAlias into it. This change clones the array before pushing to avoid this side effect.
(cherry picked from commit 72a17afaf3)
When routing between two different routes, child animations were not finishing, causing elements to be left behind in the dom. The fix ensures the proper fallback is handled to avoid automatically cancelled custom events. This ensures the animation-fallback cancelling the animation actually completes, and ensures the element is removed.
fixes: #67400
(cherry picked from commit 9e64147b73)
Partially rolls back to using TypeScript 5.9 for the builds on the patch branch, because we bundle our TypeScript version with the language service which can introduce unexpected breakages for users.
Note that we still allow users to install TypeScript 6.
Previously, Blob values were passed to `Uint8Array` this resulted in silently producing an empty array (length = 0) without throwing an error, leading to empty cached data
PR Close#67002
Use feature detection for `Uint8Array.prototype.toBase64` and
`Uint8Array.fromBase64`, falling back to the existing implementation
when native support is not available
PR Close#67002
This updates the state manager to allow intercepting and deferring commits of traversal navigations.
The issues that were encountered in the past appear to be resolved in Chrome.
The behavior of redirect is still undefined in this case, so there is an added TODO.
(cherry picked from commit 778b748694)
This ensures that when calculating longest animations, we completely ignore infinite animations. This will prevent mistakes with using the API and hopefully catch any unexpected bugs.
fixes: #67350
(cherry picked from commit 9758ea9ee9)
This addresses a reported issue where elements were being fully removed from the DOM during drag and drop operations.
fixes: #67257
(cherry picked from commit 0b59cba85d)
Same as ADEV, currently the CLI prompts for another port if 4200 is busy but the toolchain doesn't support prompts.
By defaulting to 4201 we avoid regular CLI apps from preventing to run the dev-app
(cherry picked from commit 9bb4f02bef)
The repositories for `rules_sass`, `rules_angular`, and `rules_browsers`
were recently transferred from devversion to the angular organization.
This commit updates the internal bazel module rules to rely on
the new repository locations.
(cherry picked from commit b4f68acaa1)
Improved wording to clarify how beginners can verify their environment and IDE are correctly set up after running the app.
(cherry picked from commit bdbb7cc7af)
Translators are not allowed to write HTML which creates URI attributes. I opted to ban any values going into an attribute at all, to prevent even links to malicious content, rather than just sanitizing URIs.
I also converted this blocklist into an allowlist. Now, we only allowing setting known attributes (while sanitizing URI attributes). This significantly reduces risk of missing a vulnerable attribute and does not require an exhaustive list of all potential attributes.
BREAKING CHANGE: Angular now only applies known attributes from HTML in translated ICU content. Unknown attributes are dropped and not rendered.
(cherry picked from commit 306f367899)
Replaces referenced doc blocks with inline documentation,
cleans up unused referenced code, and fixes broken list formatting
(cherry picked from commit 8739a22d28)
Removes extra padding applied to the update page so its layout
matches the rest of the documentation where no padding exists
between the title and content.
(cherry picked from commit 15b51d0777)
This commit extracts the heading ID generation logic into a shared utility
and updates both the route generation script and the markdown pipeline to use it.
This ensures consistency between the generated routes and the rendered
documentation, and fixes an issue where custom heading IDs (`{#id}`)
were ignored during route generation.
Fixes#67200
(cherry picked from commit bedfcb5644)
Aligns the errors returned from the `parse` function in
`transformedValue` to use the same convention as the rest of signal
forms (a property called `error` that can contain a single error or list
of errors)
(cherry picked from commit 23fd8fa586)
Addresses an issue where the LCP image observer incorrectly identified LCP elements when the same image URL was used multiple times on a page
Fixes#53278
(cherry picked from commit 38749698d0)
This updates the pullapprove to remove the auto labeling of requires: TGP and instead moves it to the ng-dev config for pr updates.
(cherry picked from commit d7ddebca90)
Add help link to extended template diagnostic messages to provide
users with additional guidance and documentation resources. This
enhancement improves developer experience by making it easier to
understand and resolve complex template issues through direct
access to relevant Angular documentation with detailed examples
and explanations for each diagnostic type.
(cherry picked from commit 66b472e2bc)
The JsonPipe does not unwrap signals and `JSON.stringify` will return `undefined` for signals.
To avoid confusion, we log a warning when a signal is passed to the pipe.
(cherry picked from commit 0d652ba4da)
Wrap `@defer` trigger expressions (`when`, `prefetch when`, `hydrate when`)
in a conditional context within the TCB to enable TypeScript's TS2774
diagnostic for detecting functions used without invocation.
Previously, signals and functions passed to `when` triggers without
parentheses would silently evaluate to truthy, causing unexpected behavior.
Now the compiler reports an error when a function is used as a condition
without being called.
(cherry picked from commit f90e5565e0)
avoid per-file semantic diagnostics work when warming up a newly loaded project.
add ensureProjectAnalyzed() to the language-service API and use it from the server startup path.
implement warmup through public compiler API access with existing perf tracing, and add legacy test coverage for the new warmup flow.
(cherry picked from commit 39f62fa408)
The tokenizer regex pattern `[^<]*` was consuming all non-`<` content
before custom HTML tags, causing lost content.
Changed to `\s*` which only allows leading whitespace, letting marked
properly tokenize preceding content.
(cherry picked from commit bc473cf60f)
When Zone patches Promise, it uses ZoneAwarePromise. The new Promise.try API was undefined on ZoneAwarePromise, making it unavailable when zone was present. This change gracefully passes through Promise.try to the native Promise implementation, if available, without patching it to execute in the right zone (our stance is not to add new patches but avoid destructively making new APIs unavailable).
Fixes#67057
Angular requires TypeScript >=5.9, making TODO comments that reference TypeScript 2.1 features obsolete. These comments existed in keyvalue_differs.ts and ng_for_of.ts and referenced type improvements that were deferred until TS 2.1, which has long since been surpassed.
Removes the switch for compatibility mode from the template pipeline since we never got around to removing it and at this point it causes a bunch of runtime errors.
native controls and custom controls (via transformedValue) use similar
parsing logic but it needs to be hooked up differently. This commit
extracts the common bits into a shared piece.
PR Close#66917
Supports binding `null` to a `<input type=number>`.
- Binding in `null` clears the input
- Binding in `NaN` also clears the input
- When the user clears the input, the model is set to `null`
- The model is _never_ set to `NaN` based on user interaction. It is
either set to `null` if the user cleared the input, or is unchanged
and a parse error added if the user entered an invalid number like
"42e"
PR Close#66917
Integrates native inputs with the new parseErrors API so that they can
report parse errors when the user types an un-parsable value (e.g. "42e"
in a number field).
When a user types an un-parsable value, the model does not update. It
retains its previous value and a parse error is added for the control
that received the un-parsable value.
PR Close#66917
Changes `parsedErrors` to a `linkedSignal` based on the model value.
This ensures that the parse errors are reset if the model changes from
outside the control.
PR Close#66917
The purpose for this change is to add nodes to the signal graph to make it clear when producer nodes, especially those that aren't consumed in the component being inspected, are passed to child components for consumption.
The first agent skill is a workflow for building a new Angular app from scratch. Using this skill agents will use Angular tooling for code generation where appropriate. Also includes important hints.
The `isTypeOnly` property was deprecated in TypeScript and replaced by `phaseModifier`.
Updates the check to use `phaseModifier`, which is the recommended API for detecting type-only imports.
Additionally, removes the unused `metadata` parameter from the `NgModuleExtractor`
Fixes#67051
Store custom control focus callbacks in a wrapper so method invocation keeps the original object context. Without this, custom focus methods that access instance members throw at runtime when focusBoundControl() is called.
When using ViewContainerRef to rapidly toggle animated elements in
zoneless mode (e.g. CDK Overlay menus), multiple copies of the element
could appear in the DOM. This happened because leave animations were
queued but not yet executed, and the existing `cancelLeavingNodes`
mechanism could not find the leaving element to cancel it — it ran
during template execution before the new element was in the DOM, and
used the declaration container's anchor which doesn't work for
overlay/portal patterns where elements are moved to separate
containers.
Due to explicit injector type checks, inspecting nodes that have type !== `environment` but at the same time are rendered in the Environment Injector tree, opening their details used to break the app. This change fixes this.
Antigravity does not support AGENTS.md, instead it has "workspace rules" (antigravity.google/docs/rules-workflows). This commit adds a symlink for the workspace rule.
In signal forms, it is up to the user to guard hidden fields from being
rendered in the template. To help catch instances where it is
accidentally not guarded, this commit introduces a warning in dev mode.
Removes the use of the private Protractor builder (`@angular-devkit/build-angular:private-protractor`)
from all integration test projects. Projects that still require E2E tests
now invoke Protractor directly via NPM scripts using `concurrently` to
manage the development server.
`FieldTree` was an unnecessarily specific type for the `[formField]`
input. It forced the directive to care about what _kind_ of `FieldTree`
was bound–specifically whether it was Reactive Forms compatible or not.
This made it difficult to author forms system-agnostic components with
passthrough `[formField]` inputs.
Animation runner functions (runEnterAnimation, runLeaveAnimations,
runLeaveAnimationFunction) execute asynchronously from the animation
queue via afterNextRender. By that time the lView injector may have
been destroyed, causing lView[INJECTOR].get(NgZone) to throw NG0205.
Move the NgZone and MAX_ANIMATION_TIMEOUT lookups into the setup
instructions (ɵɵanimateEnter, ɵɵanimateLeave, ɵɵanimateLeaveListener)
which run synchronously during template processing when the injector
is guaranteed to be valid, and pass them through the closures.
The dynamic component has `[value]` in its selector and this has always been reflected as a DOM attribute on the dynamically created host element, which is now also synced into the component instance.
fixes#60157
Adds an option (`ngTemplateOutletInjector="outlet"`) that instructs the ngTemplateOutlet to inherit its injector from the outlet's place in the instantiated DOM.
The `SkipSelf` flag is intended for the current injection context. When delegating to an embedded view injector, we are traversing to a parent/fallback scope, so the 'Self' has already been skipped.
Removes the `e2e` architect target from the `legacy-animations` integration test
project as it does not have actual E2E tests and was using a placeholder script.
Removes the `e2e` architect target from several integration test projects
that do not have Protractor as a dependency and are not executing E2E tests.
Affected projects:
- cli-hello-world
- cli-hello-world-lazy
- defer
- legacy-animations-async
- standalone-bootstrap
Introduces an optional `height` property in `ImageLoaderConfig`, allowing
built-in image loaders to generate URLs with explicit height parameters.
This improves layout control and enables better support for loaders that
require height-based transformations.
Closes#51723
The `action` and `onInvalid` handlers now recevie two pieces of
information:
1. The form that is being submitted
2. The specific field that the submit was triggered on
Remove the `submit()` method on field state - supporting this is complex
from a typing perspective, since the `FieldState` only knows its
`TValue` type, not the `TModel` type of its owning `FieldTree`. Rather
than try to pack additional generics on to `FieldState`, we'll just
leave the `submit` function as a standalone importable function.
Removes usages of zone-based helpers such as `fakeAsync` , `tick`
`waitForAsync` as part of the migration to zoneless tests.
Completes the transition to zoneless.
Encodes arraybuffer and blob response bodies as base64 when storing in the transfer cache, ensuring correct retrieval and usage on the client side.
Fixes#66827
The `fieldTree` property of `FieldState` returns its associated
`FieldTree`.
Note that the round trip from `FieldTree` to `FieldState` and back will
lose type information. This is because `FieldState` intentionally does
not know whether it came from a pure Signal Forms field tree, or a
Reactive Forms compatible field tree:
```ts
// Pure Signal Forms:
const x: FieldTree<string>;
x(); // FieldState<string>;
x().fieldTree; // FieldTree<unknown>
// Reactive Forms compatibility:
const y: FieldTree<FormControl<string>>;
y(); // FieldState<string>;
y().fieldTree; // FieldTree<unknown>;
```
Reoves the `parseErrors` property on `FormUiControl` and instead
introduces a new utility `transformedValue` that automatically handles
synchronizing the raw value and model value using the given `parse` and
`format` functions. It also automates the reporting of `parseErrors` to
the `FormField`, simplifying the API surface
Adds a Gemini CLI custom command (`/explain`) to generate skills for
working with code packages in this repo. Usage:
1. Add skill for a new package:
`/explain packages/common`
2. Update the skill for a package:
`/explain Update the skill for packages/core`
3. Add supplemental information:
`/explain Add supplemental info to the signal forms skill about how
schema logic is implemented`
Also adds a few skills for working with some of the packages I commonly
interact with, including:
- packages/forms/signals
- packages/core
- packages/compiler-cli
Now if there's a leave animation nested within a template, those will animate before the parent element is removed. This makes animating leaving elements a bit easier than before and adds a lot more flexibility to how animations can be structured.
fixes: #66476
Allow `validateStandardSchema()` to consume a computed schema so
validation rules stay in sync when the schema changes over time.
This supports schemas stored in computed signals (e.g. zod schemas that
depend on input signals) and ensures the effective schema updates after
initialization instead of being captured once.
Fixes#66867
Based on the discussion in #66294: now that we support arrow functions in event listeners, developers may write out something like `(click)="() => expr"` which will be a no-op. These changes update the existing diagnostic for uninvoked expressions in listeners to account for it.
Standardize on `import type ts from 'typescript'` across several files
in the language-service package.
This ensures that these files do not have a runtime dependency on a
specific version of the TypeScript module, instead relying on the
instance provided by the host during initialization.
Note: This change is not comprehensive. Several files still require
runtime access to the TypeScript module and will require further
refactoring to fully decouple the dependency.
Replace `field: any` with proper SchemaPath typing in Signal Forms custom
validation examples to match built-in validator patterns.
fixes: #66887
Update adev/src/content/guide/forms/signals/validation.md
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
This feature enables synchronized editing of opening and closing HTML tag pairs
in Angular inline templates. When the cursor is on an element tag name, editing
it will automatically update the corresponding tag.
Implementation:
- Add getLinkedEditingRangeAtPosition method to NgLanguageService interface
- Implement linked editing range detection for opening and closing tags
- Handle edge cases: self-closing elements, void elements, cursor detection
- Export through ts_plugin wrapper to override TypeScript JSX-only implementation
- For external HTML templates, VS Code built-in HTML support handles linked editing
Update `ts_plugin.ts` to use the TypeScript instance provided by the
editor during initialization instead of a local import. This prevents
potential issues caused by version mismatches between the plugin's
internal TypeScript dependency and the version used by the host.
Removes usages of zone-based helpers such as `fakeAsync` , `tick`
`waitForAsync` as part of the migration to zoneless tests.
Completes the transition to zoneless.
Updates FormOptions to accept a submission configuration object.
This allows defining default submit options (action, validation behavior, etc.)
when creating the form, which can be overridden when calling submit().
Changes the `submit` function signature to accept a `FormSubmitOptions` object instead of a direct action callback.
This allows for more flexibility, including:
- `action`: The standard submit action to perform with the data.
- `onInvalid`: A callback to execute when the submit action is not triggered due to failing validation
- `ignoreValidators`: Controls whether pending validators or invalid validators should be ignored
Also updates the return value of `submit` to a `Promise<boolean` to indicate submission success.
Replaces “one of two ways” with “one of the following ways” to avoid
hardcoding the number of supported approaches and keep the
documentation accurate if options change.
fixes: #66861
In many JS runtimes all closures created in the same scope share a context
this means that data held in one of the closures is not collected until all of the closures are collected.
This change prevents the returned promise from holding a reaction that holds the entire `Router` object in memory.
- Add registerOnChange, _unregisterOnChange for value change callbacks
- Add registerOnDisabledChange, _unregisterOnDisabledChange for disabled callbacks
- Add disabled changes effect to notify registered callbacks
- Call onChange callbacks from updateValue with emitModelEvent flag
- Add CachingWeakMap utility for memoization
- Add wrapFieldTreeForSyncUpdates Proxy wrapper
- Intercept fieldTree().value.set() calls to sync parent immediately
- Cache wrapped trees and states to preserve identity
- Add ValueUpdateOptions type with onlySelf, emitEvent options
- Add parent notification on value changes via effect
- Add parent notification helpers: scheduleParentUpdate, notifyParentUnlessPending
- Propagate dirty/touched/pristine/untouched to parent
- Support onlySelf option to prevent parent propagation
- Add valueChanges EventEmitter that emits when source signal changes
- Add statusChanges EventEmitter that emits when status changes
- Set up effects to emit to observables
- Add reset() method with optional value parameter
- Support FormControlState unboxing ({value, disabled} format)
- Add isFormControlState helper function
This commit introduces `SignalFormControl`, a bridge implementation that allows Signal-based forms to interoperate with existing Reactive Forms infrastructure. It extends `AbstractControl` with standard methods and reactive observables while handling state propagation to parent containers.
Unlike a normal `signal()`, a `linkedSignal()` can be in an error state when
its computation fails. Currently, there's a bug where `linkedSignal.update`
does not account for this error state, and will pass the internal `ERRORED`
`Symbol` as the current value to the updater function.
This commit fixes the issue by having `update()` check and throw the error
instead of calling the updater function.
Enables specifying a custom browser URL for router links via a new input,
allowing navigation to use an explicit browser URL in navigation options.
Closes#66805
Updates the plugin factory to directly invoke the 'initialize' function from the
Angular Language Service bundle. This replaces manual proxying and lazy-loading
logic with direct delegation, unifying the instantiation process within the bundle.
Previous the router tree was an opt-in feature that required manual enablement in settings.
Now the router tree is enabled by default whenever the application supports it and routes are detected.
Adds `ChangeDetectionStrategy.Eager` as an explicit alias for `ChangeDetectionStrategy.Default`. This improves readability when contrasting with `OnPush`, clarifying that the component will be checked eagerly when traversal reaches it.
Compiler findings:
- The compiler resolves `ChangeDetectionStrategy` enum members by value in `resolveEnumValue` (see `packages/compiler-cli/src/ngtsc/annotations/common/src/evaluation.ts`).
- Since `Eager` has usage value `1` (same as `Default`), it is correctly interpreted during static analysis.
- At runtime, `defineComponent` (in `packages/core/src/render3/definition.ts`) checks `changeDetection === ChangeDetectionStrategy.OnPush` (0). Any other value, including `1` (Eager/Default), results in eager checking behavior (`onPush: false`).
This commit introduces a JSON schema for angularCompilerOptions in the
Angular Language Service extension. It provides validation and autocompletion
for Angular-specific options in tsconfig.json files.
Remove `setControlValue()` from `FieldState` and convert `controlValue` to a
`WritableSignal` whose setter implements the debounced syncing behavior
of `setControlValue()`.
This commit converts the typescript import in api.ts to a type-only import
and updates the plugin factory to utilize standard TypeScript server types.
Internal interfaces and specific service types are replaced with general
types to decouple the factory wrapper from internal implementations.
Refactors the `ɵɵcontrolCreate` and `ɵɵcontrol` instructions to delegate control logic to the forms package via new `ɵngControlCreate` and `ɵngControlUpdate` lifecycle hooks. Previously, the logic for binding form state to native elements and custom controls was hardcoded within `@angular/core`.
**Compiler Changes:**
- Introduces a new compilation phase `specializeControlProperties` (in `control_directives.ts`).
- This phase detects properties named `formField` and specializes them into `ControlCreate` and `Control` IR opcodes.
- These opcodes emit `ɵɵcontrolCreate` and `ɵɵcontrol` instructions, respectively.
**Runtime Changes:**
- `ɵɵcontrolCreate` acts as the creation phase. It locates the control directive and invokes its `ɵngControlCreate` method.
- `ɵɵcontrol` acts as the update phase, and invokes the control directive's `ɵngControlUpdate` method (if present).
- Introduces a `passThroughInput` configuration in `ControlFeature`. This specifies the input name (e.g., `formField`) that triggers the control. If the runtime detects that this input is bound to multiple targets (e.g., the `FormField` directive *and* the host component), the control is flagged as "pass-through". In this state, `ɵngControlCreate` returns a no-op update function, deferring responsibility to the other consumer (e.g., the component managing the field itself).
**Forms Changes:**
- `FormField` directive implements `ɵngControlCreate` and `ɵngControlUpdate`.
- Inside this hook, `FormField` determines the type of control it is attached to (Native, CVA, or Custom Signal Control) and delegates to the appropriate handler (`nativeControlCreate`, `cvaControlCreate`, or `customControlCreate`).
- Consolidates all form binding logic within `@angular/forms/signals`, enabling support for new `FormValueControl` and `FormCheckboxControl` interfaces.
- Reorganizes the codebase by moving `FormField` from `api/` to `directive/` and splitting the binding logic into semantic pieces:
- `control_native.ts`, `control_cva.ts`, and `control_custom.ts` contain the specific handlers for each control type.
- `native.ts` and `select.ts` provide helpers for native element discovery and select-specific synchronization.
- `bindings.ts` manages the tracking and application of property/attribute bindings.
Consolidating the standard schema support into `standard_schema.ts` will
cut down on unnecessary g3 patch changes whenever we change
`validation_errors.ts`.
The standalone build.sh script for the language service is no longer
required as the vscode-ng-language-service repository has been merged
into this monorepo. Local development and testing of the extension
can now be handled via the integrated build system.
When dynamic components are rapidly added and removed with animate.leave and animate.enter, a leave animation might fire before the enter animation could, causing an element to be retained. This fix prevents that from occuring by clearing the enter animations in this case.
fixes: #66794
This commit updates the @angular/localize ng-add schematic to support
the @angular/build:unit-test builder. It ensures that @angular/localize
is added to the types array in the TypeScript configuration file
associated with the unit-test target. If no tsConfig is specified in
the target options, it defaults to tsconfig.spec.json in the project root.
Deeply nested parentheses in URLs (e.g. `(a/(b/(c...)))`) trigger recursive calls in `UrlParser`, which can lead to a `RangeError: Maximum call stack size exceeded`. While such errors are generally caught by the framework, relying on the runtime's stack limit is unpredictable across different environments and engine states (e.g. varying stack sizes in different browsers or Node.js versions).
The deeply nested parentheses can cause a stack overflow. While such URLs can be valid (e.g., `(a/(b/(c...)))`) and serialize to simple paths (e.g., /a/b/c), excessive nesting is unreasonable and likely malicious or accidental.
Linear paths (e.g. /a/b/c/d) are parsed iteratively and do NOT trigger recursion. Only parentheses trigger recursion.
This commit introduces a recursion depth limit of 50. If parsing exceeds this depth, the router will now throw a specific `UNPARSABLE_URL` error with the message "URL is too deep". This ensures a deterministic failure mode that is easier for applications to handle than a crash or generic RangeError.
The limit of 50 is chosen as it should accommodate any reasonable application URL structure (including complex named outlets) while providing a safe upper bound against abusive payloads.
This is essentially a refactor of the error state:
* Before: RangeError (System says "I'm out of stack memory")
* After: RuntimeError (Validator says "Input is invalid")
This provides:
* Semantic Correctness: The error now correctly blames the input ("URL too deep"), not the environment ("Stack full").
* Cross-Platform Consistency: The limit is the same in Chrome, Firefox, Node, and Deno, regardless of their internal recursion limits.
* Fast Failure: We stop at depth 50 instead of depth ~15,000, saving those cycles (though CPU cost is negligible either way).
"wide" URLs are now theoretically more expensive than "deep" URLs (because deep ones fail fast), but both are well within safe bounds for any reasonable input size.
This updates `RouterLinkActive`, `Router.isActive`, and the standalone
`isActive` function to accept `Partial<IsActiveMatchOptions>` which uses
the current default values as the base (paths and queryParams are
subset, fragment and matrix params are ignored).
fixes#53326
This commit refactors the `ts_plugin.ts` implementation to use a new `withFallback` helper function. This helper encapsulates the common logic of delegating requests to either the Angular language service directly (for non-TS files or when `angularOnly` is true) or trying the TypeScript language service first before falling back to the Angular language service.
Don't touch hidden, disabled, or readonly fields on submit, since they
don't contribute to form validity. This also prevents errors from
appearing immediately if they're later made interactive.
Fix#66344
Ensure `submit()` behaves as expected while a form is pending.
- Submission is not blocked by pending validation.
- Submission errors prevent pending validation errors from appearing
after they resolve on the same field.
- Submission errors don't prevent pending validation errors from
appearing after they resolve on subfields.
This updates the language service to use the detected version of angular
core in the given project on load rather than the minimum detected
version in the workspace
Updates the form documentation to link to the API reference for the `form()` function.
Also removes unused `HttpClient` import from the async validation example.
PR Close#66732
Update how dev preview, experimental and deprecated labels are visualized in the API list to avoid ambiguity with the current design on larger screens.
This commit prevents the Router from intercepting reload navigations
in the navigate event listener. This would convert hard page reloads
to SPA navigations.
fixes#66746
Update the Genkit Angular integration documentation link from the old path
/docs/angular/ to the current correct path /docs/frameworks/angular/
This ensures developers are directed to the correct and up-to-date
documentation for integrating Genkit with Angular applications.
Adds dedicated `LocationStrategy` subclasses: `NoTrailingSlashPathLocationStrategy` and `TrailingSlashPathLocationStrategy`.
The `TrailingSlashPathLocationStrategy` ensures that URLs prepared for the browser always end with a slash, while `NoTrailingSlashPathLocationStrategy` ensures they never do. This configuration only affects the URL written to the browser history; the `Location` service continues to normalize paths by stripping trailing slashes when reading from the browser.
Example:
```typescript
providers: [
{provide: LocationStrategy, useClass: TrailingSlashPathLocationStrategy}
]
```
This approach to the trailing slash problem isolates the changes to the
existing LocationStrategy abstraction without changes to Router, as was
attempted in two other options (#66452 and #66423).
From an architectural perspective, this is the cleanest approach for several reasons:
1. Separation of Concerns and "Router Purity": The Router's primary job is to map a URL structure to an application state (ActivatedRoutes). It shouldn't necessarily be burdened with the formatting nuances of the underlying platform unless those nuances affect the state itself. By pushing trailing slash handling to the LocationStrategy, you treat the trailing slash as a "platform serialization format" rather than a "router state" concern. This avoids the "weirdness" in #66423 where the UrlTree (serialization format) disagrees with the ActivatedRouteSnapshot (logical state).
2. Tree Shakability: If an application doesn't care about trailing slashes (which is the default "never" behavior), they don't pay the cost for that logic. It essentially becomes a swappable "driver" for the URL interaction.
3. Simplicity for the Router: #66452 (consuming the slash as a segment) bleeds into the matching logic, potentially causing issues with child routes or wildcards effectively "eating" a segment that should be invisible. This option leaves the matching logic purely focused on meaningful path segments by continuing to strip the trailing slash on read.
4. Consistency with Existing Patterns: Angular already uses LocationStrategy to handle Hash vs Path routing. Adding "Trailing Slash" nuances there is a natural extension of that pattern—it's just another variation of "how do we represent this logic in the browser's address bar?"
fixes#16051
This implements `onDidChangedWatchedFiles` in the language server, which
allows the client to communicate changes to files rather than having the
server create system file/directory watchers.
This option is enabled in the extension via the
`angular.server.useClientSideFileWatcher` setting.
When enabled, the extension registers a FileSystemWatcher for .ts, .html, and package.json files and forwards events to the server. The server completely disables its internal native file watchers (via a new 'ServerHost' implementation that stubs watchFile/watchDirectory).
This is significantly more performant and reliable than native watching for several reasons:
- Deduplication: VS Code already watches the workspace. Piggybacking on these events prevents the server from duplicating thousands of file watchers.
- OS Limits: Since the server opens zero watcher handles, it is impossible to hit OS limits (ENOSPC), no matter how large the repo is.
- Optimization: VS Code's watcher uses highly optimized native implementations (like Parcel Watcher in Rust/C++) which handle recursive directory watching far better than Node.js's 'fs.watch'.
- Debouncing: The client aggregates extremely frequent file events (e.g., during 'git checkout'), reducing the flood of processing requests to the server.
This option was tested in one very large internal project and observed
~10-50x improvement of initialization times.
fixes#66543
Parse errors allow a custom control to communicate that it is currently
unable to produce a valid value.
Parse errors are reported by implementing the optional `parseErrors`
property on the `FormUiControl`. The property should be a signal of the
current parse errors.
Also renames several `*Field` types to `*FieldTree`. This aligns with the new naming of the concept after `Field` was renamed
to `FieldTree`.
Previously, ng_package applied version stamping to all source files, which corrupted binary files like SQLite databases.
This change ignores text substitution for files passed to the `data` attribute, ensuring binary assets are preserved intact in the final package.
fixes#66637
When synthesizing an import corresponding with a .tsx file, the extension
would not be removed unlike regular .ts files. Adjust the import generators
to also drop any .tsx extension from module specifiers.
Closes#66262
When producing a listener, the template pipeline does the following in separate phases:
1. Generates all the variables available within its scope.
2. Adds `restoreView` and `resetView` calls if there are any referenced to local variables (e.g. `@let` or local refs).
3. Optimizes away the variables that aren't used.
This means that we can end up in a situation where the references to the variables in the scope no longer exist, but we still enter and leave the view as if they're there which is unnecessary.
These changes add a simple optimization pass that looks specifically for the pattern of a `restoreView` followed by a `return resetView(expr)`. Furthermore, by changing the order of some optimizations, we're able to drop the `getCurrentView` variable as well.
Fixes#66286.
Add support for `@defer`-only blocks (previously, they weren't rendered in the component tree at all); Fix declared blocks section in the details
PR Close#66546
Add the host/container comment node to the `DeferBlockData`. This node can be used as a `@defer` block locator in the DOM tree in the absence of root nodes.
PR Close#66546
Previously our system only found the first matching symboling to link to within a code block on each line, now we set up a link for all of the discovered symbols on each line
Fixes#65403
Update the skip-to-main-content behavior to focus the <main> element when present, with a fallback to the first heading for legacy layouts without a main landmark.
There has been a bunch of confusion as to how `animate.leave` works on child nodes when the non-animated parent is removed. This section addition should clarify that.
Extends the `focus` method of form fields and custom controls to accept and propagate `FocusOptions`.
This enables developers to control focus behavior more precisely, for example, preventing scrolling when focusing an element.
The Zone.js build was depending on the `--outFile` flag from TypeScript which is deprecated. These changes switch to using `--outDir` and copying the files out of the directory instead.
Previously we were unconditionally setting the control value back into
the value, regardless of if it had actually been changed. This PR
changes the logic to flush the pending sync on touch if there is one, or
just skip it if there isn't.
Currently migrating from `[ngClass]` to `[class]` isn't entirely supported, because `[ngClass]` supports `Set` values while `[class]` ignores them.
These changes add a bit of logic to bring them closer together and make the migration easier.
This PR adds the ability to manually register a binding with the
`FormField` directive. This is useful for a lower-level implementation
that takes the field tree as an `input()` rather than relying on the
automatic binding from `FormUiControl`.
```ts
@Component(...)
class Outer {
constructor() {
@Component(...)
class Inner {}
}
}
```
previous behavior was that IVy transformation was only applied to `Inner`, thus breaking `Outer` transformation.
Fixes an issue where a trailing slash was sometimes added to the end of URLs in the sitemap, causing unnecessary redirects.
Example of problematic URL:
```xml
<loc>https://angular.dev/</loc>
```
- Ensure there is a GITHUB_TOKEN environment variable at the start so we can push the release
- More robust handling for finding releaser's fork if it's not 'origin'
Updates the syntax definition to handle arrow functions. The definition is largely based on TypeScript's own syntax highlighting since it's quite complex.
We had some reports of LLMs claiming that `ngOnChanges` does not include
changes for signal-based inputs. This is wrong (and the LLMs just made
it up), but we can update the docs at least to demonstrate `ngOnChanges`
with signal-based inputs.
Previously, the API reference used a real test as a code example, but
updating the test to a signal-based input is more involved than this
change needs to call for.
Convert the signal graph to a Devtools-FE-specific signal graph that supports clusters; Add support for `resource` clusters; Introduce some improvements to the signal graph viz
- Fetch tags explicitly to ensure local availability.
- Implement `getPreviousTag` to reliably determine the base for changelog generation, falling back to the latest `vsix-*` tag if the specific previous version tag is missing.
- Filter changelog commits by subject to exclude duplicates (e.g. cherry-picks) that are already present in the previous release history but have different hashes.
This builds off of #66197 by retaining the original navigateEvent across redirects
so the NavigateEvent can more accurately track the lifecycle of a navigation,
which may span across several NavigationStart events due to redirects
* Define `ResourceSnapshot<T>` as a type union of possible states for a
`Resource<T>`.
* Add `Resource.snapshot()` to convert a `Resource` to a signal of its
snapshot.
* Add `resourceFromSnapshots` to convert a reactive snapshot back into a
`Resource`.
By converting resources from/to `Signal<ResourceSnapshot>`s, full
composition of resources is now possible on top of signal composition APIs
like `computed` and `linkedSignal`.
For example, a common feature request is to have a `Resource` which retains
its value when its reactive source (params) changes. This can now be built
as a utility, leveraging `linkedSignal`'s previous value capability:
```ts
function withPreviousValue<T>(input: Resource<T>): Resource<T> {
const derived = linkedSignal({
source: input.snapshot,
computation: (snap, previous) => {
if (snap.status === 'loading' && previous?.value) {
// When the input resource enters loading state, we keep the value
// from its previous state, if any.
return {status: 'loading', value: previous.value.value};
}
// Otherwise we simply forward the state of the input resource.
return snap;
},
});
return resourceFromSnapshots(derived);
}
// In application code:
userId = input.required<number>();
user = withPreviousValue(httpResource(() => `/user/{this.userId()}`));
// if `userId()` switches, `user.value()` will keep the old value until
// the new one is ready!
```
Prior to this change, binding to radio value was sensitive to the order in which `value` & `formField` where binding in the template.
The compiler change makes that order non-important.
fixes#66402
Add comprehensive test cases to validate behavior when multiple
pattern validators are applied to the same field.
These tests clarify that multiple patterns operate with AND logic,
where each pattern is validated independently and produces its own
error when it doesn't match.
build: update dev container configuration
build: update dev container configuration
Update dev container configuration files to support latest environment.
- Use customizations.vscode structure instead of deprecated extensions property.
- Update bazel extension to BazelBuild.vscode-bazel.
- Ignore .pnpm-store directory.
- Update ports list
- Use forwardPorts instead appPort
Document the usage of Dev Containers in building-and-testing-angular.md.
Replaced padding-block-start with margin-block-start on
.docs-reference-section-heading to prevent anchor hover and click areas from extending into empty space above the heading. This ensures hover behavior aligns with the visible text.
The list of valid links is generated from navigation data configuration in the ADEV app.
Redirections are knowingly exclude so we stop referencing them.
Block entries (@if, @defer, @for,@let, @switch) were falling back to the generic
DocsReference template, causing the description to appear twice - once in
the header section and once in the main content area.
This commit adds a dedicated rendering path for block entries:
- Creates BlockEntryRenderable type and associated transforms
- Adds BlockReference template that uses RawHtml directly
- Modifies HeaderApi to accept hideDescription prop
- Updates processing and rendering pipelines to handle blocks
The fix ensures block documentation displays only one description section
while preserving the existing behavior for all other API entry types.
Update adev/shared-docs/pipeline/api-gen/rendering/transforms/block-transforms.mts
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
Removes the unnecessary `Component` suffix from examples.
Also fixes button styling in the animations examples, which previously did not render correctly in dark mode.
Error message links now point to the archived documentation site (v*.angular.dev)
so that referenced content matches the framework version in use.
See angular#44650
PR Close#66374
Error message links now point to the archived documentation site (v*.angular.dev)
so that referenced content matches the framework version in use.
See angular#44650
PR Close#66374
This completes the rename started in #66136. `[field]` is too generic of
a selector for the forms system to own, and likely to cause naming
collisions with existing components. Therefore it is being renamed to
`[formField]`
The common-to-standalone migration did not check for existing imports
when adding needed imports after removing CommonModule. This change adds deduplication
logic to filter out imports that already exist in the imports array
before adding them, ensuring each import appears only once.
Reworks how we store arrow functions in the following ways:
1. Rather than the `storeCallback` and `getCallback` instructions, we generate a single `arrowFunction` instruction.
2. The `arrowFunction` instruction uses a factory to create a new instance of the function when a function is read for the first time.
3. We now keep arrow functions in listeners in line so that they have access to `$event`.
Adds support for using arrow functions in Angular expressions. They generally behave like JS arrow functions with the same access as other Angular expressions, but with the following limitations:
* We only support arrow functions with implicit returns, e.g. `(a) => a + 1` is allowed while `(a) => { return a + 1 }` is not.
* Pipes can't be used inside arrow functions, but they can be passed through to pipes.
To avoid recreating the functions in each change detection, the compiler applies a couple of optimizations:
* If an arrow function only references its own parameters, it is extracted into a top-level constant that is passed around to the different usage sites.
* If an arrow function has references to the template context, we store it on the current view and read the stored value later on.
Fixes#14129.
The `countVariables` phase visits all ops in the list and all nested expressions in order to count how many variables are used. Currently it does so by going through `unit.ops()` and then calling `visitExpressionsInOp` on each op.
This leads to expressions in ops that have nested ops (e.g. `ListenerOp`) to be visited twice, because `unit.ops()` descends into child ops and then `visitExpressionsInOp` does the same. It hasn't been a problem so far, because the only expressions that can have vars in host bindings are pure functions and they aren't generated for listeners, but it will become a problem for arrow functions since they can be used in listeners.
These changes resolve the issue by iterating over the `unit.create` and `unit.update` instead.
Adds the `ɵɵstoreCallback` instruction that allows for a callback to be stored for later usage, as well as `ɵɵgetCallback` which can be used to retrieve it.
Updates the template type checker to support arrow functions. The main challenge was getting the current infrastructure not to rewrite references to arrow function parameters.
Updates the expression parser to handle arrow functions. Since arrow functions share syntax with other AST nodes, we have to detect them by looking ahead and then potentially jumping backwards depending on what we see.
The `precommitHandler` of the Navigation API unlocks some of the truly
powerful features for Routers like Angular's which defer the URL
updates. Without the `precommitHandler`, we cannot initiate a navigation
until we are ready to commit the URL because it causes the URL to update
immediately.
With `precommitHandler` support, we are able to create a `NavigateEvent`
_immediately_ on navigation, which allows the browser to show that a
navigation is happening with a loading indicator. Site visitors will
also have the ability to cancel the navigation with the "stop" button.
When we are ready to commit the URL, the precommitHandler supports a
"redirect" function that we can use to first redirect the navigation to
a new location immediately before committing it.
The commit operation is not synchronous because the API waits for all
precommitHandlers to resolve. This commit adds a small bit of handling
to account for this so that the Router's transition does not advance
to the next stage until the URL has been committed.
This commit ensures the Document used by `FakeNavigation` is the one
passed in the constructor rather than the global `document`, which may
be different.
Previously, object literal keys in the TCB did not have source spans attached. This made it difficult for the Language Service to distinguish between keys and values, leading to incorrect completion contexts and diagnostic locations.
This commit ensures that source spans are properly attached to the keys in the TCB.
Update fake navigation implementation to correctly handle traversals that are cancelled (e.g. by a precommit handler).
Ensure prospective index is calculated correctly so that subsequent traversals target the correct entry.
Add regression test for cancelled traversals.
The .docs-primary-btn hover state in dark mode had a contrast ratio of 2.18:1,
failing WCAG 2.1 SC 1.4.3. This change reuses the existing
--hot-pink-to-electric-violet-radial-gradient to achieve 4.5:1+ contrast.
This commit introduces a highly requested `trailingSlash` configuration option to the Angular Router, allowing developers to control how trailing slashes are handled in their applications. The options are:
- 'always': Enforces a trailing slash on all URLs.
- 'never': Removes trailing slashes from all URLs (default).
- 'preserve': Respects the presence or absence of a trailing slash as defined in the UrlTree.
This publishes the work that was done to integrate with the Navigation
API as an experimental router feature. Browser support is limited and in
active development. There are also known bugs in the browser implementations
and only Chromium browsers supported deferred URL updates with the
`precommitHandler`. Relates to #53321, which I would likely not mark as
completed until this is at least in dev preview, which likely won't
happen until it is widely available and potentially delayed until
`precommitHandler` is widely available as well.
The final form of this api might not even be a "router feature" in the end, but instead be
something similar to what other frameworks have to provide different
platform integrations (e.g. `provideNavigationRouter`). That would
support omitting the history-based integration from the bundle when only
the navigation integration is used. Alternatively, the current
`provideRouter` could require one of `withHistory` or `withPlatformNavigation`.
Remove the `customError` function and `CustomValidationError` type.
These were made obsolete by support for returning plain object literals
as custom errors.
This also catches few `field` properties that were missed in the
renaming to `fieldTree`.
Firefox-specific workaround: Firefox 144+ creates the `updateCallbackDone` promise
internally during error handling (e.g., duplicate view-transition-name), even before
the property is accessed. This can cause unhandled promise rejections to appear in
error tracking tools like Rollbar/Sentry. We must attach catch handlers to all three
promises immediately to prevent these unhandled rejections.
See: https://bugzilla.mozilla.org/show_bug.cgi?id=1999336 (if applicable)
Spec: https://drafts.csswg.org/css-view-transitions-1/#dom-viewtransition-updatecallbackdone
The `thisArg` in pure functions isn't used so we can drop it. We still need to keep it on the underlying implementation, because pipe instructions rely on it.
Fixes combobox dialog styles to ensure correct text color and contrast in dark theme.
This improves readability and visual consistency when using the docs in dark mode.
There was a bug introduced in #60875. While RouterLink doesn't
necessarily depend on Router state, its link can change when navigations
cause the `ActivatedRoute` paths to change. It is difficult to determine
which segments the link depends on. Luckily, the commit had flawed
logic:
```
!this.queryParamsHandling && !dependsOnRouterState(this.options?.defaultQueryParamsHandling);
```
The subscription gets created whenever `queryParamsHandling` was not
defined, or it was non-default. This is pretty much all scenarios since
nobody is likely to set it explicitly to the default value. In addition,
the `click` handler recomputes the tree because `urlTree` is a getter
that does the computation.
This commit effectively rolls back #60875
Removes the abort event listener once the debounce timeout completes.
This avoids lingering listeners, prevents potential memory leaks, and ensures
the abort logic runs at most once.
Previously there is no feedback when clicking this button in Angular DevTools itself, which can produce some confusion if the user does not have the browser console open as well, or if they accidentally turned on some filtering in the browser console.
Now Angular Devtools uses mat snack bar to inform the user that the task was successful
The animations code currently tracks which views have running leave animations by adding them to a `Set`. This can leak memory if we don't clean something up on time.
These changes switch to tracking the views by their ID which doesn't risk retaining the view.
Fixes#66255.
This change deprecates `Router.isActive` in favor of a function that
creates a computed which tracks whether a given url/UrlTree is active,
following changes in the router state.
`Router.isActive` contributes ~1333b to the bundle size, but is only
used by developers who use the API directly or who use
`RouterLinkActive`. It should not contribute to bundle sizes of
applications that do not use this functionality.
This will replace the `[field]` directive, since `[field]` is a very
generic name for signal forms to commandeer
refactor(forms): hook up `formField` directive in compiler
Hooks up the `formField` direcive to get the same treatment as the
`field` directive in the compiler.
apply updated formatting
This builds off of #66197 by retaining the original navigateEvent across redirects
so the NavigateEvent can more accurately track the lifecycle of a navigation,
which may span across several NavigationStart events due to redirects
The `precommitHandler` of the Navigation API unlocks some of the truly
powerful features for Routers like Angular's which defer the URL
updates. Without the `precommitHandler`, we cannot initiate a navigation
until we are ready to commit the URL because it causes the URL to update
immediately.
With `precommitHandler` support, we are able to create a `NavigateEvent`
_immediately_ on navigation, which allows the browser to show that a
navigation is happening with a loading indicator. Site visitors will
also have the ability to cancel the navigation with the "stop" button.
When we are ready to commit the URL, the precommitHandler supports a
"redirect" function that we can use to first redirect the navigation to
a new location immediately before committing it.
The commit operation is not synchronous because the API waits for all
precommitHandlers to resolve. This commit adds a small bit of handling
to account for this so that the Router's transition does not advance
to the next stage until the URL has been committed.
This commit updates the DOM security schema and sanitization logic to properly recognize and sanitize `href` and `xlink:href` attributes on SVG `<script>` elements.
The framework will now bind all field state properties to their
corresponding native properties (if any) on interop form controls (those
using `ControlValueAccessor`), excluding those handled explicitly by
`ControlValueAccessor` such as `disabled`.
Since the `Field` directive manages binding `FieldState` properties to
the underlying form control automatically, the type checker prohibits
explicit bindings to the same properties to avoid conflicts. This proved
problematic in cases where developers wanted to bind these properties to
the inputs of other directives on form controls. Now the framework will
bind the field state properties to all matching directive inputs on
native controls.
Fix#65617
Mutating the `UrlTree` that is returned by `createUrlTree` can cause the
input, which might even be an active route, to be mutated. This ensures
the `UrlSegment`s are recreated and do not mutate the input.
fixes#54624
We had `any` types for `LiteralArray.expressions`, `Chain.expressions`, `BindingPipe.args`, `LiteralPrimitive.value` and `LiteralMap.values`. These changes add proper types to them.
Add @see JSDoc tags to Signal Forms API functions and classes to link to the essentials guide and detailed documentation pages. This improves discoverability of Signal Forms documentation from the API reference.
Each tree-visualizer render cycle resets the snapped node in an effort to not end up with a non-existent snapped node. However, each render cycle doesn't constitute a completely different tree. This change retains the snapped node as long as it exists in the tree.
Introduce an equality function for transformed injector trees in order to omit redundant D3 tree visualization render cycles when the tree hasn't been changed.
Those rewrites focus on using Vitest instead of jasmine, drop usages of `fakeAsync`, present modern testing strategy that rely on `whenStable` more than explicit calls to `detectChanges`.
fixes#42748, #48510, #64962, #65987, #66029, #66150
The removeValidators and hasValidator methods both had identical "Reference to a ValidatorFn" section titles, causing duplicate entries in the API documentation table of contents.
0.0.0 is the version in the local repo when building from sources. Update the
extension to see this as some arbitrarily large version so it uses the most recent features
This updates the pre-v19 integration test to use the regular integration
project but pass a specific version and update file contents as
necessary to excersise the code path that uses the default standalone
value. This allows us to remove the old project from the workspace,
allowing the language service to use more recent versions when working
with the adev project, for example.
Adds new tree-shakeable runtime error codes to improve error reporting for
NgModule resolution issues (duplicate or missing IDs) and invalid ViewContainerRef
operations involving destroyed views.
This commit introduces a new feature to automatically destroy `EnvironmentInjector`s associated with routes that are no longer active or stored. This helps in managing memory by releasing resources held by unused injectors.
This commit introduces the infrastructure for embedding code examples within Angular packages, enabling them to be consumed by the Angular CLI's MCP server.
The `@angular/forms` package is the first to adopt this new feature. A new `ng_examples_db` Bazel rule is used to build a SQLite database from markdown files containing code examples. This database is then included in the published npm package.
The `package.json` for `@angular/forms` has been updated with an `angular.examples` field to allow tooling to discover and use the code examples.
Update the documentation example to import input instead of Input,
ensuring the code reflects the signal-based API and current Angular
recommendations.
To avoid manually adding classes like `.ng-valid`, `.ng-dirty` etc to every field, you can provide a global configuration using `provideSignalFormsConfig`.
PR Close#66111
Remove usages of `detectChanges` and rely on `whenStable`.
This commit also removed the usage of `provideZonelessChangeDetection` which is no longer necessary.
Sets up the compliance tests to target es2022 since that's the default in the CLI. Also updates all of the tests, primarily because the generated output for static properties has changed.
Fixes an issue where the copy-to-clipboard icon moves to a new line when heading text is long and wraps.
Applies improved text wrapping for headings to keep the icon visually aligned.
Fixes#66239
Back in #39323, I added a new `ThisReceiver` node to represent accesses done through `this` and I ended up making it inherit from `ImplicitReceiver`. The logic was that in most cases accessing through `this` was the same as the implicit access.
Over the years this has proven to not be a great idea, because no other AST nodes do this and one has to keep it in mind whenever dealing with `ImplicitReceiver`.
These changes remove the inheritance and update all of the usage sites accordingly.
PR #60455 improved error reporting for `@Component.imports` by scoping the diagnostic to an individual
element within the `imports` array, but this may introduce hard to track diagnostics when it ends
up being reported (far) away from the component itself.
This can be even more problematic when the diagnostic would end up being reported in a declaration file,
as happened in issue #65686; the declaration files of an imported library contained syntax that the
static interpreter did not support, hence the `@Component.imports` was rejected with a diagnostic reported
in the library's declaration file. This diagnostic isn't guaranteed to be reported (e.g. the CLI only
gathers Angular-specific diagnostics for Angular-compiled files, which excludes declaration files).
This commit changes the diagnostic location to ensure it is being reported within the `@Component.imports`
expression, in most cases retaining the desirable effect of #60455 while avoiding out-of-band diagnostics.
Improves the localization documentation by updating code highlight syntax issues
and removing outdated TODOs.
Additionally, the CDK examples have been updated to use the viewChild query signal API,
aligning the docs with current recommended patterns.
Since Manifest V3, the service worker (background) gets terminated after 30s of inactivity. This can break the initialization phase of DevTools or the BE-FE communication channel, if already initialized. To prevent that, we emit a heartbeat in a >30s interval.
* Allow custom controls to make `pending` a required input
* Refactor test for `pending` input to be consistent with other control
properties
* Test that `pending` inputs are reset when the field binding changes
* Refactor test for `disabledReasons` input to be consistent with other control
properties
* Test that `disabledReasons` inputs are reset when the field binding changes
* Allow custom controls to make `dirty` a required input
* Refactor test for `dirty` input to be consistent with other control
properties
* Test that `dirty` inputs are reset when the field binding changes
* Refactor test for `invalid` input to be consistent with other control
properties
* Test that `invalid` inputs are reset when the field binding changes
* Allow custom controls to make `hidden` a required input
* Refactor test for `hidden` input to be consistent with other control
properties
* Test that `hidden` inputs are reset when the field binding changes
* Recognize directives with non signal-based models as valid custom controls
* Relax type checker to allow non signal-based models
The `FormValueControl` and `FormCheckboxControl` interfaces still
require a `model()`-input, however, a custom control need not implement
either interface to be bound by the `Field` directive.
All of the following examples can be used to define a custom control:
```ts
// Preferred: model()
class MyFormControl implements FormValueControl<string> {
readonly value: model.required<string>();
}
// Supported: input() + output()
class MyFormControl {
readonly value: input.required<string>();
readonly valueChange: output<string>();
}
// Supported: @Input() + @Output()
class MyFormControl {
@Input({required: true}) value!: string;
@Output() valueChange: new EventEmitter<string>();
}
```
The latter two may still choose to implement `FormUiControl` for other
properties, but again it is not required.
Fix#65478
Change the order of precedence that `[field]` binds to from
1. Custom control (`FormValueControl`, `FormCheckboxControl`)
2. Interop control (`ControlValueAccessor`)
3. Native control (`<input>`, `<select>`, `<textarea>`)
to
1. Interop control (`ControlValueAccessor`)
2. Custom control (`FormValueControl`, `FormCheckboxControl`)
3. Native control (`<input>`, `<select>`, `<textarea>`)
This ensures that Reactive Forms controls authored to use
`ControlValueAccessor` work correctly with Signal Forms, even if they
happen to conform to the `FormValueControl` interface.
Adds new runtime sanitization error codes. Adds `ngDevMode` guards around
error message strings to ensure detailed diagnostics are included only
in development mode. This allows production builds to tree-shake verbose error descriptions, reducing bundle size.
This commit adds a utility method to debug why the application has not stabilized after
a set period of time (9 seconds, or `hydrationTimeout-1`).
fixes#52912
If the computed's `toString` is called and `node.value` is a Symbol, the browser will throw an exception `ERROR TypeError: Cannot convert a Symbol value to a string`
Symbols cannot be implicitly changed to strings. This change changes the conversion to be explicit by wrapping `node.value` with `String()`
This can be reproduced if you create a computed with `createComputed(computation, equal)` and call `toString()` while `node.value` is something like `Symbol(UNSET)`
This change omits treating `{{ }}` interpolation syntax as valid inside `@let` binding strings, preventing the interpolation curly braces from superseding the match of the surrounding binding expression and ensuring the highlighter reflects the correct semantics of `@let` bindings.
fixes#61643
The `RESPONSE_INIT` token previously used `ResponseInit`. However, `@types/node` (and `undici`) definitions for `ResponseInit` mark properties as `readonly`, which differs from the standard DOM `ResponseInit`.
This commit introduces a `ResponseInit` type that explicitly removes `readonly` modifiers to ensure compatibility and allow for mutable options. This type is now used by the `RESPONSE_INIT` token and is exported from `@angular/core`.
If the computed's `toString` is called and `node.value` is a Symbol, the browser will throw an exception `ERROR TypeError: Cannot convert a Symbol value to a string`
Symbols cannot be implicitly changed to strings. This change changes the conversion to be explicit by wrapping `node.value` with `String()`
This can be reproduced if you create a computed with `createComputed(computation, equal)` and call `toString()` while `node.value` is something like `Symbol(UNSET)`
Previously, Angular would switch from the macrotask to a microtask
scheduler _only_ when the scheduler was the trigger for the
synchronization. This microtask scheduling is to ensure patterns such as
`Promise.resolve().then(() => updateAppStateAgain())` _during_
synchronization are caught and synchronized again within the same event
loop (guaranteeing that they aren't split across multiple browser paints).
The microtask scheduler should be used after any tick, not just from
those than run within the scheduler to always account for the promises
within synchronization. This is encountered most frequently during
bootstrap, which triggers the tick directly.
In this change we exempt `TestBed.tick` and
`ComponentFixture.detectChanges` from this behavior. Doing so would affect
the timing of stability and tests are quite sensitive to this (e.g.
`fixture.whenStable`). It is somewhat unfortunate that we have "special" test-only
behavior. However, it is important to acknowledge that this only affects
the test-only APIs as well. Any code in the application under test that
triggers `ApplicationRef.tick` directly would still use the microtask
scheduling behavior.
fixes#65444
The` platformIsServer` flag is no longer referenced by the renderer and is effectively unused.
Removing it simplifies the implementation and avoids carrying redundant state.
The removed target was not used and was generating an empty output which causes `java.io.IOException: mandatory output packages/localize/init/localize_docs_html was not created`
Replaces custom docs-code components with fenced ```json``` blocks for
CLI builder examples, improving readability, consistency, and copy
support across the documentation.
Fixes#66060
- Stop indefinite `detectAngular` messages after the backend is installed.
- Do not attempt handshake with the BE (from content scripts) until it's installed.
Updates signal forms to pass the full `Field` directive to the class
configuration functions, rather than just the state. This allows
developers to take the element as well as the state into consideration
when deciding classes to apply.
Closes#65762
BREAKING CHANGE: The shape of `SignalFormsConfig.classes` has changed
Previously each function in the `classes` map took a `FieldState`. Now
it takes a `Field` directive.
For example if you previously had:
```
provideSignalFormsConfig({
classes: {
'my-valid': (state) => state.valid()
}
})
```
You would need to update to:
```
provideSignalFormsConfig({
classes: {
'my-valid': ({state}) => state().valid()
}
})
```
Currently circular references in user code manifest themselves with an error like `Cannot read properties of undefined (reading 'ɵcmp')`. This is a bit cryptic so these changes add an assertion mentioning circular references.
Relates to #65917.
Removed redundant `src/app/` prefixes from <docs-code> headers to make
examples cleaner and easier to read. The full path remains available via
the `path` attribute, so the shortened headers improve clarity without
losing context.
As written, the example rewrote the input value as the user edited it,
causing all kinds of confusing behavior which rendered the input nearly
unusable. While such implementations are possible, they require great
care to manage the cursor position while editing. For the sake of
brevity, this example now only updates the model on `blur` events; once
the user is done editing.
Prevents the deprecation warning that was incorrectly triggered when
defining an InjectionToken with only a `factory`, which correctly
defaults to the `root` scope.
Add aria-hidden="true" to decorative icon elements in the ARIA menu documentation
example to prevent screen readers from announcing both icon names and labels.
This improves the accessibility experience by ensuring only meaningful text
is announced to screen reader users.
Fixes: #65768
We recently allowed users to have a dynamic input `type` with signal forms, but the logic that infers the value type falls back to `string` even though in theory it can be any of the other types.
These changes expand the inferred type to `string | number | boolean | Date | null` if we detect a dynamic `type` binding.
Wrap operationsCounter method calls (recordCreate, recordDestroy, reset)
with ngDevMode guards to ensure they are tree-shaken in production builds.
This aligns with the existing pattern where operationsCounter is only
initialized in development mode, and eliminates unnecessary method call
overhead in production.
The optional chaining (?.) is retained as TypeScript doesn't narrow types
based on ngDevMode checks, but the entire expression will be removed during
production builds.
Ideally this tutorial would have used signals but didn't. That's a bigger change than
we are able to make right now and there are other things we would like
to update at the same time. This fix is a temporary patch to the
existing content until there is time to redo the tutorial and videos
entirely.
fixes#65863
users should use the entry from `upgrade/static`.
DEPRECATED: `VERSION` from `@angular/upgrade` is deprecated. Please use the entry from `@angular/upgrade/static` instead.
This shows a more prominent warning when multiple versions of Angular
are detected in the workspace and we are forced to choose one to use for
the language server. This also logs those versions with their locations
and directs the user to view the output panel.
fixes#65466
This PR makes a number of changes to the metadata API to address design
flaws in the previous API. Some of the changes include:
- Replaces the previous `MetadataKey` and `AggregateMetadataKey` with a
single unified `MetadataKey` that is used for all metadata.
- The new `MetadataKey` is only defined for fields that explicitly set
it in their schema logic
- All metadata now has reducer / aggregate behavior
- The new `MetadataKey` has an option to create a managed key which
wraps the result of its computed aggregate into some other structure
such as a `Resource` or `linkedSignal`
- There are now two APIs to create metadata keys
- `createMetadataKey` for pure computed metadata
- `createManagedMetadataKey` for metadata that manages its computation
internally
Add CSS rule to hide the last empty line in code blocks to prevent displaying
unnecessary empty lines when source files end with a newline character.
The empty line remains in the DOM for proper copy-paste functionality.
This change replaces all remaining occurrences of `typeof ngDevMode !== undefined`
with the correct `typeof ngDevMode !== 'undefined'` form. This aligns the codebase
with JavaScript typeof semantics and maintains consistency with other Angular code.
Replace the 'any' type with ClassDebugInfo for the debugInfo parameter in
stringifyTypeFromDebugInfo function. This removes the TODO comment that was
tracking the need for proper typing without creating circular dependencies.
The change improves type safety while avoiding circular imports since
stringify_utils.ts doesn't export anything that definition.ts imports.
Introduces the new complexity badge in recommendation cards.
The implementation utilizes CSS variables and `color-mix` to efficiently
handle color themes (Basic, Medium, Advanced) and dark mode support.
Closes#65378
Do not call `getSupportedApis` in a prod app since it throws an error due to the absence of `ng`, which prevents the FE from getting the `ngAvailability` message and, respectively, the proper info screen that DevTools cannot be used on a prod app.
This moved the `NG_FORCE_TTY` from individual `ng_web_app` rules to a global Bazel build flag as this is also needed for integration tests that under the hood run `ng serve` .
This commit updates the CONTRIBUTING.md file to provide clearer
guidelines for new contributors, including sections on code style,
testing, and the pull request process.
Adds the ability to hide the copy button on code snippets.
Updates documentation to use the new `hideCopy` option with the new
markdown code fence syntax.
Updates the linkedSignal documentation to specify that it updates its value when the source changes or when any signal referenced in the computation changes, ensuring the description accurately reflects its behavior.
Convert the `TreeVisualizer` to a signal, in the `TreeVisualizerComponent`, to ensure that the router tree render effect is always called; Use explicit `afterNextRender` phases.
There is a bug (?) in all browsers where the timing of the entry change
is delayed when a navigation is initiated by a click on a link via user
interaction. In this case, we need to ensure we do a 'push' navigation
rather than a 'replace'.
Programatically doing element.click() does not reproduce
this behavior, so adding a test for this is difficult (would require
webdriver).
Previously, navigating a `FieldTree` in signal forms involved reactive reads
of the value of the parent field(s), both directly and via `.childrenMap()`.
This meant that on _any_ change to the value of a field, reactive
notifications would trigger updates of computeds, reruns of effects, etc.
So for example, this effect would run on every change to the form:
```ts
const f = form(signal({data: 'abc', unrelated: 0}));
effect(() => {
// accessing f.data incurs a dependency on f().value() which changes
// on every change in the whole form
console.log(f.data().value());
});
```
This is deeply counterintuitive and troublesome when attempting to write
effect logic, and also results in `computed`s unnecessarily updating.
This change introduces the concept of a "reader" computed, which memoizes
the access of a field at a given key via the reactive graph. With this, the
same `f.data` access above now depends on the `data` reader in `f` only,
which is effectively a constant computed. As a result, the effect only
reruns on changes to `data`'s value, as intended.
PR Close#65802
Previously, several values were being passed into the creation of
`FieldNodeStructure`s that were only used in the creation of child nodes.
Separately, we also passed a `createChildNode` function which these values
were passed back into.
Instead, this moves the small bit of logic from structure.ts behind the
`createChildNode` callback, which reduces the passing of values back-and-
forth and gives `createChildNode` a much more suitable signature.
PR Close#65802
Move the instructions used to dynamically bind a `Field` directive to a
form control onto the `Field` itself. This way the instructions are only
retained if the app uses the `Field` directive.
PR Close#65599
When registering providers, the DI system assumes that `viewProviders` are registered before plain `providers`. This was reinforced by components always being first in the array of directive matches, only one component being allowed per node and the fact that only components can have `viewProviders`.
This breaks down if there are host directives with `providers` on the component, because they'll execute earlier, throwing off the order of operations.
These changes fix the issue by separating out the resolvers for `viewProviders` and plain `providers` and explicitly running the component's `viewProviders` resolver before any others. This also has the benefit of not attempting to resolve `viewProviders` for directives which are guaranteed not to have them.
Fixes#65724.
Previously, the XSRF interceptor only added the XSRF token to requests with relative URLs.
This commit updates the interceptor to also add the token to requests with absolute URLs, provided they match the current origin.
This commit adds a `.catch()` handler to `transition.finished` from `document.startViewTransition` to prevent unhandled promise rejections. The finished promise can reject with `TimeoutError` or `InvalidStateError` when transitions fail during or after the animation phase.
Based on the Blink source code, the `finished` promise can reject with:
* `TimeoutError`: "Transition was aborted because of timeout in DOM update"
* `InvalidStateError`: "Transition was aborted because of invalid state"
This may happen when the DOM update phase exceeds the browser's internal timeout threshold.
Previously we extracted the regions and only made the visible region visible on the page, but since there is not a need for the
non-visible code to be presented, we don't need to include it in the generated code snippets.
This adds additional tests following the initial implementation in #64737 that cover
the use-case of path parameters before and after the wildcard segment.
Unnecessarily aborting traversal navigations will break focus and scroll
restoration. We need to keep them open rather than replacing them with
an identical router-initiated navigation.
The end of the Router navigation is a block of synchronous logic that
can be compressed into a single operator rather than splitting it across
several, making it harder to step through. The only benefit from the
split is automatic unsubscribe/cancellation, which we can replicate
with an additional 'shouldContinue' check before proceeding.
Currently when the signal debug name transform sees something like `const foo = signal(0);`, it transforms the signal into `signal(0, {...(ngDevMode ? { debugName: 'foo' } : {})})`. After minification this becomes `signal(0, {})` which will allocate memory for the empty object literal.
These changes rework the logic to produce `signal(0, ...(ngDevMode ? [{ debugName: 'foo' }] : []))` which will be fully tree shaken away to `signal(0)`.
In the case that a component injector is destroyed before the animation
queue runs, the animation queue would fail to run because it was using a
destroyed injector. This commit changes the animation queue to run in the
context of the EnvironmentInjector, which is not destroyed until the app
is destroyed.
fixes: #65628
This is necessary to exclude a race condition where the MutationObserver initialized by the instruction fired before the inputs are binded.
fixes#65678
Move the header id tracking into the renderer context rather than a global state. Since the RendererContext is
initialized for each execution of the marked parser, we can store the context of which header ids have been seen within
a single page there which allows us to run these parse interactions in parallel.
Rather than manually calling the transformer we use for headings from within a render function, we now properly call into the Renderer to do them
via the tokens they are require instead. This is being done to allow us to have a per Renderer instance of state instead of a global state, which will
allow us to run marked async and hopefully speed up the pipeline
Replaced plain code-form usage of `inject` with a link to the
API docs (`/api/core/inject`) to improve navigation and
help readers access detailed reference information more easily.
Updated various template examples to use self-closing component tags
(e.g., `<my-comp />`) instead of the expanded form (`<my-comp></my-comp>`),
improving consistency across the documentation and aligning with current
Angular style recommendations.
Improves the symbol linking logic to handle Angular component selectors (e.g., ngCombobox). It attempts to convert Angular selector patterns to their corresponding class names, improving navigation to Angular API documentation.
Add Cmd+S/Ctrl+S keyboard shortcut to the adev code editor that prevents
the annoying browser save dialog from appearing. The shortcut is a no-op
since the editor already has auto-save functionality that persists changes
after 500ms of inactivity.
This commit implements a security fix to prevent XSS vulnerabilities where SVG animation elements (`<animate>`, `<set>`, etc.) could be used to modify the `href` or `xlink:href` attributes of other elements to `javascript:` URLs.
When signals throw errors on read, the devtools will show the same error message as the signal custom formatter.
We also don't log errors anymore to the console as those might be surprising to see as errors and are buggy behavior of the devtools.
Add test coverage for bundling dynamic component creation API like
`createComponent()` and `inputBinding()`. This will be used to test that
Signal Forms related features for #64632 can be tree-shaken when unused.
The XSRF interceptor previously failed to detect protocol-relative URLs (starting with `//`) as absolute URLs. This allowed requests to such URLs to include the XSRF token, potentially leaking it to external domains.
This change updates the interceptor to correctly identify protocol-relative URLs as absolute and exclude them from receiving the XSRF token.
Adds a mark for signal forms so we can track adoption. Also moves the call for `@let` into `declareLet` since we don't need it to fire as often as in `storeLet`.
This ensures that the right document is used and that `CSP_NONCE` can be used in `provideAppInitializer` and `provideEnvironmentInitializer`.
Closes#65624
Escape @-prefixed template control flow constructs during doc extraction so JSDoc parsing keeps description text intact. Add regression coverage for @for snippets.
Adds a DI configuration option for signal forms that allows the
developer to specify CSS classes that should be automatically added
by the `Field` directive based on the field's status.
The analytics tracking example contained unused and missing imports,
and it incorrectly referenced the page's URL.
This update fixes the imports and ensures the handler uses `event.url`,
allowing the example to work correctly.
We track all effects that are created for debugging purposes in the `resolverToEffects` map. This ends up leaking memory for effects registered on long-living resolvers (e.g. on the root injector), because they stay in the array, even if the effect itself has been destroyed.
These changes add a callback to clean up the references.
Fixes#65265.
Support binding `[field]` to directives that implement
`FormValueControl` or `FormCheckboxControl`.
The `[field]` binds to whichever directive (or component) matches first in the
event there are multiple implementations. We are considering whether to make
this an error state, which could be reported during type checking.
Closes#63910, Closes#64992
Migrate docs-alert to be inline instead of block, this ensures that the content is placed within a <p> tag as expected. This is important
for ensuring that the iconography is placed correctly within the wrapper div generated for the alert. Additionally, we refactor the matcher
code to be more efficient, running with fewer loops.
Currently when we detect a `field` binding on a native element, we treat it as a built-in native control. This might not be the case if it's a pre-existing `ControlValueAccessor` relying on the CVA interop.
These changes try to detect any CVA-like directive on the element and disable the additional type checking if there are any.
Fixes#65468.
the common-to-standalone migration only matched [ngTemplateOutlet] and
[ngComponentOutlet] bindings and missed their structural forms
(*ngTemplateOutlet and *ngComponentOutlet). This caused missing imports
when removing CommonModule. This change adds structural directive
patterns so the migration correctly identifies needed imports.
Ensures the example viewer header displays correctly by keeping the "Show code"
button aligned to the right and preventing metadata text from wrapping.
Improves layout consistency across documentation examples.
This commit updates the release script to support cherry-picking changelog updates to the main branch when releasing from a patch branch. It also introduces a marker in the changelog to separate releases and ensures the GitHub release uses the formatted changelog from disk.
Replace absolute URLs (https://angular.dev/...) with relative URLs
(/...) to prevent internal documentation links from being treated
as external links and opening in new tabs.
The example incorrectly persisted the error message after a successful
navigation retry because the stream only emitted NavigationError events.
This update removes the filter and returns an empty string for non-error
events, allowing the signal to clear the message on normal navigation.
Replaced <docs-code language="json" header=".postcssrc.json"> with fenced
JSON code blocks using ```json {header: '.postcssrc.json'} for improved
readability and consistency across documentation.
Rather than using multiple view modes for code examples, we can just treat the previous snippet mode as
as multifile mode that just only has one file in it.
Update the strictInputAccessModifiers documentation to clarify that:
- The flag applies to both @Input() decorator and input() signal-based inputs
- The checking only applies to inputs, not outputs
- format interface with fenced block
Fixes docs part of #65243
Updates syntax highlighting rules to properly handle inline templates defined within decorators, improving readability and consistency in code examples
Standalone components are now the default, so explicitly specifying
`standalone: true` is no longer required. Updated relevant documentation
examples to avoid redundant configuration and keep the guides concise.
Ignore files that fail fs.exists() rather than throw ENOENT. Some applications deliberately create "broken" symbolic links that are not relevant to compilation (e.g. emacs lock files that link to owner "user@host").
Adds the missing ARIA usage patterns and links to the relevant API reference
sections to improve accessibility guidance and ensure examples follow recommended
best practices.
Previously, the Algolia index name was hardcoded in the configuration, requiring manual updates for every new major release branch.
This commit automates the index name selection by deriving the version directly @angular/core. It dynamically assigns:
- `angular_next_dev` for pre-releases (`-next`, `-rc`) and local snapshots (`0.0.0`).
- `angular_vXX` (e.g., `angular_v19`) for stable releases.
This commit updates the Tailwind CSS integration guide (`adev/src/content/guide/tailwind.md`) to introduce `ng add tailwindcss` as the primary, automated method for integrating Tailwind CSS.
Although the prior commit has made more profiler events guaranteed symmetric
through the use of finally-blocks, there continue to be some situations
that could potentially result in asymmetric events, e.g. application
bootstrap doesn't guarantee symmetric events. This commit makes the profiler
lenient to these situations by unrolling the stack past the asymmetric event
data, eventually reaching the expected start event.
Profiler events are expected to be symmetric, yet in the case of errors this symmetry may break
if events aren't always kept in sync with their corresponding start event. This commit moves
various end events to be run from a finally-block, allowing them to notify the profiler even
when an error has occurred.
Fixes#62947
This commit adds the `translate="no"` attribute to the icon elements to ensure they are preserved in their original form and not modified by translation tools.
Closes#65406
This commit moves documentation for Zone.js-dependent testing utilities
(`waitForAsync`, `fakeAsync`, `tick`, `discardPeriodicTasks`, `flushMicrotasks`)
from `testing/utility-apis.md` to a new dedicated guide:
`testing/zone-js-testing-utilities.md`.
The `getControlDirective` is called multiple times, both at init and during each update run. Under the hood it performs a linear search for the `Field` directive.
We can speed this up by finding its index once and reusing it since the array of directive matches is static.
This commit introduces several improvements to the release process:
- Adds a clear warning and instructions to test the extension before merging the release PR
- Removes the explicit `vsce login` command.
Adds a parallel example for style bindings alongside the existing class binding example, demonstrating the preferred syntax of [style.property] and [style] over [ngStyle] directive.
Force adev and devapp to run in non-TTY mode so it doesn't create a prompt that can't be interacted with. This will initially have no effect,
but the fix is expected to land in CLI to make this work as expected in the next few days.
Show the signal graph button only when a signal-graph-eligible node from the directive explorer is selected; Fix client app error when a `defer` node is selected (related)
Following https://github.com/angular/angular/pull/64509 we started
choking on unbalanced closing parentheses in declaration blocks,
specifically in quoted background-image urls. This was reported in
https://github.com/angular/angular/issues/65137.
This occured because we previously (and now again) traverse the entire
declaration block when selecting for :host-context() selectors to shim.
This is an oddity of how we parse styles today, and is likely something
we'd want to remove if we parsed selectors properly.
This change adds a new flag to _splitOnTopLevelCommas which allows it to
continue past unbalanced closing parentheses in the declaration block,
returning _convertColonHostContext to its previous behavior while
keeping support for the extra nesting in :host-context().
We didn't get much report on the feature itself so we feel confident about promoting it to stable. In parallel we'll also land #62959 but one is not blocking the other.
fixes#64996
It can be useful for a developer to set `NaN` as the value for a number
input, as a way to say "clear the input". However, directly setting this
value to the `.valueAsNumber` causes a console warning. This PR fixes
the console warning by just doing `.value = ''` when we would otherwise
to `.valueAsNumber = NaN`
An early piece of feedback received regarding custom controls hosted on
native inputs was that they required a lot of boilerplate to bind
`FieldState` properties. Each property required an input to accept the
property, and a host binding to forward it to the native control.
Although the prior commit has made more profiler events guaranteed symmetric
through the use of finally-blocks, there continue to be some situations
that could potentially result in asymmetric events, e.g. application
bootstrap doesn't guarantee symmetric events. This commit makes the profiler
lenient to these situations by unrolling the stack past the asymmetric event
data, eventually reaching the expected start event.
Profiler events are expected to be symmetric, yet in the case of errors this symmetry may break
if events aren't always kept in sync with their corresponding start event. This commit moves
various end events to be run from a finally-block, allowing them to notify the profiler even
when an error has occurred.
Fixes#62947
Updated shell command examples to use fenced code blocks (```shell) instead of <docs-code> components, improving formatting consistency and aligning with current documentation standards.
Updated bash command examples to use fenced code blocks (```bash) instead of <docs-code> components, improving formatting consistency and aligning with current documentation standards.
- Removed unused code and imports
- Migrated to signal-based input() APIs
- Added readonly to Angular-initialized inputs and removed explicit type annotations
- Updated templates to use self-closing tags for consistency
* Apply any debounce rules to updates from interop controls (if configured).
* Add tests to ensure debouncing works for all control types (native, custom,
and interop).
Updated shell command examples to use fenced code blocks (```shell) instead of components, improving formatting consistency and aligning with current documentation standards.
- Replaced <a><button></button></a> with a proper <a> containing text and
aria-label to ensure links have discernible text.
- Added main tag in home page to provide
a consistent main landmark, improving accessibility for screen readers
and satisfying WCAG and Lighthouse requirements.
Fixes#65181.
Code blocks with `bash` language identifier were not rendering the `$`
prefix, while `shell` blocks did.
This ensures consistent command-line prompt rendering across both
`bash` and `shell` code blocks in the documentation.
This commit updates the testing documentation to include `bun` as a package manager option in all relevant code examples.
Additionally, it standardizes the presentation of package manager commands by:
- Consistently using a multi-tab format (`<docs-code-multifile>`).
- Enforcing a consistent order: `npm`, `yarn`, `pnpm`, `bun`.
These changes improve the user experience by providing clear instructions for multiple package managers and ensuring consistency across the testing guides.
This commit updates the unit testing, code coverage, and debugging guides to align with the Vitest test runner, which is now the default for new Angular CLI projects.
Key changes include:
- **Unit Testing Overview**: Revised to focus on Vitest, including details on DOM emulation (jsdom/happy-dom), browser testing setup, and custom Vitest configuration via `runnerConfig`. A prominent note links to the Karma-to-Vitest migration guide.
- **Code Coverage**: Updated to reflect Vitest-specific prerequisites (`@vitest/coverage-v8`), command-line flags, and `angular.json` configuration for coverage reporting and threshold enforcement.
- **Debugging**: Completely rewritten to provide instructions for debugging Vitest tests in both Node.js and browser environments using the `--debug` flag.
- **Navigation Reordering**: The 'Testing' section in `sub-navigation-data.ts` has been reordered to present a more logical educational flow, starting with core concepts and progressing to advanced topics and migration.
The example viewer has some `::ng-deep` styles that are used to reset global styles that leak into the live examples. It works by applying a style like `.docs-example-viewer-preview * {all: revert;}`.
The problem with this is that depending on when the first example is rendered, the styles will be lower or higher in the cascade, thus making the reset unreliable. Furthermore, it can affect structural styles from the CDK which intentionally have low specificity.
These changes move the resets into the global stylesheet to make them more predictable.
Removed redundant "src/app/" prefix from file headers (e.g.,
"src/app/open-close.component.ts" → "open-close.component.ts")
to make code examples cleaner and more focused.
This commit updates the elements and tailwind guides to use the standardized `docs-code-multifile` format for package manager commands. This change introduces `yarn`, `pnpm`, and `bun` alternatives to the existing `npm` commands, providing a consistent experience for users across different package managers.
If we're calling `min` on a path that's guaranteed to be `number` we
don't want to make the users validator function handle the `null` or
`string` cases.
This uncovered an issue in the `SchemaTreePath` type which needed to be
fixed by preventing the model type from being distributed over.
PR Close#65212
Relaxes the constraints on which paths can be used with the `min` &
`max` validation rules, since people may want to validate a
potentially-null number, or a numeric value represented as a string
PR Close#65212
Refactors the logic that disables the action button for lazy-loaded routes.
Now relies on the isLazy property from the route data instead of string comparisons on the component field.
The `type_check_block.ts` file was getting quite large and difficult to navigate. These changes split up the different pieces of functionality into separate files.
Test that a component with a bound `[field]` input is not treated as a
control, and that `fieldBinding` does not include the corresponding
`Field` instance.
This PR fixes a parameter mismatch in the `apiClientFactory` function documentation example. The factory was previously passing only http and `userService` to the ``ApiClient`` constructor, but the constructor actually requires http, `baseUrl`, and `rateLimitMs` as separate parameters.
Key Changes:
Extracts baseUrl and rateLimitMs from UserService using getter methods
Updates the ApiClient instantiation to pass all three required constructor parameters
Adds a comment explaining the assumption about UserService providing these values
The regex for caching generated files in firebase.json has been updated to
include lowercase letters and underscores in the 8-character hash. This
ensures that files with names like `chunk-CrXHmw_W.js` are correctly
cached.
Add an `AbortSignal` parameter to `Debouncer`. Implementations may
choose to accept this parameter to be informed when a debounced
operation is aborted. This may be useful for canceling pending timers or
avoiding unnecessary work.
Replaced the <docs-code> wrapper with a Markdown fenced code block to improve
copy/paste usability, syntax highlighting consistency, and alignment with current
documentation formatting standards.
Inspired by #65043
Replaced the <docs-code> wrapper with a Markdown fenced code block to improve
copy/paste usability, syntax highlighting consistency, and alignment with current
documentation formatting standards.
Inspired by angular#65043
This commit introduces a new guide for migrating existing Angular projects from Karma/Jasmine to Vitest.
The guide covers:
- Manual steps for installing dependencies and updating `angular.json`.
- Handling custom `karma.conf.js` configurations.
- Removing Karma-related files and packages.
- Configuring browser mode for Vitest.
- Details on the `refactor-jasmine-vitest` schematic for automated test refactoring.
The guide also clarifies that while Vitest is the default for new projects, migration for existing projects is experimental. It emphasizes reviewing changes and provides guidance on adapting custom Karma configurations to Vitest.
Renames `experimental-unit-test.md` to `migrating-to-vitest.md` and updates `sub-navigation-data.ts` accordingly.
Reworks the way we approach type checking of signal forms to be closer to the behavior at runtime. There are a couple of scenarios that we handle:
1. For native controls, we now produce simplified type checking code that looks as follows:
```
var t1 = null! as number | string; // Type depends on the input `type`.
t1 = someField().value();
```
2. For custom controls we generate bindings to the individual inputs, rather than checking conformance against `FormValueControl`/`FormCheckboxControl`. This is closer to the behavior at runtime and it allows us to handle generic directives properly.
This change configures pnpm to allow any version of `@angular/*` packages to satisfy peer dependencies. This is necessary because `@angular/*` packages are managed within this monorepo, and this rule prevents issues with peer dependency resolution when different versions might be present during development or testing.
Refactor .pnpmfile.cjs to use a Set for localAngularPackages for better performance.
Adjust typescript dependency handling in compiler-cli to correctly use devDependencies.
Promote rxjs and zone.js from peer dependencies to regular dependencies for local packages.
These changes streamline dependency resolution and align with pnpm's behavior for workspace dependencies.
:nth-child() (and its siblings) support complex expressions, e.g.
`:nth-child(2n of :is(.foo, .bar))`. Previously we'd choke because of
the `:is()`. Now, we reuse the `_parenSuffix` subexpression to match
nested parentheses the same way we do for :host() and :host-context().
Note that we only support 3 levels of nesting, so a selector like
`:nth-child(n of :is(:has(:not(.foo))))` will still break.
I'll say yet again that we really should add a proper parser so we stop
getting bug reports like this :)
Fixes#64913
Refactor to use async/await for clearer asynchronous operations and enhanced error handling.
Simplify resource caching and streamline the resolution of component templates and styles.
Update in the router to align with the new async resource resolution.
The `debounce()` rule allows developers to control when changes to a
form control are synchronized to the form model.
This feature necessitated some changes to `FieldState`:
* `controlValue` is a new signal property that represents the current
value of a form field as it appears in its corresponding control.
* `value` conceptually remains unchanged; however, its value may lag
behind that of `controlValue` if a `debounce()` rule is applied.
The `debounce()` rule essentially manages when changes to `controlValue` are
synchronized to `value`. The intent is that an expensive or slow
validation rule can react to the debounced `value`, rather than a more
frequently changing `controlValue`.
Directly updating `value` immediately updates `controlValue`, and cancels any
pending debounced updates.
When multiple `debounce()` rules are applied to the same field, the last
currently active rule is used to debounce an update. These rules are
applied to child fields as well, unless they override them with their
own rule.
This removes the need to specify type arguments for
`reducedMetadataKey()` when the value returned from the `getIntial`
callback is a subtype of the accumulated type.
The flag `skipFormatting` got renamed to `ngSkipFormatting` during review of https://github.com/angular/angular/pull/64000, but a couple usages got missed, causing some unfortunate UI recursion.
The `fullInheritane` flag from the metadata and the `CopyDefinitionFeature` that it controls appear to no longer be used since `fullInheritance` is always false. The feature appears to have been there to support ngcc which was removed some time ago.
This is necessary to use SSR safely with `createApplication` and avoid constraining users to `bootstrapApplication`. It is one more step towards feature parity between `createApplication` and `bootstrapApplication`.
Prior to this commit, attempting to resolve a `ChangeDetectorRef` after views or app have been destroyed would result in an error. In this commit, we clean up listeners once the view is destroyed, before the placeholder loads or fails to load.
Wraps InjectionToken names with `typeof ngDevMode !== 'undefined' && ngDevMode`
checks to enable tree-shaking of descriptive token names in production builds.
This ensures debug-only strings are removed from production bundles, reducing size.
Also removes unused imports found during refactor.
Annotate the `new Version(...)` call with `/* @__PURE__ */` to signal to optimizers that the constructor is side-effect free.
Without this hint, bundlers such as Terser or ESBuild may conservatively retain the `VERSION` instantiation even when unused. With the annotation, the constant can be tree-shaken away in production builds if not referenced, reducing bundle size.
Replaces the <docs-code> component with standard markdown code fences in the service worker documentation. This improves the readability and maintainability of the documentation.
Replace URL-based active route detection with direct traversal of the ActivatedRoute tree.
This solution is more reliable than the previous approach because it directly compares router tree configuration objects against the active router instance state with router.routerState.
Replace `@Optional() link: RouterLink` constructor parameter with
`link = inject(RouterLink, {optional: true})` to enable tree-shaking
of the `Optional` decorator and its factory scaffolding.
Bundle size reduction: `Optional` is a runtime value created by
`makeParamDecorator()`. Even in production builds, ESBuild and other
bundlers must keep their factory code because it is referenced via
`Optional`. With `inject()`, this class is no longer referenced,
allowing it and the `makeParamDecorator` scaffolding to be tree-shaken
when unused elsewhere.
Note: This updates the constructor signature but should not be
considered a breaking change. Angular's official guidance is that
directives, components, and pipes should be instantiated by the
framework, not by user code. Directly calling `new RouterLinkActive(...)`
is an unsupported pattern that goes against Angular's design principles.
This adds handling of the abort event on the signal of the
`NavigateEvent`, allowing us to cancel the Router's ongoing navigation
transition when its related navigation was aborted.
Added `language="shell"` to installation command examples to display
the shell prompt `$` icon consistently across npm, pnpm, yarn, and bun
code blocks.
Removed redundant "src/app/" prefix from file headers (e.g.,
"src/app/open-close.component.ts" → "open-close.component.ts")
to make code examples cleaner and more focused.
I took a quick look at my recent changes to see if I had inadvertently
fixed this bug, but I couldn't seem to reproduce it even before my
changes. Seems like it's working, though.
Closes#58436
`new RegExp()` with computed strings can't be analyzed statically. The bundler can't prove the template string evaluation has no side effects; as thus this expression is considered a side-effect.
Remove an unnecessary TODO comment. The native `<select>` tracks its
`value` by keeping track of the selected `<option>`. Thus if the value
was set *before* the corresponding option is created, the `<select>`
will ignore it, but the framework doesn't know that and will cache the
bound value anyways. Therefore, checking if the value changed since it
was last bound when the mutation that creates the selected `<option>`
occurs would in fact prevent a needed update, leaving the `<select>` and
field values out of sync.
Furthermore, we know the control type is a native `<select>` element, so
we can update its value directly instead of going through
`updateNativeControl()` which would perform a redundant input type
check.
\#64806 drops the `href` part of `SamePageMessageBus` URIs. This creates a conflict, which breaks the directive explorer, between the prod Devtools (i.e. the extension) and the dev Devtools app due to the backend URIs using the same string for both prod and dev.
This adds a handler to the `NavigationInterceptOptions` when we are
intercepting a `NavigateEvent`. This means that the scroll and focus
restoration will be delayed until the handler promise resolves. It also
means that we can provide better indication of an ongoing navigation
event.
https://github.com/angular/angular/pull/64590 implemented change
detection for field bindings, but only for those bound to native or
custom form controls. This change extends that optimization to apply to
field bindings on interoperable controls built using Reactive Forms as well.
Currently the logic for detecting `Field` directives only works if it's imported from `@angular/forms/signals` which doesn't cover our own tests.
These changes make the check more robust.
Adds some logic that won't report the `value` or `checked` inputs as missing when the `Field` directive is present since it will bind to the inputs implicitly.
Switches to checking against `FormValueControl<any>` instead of `FormValueControl<unknown>` when checking whether custom controls conform to the interface.
Fixes#64946.
This addresses a potential memory leak in plugin-factory.ts.
The require call inside the create function reloads the entire language
service module for every new project, which is inefficient and could be a cause of the memory leak during branch
switching. This ensures the module is loaded only once and the same
instance is shared across all projects.
The file is no longer included in the VSCode extension package.
This change updates the golden file and the file to reflect this exclusion.
PR Close#64991
This commit introduces a golden file test to verify the contents of the VSCode extension package.
The test ensures that the list of files included in the extension package remains consistent.
A new Bazel rule is added to generate the list of files, and is used to compare it against the golden file. A helper script is also added to facilitate the generation of the golden file.
PR Close#64991
This change adds support for commas in :host() arguments (e.g.
`:host(:not(.foo, .bar))` as well as in nested parens when the argument
is applied without parens (e.g. `:host:not(:has(.foo, .bar))`).
Previously these selectors would receive an extra `[nghost]` attr, e.g.
`[nghost]:not(.foo, [nghost].bar)`.
I didn't file a bug for this one, but it's also blocking on an internal
LSC. Like the other CSS changes, I'll run a TGP to confirm this isn't
breaking.
Replaced multiple component tags such as `<example></example>` with
self-closing syntax (`<example />`) across documentation examples.
This improves readability and aligns with the current Angular
style conventions.
The current section `Services with dependencies` within the testing services
guide is non-functional and has been removed. The example service is using
`inject` but the test code is using constructor-based injection. The further
sections discuss the use of TestBed to adjust providers which better handles
these cases.
This makes it easier to debug in production by including sourcemaps unconditionally. It also processes vendor sourcemaps (which includes Angular FW in this setup) and should improve debuggability of FW code by including sourcemap coverage.
This commit updates the testing documentation to reflect the introduction of Vitest as the default test runner, while ensuring Karma testing instructions are still available.
Key changes include:
- Adding a new guide for "Testing with Karma" (`guide/testing/karma.md`).
- Updating the "Code Coverage" guide (`guide/testing/code-coverage.md`) to use `angular.json` for coverage enforcement and referencing Vitest documentation.
- Modifying the "Testing Overview" guide (`guide/testing/overview.md`) to introduce Vitest as the default, update `ng test` output examples, and link to the new Karma guide.
- Updating navigation data to include the new Karma testing guide.
By intersecting with `object` instead of `unknown` in the primitive and
`FormControl` cases, we get TypeScript to show nicer type errors that
mention `FieldTree<...>` insetad of `() => FieldState<...>`
* Define `ResourceSnapshot<T>` as a type union of possible states for a
`Resource<T>`.
* Add `Resource.snapshot()` to convert a `Resource` to a signal of its
snapshot.
* Add `resourceFromSnapshots` to convert a reactive snapshot back into a
`Resource`.
By converting resources from/to `Signal<ResourceSnapshot>`s, full
composition of resources is now possible on top of signal composition APIs
like `computed` and `linkedSignal`.
For example, a common feature request is to have a `Resource` which retains
its value when its reactive source (params) changes. This can now be built
as a utility, leveraging `linkedSignal`'s previous value capability:
```ts
function withPreviousValue<T>(input: Resource<T>): Resource<T> {
const derived = linkedSignal({
source: input.snapshot,
computation: (snap, previous) => {
if (snap.status === 'loading' && previous?.value) {
// When the input resource enters loading state, we keep the value
// from its previous state, if any.
return {status: 'loading', value: previous.value.value};
}
// Otherwise we simply forward the state of the input resource.
return snap;
},
});
return resourceFromSnapshots(derived);
}
// In application code:
userId = input.required<number>();
user = withPreviousValue(httpResource(() => `/user/{this.userId()}`));
// if `userId()` switches, `user.value()` will keep the old value until
// the new one is ready!
```
Currently we maintain the pathKeys internally, but do not expose them
through the `FieldContext`, this PR updates the `FieldContext` to expose
this property.
Previously we supported one level of nested parentheses inside of a
`:host()` selector, e.g. `:host(:not(p))`. This caused a breakage in g3
when I migrated a selector from `:host:not(:has(p))` to
`:host(:not(:has(p)))`. This change adds support for just one more level
of nesting.
It'd be nice to move everything to a real CSS parser (or even update it
to count parentheses like I did with :host-context()), but I wasn't able
to get that to work in ~20 minutes and I'm focusing on other things at
the moment.
This change punts the problem until somebody tries to use just one more
level of nesting in a selector.
Fixes#64830
This commit improves the release process for the vscode-ng-language-service by adding automated changelog generation and updating the package.json version.
This further builds out the Router integration with the platform
Navigation API. Key features in this state include:
* History restoration via direct platform APIs rather than markers left on
`history.state`. This means more guaranteed correctness and less
internal code to compute traversal restorations.
* Ability to observe navigations triggered outside the Router APIs.
Practically speaking, this means some navigations can be performed
through the platform rather than requiring `Router.navigate`. Note
that because the `NavigateEvent` is never intercepted at this point of
the implementation, regular anchor tags cannot be used because they
will still trigger a popstate navigation.
This implementation does _not_ intercept the `NavigateEvent` but future
iterations should. By omitting the interception, we are missing out on
features such as:
* Platform-supported scroll and focus reset
* Holding the navigate event open for the duration of the router
navigation, allowing for a visual loading indicator in the browser
* Support for intercepting navigations from regular anchor tags (e.g.
not `RouterLink`s) and converting those to SPA navigations.
PR Close#64905
When we set the `value` on a `<select>` element we're really just
setting the selected `<option>`. It treats the selected option as the
source of truth, rather than the actual value. This means that if
options are added or removed or their value changes, the `<select>` may
wind up with a different `value` than what's in our model.
This PR resolves this issue by adding a `MutationObserver` to the select
that is used to resync its value to the model whenever the options may
have changed.
Update the diff relase package script to properly recursively apply the chmod and support a flag for writing the
diff to a file instead of only logging it to the console.
This script orchestrates the release process for the Angular Language Service VSCode extension. It handles versioning, changelog generation, building, and publishing the extension.
Long code blocks overflow the headings on narrow screen (like mobiles), this messes up the global layout of the page. With the ellipsis with fix that.
fixes#64845
We accounted for skipping leave animations during moves, but not swaps.
This accounts for the swap cases and updates how we deal with swaps and
moves. Now we always queue animations and then essentially dequeue them
if we attach them back in the same render pass.
fixes: #64818fixes: #64730
For each field state property, check if it has changed since the last
time it was checked before writing it the corresponding form control
property.
The `pattern` and `required` properties of the field state now return a
default value rather than `undefined` if not defined by metadata.
In https://github.com/angular/angular/pull/64745, a fix was introduced for templates referenced with a trailing semicolon. However, templates are still incorrectly removed when there are whitespace characters before the template name.
This commit updates the control flow migration logic to ensure templates referenced with preceding whitespace are not removed.
Fixes#64854
We automatically generate the sitemap for the angular.dev deployment and include it in the assets pushed
to firebase.
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
Prior to the change to support defining required segments before and after the wildcard, the meaning of the wildcard
path was '0 or more' so path: foo with a child of ** will still match the ** route when the URL is only 'foo'.
If developers want to _require_ something, they can still use path: foo/:anyRequired/**/bar
Fix the URIs by stripping any query parameters and/or fragments from the compound URLs, since they may prevent the extension from successfully establishing a handshake in some instances.
Removes redundant `standalone: true` declarations from code examples.
Standalone components are now the default in Angular, so the flag is
no longer necessary in documentation snippets.
Adds a new landing page for developer events, starting with the v21 page. It also includes an ICS file link for calendar invites. Also updated the tests for the docs-pill to support two new attributes so developers can add the event to their calendars.
Currently when a required input is missing, we produce a diagnostic on the entire start tag. This can be really noisy if there are already some attributes on the element.
This change switch to only highlighting the tag name instead.
Consolidate separate scripts for updating Aria, CDK, and CLI documentation into a single, unified script. This change streamlines the documentation update process and improves maintainability. The workflow file has been updated to use the new consolidated script.
PR Close#64792
Fixed the import error message in the editor section. The build would complete successfully, but an error message would be incorrectly reported.
PR Close#64701
When a firebase command line execution fails, the github action should be shown as failing instead of continuing to attempt to run and resulting in
an exit code of 0 and success
PR Close#64801
this adds support for both leading and trailing segments before/after wildcard
route. Exposig the segments in a new _splat param would require a
breaking change to the return value of the matchers.
fixes https://github.com/angular/angular/issues/60821
PR Close#64737
isValidUserId = true is logically wrong to use to disable the Save button.
So is logically wrong to use isValidUserId = false to enable the Save button.
Also the default state of this button should be most likely disabled, if we are bothering to check, so the initial value of the signal should most likely be set to true.
To resolve these 2 issues, I propose to use:
- isInValidUserId instead of isValidUserId and:
- isInValidUserId = signal(true); // isValidUserId = signal(false);
After these 2 changes the snippet should make logical sense.
Interfaces with no extends clause were incorrectly rendered with a trailing extends keyword followed by nothing, resulting in invalid TypeScript syntax
The DocViewer component's getCodeSnippetsFromMultifileWrapper method was not
extracting the header attribute from nested <docs-code> elements, causing the
ExampleViewer to fall back to displaying file paths instead of custom headers
in tab labels.
This change adds title extraction from the header attribute when processing
multifile code snippets, ensuring that custom headers are properly displayed
in the code viewer tabs.
Fixes#64760
This commit fixes a behavior where under certain conditions, the migration script ignored
a template reference with a trailing semicolon and incorrectly removed the definition
of a referenced template.
Fixes#64741
In some cases the logic order was not preserved properly when using `apply`. In particular this occurs when some logic is registered on a child of the root, followed by an apply to the root, followed by further logic registered on a child. In this case the final registered logic wound up running before the applied logic.
This happened because `FieldPathNode` for a child path was caching its `LogicNodeBuilder` at creation time. This meant that if the parent's `LogicNodeBuilder` changed (e.g., due to an `apply` call), the child would still be using the old one.
This commit fixes the issue by dynamically resolving the `LogicNodeBuilder` for a child path whenever it is accessed.
This commit changes arrays in a parent array to be tracked the same way
as primitive values like strings and numbers. This is necessary because
the tracking key symbol used to maintain identity for objects in an
array does not survive the array spread operation:
```
return {...oldValue} // tracking symbol preserved ✅
return [...oldValue] // tracking symbol lost ❌
```
- Deletes the old Karma configuration and test entry point.
- Updates `angular.json` to use the `@angular/build` builders.
- Adjusts test files to align with the new setup.
This change updates the rollup configuration for the core schematics to exclude all `@angular/*` packages from the bundle. This is possible following https://github.com/angular/angular/pull/64703
This significantly reduces the size of the `@angular/core` schematics bundle, resulting in a size reduction to 5.8mb.
The navigation list component was using `routerLinkActive` with
`{ exact: true }`, which required an exact URL match including query
parameters. When visiting `/update-guide?v=19.0-20.0&l=1`, the link
`/update-guide` didn't match, so the active class wasn't applied.
Updated `routerLinkActiveOptions` to ignore query parameters while
maintaining exact path matching so the navigation item stays highlighted
when interacting with the update guide form.
Changed terminal output code block in installation.md from shell
language to plain text to prevent rendering of shell prompt ($).
The block displays read-only log output that users should not
execute as commands.
this adds support for both leading and trailing segments before/after wildcard
route. Exposig the segments in a new _splat param would require a
breaking change to the return value of the matchers.
fixes https://github.com/angular/angular/issues/60821
If a component template contains an icu expression it is being retained until the next change detection cycle for that template. This results in a net retention of only ever a single copy of the given lView but that creates an opportunity for compounding leaks.
Change the icu i18n_icu_container_visitor to free the IcuIteratorState retained lView when the stack is empty so that garbage collection can occur when the view is discarded.
Previously we supported one level of nested pseudo-element selectors
inside :host-context(), e.g. :host-context(:is(.foo, .bar)). This was
based on a regex-based approach. We could support deeper levels of
nesting by updating the regex, but using a regex approach prohibits us
from supporting arbitrary nesting.
Rather than just adding one more level to the existing expression, I've
added a new generator function which splits selectors on commas in a
parenthesis-aware way. This allows us to support arbitrary nesting.
It's likely we'll want to reuse this in other places where we're not as
careful today. We'll probably do this on a request-based basis, though.
Fixes#59176
This commit moves the best-practices.md file from adev/src/context to packages/core/resources. The BUILD.bazel files and other configuration files have been updated to reflect this change.
The ExampleViewer component was extracting only innerHTML from code
blocks in multifile examples, which lost the shell class applied by
the formatCode function. This caused the $ prompt to not appear for
shell commands in multifile blocks even when language="shell" was set.
Modified the Snippet interface to track shell language state and
updated getCodeSnippetsFromMultifileWrapper and getStandaloneCodeSnippet
methods to preserve the shell class. Updated example-viewer template
to conditionally apply the shell class to the code wrapper element.
Fixes inconsistency between standalone and multifile shell code blocks.
This commit adds the ability to control the behavior of scrolling in the
`NavigationBehaviorOptions`. The options directly correlate with the
intercept options of the Navigation API `NavigateEvent#intercept`:
https://developer.mozilla.org/en-US/docs/Web/API/NavigateEvent/intercept#scroll
While we do not currently have an integration with the navigation API,
this change would be necessary to provide the ability to configure that behavior
if/when we do. In the meantime, this option is also useful to control
the behavior of scrolling when the in memory scroller is enabled.
resolves#26744
Previously we would look in the DI tree for a token named 'Router' and resolve its value.
Now we use the already existing getRouterInstance, which depends on ng global debug APIs to get the router instance of an application.
Previously '/' could cause confusion with other routes that use a path here. I think because this node is unique in that it is not actually a "Route" we should make it clear with the label that is simply the App Root.
This adds a (private) provider for integrating with the browser Navigation API.
This provider ensures that interactions with the `Location` service
use the underlying platform navigation rather than the history and
location APIs.
This commit moves the best-practices.md file from adev/src/context to packages/core/resources. The BUILD.bazel files and other configuration files have been updated to reflect this change.
This commit enables the 'auto' merge strategy for pull requests.
This strategy automatically determines the best merge method based on the
pull request's commits.
The auto merge strategy can:
- Delegate to the autosquash merge strategy if the PR has fixup/squash
commits against multiple normal commits.
- Squash commits if the PR has only one normal commit and some
fixup/squash commits.
- Rebase commits if the PR has no fixup/squash commits.
This improves the developer experience by automating the merge process. A
key benefit is that PRs that can be cleanly rebased will now appear as
'merged' in GitHub's UI, providing a clearer history than the previous
'unmerged' status that could occur with squashing.
Additionally, `dev-infra` and `bazel` are removed from the exempted scopes
for target labels as they are no longer necessary.
PR Close#64624
The directive implemnetation might set CVA values during the template evaluation. Since the template is a reactive context we need to untrack when setting the CVA values to prevent writing to signals in a reactive context.
fixes#64614
PR Close#64618
This cleans up the navigation transitions a bit by removing some
unnecessary operators. Combining operators makes debugging easier by
making it possible to step through the code.
PR Close#64480
When working with a proxy object such as signal forms' `Field`,
accessing the `lenght` or `Symbol.iterator` may trgger a reactive read.
This change ensures that `@for` properly captrues this before clearing
the active consumer.
PR Close#64113
Renames the field state related to metadata to reflect the new
"metadata" name. In particular:
- `property(...)` is renamed to `metadata(...)`
- `hasProperty(...)` is renamed to `hasMetadata(...)`
PR Close#64603
Renames logic functions related to metadata to align with the new
"metadata" name. Notably:
- `property(...)` => `metadata(...)`
- `aggregateProperty(...)` => `aggregateMetadata(...)`
PR Close#64603
These have been renamed to `MetadataKey` and `AggregateMetadataKey`
respectively. The team consensus is that the term "property" is so
overloaded that it makes the topic difficult to explain & discuss, hence
the rename.
PR Close#64603
Previously, the `DefaultUrlSerializer` would incorrectly parse URLs with a parenthesized outlet that did not have a name, such as `/(left)`. This would result in an `undefined` outlet name in the serialized URL.
This commit fixes the issue by ensuring that parenthesized outlets without a name are treated as primary outlets.
fixes#58516. Based on the description, either the URL was constructed
manually or by custom serializer.
PR Close#64507
test functions
This improves the fakeAsync error message when importing it, describe,
etc from jest
We will not be further expanding the ZoneJS patches to support
additional use-cases.
fixes#47603
PR Close#64497
We were clearing duplicate nodes when `animate.enter` fired fast, but not when solely `animate.leave` is fired and rapid toggles occur. This ensures that the `cancelLeavingNodes` function is called in all cases instead of just enter animations.
fixes: #64581
PR Close#64592
This adds a new compilation error if someone attempts to put legacy animations and `animate.enter` or `animate.leave` in the same component.
PR Close#64569
Fixes a bug in the missingStructuralDirective diagnostic where structural directives with missing imports were not reported when the element using the structural directive contained other directives
Fixes#64467
co-authored-by: Matt Lewis <npm@mattlewis.me>
PR Close#64579
The `requireSynchronousElementRemoval` property was not being passed in all the locations it was needed. This was preventing leave animation timing from behaving properly in some cases.
fixes: #64525
PR Close#64565
Prior to this change, `FieldState` defined a signal for each built-in
property. This unfortunately meant that the `Field` directive had no way
of knowing which property had actually been defined in the schema, and
would thus attempt to propagate them all to the bound form control. This
meant that the default values of these signals would override the
default or template defined values of these control properties.
Now these properties are `undefined` by default, and only initialized if
defined in the schema. Thus the `Field` directive will not attempt to
bind any properties that aren't explicitly managed by the schema.
PR Close#64446
Note that unlike the other built-in properties, `pattern` is not
propagated to native controls so the lack of symmetry with other
property tests is intentional.
PR Close#64446
In certain scenarios `Element.animate` fails, manifesting in an exception (Firefox)
or a null return value (Chromium). The null value is not conform WebIDL but handled
gracefully in this commit regardless.
Closes#64486
PR Close#64506
Updates the selector for `RouterOutlet` to allow for it to be set on an `ng-container`. This allows it to not render the host node which can affect the layout.
Fixes#64553.
PR Close#64562
Previously, query parameters passed to `router.createUrlTree` were simply converted to strings. This meant that any custom serialization logic in a custom `UrlSerializer` was not applied. This could lead to inconsistencies between navigations triggered from the URL bar (which are parsed by the serializer) and navigations triggered programmatically.
This change ensures that query parameters are normalized using the provided `UrlSerializer`. The values are serialized and then parsed to ensure they are in the same format as if they had come from a URL. This allows custom serializers to handle complex objects in query parameters consistently.
Fixes https://github.com/angular/angular/issues/47307
PR Close#64449
Currently it's easy to make a mistake when accessing properties on `SimpleChanges`, because the keys aren't typed. These changes add an optional generic to the interface so that users can get a compilation error if they make a typo.
A few things to note:
1. The generic argument is optional and we revert to the old behavior if one isn't passed for backwards compatibility.
2. All of the keys are optional, because they aren't guaranteed to be present for any `ngOnChanges` invocation.
3. We unwrap the values of input signals to match the behavior at runtime.
Fixes#17560.
PR Close#64535
This change omits the injection of the template syntaxes inside any
existing block scope. The injection is not needed because the template
and expression scopes are included explicitly as patterns where
appropriate under the template-blocks definitions.
This change prevents the interpolation curly braces from superseding the
match for the open curly of the block body. This issue also happens with
ICUs (#62697), but those do not have any named scopes to exclude as of
today.
fixes https://github.com/angular/vscode-ng-language-service/issues/1991
PR Close#64392
This further simplifies the `loadComponent` logic in the Router by using
the promise returned from the config loader directly instead of
converting it to an observable.
PR Close#64450
These methods are only intended to be used internally within framework
instructions. Prefix them with `ɵ` to indicate that they are
framework-private and should not be called from user code.
PR Close#64471
Add support for interoperability between signal forms and reactive forms that
commit effccffde0 had removed.
A signal forms field can once again be bound to any element or component with a
`ControlValueAccessor`.
PR Close#64471
From my investigation what I know for sure:
- when the graph pans or zooms it updates the transform property on the g element, which in turn causes the browser to repaint the visible space in the g element
- stroke-dasharray is the cause of major performance issues in large graphs.
What I suspect:
- When the g element repaints, it also has to repaint all of the child svg elements. When the dashed line path svgs repaint, the stroke-dasharray calculation is not GPU accelerated, but instead occurs on the CPU, causing extreme lag whenever the svg graph is panned or zoomed.
Temporary solution: remove this dashed edge functionality. We can investigate alternatives for communicated that a path is lazy loaded.
Future long term solution: migrate to canvas based graph renderer for router tree and injector graph.
PR Close#64532
Fixes a bug in the missingStructuralDirective diagnostic where structural directives with missing imports were not reported when the element using the structural directive contained other directives
Fixes#64467
PR Close#64470
The existing implementation of `PlatformLocation` uses a custom URL parsing mechanism that can be brittle and doesn't properly update the `href` property. This change refactors the URL parsing to use the native `URL` constructor, providing more robust and accurate parsing of URLs, which also correctly updates the `href` property.
The tests for `PlatformLocation` have also been moved to a dedicated file to improve organization and clarity.
PR Close#64494
This further simplifies the `loadComponent` logic in the Router by using
the promise returned from the config loader directly instead of
converting it to an observable.
PR Close#64450
Previously, query parameters passed to `router.createUrlTree` were simply converted to strings. This meant that any custom serialization logic in a custom `UrlSerializer` was not applied. This could lead to inconsistencies between navigations triggered from the URL bar (which are parsed by the serializer) and navigations triggered programmatically.
This change ensures that query parameters are normalized using the provided `UrlSerializer`. The values are serialized and then parsed to ensure they are in the same format as if they had come from a URL. This allows custom serializers to handle complex objects in query parameters consistently.
Fixes https://github.com/angular/angular/issues/47307
PR Close#64449
Ensures the repository reference uses the correct name to prevent confusion and maintain consistency across generated documentation entries.
PR Close#64487
Removes a number of commit message scopes that are no longer in use.
- `bazel`: Now part of `dev-infra`
- `changelog`: The changelog is autogenerated and doesn't have dedicated commits.
- `packaging`: Is handled by `dev-infra` as well.
PR Close#64492
In some rare cases, it seems the animation queue disappears despite being afterEveryRender. This updates the animation scheduler to be afterNextRender instead and only schedules it when we need to.
fixes: #64423
PR Close#64441
Improves user experience by displaying UI notifications when attempting to view source for unsupported routes, replacing developer-only console warnings with visible snackbars
PR Close#64458
Introduces a migration that replaces CommonModule usage with individual imports from @angular/common, aligning with Angular's standalone component approach and improving module import clarity
PR Close#64138
This fixes a performance regression from #63754, which is almost a revert of the
prior performance fix in #57291; the latter was provided as quick fix to address
the severe performance overhead this extended diagnostic used to have, with #57337
as follow-up change to address the false negatives that were introduced in #57291.
That follow-up never landed, though, so this commit is re-applying the changes
from #57337 to fix the performance regression.
Fixes#64403
PR Close#64410
When adding and removing items in a `@for` loop, the `animate.leave` event binding instruction was not updated to use the same logic as the class function when the animation queue was added. We were not returning the correct signature for the `animate.leave` function, which caused the animation to not trigger correctly. This updates the event binding instruction to use the same logic as the class function when adding the animation to the queue.
fixes: #64336
PR Close#64413
This replaces the error we were throwing before the change. This allows component with defer triggerrs to be used on both SSR'd and CSR.
fixes#64184
PR Close#64185
In some cases, the leave animation stylesheets were getting pruned too early due to the renderer removal happening before the animation function was run. This ensures that while queuing a leave animation, we guarantee the lView is referenced in the leaving animations set. This guarantees the style sheet pruning knows about the animations existing and skips the prune step.
fixes: #64326
PR Close#64335
When a directive injects a `ViewContainerRef`, the runtime inserts a container that was throwing off the logic that recognizes native controls.
These changes switch to check if the node is a native control through the `TNode`. This also makes it a bit less prone to breaking during SSR.
Fixes#64362.
PR Close#64368
This commit adds `applicationProviders` to the `bootstrapModule` options
object. This allows specifying additional providers at the location of
bootstrap, which makes default providers much easier to accomplish.
Using this, we can refine the approach taken for downgrade_module to use
this more direct API rather than the additional provider variable dance.
PR Close#64354
This fixes the code to retain ZoneJS by default in the providers for
downgradeModule when the `bootstrapModule` is used. Prior to this
change, the async `bootstrapModule`/`compileNgModuleFactory` could be
called multiple times through `downgradeModule` before
`bootstrapModuleFactory` got called and used the zone providers.
Note: marked refactor since this only applies to the -next release and
we shouldn't have this change in the changelog as a fix.
PR Close#64354
Caches information about the kind of form control that a `TNode`
represents in `TNodeFlags`. This avoids redundant computations on
subsequent template create and update passes.
Renames the `INVALID_CONTROL_HOST` error code to
`INVALID_FIELD_DIRECTIVE_HOST` for clarity and adds a test for it.
PR Close#64351
Warns when @defer blocks define unreachable or redundant triggers, such as multiple main triggers, ineffective prefetches, or timer delays not scheduled before rendering.
PR Close#64069
Replaces inline comments with structured Before and After sections
to enhance readability and consistency. This helps developers better
understand the transformation from non-self-closing to self-closing
tags during migration.
PR Close#64388
Adds support for the `referrerPolicy` option in `HttpResource`, allowing developers to control how much referrer information is sent with each HTTP request.
PR Close#64283
This simplifies code by using async/await instead of rxjs in the config
loading internals. While loadChildren/loadComponent could _technically_
return a synchronous value, the expectation is that this would be used
for dynamic imports, which are necessarily async.
PR Close#64322
Renames the control directive and the input that users set to bind a
field to a UI control.
Previously users would do:
```
<input [control]="someField">
```
Now users will do:
```
<input [filed]="someField">
```
PR Close#64300
When the migration command was run for inputs, if the input had more than one reference in a method the migration would generate incorrect code
Fixes#63018
PR Close#64367
Replaces old deep-linked MDN tutorial URLs with top-level documentation
links for JavaScript, HTML, and CSS to provide more general and reliable references.
PR Close#64383
Updated examples to align with the latest Angular style:
- Removed `standalone: false` since it is unnecessary.
- Dropped module-based implementation in favor of standalone.
PR Close#64167
This commit updates the scripts to use the version from `package.json` for snapshot builds, ensuring that the git tags are aligned with the package version. This change simplifies referencing snapshot builds in the `package.json` file.
PR Close#64350
This commit introduces a mechanism to use snapshot builds for @angular/language-service dependencies when building the VSCode extension.
A new --//:enable_snapshot_repo_deps flag allows swapping the stable versioned dependency with a snapshot build from the angular/language-server-builds GitHub repository. This enables testing and development against the latest unreleased version of the language service.
PR Close#64334
Previously, the example returned a plain value instead of an object,
causing destructuring in the `stream` function to fail. Updated to
`params: () => ({ userId: this.userId() })` for correctness.
fixes: #64313
Update adev/src/content/ecosystem/rxjs-interop/signals-interop.md
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
PR Close#64327
Adding some typing to infer the expected types and drop the usages of `arguments` which isn't really typesafe.
The argument mis-match didn't result in an issue because they didn't end up being used futher down the line.
fix 63973
PR Close#64260
When the scroll position is being restored, this change upates the
behavior to use 'instant' rather than the default 'auto', which will
be whatever the browser behavior is for 'window.scrollTo'. The 'smooth'
behavior does not match how browsers behavior when performing a
traversal navigation for MPAs, which is 'instant'.
related to #58258
PR Close#64299
The `xvfb.start()` and `xvfb.stop()` methods are asynchronous but were being called synchronously. This can lead to race conditions where the tests start running before the virtual frame buffer is fully initialized, or the process exits before it's fully stopped.
This commit promisifies the `start` and `stop` methods to ensure they are properly awaited, making the e2e test setup more robust.
PR Close#64310
Currently if `TestBed.overrideComponent` is used on a class that uses initializer APIs (e.g. `input()`), the initializer metadata will be wiped out, because `overrideComponent` re-compiles the class with the information set by `setClassMetadata`. `setClassMetadata` only captures decorated members at the moment.
These changes introduce some logic to capture the new initializer-based APIs in `setClassMetadata` as well.
Fixes#57944.
PR Close#63957
Reworks the logic that tracks the decorator metadata for members to do so using the output AST, rather than wrapping the TypeScript AST. This makes it easier to programmatically generate new members that weren't part of the TypeScript AST before.
PR Close#63957
This commit migrates the vscode-ng-language-service to use the in-repo `ts_project` macro, which has strict dependency checking enabled. This improves build-time dependency validation and helps ensure that all dependencies are explicitly declared.
As part of this change, redundant `tsconfig.json` files have been removed in favor of a centralized configuration, and `jasmine_test` rules have been updated to the standard macro. A minor code adjustment in `server/src/session.ts` was also made to improve error handling.
PR Close#64306
This change updates the build configuration to include the
@angular/language-server package in the standard framework release
output.
By integrating it into the release train, we ensure that it is versioned and published consistently with the rest of the Angular framework.
PR Close#64306
This commit updates the VSCode Angular Language Service extension to use the `@angular/language-service` package built from source within the workspace, rather than a version downloaded from npm.
This change simplifies development and testing by ensuring the extension always uses the latest code from the local repository. The Bazel build configuration, VSCode launch settings, and e2e tests have been updated to reflect this change.
PR Close#64306
The `@angular/language-service` package was not needed for integration tests or benchmarks. Removing this dependency simplifies the build configuration.
PR Close#64306
Adds support for customizing the `IntersectionObserver` options for the `on viewport`, `prefetch on viewport` and `hydrate on viewport` triggers.
Note that the options need to be a static object literal, e.g. `@defer (on viewport(trigger, {rootMargin: '123px'})`.
Fixes#52799.
PR Close#64130
Currently we produce the string value of a defer `on` trigger by concatenating the string values of all of its tokens. This ends up ignoring whitespaces which in turn throws off source spans.
These changes switch to producing the string by taking the text between the start and end tokens, as well as tracking the start index.
PR Close#64130
Set `pointer-events` of the `iframe` to `none` while dragging. This should stop the events context interference and make resizing of the panel easier.
PR Close#64307
I've updated the test to assert what I believe it was trying to assert
before. Without this change, the CSS is invalid so it's unclear what
behavior we're demonstrating.
PR Close#64036
Fix a bug where the min property of a form field was not correctly
propagated to custom controls. Also ensure that min and max are only
bound to native input elements that support them.
PR Close#63884
Fix several typos caught by the added test cases:
* `disabled` attribute for native controls
* `readonly` property for custom controls
Note that the `name` test cases have been marked `pending()` due to
https://github.com/angular/angular/issues/63882.
PR Close#63884
The legacy `workspace` integration test asset folder has been removed as it was unused and no longer representative of modern Angular CLI workspaces.
In line with this cleanup, the Bazel dependency definitions for the integration tests have been reorganized. Runtime data dependencies have been moved from the `js_test` rules to the `data` attribute of their corresponding `ts_project` rules. This is a cleaner and more appropriate approach as it co-locates a test's runtime data dependencies with its source code definition, making the relationship between the code and its required assets more explicit and improving the overall maintainability of the build configuration.
PR Close#64271
Introduces a referrer policy option for HTTP requests to allow specifying the referrer information sent, improving privacy and security controls.
PR Close#64116
The repository URL in `package.json` is updated to point to the `angular/angular` monorepo. This ensures that the package metadata correctly reflects its location within the main repository.
PR Close#64220
The supported Node.js versions for the language service server are updated to align with the versions supported by Angular. This ensures a consistent and stable environment for developers.
PR Close#64220
This commit revamps the debugging setup and enabling developers to set breakpoints directly in the source TypeScript files.
Key changes include:
- Updated `launch.json` with source map path overrides to correctly map compiled output back to the original source code.
- Switched from `external` to `linked` sourcemaps in the Bazel build configuration for better debugging support.
- Consolidated the recommended VSCode settings into the main `launch.json` and `tasks.json`, removing the separate `recommended-*.json` files.
- Updated the debugging documentation to reflect the new, simplified workflow.
These changes significantly improve the developer experience for contributors working on the language service, making it much easier to debug and troubleshoot issues.
This applies to both the framework packages and vscode-ng-langugage-service.
PR Close#64220
This commit refactors the VSCode extension's build and launch configurations to align with `vsce` and `pnpm` workspaces.
The following changes are included:
- Updated `.vscode/launch.json` to use new `vsce:` prefixed tasks and simplified launch configurations.
- Updated `.vscode/tasks.json` to use `pnpm` workspace commands for watching and packaging the extension.
- Adjusted `BUILD.bazel` and `package.json` files to reflect the new build output paths.
These changes streamline the development workflow for the VSCode extension, making it easier to build, debug, and package.
PR Close#64220
Previously, the router tree would not properly clean up css classes placed on nodes which would lead to some nodes being incorrectly visualized after each update.
PR Close#63979
Our code ensuring host binding composition for animations was causing the early exit and removal of
elements when multiple transitions were present on the same element. This commit fixes the issue by
ensuring that we properly keep track of all the promise resolvers on the LView and then only
call them once we've properly waited for the longest animation to finish.
fixes: #64209
PR Close#64225
There may be cases where the longest animation info has been cleaned up before the end animation fires. We should still do the end processing in that case.
PR Close#64225
These tests were not properly validating against the host binding changes due to the fact that the styles were on the wrong components in some of the host binding cases.
PR Close#64225
Use `implements ErrorHandler` instead of extending the base class to follow Angular
conventions. Marked injected dependencies as `readonly`, made `openErrorSnackBar`
private, and improved overall code consistency.
PR Close#64237
Now that the control flow migration is running as a part of `ng update`, we need to be a bit forgiving about there not being any matching files since it can break the entire update process.
These changes switch the error to a warning and it counts the files for the entire workspace, not the individual projects.
PR Close#64253
Caches the downloaded vscode binary in the CI workflows to speed up the e2e tests for the vscode extension. This avoids downloading vscode on every CI run.
PR Close#64219
Previously this would take ~3500ms adev.
This updated logic avoids the constant JSON.stringify implementation and instead checks for serializable values directly.
After this change this code path for adev takes less than 20ms.
(Benchmarks taken on an M1 Macbook Pro)
PR Close#64234
Move most of the implementation of the `Control` directive into core
framework instructions. This allows field state changes to be propagated
to their corresponding UI controls directly during execution of a
template update block, instead of relying on `effect()`s to synchronize
each change later during the update (and too late in the case of
required inputs).
* Define a private API in `@angular/core` for signal forms to implement:
* `ɵControl` for the `Control` directive.
* `ɵFieldState` for the control's associated `FieldState`.
* Emit specialized instructions when compiling a `[control]` binding:
* `ɵɵcontrolCreate` sets up the `ɵControl` directive if present,
determines whether it's bound to a native control element or a
custom control component, and adds the appropriate event listeners
to notify the `ɵFieldState` of UI changes.
* `ɵɵcontrol` propagates changes from `ɵFieldState` properties to their
corresponding UI control properties (in additional to binding the `control`
property itself).
PR Close#63773
* Emit a `ɵɵcontrol` instruction in place of `ɵɵproperty` for property
bindings named "control". This instruction cannot be chained, but is
otherwise functionally equivalent.
* Upcoming changes will use the `ɵɵcontrol` instruction to bind a signal
form field to a UI control (be it a native element or custom directive).
PR Close#63773
There was a bug in the logic for checking if a leave animation exists for a node. This was affecting timing of nodes with enter animations.
PR Close#64226
There are two primary reasons for this renaming:
1. It better reflects the actual nature of the proxy object, namely that
the form is represented as a tree, and that this object is used for
navigating the tree structure (while `FieldState` is used for getting
the state at a particular point in the structure).
2. This frees up the name `Field` to be used for the directive that
binds a `FieldTree` to a UI control.
PR Close#64214
This commit updates the internal transition to handle context retention
through the abort function. This retention chain included the
previousNavigation and setting this to a noop function resolves the
issue.
fixes#63983
PR Close#64141
Ensures that file names remain visible even if the associated code block
is collapsed or hidden, improving readability and context in the docs.
PR Close#64204
Content Projected nodes are not destroyed and recreated, like every other
situation. Enter and Leave animations were ephemeral and are
expected to run once, and then be cleared. This means that for content projection
cases, the animations would only ever work the first time they were shown / hid.
In order to resolve this, we move to an animation queue that re-runs the animation
functions stored in the LView. In most cases, this animation will run once on creation.
For content projection, the enter and leave animations will fire more than once. Animations
are stored on the LView, but indexed and scheduled by whichever RNode needs to be animated.
So we only run animations for an affected RNode, rather than potentially all in the LView.
This also moves the queue to afterRender, which is safer than right after template
execution in refreshView.
fixes: #63418fixes: #64065fixes: #63901
PR Close#63776
Improve error handling when `rawDelays` contains fewer items than `transitionedProperties`, preventing a toLowerCase of undefined error in `parseCssTimeUnitsToMs`.
PR Close#64181
Since HTTP/2, responses no longer contain a status text besides the status code, which caused our default value of 'OK' to be used in HttpErrorResponse.message.
DEPRECATED: `HttpResponseBase.statusText` is deprecated
PR Close#64176
Stop multiple component tree traversals if the app root is the body tag. This caused the devtools ui to duplicate the component information, if the app root was the body tag
PR Close#64161
BREAKING CHANGE: Fix signal input getter behavior in custom elements.
Before this change, signal inputs in custom elements required function calls to access their values (`elementRef.newInput()`), while decorator inputs were accessed directly (`elementRef.oldInput`). This inconsistency caused confusion and typing difficulties.
The getter behavior has been standardized so signal inputs can now be accessed directly, matching the behavior of decorator inputs:
Before:
- Decorator Input: `elementRef.oldInput`
- Signal Input: `elementRef.newInput()`
After:
- Decorator Input: `elementRef.oldInput`
- Signal Input: `elementRef.newInput`
closes#62097
PR Close#62113
Removed `standalone: true` since it is now the default
and no longer necessary.
refactor(common): update ngComponentOutlet and ngTemplateOutlet examples and remove redundant standalone flag
Removed `standalone: true` since it is now the default
and no longer necessary.
PR Close#64155
The Angular Package Format has been updated to group all TypeScript declaration files (`.d.ts`) under a single `types/` directory within the package. Previously, these files were located at the package root or within entry-point specific directories.
This commit updates the APF documentation to reflect this new structure, including:
- The example file layout.
- The file purpose description table.
- The `package.json` exports field example.
- The legacy typings field example.
This brings the documentation in line with the current package structure, providing accurate guidance for library authors and tool developers.
PR Close#64168
Content Projected nodes are not destroyed and recreated, like every other
situation. Enter and Leave animations were ephemeral and are
expected to run once, and then be cleared. This means that for content projection
cases, the animations would only ever work the first time they were shown / hid.
In order to resolve this, we move to an animation queue that re-runs the animation
functions stored in the LView. In most cases, this animation will run once on creation.
For content projection, the enter and leave animations will fire more than once. Animations
are stored on the LView, but indexed and scheduled by whichever RNode needs to be animated.
So we only run animations for an affected RNode, rather than potentially all in the LView.
This also moves the queue to afterRender, which is safer than right after template
execution in refreshView.
fixes: #63418fixes: #64065fixes: #63901
PR Close#63776
Fixes two issues that were preventing template literals from being recovered properly if one of the interpolated expressions is broken:
1. We weren't updating the expected brace counter when an interpolation starts which in turn was throwing off the recovery logic in `skip`.
2. When producing tokens for template literals, we were treating the closing brace as an operator whereas other places treat it as a character. Even after fixing the first issue, this was preventing the recovery logic from working correctly.
Fixes#63940.
PR Close#64150
Prevents migration of @input() properties that contain references to 'this' in their initializer functions. This ensures that functions accessing class members via 'this' remain unchanged, preventing potential build errors.
PR Close#64142
Updated pipe examples to explicitly import the pipe for clarity and
correctness. Also removed `standalone: true` since it is now the default
and no longer necessary.
PR Close#64135
The VS Code extension build is failing due to some dependency issues. This commit updates the dependencies and build configuration to fix the build.
- Update `pnpm-lock.yaml` to reflect the dependency changes.
- Update `BUILD.bazel` files to adjust the external dependencies for `esbuild` and to correctly package the VSIX file.
PR Close#64154
This commit updates the TypeScript configuration across the project to use `moduleResolution: "bundler"`. This modernizes our module resolution strategy to align with current TypeScript best practices and bundler behaviors.
The following changes are included:
- Updated `tsconfig.json` files to set `moduleResolution` to `"bundler"`.
- Updated the `rules_angular` bazel dependency to a version compatible with these changes.
- Adjusted related test files and golden files to reflect the new module resolution strategy.
PR Close#64125
Some properties (like gets) might throw when we try to read them.
With this commit we fail gracefuly and show a warning message for the property that can't be read.
fixes#56755
PR Close#64096
The paths for `pre_apf_project` and `pre_standalone_project` in the renovate configuration were missing the `package.json` suffix. This resulted in renovate not being able to find and disable updates for these projects as intended.
This commit corrects the paths to include `package.json`.
PR Close#64102
The language service integration tests were modifying files in the source tree, which made them flaky and non-hermetic. This also required the tests to be run with `no-remote-exec` and `no-sandbox` tags in Bazel.
This commit refactors the tests to copy the test projects to a temporary directory before running the tests. This makes the tests more robust, isolated, and allows them to be run remotely and in a sandbox.
Additionally, dependencies for the `pre_apf_project` and `pre_standalone_project` test fixtures have been reverted to older Angular versions. This is to ensure we are correctly testing against legacy project setups as was originally intended.
PR Close#64098
The lsp integration tests had a circular dependency with other integration tests, which made the build setup complex and fragile. This was previously handled by using 'copy_to_bin', which is not ideal as it hides the true dependency graph.
This commit refactors the build configuration to break this cycle by introducing a dedicated 'ts_project' for the lsp tests with its own 'tsconfig.json'. This change simplifies the build logic and makes dependencies explicit.
PR Close#64091
The event listeners for animationstart and animationend weren't properly checking whether the animation event fired matched the node we're bound to, since animation events bubble. This resulted in child node animation events bubbling up and causing elements to get prematurely removed.
fixes: #64084
PR Close#64088
The lsp integration test is flaky and can fail intermittently. This change marks the test as `flaky = True` to prevent it from failing the build.
Additionally, the `no-remote` tag is updated to `no-remote-exec`. The former disables remote caching, while the test can still benefit from it.
PR Close#64085
This commit configures the Bazel RBE setup action to use the 'RBE_TRUSTED_BUILDS_USER' secret for authentication. This is necessary to ensure that the CI can properly connect to the remote build execution environment.
PR Close#64070
`git config` only lists the configured value, but `git remote get-url` actually resolves the URL and is more stable.
I had a local configuration which aliased `gh:` to the appropriate GitHub URL:
```
[url "git@github.com:"]
insteadOf = "gh:"
pushInsteadOf = "git@github.com"
```
In this scenario, `git config` returns `gh:dgp1130/angular`, but `git remote get-url` returns `git@github.com:dgp1130/angular`, which is what the subsequent regex expects.
PR Close#64062
This commit updates several dependencies to their latest versions and adjusts the build configurations accordingly.
Key changes include:
- Upgraded various development and runtime dependencies.
- Removed outdated jasmine test runner configuration.
- Updated Bazel build files to align with new dependency structures.
Some dependencies like `vscode-language*` have been added to Renovate's ignore list as they require a more significant refactoring effort that is planned for a future update.
PR Close#64073
The control flow migration was incorrectly removing `ng-template` elements in scenarios where they were referenced by multiple `*ngIf` directives' `else` clauses and also used independently via `ngTemplateOutlet`.
PR Close#63996
When `noUncheckedIndexedAccess` is not enabled, indexed accesses do not include `undefined` in the type.
This makes the OptionalChainNotNullableCheck inconvenient when wanting to safe guard an indexed access (and when the typings isn't helping you).
Ideally project should enable `noUncheckedIndexedAccess` for better typesafety, but this is often inconveninent (we do not enable it by default) and often not the resort of the developer.
So more better coding convinience, `OptionalChainNotNullableCheck` will not raise an error/warning on indexed Acessed followed by an optional chaining when `noUncheckedIndexedAccess` is not enabled.
See also #63809 which will detect more cases
PR Close#64007
Previously we would visualize route config "types" by colouring different nodes.
Now the we only colour nodes to represent the active route path. Lazy loaded routes are represented with dashed line edges that point in the direction of loading.
PR Close#63980
This commit changes `Resource.hasValue()` and its derived types to improve narrowing
of resources whose generic type either does not include `undefined` (i.e. when a default
value has been provided) or when the generic type is `unknown`. This fixes the undesirable
behavior where `hasValue()` would cause the `else` branch of an `hasValue()` conditional
to have a narrowed type of `never`, given that the `hasValue()`'s type guard covers the
entire type range already (meaning that the type in the else-branch cannot be inhabited
in the type system, yielding the `never` type).
By making the `hasValue()` method only a type guard when the generic type includes `undefined`
these problems are avoided.
Fixes#60766Fixes#63545Fixes#63982
PR Close#63994
Fixes an error where using an alias in a defer block caused the compiler CLI to fail when parsing. The resolution logic in ComponentDecoratorHandler was updated to correctly handle deferred dependencies with aliased imports.
PR Close#63966
Since those are top level APIs, `ngDevMode` might not be available at runtime if they're invoked before the variable is set.
fixes#62796
PR Close#63875
This adds an optional flag to the renderer on `removeChild` called `requireSynchronousElementRemoval`, which can tell any downstream renderer that elements need to be removed synchronously. This gets passed down to the legacy animation renderer to ensure that any elements that set this flag aren't impacted by that renderers changes to timing.
fixes: #63893
PR Close#63921
An invalid APP_ID could be responsible to generating broken CSS selectors. (eg `:` is an example for a character that breaks a selector by being a separator for pseudo-selectors.)
We now throw an error if the provided value is not alphanumerical
PR Close#63252
https://github.com/angular/angular/pull/62630 made it so that all ARIA
property bindings would write to their corresponding attribute instead.
The primary motivation for this change was to ensure that ARIA
attributes were always rendered correctly on the server, where the
emulated DOM may not correctly reflect ARIA properties as attributes.
Furthermore, this change added support for binding to ARIA attributes
using the property binding syntax (e.g. `[aria-label]`).
Unfortunately, https://github.com/angular/angular/pull/62630 relied on
the incorrect assumptions that an ARIA property name could be converted
to its attribute name (without hardcoding the conversion), and that the
value of an ARIA property matched its corresponding attribute. For
example, the `ariaLabelledByElements` property's value is an array of
DOM elements, while the corresponding `aria-labelledby` attribute's
value is a string containing the IDs of the DOM elements.
This partially reverts https://github.com/angular/angular/pull/62630 so
that only property bindings with ARIA attribute names (begin with
`aria-`) are converted to attribute bindings.
* `[ariaLabel]` will revert to binding to the `ariaLabel` property.
* `[aria-label]` will continue binding to the `aria-label` attribute.
Note the only difference between `[aria-label]` and `[attr.aria-label]`
is that the former will attempt to bind to inputs of the same name while
the latter will not.
PR Close#63925
Fixes a bug in the standalone migration where 2 imported modules have the same class name but 1 is imported with an alias and would not be added to the component imports array when migrating
Fixes#63913
PR Close#63934
During a previous PR review, it was noted that the `next` tag was causing confusion. This commit updates the dependencies for the integration tests to resolve this ambiguity and ensure clarity going forward.
Additionally, this change uses the `link:` protocol to ensure that `pnpm i` does not fail when lockfiles or dependencies are updated outside of Bazel.
PR Close#63937
This commit introduces several optimizations to the adev CI workflows:
- The adev preview build now uses a more powerful runner and creates a production build.
- Remote execution is disabled for adev builds to improve performance.
Note: Bazel cache is still being used, and the built times are reduces by about 10mins when the cache is missed.
PR Close#63941
Currently if `TestBed.overrideComponent` is used on a class that uses initializer APIs (e.g. `input()`), the initializer metadata will be wiped out, because `overrideComponent` re-compiles the class with the information set by `setClassMetadata`. `setClassMetadata` only captures decorated members at the moment.
These changes introduce some logic to capture the new initializer-based APIs in `setClassMetadata` as well.
Fixes#57944.
PR Close#63904
Reworks the logic that tracks the decorator metadata for members to do so using the output AST, rather than wrapping the TypeScript AST. This makes it easier to programmatically generate new members that weren't part of the TypeScript AST before.
PR Close#63904
This commit removes Yarn as a package manager for integration tests and migrates to pnpm. This change aims to standardize package management across the project, leveraging pnpm's efficiency and consistent behavior for dependency resolution and installation.
PR Close#63902
This removes the Zone providers from the `BrowserTestingModule`. These
already exist by default in all other entrypoints to Angular
environments (TestBed compiler, bootstrapModule, and createApplication).
PR Close#63872
Previously, HOST_TAG_NAME had its __NG_ELEMENT_ID__ set at the top level. This
prevented tree-shaking, since the bundler had to keep the assignment as a
potential side effect even when the token was never used.
This change moves the token creation and __NG_ELEMENT_ID__ assignment into a
@__PURE__ IIFE. If HOST_TAG_NAME is not injected anywhere, the IIFE result is
unused and can be dropped entirely by the optimizer. If it is used, the token
still behaves the same at runtime.
PR Close#63861
Prior to this change the template type-check generator would incorrectly apply inputs
and attributes to a structural directive, where only the bindings as present in microsyntax
are actually bound to the directive. This introduced a problem where usages of template
variables could not be resolved, because the template variables are out-of-scope of the
template element itself.
Closes#49931
PR Close#52453
pnpm v10.17.0 adds support for wildcards in 'minimumReleaseAgeExclude'. This simplifies the configuration by allowing the use of '@angular-devkit/*' and '@angular/*' instead of listing each package individually.
PR Close#63870
This change configures pnpm's `minimumReleaseAge` setting to 1 day (1440 minutes). This is a security measure to mitigate dependency chain attacks, where malicious actors publish a new version of a dependency with malicious code and then trick users into updating to it before it can be discovered and reported.
By delaying the adoption of new releases, we reduce the window of opportunity for such attacks. The list of excluded packages contains trusted and frequently updated dependencies from the Angular team, which are considered safe to use without this delay.
PR Close#63862
The zoneless scheduler is always enabled, so if hydration works with zoneless, it works
for all Angular apps. There is no need for detection of custom zone implementations
PR Close#63847
Previously we used a configuration flag for adev, instead we now separate into two different targets since our flag didn't
need to cause a full reanalysis to run since everything before the final target should be a cache hit.
PR Close#63845
This commit drops special-case handling for old-style "zoneless" that
would disable the internal scheduler when zoneless was not explicitly
enabled but Zone was not defined. This scheduler is now enabled in _all_
applications, providing consistent expectations for developers.
BREAKING CHANGE: Using a combination of `provideZoneChangeDetection`
while also removing ZoneJS polyfills will no longer result in the
internal scheduler being disabled. All Angular applications now
consistenly use the same scheduler, and those with the Zone change detection
provider include additional automatic scheduling behaviors based on
NgZone stabilization.
PR Close#63846
This makes the zoneless-by-default change a flag flip that can be
individually enabled in tests, createApplication, and bootstrapModule
for gradual rollout. In addition, the "require on CD provider" check is
also made individually flippable for gradual rollout.
PR Close#63382
This change removes the internally provided `ZoneJS`-based change
detection scheduler. This makes Angular Zoneless by default and allows
tree-shaking of the Zone change detection providers.
BREAKING CHANGE: Angular no longer provides a change detection scheduler
for ZoneJS-based change detection by default. Add
`provideZoneChangeDetection` to the providers of your
`bootstrapApplication` function or your `AppModule` (if using
`bootstrapModule`). This provider addition will be covered by an
automated migration.
PR Close#63382
Non-typed `transform` functions were stripped by the migration prior to this commit (while still logging an error).
This behavior will now only happen with `--best-effort`.
#63541
PR Close#63547
In production builds, `ngDevMode` is replaced with `false`, so the guard compiles to `return;`. However, bundlers like ESBuild still keep the remaining statements after the return as unreachable code instead of removing them. This leaves behind unnecessary dead code in the output.
Technically, the body is unreachable. But to prove that, the bundler must be 100% certain that:
- `return` cannot be removed by some transform
- there's no later transformation that changes control flow
As thus, it's always conservative.
This also allows dropping `assertDefined`, which was previously
referenced only inside `prependTokenToDependencyPath`. With the
function now fully inlined and dev-only, `assertDefined` is also
eliminated from production builds, further reducing bundle size.
PR Close#63354
Copy-pasting commands like `$ pnpm lint` caused errors in shells (e.g. zsh). Updated docs to use `pnpm lint` directly so they run without modification.
PR Close#63795
To avoid the need for specifying `provideZoneChangeDetection` in any/all
modules used with `downgradedModule`, this change adds the zone-based change detection
providers by default. This also adds the zone providers to
`UpgradeModule` by default as well.
PR Close#63814
To avoid the need for specifying `provideZoneChangeDetection` in any/all
modules used with `downgradedModule`, this change adds the zone-based change detection
providers by default.
PR Close#63814
To avoid the need for specifying `provideZoneChangeDetection` in any/all
modules used with `downgradedModule`, this change adds the zone-based change detection
providers by default.
PR Close#63814
The `checkNoChanges` method previously used an early-return guard:
if (!ngDevMode) return;
// dev-only code ...
In production builds, `ngDevMode` is replaced with `false`, so the
guard compiles to `return;`. However, bundlers like ESBuild
still keep the remaining statements after the return as unreachable
code instead of removing them. This leaves behind unnecessary dead
code in the output.
This commit updates the method to instead wrap the full body:
if (ngDevMode) {
// dev-only code ...
}
With this change, the method collapses to an empty function in
production builds:
checkNoChanges() {}
This ensures that the dev-only logic and its dependencies
(e.g. `checkNoChangesInternal`, `UseExhaustiveCheckNoChanges`) can be
fully tree-shaken, reducing bundle size.
PR Close#63387
This option was deprecated by #55778.
BREAKING CHANGE: The `interpolation` option on Components has been removed. Only the default `{{ ... }}` is now supported.
PR Close#63474
The diagnostic will raise an error when required initializers (input, model, queries) are invoked the context of property initializers and contructors.
Docs will be provided in a follow-up
fixes#63602
PR Close#63614
The diagnostic that flags signals which haven't been invoked has some logic to skip over inputs, however it was looking at the used directives across the entire template, not the ones on the specific node.
Fixes#63739.
PR Close#63754
This change updates the Gemini model version from 2.0 Flash to 2.5 Flash on the AI overview page to align with the official Genkit documentation.
The source documentation at https://genkit.dev/docs/frameworks/angular/ has been updated, and this commit ensures our documentation reflects that change accurately.
PR Close#63800
The contribution guide is updated to provide clearer instructions on when to use the `docs-infra` scope versus the `docs` type.
This change helps contributors understand that `docs-infra` should only be used for infrastructure-related changes (application code, tooling, configuration) within the `/adev` directory. For simple content modifications, such as editing a `.md` file, `docs` without a scope is the correct choice.
PR Close#63799
This is a pure re-organization of the animations code. No functionality changes, but it should be easier to navigate now. Utility classes have been moved to a `utils.ts` file. The related functions in the instructions have been grouped closer together.
PR Close#63775
Adds the 'target: automation' label to the 'update-cdk-apis' and 'update-cli-help' jobs in the 'update-cdk-apis-and-cli-help.yml' workflow. This will help to better track and manage automation tasks.
PR Close#63753
The logic to update the renovate config during the release to switch the target labels from target: rc to target: patch has been removed. Instead, a static target: automation label is added to the default renovate preset.
PR Close#63752
When a user has `animate.leave` on a list of items in a `@for`, but are only showing a subset using a computed, removing the second to last item results in a move operation on the last item. There's no native atomic move API in the browser. So this results in the element being detached and attached at its new index. The detaching of the node resulted in leave animations firing.
This fix addresses this by adding a flag in the `LView[ANIMATIONS]` `AnimationLViewData` interface to allow for skipping animations. During list reconciliation, we set this flag so that the animations are skipped over. The flag is flipped back after the move operation is complete.
There is one complication that results from this. The index adjustment of elements in the list happens synchronously while the leave animation is asynchronous. This results in the leaving item getting shifted to the end of the list. This is not ideal but likely can be addressed in a future refactor.
fixes: #63544
PR Close#63745
Previously we relied on the default port of 4200, but if it was already in use then we would run into issues where the cli provided a prompt which we were unable to respond to. Instead we now request port 0 which will automatically find an available port.
PR Close#63740
Documents how to create custom service worker scripts to handle push notifications, background sync, and other events by importing and extending Angular's default behavior
PR Close#63629
When a new branch is created for a feature, it may not exist in the downstream repo. For example, during an exceptional minor release. In such scenarios, we fallback to the last known branch. This was previously handled in a catch block, but this change makes the fallback more explicit.
PR Close#63733
This makes it possible to batch effects, where we can "reopen" consumers
during initial render and then finalize them after we are finally done
adding all the effects to a batch:
```
function createBatch() {
const effect = // ... create effect node
resetConsumerBeforeComputation(effect);
return effect;
}
// pseudo-code
function appendEffect(effectBatch, updater) {
if (value is a signal) {
const prevConsumer = setActiveConsumer(effectBatch.node);
const output = value();
setActiveConsumer(prevConsumer);
effectBatch.push({ signal, updater });
return output;
}
}
function finalizeBatch(effectBatch) {
if (effectBatch.length > 0) {
finalizeConsumerAfterComputation(effectBatch.node);
}
}
const effectBatch = createBatchEffectNode();
appendEffect(signal1, (newValue) => /* something */);
appendEffect(signal2, (newValue) => /* something different */);
finalizeBatch(effectBatch);
```
PR Close#62549
In the `deploy-docs-site` GitHub action, esbuild fails to resolve `pnpapi` during the bundling process. This is because `pnpapi` is a dependency that is available in the Node.js environment at runtime and should not be bundled.
This commit marks `pnpapi` as an external dependency for esbuild to prevent it from being bundled and resolve the build failure.
```
✘ [ERROR] Could not resolve "pnpapi" [plugin bazel-sandbox]
```
See: https://github.com/angular/angular/pull/63722#issuecomment-3278922553
PR Close#63723
The reviewer note for Firefox addons included a message that was intended for manual releases. This is no longer necessary with the automated release process.
PR Close#63731
Dropping `any` in favor of `Node` for better type safety and clarity.
BREAKING CHANGE: `ngComponentOutletContent` is now of type `Node[][] | undefined` instead of `any[][] | undefined`.
fixes#63538
PR Close#63674
This updates the enter and leave logic to use the stored LView data to dispatch the enter and leave animations at the right points in the lifecycle. This should fix issues with signals not being available yet, parallel animations, and also eliminate the need for the element registry.
fixes: #63391fixes: #63388fixes: #63369
PR Close#63450
In order to point the right context, links in error messages will target the archived version of the online doc site (v*.angular.io).
See #44650
PR Close#63512
In some cases, such as when a new exceptional minor branch is created. The branch may not exist in the downstream repo. For example, during an exceptional minor release (e.g. FW 20.3.x and Components: 20.2.x).
This commit introduces a fallback mechanism to handle such scenarios. If the current branch is not found in the downstream repository, the script will now fall back to the last known branch from the build information. This ensures that the files can be updated properly.
PR Close#63678
This commit introduces a new `pnpm run devtools:release` command to streamline the Angular DevTools release process.
The command automates the entire release workflow, including checking for new commits, updating version numbers, creating a release commit, and guiding the user through the publishing steps for both Chrome and Firefox extensions.
The `devtools/docs/release.md` documentation has been updated to reflect the use of this new command, providing a single entry point for the release process.
A new script `devtools/tools/release.mts` has been added to implement the release logic, and `package.json` has been updated to include the new script.
PR Close#63599
Keep the selected node (component/element) visible when the directive tree component resizes (e.g. signal graph pane becomes visible).
Closes#63670
PR Close#63681
This will allow manually subscribed animation events to still fire when using `animate.leave`. Otherwise they were being cleaned up before the animations happened.
fixes: #63391
PR Close#63414
This updates tests and examples only to prepare for zoneless by default.
These changes were identified and made as part of #63382. Anything that
failed gets `provideZoneChangeDetection` unless the fixes were easily
and quickly determined.
It also adds the zoneless provider to the `initTestEnvironment` calls
for tests in this repo to prevent regressions before #63382 is merged.
PR Close#63668
Type checking of host bindings was added in v20. We're now confident enough in it to enable it by default.
BREAKING CHANGE:
* Previously hidden type issues in host bindings may show up in your builds. Either resolve the type issues or set `"typeCheckHostBindings": false` in the `angularCompilerOptions` section of your tsconfig.
PR Close#63654
Add some documentation that's mentioned in the material.angular.dev version of the component hanress docs, but was missing from the adev version.
PR Close#63620
This commit updates the `runs-on` configuration in the CI workflows
(`ci.yml`, `manual.yml`, `pr.yml`) from specific `ubuntu-latest-Xcore`
labels to the more general `ubuntu-latest`. This change reduces
resource consumption. This change should not be needed for RBE and remote cache.
PR Close#63656
Add some documentation that's mentioned in the material.angular.dev
version of the drag & drop docs, but was missing from the adev version.
PR Close#63619
This commit introduces a number of changes to the server bootstrapping process to make it more robust and less error-prone, especially for concurrent requests.
Previously, the server rendering process relied on a module-level global platform injector. This could lead to issues in server-side rendering environments where multiple requests are processed concurrently, as they could inadvertently share or overwrite the global injector state.
The new approach introduces a `BootstrapContext` that is passed to the `bootstrapApplication` function. This context provides a platform reference that is scoped to the individual request, ensuring that each server-side render has an isolated platform injector. This prevents state leakage between concurrent requests and makes the overall process more reliable.
BREAKING CHANGE:
The server-side bootstrapping process has been changed to eliminate the reliance on a global platform injector.
Before:
```ts
const bootstrap = () => bootstrapApplication(AppComponent, config);
```
After:
```ts
const bootstrap = (context: BootstrapContext) =>
bootstrapApplication(AppComponent, config, context);
```
A schematic is provided to automatically update `main.server.ts` files to pass the `BootstrapContext` to the `bootstrapApplication` call.
In addition, `getPlatform()` and `destroyPlatform()` will now return `null` and be a no-op respectively when running in a server environment.
PR Close#63562
Moves the control directive under api/ since it is part of the public
API. Also removes the interop abstract control from the public API
PR Close#63616
Tests validate the current behaviour of the injector tree feature.
- Nodes should be displaying on entering the tab
- Hide framework / Hide injectors with no providers flags should filter the tree properly
- Providers side tab should be able to be opened and filtered properly using the 2 filter input fields for token and type
PR Close#62844
Adds additional handling for input types that handle numbers:
- number
- range
- datetime-local
As well as input types that handle dates:
- date
- month
- week
- time
- *not* datetime-local which does not allow setting valueAsDate
This PR allows binding either a `Field<string>` or `Field<number>` to
the number type inputs and a `Field<string>`, `Field<numebr>`, or
`Field<Date | null>` to the date type inputs. Binding uses the
corresponding `.value`, `.valueAsNumber`, or `.valueAsDate` according to
the type of the `Field`.
When reading new values out of the input, the `Control` directive will
read the property that aligns with the type of the existing value in the
`Field` and write back the same type.
PR Close#63585
Updates the version range to drop support for TypeScript 5.8.
BREAKING CHANGE:
* TypeScript versions less than 5.9 are no longer supported.
PR Close#63589
TransferState is only written into the DOM once during SSR and is not kept in sync with the runtime state on the client. Pressing the refresh button always re-reads the initial serialized script tag, which never changes after bootstrap.
PR Close#63592
The logic to track if the transfer state has been serialized is simplified by removing the need for `APP_ID`. Instead of maintaining a `Set` of application IDs, a simple boolean flag is used.
PR Close#63525
The `TRANSFER_STATE_SERIALIZED_FOR_APPID` provider was previously configured at the platform level, causing its state to be shared across all concurrent server-side rendering requests. This created a race condition where one request could see the `appId` from a different, concurrent request, leading to false warnings about duplicate state serialization.
This commit changes the provider's scope to ensure that each application instance gets its own unique state. This correctly isolates the serialization check to each individual request, resolving the issue of false warnings in concurrent environments.
Closes#63524
PR Close#63525
Addresses some cleanup items for the router tree:
- No longer loads router ng global APIs as a side effect of importing the router. Rather this is now a runtime step that occurs when provideRouter is called.
- No longer depends on router.navigateByUrl in Angular DevTools. There is now a dedicated global util for this
- Router instance logic no longer depends on token name
- Prevents navigating to lazy or redirect routes (these don't have an associated component)
PR Close#63081
This fixes a bug introduced in #63485 where `firstValueFrom` was used. This
doesn't work in all situations here because some observables don't
emit before completing. These errors should result in the route matching
logic moving on to the next route.
Note: This is marked as a refactor rather than fix because the commit above is not in
any release yet.
PR Close#63546
Removes the deprecated `ApplicationConfig` export from `@angular/platform-browser`.
This export was deprecated in a prior version and developers should import `ApplicationConfig` from `@angular/core` instead.
BREAKING CHANGE:
The deprecated `ApplicationConfig` export from `@angular/platform-browser` has been removed.
Please import `ApplicationConfig` from `@angular/core` instead.
PR Close#63529
This option was introduced out of caution as a way for developers to opt out of
the new behavior in v18 which scheduled change detection even when
events happened outside the NgZone. 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`.
This option was deprecated in v18.2, less than 3 months after it was
introduced in v18. We do not really expect it to be used.
BREAKING CHANGE: `ignoreChangesOutsideZone` is no longer available as an
option for configuring ZoneJS change detection behavior.
PR Close#62700
Fix the runtime errors caused by the tree visualizer node auto-snapping when a tab is changed. The errors are caused since we only visually hide the tabs.
PR Close#63531
The internal error handler in TestBed rethrows errors to prevent them
from being silently ignored in tests. Prior to this commit, tests which
used `provideZoneChangeDetection` in the providers would override the
internal error handler of TestBed and prevent these errors from being
rethrown.
BREAKING CHANGE: (test only) - Using `provideZoneChangeDetection` in the
TestBed providers would previously prevent `TestBed` from rethrowing
errors as it should. Errors in the test will now be rethrown, regardless
of the usage of `provideZoneChangeDetection`. Tests should be adjusted to
prevent or account for these errors. As in previous major versions,
this behavior can be disabled with `rethrowApplicationErrors: false` in
`configureTestingModule` as a last resort.
PR Close#63404
This updates the error thrown when both `provideZoneChangeDetection` and
`provideZonelessChangeDetection` are both used in the application
providers to be a warning instead. The reasons for this are twofold:
1. The migration we need for using zoneless by default isn't perfect and
may add `provideZoneChangeDetection` when the zoneless provider
exists. This change will prevent that from causing an error
2. There might be valid situations where a "default" is used in a common
provider but that can be overridden by individal applications. In
tests, we do allow this type of thing, where `initTestEnvironment`
may have a default but individual tests might want to use a different
one. The same logic might apply to applications in some environments.
PR Close#63457
This option would require one of either the zone or zoneless provider so
applications don't accidentally enable zoneless when the default flips if we
missed it in the migration. It'll be a hard failure at bootstrap, but that's a
lot easier to notice than zoneless getting turned on accidentally since
many things might just work.
PR Close#63486
This allows passing errors and disabled reasons that did not originate
from `@angular/forms/signals` in case the the control is being used
separately from the forms system
PR Close#63455
Removes custom handling of emptiness in several of the validators and
replaces it with a common `isEmpty` check. The common empty check
considered the following values to be empty: `null`, `undefined`, `''`,
`false`, `NaN`
Generally most validators should treat an empty value as valid. This
aligns with both the behavior or native HTML validators and reactive
forms validators.
As an example, consider an optional email field. If the email validator
considered empty string to be an invalid email, there would be no way
for the user to not enter it.
There are several exceptions to this rule:
- `required` whose entire purpose is to ensure that the field is *not*
empty
- `validateStandardSchema` which should subject all values including
empty ones to the specified standard schema. It is up to the schema to
decide whether an empty value is valid or not
- `validate`/`validateAsync` which leaves it up to the user's custom
validation logic to decide if an empty value is valid.
PR Close#63456
This fixes a bug introduced in #62994 where `toPromise` was used. This
doesn't work in all situations here because some observables don't
complete. This only affected the redirect path, since the others are
already behind other rxjs code which takes the first value from the user
guards.
Note: This is marked as a refactor rather than fix because the commit above is not in
any release yet.
PR Close#63485
To aid in hitting external breaking change deadlines without pressure
of fixing everything in g3 first, add an internal opt out flag.
This also adds a privately exported provider to revert to the old
rxjs-based behavior, which can be synchronous, until any issues that
come up are addressed.
PR Close#62994
This is effectively a revert of https://github.com/angular/angular/commit/72e6a948bb8ec58f14b87d297d5f81baf2e1942d.
Debugging the recognize stage is considerably easier with async/await
stacks compared to rxjs. This also improves maintainability and is a
better 1:1 with server-side logic that has been implemented to match
and can be more easily kept in sync.
This also ensures that the recognize step is always async, whereas it
can sometimes be synchronous with rxjs.
BREAKING CHANGE: Router navigations may take several additional
microtasks to complete. Tests have been found to often be highly
dependent on the exact timing of navigation completions with respect to
the microtask queue. The most common fix for tests is to ensure all
navigations have been completed before making assertions. On rare
occasions, this can also affect production applications. This can be
caused by multiple subscriptions to router state throughout the application,
both of which trigger navigations that happened to not conflict with the
previous timing.
PR Close#62994
The new animations was not correctly looking for the `.` when parsing bindings. This resulted in arbitrary event bindings creating animate.leave instruction calls.
fixes: #63466
PR Close#63470
This commit introduces an experimental version of a new signal-based forms API for Angular. This new API aims to explore how signals can be leveraged to create a more declarative, intuitive, and reactive way of handling forms.
The primary goals of this new signal-based approach are:
* **Signal-centric Design:** Place signals at the core of the forms experience, enabling a truly reactive programming model for form state and logic.
* **Declarative Logic:** Allow developers to define form behavior, such as validation and conditional fields, declaratively using TypeScript. This moves logic out of the template and into a typed, testable schema.
* **Developer-Owned Data Model:** The library does not maintain a copy of data in a form model, but instead read and write it via a developer-provided `WritableSignal`, eliminating the need for applications to synchronize their data with the form system.
* **Interoperability:** A key design goal is seamless interoperability with existing reactive forms, allowing for incremental adoption.
* **Bridging Template and Reactive Forms:** This exploration hopes to close the gap between template and reactive forms, offering a unified and more powerful approach that combines the best aspects of both.
This initial version of the experimental API includes the core building blocks, such as the `form()` function, `Field` and `FieldState` objects, and a `[control]` directive for binding to UI elements. It also introduces a schema-based system for defining validation, conditional logic, and other form behaviors.
Note: This is an early, experimental API. It is not yet complete and is subject to change based on feedback and further exploration.
Co-authored-by: Kirill Cherkashin <kirts@google.com>
Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>
Co-authored-by: Leon Senft <leonsenft@users.noreply.github.com>
Co-authored-by: Dylan Hunn <dylhunn@gmail.com>
Co-authored-by: Michael Small <michael-small@users.noreply.github.com>
PR Close#63408
This commit updates provider definitions that relied on the `deps` array
with `new Optional()` and `new SkipSelf()` to instead use the modern
`inject(..., { optional: true, skipSelf: true })` API.
Previously:
deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
Now:
const parent = inject(KeyValueDiffers, { optional: true, skipSelf: true });
**Bundle size reduction**: `Optional` and `SkipSelf` are runtime values
created by `makeParamDecorator()`. Even in production builds, esbuild
and other bundlers must keep their factory code because they are
referenced with `new Optional()` / `new SkipSelf()`. With `inject()`,
those classes are no longer referenced, allowing them and the
`makeParamDecorator` scaffolding to be tree-shaken when unused.
As a result, production bundles can drop both `Optional`, `SkipSelf`, and
their supporting factory code when not used elsewhere, reducing code size
while keeping the same behavior.
PR Close#63386
Add support for the Fetch API's responseType property in HttpResponse and HttpErrorResponse when using HttpClient with the withFetch provider.
PR Close#63043
When toggling visibility on an element over and over, the enter animations were supposed to be cancelled and then the classes removed. There was a race condition happening that resulted in the cancelled animation being the leave animation. Rather than using the animation.cancel functionality, it's safer to just remove the enter classes.
fixes: #63439
PR Close#63442
This commit updates the devtools step by disabling the package manager cache. This change is necessary because Cypress downloads its binary to a cache directory during installation, which requires a post-install script. However, when the cache is hit this is skipped.
This update also disables `pnpm install` in the Cypress action to avoid a redundant installation step. And adds a seperate cache for the downloaded Cypress binary.
See: https://docs.cypress.io/app/get-started/install-cypress#pnpm-configuration
PR Close#63441
Within our module.bazel file when describing the version of typescript to use for rules_ts, we use ts_version instead of ts_version_from to prevent our package.json file from being
part of the set of files used to calculate the sha for the lock file. Any unrelated change to the version of the typescript file would end up causing our lockfile to be out of date.
This amount of churn has proven to be too much for our current setup. We instead now test to validate the versions defined in the package.json and MODULE.bazel files match.
PR Close#63431
Annotate the `new Version(...)` call with `/* @__PURE__ */` to signal to
optimizers that the constructor is side-effect free.
Without this hint, bundlers such as Terser or ESBuild may conservatively
retain the `VERSION` instantiation even when unused. With the annotation,
the constant can be tree-shaken away in production builds if not referenced,
reducing bundle size.
PR Close#63400
This commit prevents lazy injection of the internal `ErrorHandler` from a destroyed injector, which would otherwise result in a secondary "destroyed injector" error.
The `handleUncaughtError` function is used in a wrapped event listener that invokes the `ErrorHandler` if the listener throws. A simple case in a micro-frontend application:
```ts
onNavigationToAnotherApp() {
this.appRef.destroy();
do_some_stuff_ie_loggin_that_may_throw();
}
```
If the function throws an error, Angular attempts to inject the `ErrorHandler` from a destroyed injector.
PR Close#62275
When declaring directives, the standalone flag is set to true by default in current Angular versions.
The docs for the directive decorator should correctly explain the default behavior, while still mentioning when to set it to false.
PR Close#63329
The 4 second removal timeout was applying in all cases, but it should only actually apply to the situation where the event binding syntax is used for animate.leave. This ensures that's the only case in which it'll apply.
PR Close#63393
Deprecated since v5. Use `upgrade/static` instead, which also supports aot.
BREAKING CHANGE: `UpgradeAdapter` is no longer available. Use
`upgrade/static` instead
PR Close#61659
The animate instructions were getting applied to the container comment nodes as well as the element nodes. This prevents that on the compiler level.
fixes: #63371
PR Close#63390
signalGraphEnabled was previously passed down the component tree.
This change refactors the logic to use the settings service instead,
which already holds the value and allows sharing it across components.
PR Close#63374
This commit drops the `X-Request-URL` header. It was a non-standard HTTP response header, deprecated long ago and never part of any official specification. Modern browsers now expose the final URL via the `XMLHttpRequest.responseURL` property, as defined in the WHATWG spec.
PR Close#61943
This fixes the rare case that someone uses binding syntax with `animate.leave` providing a value with a string that has spaces in it. For example:
```
<example `[animate.leave]="'class-a class-b"` />
```
fixes: #63365
PR Close#63366
This updates the adev navigation to consider the new enter-and-leave path to be the definitive animations guide.
It also prefixes all the prior animations package docs with legacy and updates all links.
PR Close#63368
With #63162, we added automatic link creation on API symbols. The side effect was that we created HTML in some specific cases. For example with the docs-card we could have nested anchor elements which is invalid.
This commit prevent creating nested links inside docs-cards.
fixes#63351
PR Close#63352
Change direct deps in bazel targets and import specifiers within files to maintain strict deps requirements ahead of enabling strict deps tests in the repo
PR Close#63323
There's special logic in place to prevent duplicate nodes from showing up in the case when an `@if` toggles a view quickly. This had the unfortunate side effect of causing `@for` leave animations to get cancelled when an add and remove happened simultaneously, even if it was a different index. This fix prevents that from happening in the `@for` loop case.
fixes: #63307
PR Close#63328
The `FormArrayDirective` will allow to have a `FormArray` as a top-level form object.
* `NgControlStatusGroup` directive will be applied to the `FormArrayDirective`
* `NgForm` will still create a `FormGroup`
Fixes angular#30264
BREAKING CHANGE: This new directive will conflict with existing FormArray directives or formArray inputs on the same element.
PR Close#55880
Ts 5.9 introduced a regression coming from 5.8 when parenthesis aren't generated for expressions like (`(a ?? b) && c`).
This fix works around this explicitly specifying that we want to keep those parenthesis that we're aware of in this specific case;
This change can be reverted if the root issue (https://github.com/microsoft/TypeScript/issues/61369) is fixed. (but let's keep the tests in any case for the coverage)
fixes#63287
PR Close#63292
This commit adds `lockfile_mode=error` to the `.bazelrc` file. This change ensures that any future builds will fail if the lock file is not up-to-date with the `BUILD.bazel` file, preventing inconsistencies and encouraging developers to commit updated lock files.
PR Close#63260
This is a first step to create links to API entries automatically.
It adds support for
- code spans (`` `symbol` ``)
- code blocks (`` ```some code here``` ``)
Links are generated from on a K/V map of API entries (symbol => package name).
The map is generated from the API manifest that we're already generating for the API docs.
For the moment, entries with identical names are skipped.
PR Close#63162
Fixes that the HMR extraction logic didn't accoubnt for expressions with type arguments (e.g. `viewChild('foo', {read: TemplateRef<unknown>})`).
Fixes#63240.
PR Close#63261
In the context of TypeScript (TS), a re-exported symbol is considered a distinct symbol.
This means that a developer can choose to import either the re-exported symbol or
the original symbol. However, in the context of Angular, the re-exported symbol
is treated as the same component because it uses the same selector.
This pull request will utilize the most recent re-export component file to
resolve the module specifier.
PR Close#62585
Add "Show graph" button to the signal properties in the side pane only for Angular apps. This required storing the signal graph in a separate service.
PR Close#62853
In the case that someone wants to disable animations via selector specificity, for example by adding an `.animate-disabled` class to a parent node, we need to make sure the animate instructions don't misbehave. Now we detect if animations exist in the provided classes and react accordingly.
fixes: #63161
PR Close#63242
The Tailwind CSS guide already resides within the Angular documentation, making a link to the Angular documentation redundant. This commit removes the unnecessary link.
PR Close#63205
Adds a new guide that explains how to set up and use Tailwind CSS in an Angular project. This guide covers installation, configuration, and provides a basic usage example.
PR Close#63205
Ensure consistency in error message wording by aligning the NG0303
error with other Angular error strings. This improves clarity and
maintains a uniform developer experience
PR Close#63222
Host bindings for `(animate.enter)` and `(animate.leave)` were not firing properly. This fixes the compiler ingest to make sure they do fire.
fixes: #63199
PR Close#63217
Previously, Angular devtools would mistakenly traverse the same DOM elements multiple times while doing traversal for the component tree explorer. This error case would occur when more than 1 Angular application root component was present on the same page and in distinct DOM branches.
Some example cases that did work previously:
```html
<app-root>
...
</app-root>
```
```html
<app-root>
...
<app-root-2></app-root-2>
...
</app-root>
```
An example of where it would enter the irregular behaviour
```html
<app-root>
...
</app-root>
<app-root-2>
...
</app-root-2>
```
Now, we properly ignore duplicate DOM paths when looking for application and non-application root component to begin the Angular DevTools component discovery logic.
PR Close#62719
This applies the same fix that fixed the class version to the event binding version. It prevents duplicate elements from being on screen when animations have been toggled too fast.
fixes: #63127
PR Close#63216
This change fixes an issue where long lists of enum values would display on a single line, running off the screen, especially on mobile devices.
PR Close#63211
The value type was not being displayed when a value had an enum, which was misleading. This change ensures the value type is always shown, so users know whether to expect a single value or an array of values.
PR Close#63211
This commit extracts helper functions to reduce code duplication across animation instructions and adds early return when animations are disabled.
PR Close#63163
Fixes that the pipeline wasn't processing the fallback content of `ng-content` for i18n which resulted in a compiler error further down the line.
Fixes#63065.
PR Close#63156
Similar fix as #63082, but for template attributes. The root cause is the same where we should be using `fullStart` instead of `start` in order to account for whitespaces being skipped.
Fixes#63157.
PR Close#63175
This commit updates the MCP server documentation with the following changes:
- Updates the description of the `ng mcp` command behavior.
- Adds a configuration example for the Gemini CLI.
- Adds a new section for command options, including `--read-only` and `--local-only`.
- Alphabetizes the IDE configuration sections for better readability.
- Alphabetizes the "Available Tools" table.
PR Close#63141
Running the Angular compiler with declaration-only emission is dangerous
because Angular does not yet support this mode as it relies on the Ivy
compilation which does not run in this mode
In the best case, everything works fine as incidentally there's no
difference in the emitted type declarations (e.g. this is the case for
TS files containing no Angular annotations or only `@Injectable`
annotations).
In the worst case, compilation silently fails in that the compilation
succeeds but the resulting type declarations are missing the Angular
type information and are therefore incomplete. This happens for all
components, directives and modules.
BREAKING CHANGE: The Angular compiler now produces an error when the
the `emitDeclarationOnly` TS compiler option is enabled as this mode is
not supported.
PR Close#61609
This commit also include an `ng update` migration to ensure `lastSuccessfulNavigation` is invoked.
BREAKING CHANGE: `lastSuccessfulNavigation` is now a signal and needs to be invoked
PR Close#63057
This commit adds brief documentation for `rxResource` to the "Using
Angular with RxJS" guide. The only available documentation for
`rxResource` today is the API reference, which lacks any code examples.
PR Close#63125
This removes the common pitfall for if blocks in the best practices, as this is no longer true in Angular v20.2, see angular/angular@a409534
PR Close#63132
This will allow us to build adev while the CLI and the FW major versions are mismatched.
we can remove this patch once the CLI has published a v21 pre-release (or a flag to disable that error).
PR Close#63098
This was missing from the RxJS interop guide. I came across it while
cleaning up some Google-internal docs and realized I had nothing on adev
to which I could link.
PR Close#63122
This fix updates the adev `DocViewer` component to support rendering with the `main[docsViewer` selector so that the primary content for the page is inside of a `<main>` element (without introducing an extra DOM element).
PR Close#63121
When using `file:` renovate updates fails due to ` ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND ` this is due to a different behaviour between `link:` amd `file:`. `link:` however will not fail when the directory does not exist.
PR Close#63111
The `pnpm install` command was failing for the `packages/core/test/bundling` project with the error:
`ERR_PNPM_NO_MATCHING_VERSION No matching version found for @angular/compiler-cli@0.0.0-PLACEHOLDER`
This happenes only in renovate updates.
PR Close#63105
During `pnpm install` in a monorepo setup, the `packages/zone.js/test/typings` project would fail with the error: `ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND: Could not install from "/.../node_modules/typescript" as it does not exist.`
PR Close#63105
When parsing expressions inside a bound attribute, we offset all of its spans by an `absoluteOffset` in order to get the right spans in the source file. The offset was incorrect when parsing an attribute with leading spaces during the construction of the Ivy AST, because of the combination of:
1. We were setting the offset by looking at `valueSpan.start`.
2. The Ivy parser sets `leadingTriviaChars: [' ', '\n']` which means that spaces and new lines will be ignored in the `sourceSpan.start`.
These changes resolve the issue by using `valueSpan.fullStart` which includes the leading spaces.
Fixes#63069.
PR Close#63082
In #62758 we started loading the component resources during bootstrap in JIT mode to ensure that they're in place by the time we create the component. This won't work for lazy-loaded components in the router, because they don't exist at bootstrap time.
These changes add similar logic when the router loads a component.
PR Close#63062
Adds handling and logging for unhandled promise rejections to improve debugging and prevent silent failures. Updates tests and test harness to verify logging of rejection reasons
PR Close#63059
In the case that a leave animation is running and someone toggles an `@if`, a new node would be inserted. For a brief moment, there may be two of the same nodes visible at once. While this is expected with native CSS, it's not ideal. Instead, we retain a reference to the leaving element and can remove that node when the new node is entering.
fixes: #63020
PR Close#63048
Fixes that the compiler was throwing an error if type checking of host bindings is enabled for a generic directive. The problem was that we were always using the `TcbNonGenericDirectiveTypeOp`.
Fixes#63052.
PR Close#63061
Benefits of auto-ticking mock clocks have been described in other PRs,
such as https://github.com/jasmine/jasmine/pull/2042 and
https://github.com/sinonjs/fake-timers/pull/509. In short, `fakeAsync`
cannot work when some tasks are required to be truly async, such as XHRs
or observers like ResizeObserver. In addition, auto ticking mock clocks
can be applied to tests without the tests then needing to update
everything to manually flush timers.
PR Close#62135
Deprecated diagnostics can appear on the context guard becaues the
directive itself may be deprecated.
For example, context guards look like `if (i1.NgForOf.ngTemplateContextGuard(_t8, _t9) /*331,378*/) {...}`
and typescript will report the deprecation on the whole element, from
start to end tag, because the span for that node includes it.
fixes https://github.com/angular/vscode-ng-language-service/issues/2203
PR Close#63054
This fixes an issue caused by
https://github.com/angular/angular/pull/62648 for older versions of
Angular when the newest version of the language service is used. This
prevents the TCB from attempting to use the assertType when it does not
exist.
fixes#63046
PR Close#63053
This new signal property is convenient to derive a `isNavigating` state.
`isNavigating = computed(() => !!this.router.currentNavigation())`
DEPRECATED: The Router.getCurrentNavigation method is deprecated. Use the Router.currentNavigation signal instead.
fixes#62958
PR Close#63011
Save user settings in the `SettingsStore`.
NOTE: The theme is omitted since the change is not trivial and it will be handled in a separate PR.
PR Close#62429
Enables specifying the script type ('classic' or 'module') when registering Service Workers, improving compatibility with ES module features.
PR Close#62831
Enables users to add an array of FormControls to a FormArray using its existing .push() method,
instead of pushing each new FormControl one by one triggering events along the way.
PR Close#57102
This deprecates `BootstrapOptions` since `NgZone` can now be configured
in the providers. This is a necessary step because when zoneless becomes
the default, developers will have to add ZoneJS via
`provideZoneChangeDetection` and that will override anything defined in
`BootstrapOptions`.
PR Close#62690
Any time something causes styles to recalculate,
`element.getAnimations()` will be empty. This updates `animate.enter`
and `animate.leave` to rely on `getComputedStyles` to determine the
longest animation instead.
fixes: #63006
PR Close#63007
Adds an internal token to detect when both hydration and blocking initial navigation are enabled. Logs a warning during app initialization if this unsupported combination is found, helping developers avoid misconfiguration and potential runtime issues.
PR Close#62963
Now that the packages are avaiable at the base node_modules we can treat local packages as normal packages and not leverage the archive package versions
PR Close#62996
Currently when loading external resources in JIT, when `fetch` fails,
the `text` is empty and the component is loading. This hides the actual
underlying fetch error. We should properly detect this and error out.
PR Close#62992
In the case when composing animation classes with `animate.enter` on the
element itself and also with host bindings, the removal would only
have context for one of the classes added: the last one added. This
allows for tracking of the classes added by `animate.enter` via a
WeakMap so we know the exact classes added and which to remove.
Also shores up the tests to make sure we are fully testing animate.enter.
PR Close#62981
This new signal property is convenient to derive a `isNavigating` state.
`isNavigating = computed(() => !!this.router.currentNavigation())`
DEPRECATED: The Router.getCurrentNavigation method is deprecated. Use the Router.currentNavigation signal instead.
fixes#62958
PR Close#62971
Currently the code that type checks host bindings assumes that all listeners are bound to the DOM, however that's not the case since host bindings can also bind to own outputs.
These changes update the TCB to generate the proper code for type checking such outputs.
Fixes#62783.
PR Close#62965
Space separated strings, e.g. `class-1 class-2`, should work with both enter and leave animations. `animate.leave` lost that functionality in a refactor. Tests are now added to catch this.
fixes: #62964
PR Close#62979
This adds information about the new `MAX_ANIMATION_TIMEOUT` token used
for configuration the maximum amount of milliseconds Angular will wait
for animations to complete before removing the element.
PR Close#62949
When animate.leave is used, stylesheet pruning causes issues. Stylesheets with the appropriate animations get pruned before the animations can run. This will delay the removal in the case that the registry is present.
fixes: #62942
PR Close#62943
make effects purple instead of invisible, fix epoch animations for new nodes, and remove graph transitions when switching between two components in the component tree
PR Close#62912
In some patterns, `element.getAnimations()` will be an empty array despite the animation class being present during animation start and the style sheet showing a keyframe animation.
Moving the longest animation check to the end resolves this problem.
fixes: #62923
PR Close#62925
It appears that the intent is to return an unlisten function when `on` is called. The message bus implementations indicate that. However, the `MessageBus` abstract class returns `void` instead.
Change to `on: () => void`.
PR Close#62898
The inject migration wasn't implementing file filtering properly which resulted in it passing an invalid tsconfig path to TypeScript.
Fixes#62866.
PR Close#62913
The addBody function was not preserving all fetch API options like integrity and referrer when creating request options for POST/PUT/PATCH requests. This caused these options to be stripped out during request construction.
PR Close#62881
In this commit, we align the service worker types with those provided by TypeScript. The `ServiceWorkerContainer.getRegistration()` method returns a `Promise<ServiceWorkerRegistration | undefined>`, but we were casting it to `Observable<ServiceWorkerRegistration>`, ignoring the possibility of `undefined`.
This is unsafe, as we should account for the case where the registration is `undefined` and handle it appropriately in the push manager.
PR Close#62497
The diagnostic was displaying `'Function in text interpolation should be invoked: ect Object]()` instead of `'Function in text interpolation should be invoked: firstName()'.
PR Close#62842
This deprecates the animations package in favor of using `animate.enter` and `animate.leave` with intent to remove the full package in v22.2.
DEPRECATED: @angular/animations
PR Close#62795
This adds a test module configuration to define whether animations should be enabled or disabled in test. By default, they are disabled.
PR Close#62764
Fix the text size of the transfer state settings menu item. Also, rename "Show" to "Enable" to match the rest of the non-default tabs text.
PR Close#62851
fixes Plugin activation failed: Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './bundles/language-service.js' is not defined by 'exports'
PR Close#62811
Adds documentation for the tools available in the Angular CLI MCP server. This includes:
- get_best_practices
- search_documentation
- list_projects
Also includes a section for providing feedback and ideas for new capabilities.
PR Close#62777
Simplifies destruction logic by relying directly on the injector's destroyed state.
Eliminates unnecessary retrieval of a separate destroy reference
PR Close#62738
Add support for the Fetch API's redirected property in HttpResponse and HttpErrorResponse when using HttpClient with the withFetch provider.
The redirected property indicates whether the response was the result of an HTTP redirect, providing valuable information for security, debugging, and conditional logic.
PR Close#62675
Add client notification when an app version fails, improving error
visibility and debugging capabilities. When a version encounters a
critical error, all clients using that version are now notified
with details about the failure.
- Add notifyClientsAboutVersionFailure method call in versionFailed
- Ensure clients receive VERSION_FAILED events with error details
- Improve service worker error transparency for better debugging
PR Close#62718
This updates async router tests to use the jasmine autoTick feature. Observed test timings
for the chromium tests went down from ~7.5s to ~3.5-4s. For node, these decreased from ~5.5s to ~3s.
In addition to the speed improvement, this feature:
* Removes the need to be careful about timeout ordering when there are several timeouts in tests.
* Removes the need to ensure test timeouts are kept sufficiently small
* Reduces overall flakiness
PR Close#62776
The fetch backend now propagates the plain body when parsing the body fails.
This replicates the behavior of the XHR backend introduced in #19773.
The current state completely obfuscates errors of the "wrong" response type.
However, it's not uncommon for successful requests to return one type and
errors to return another type. Propagating the plain error allows downstream
error consumers to reason about the error body and decide how to parse it
depending on application needs.
PR Close#62765
Adds proactive storage capacity checks using the Storage API
to better handle near-full conditions during data caching.
Replaces previous TODOs with actual usage monitoring and
logging to help prevent cache failures due to quota exhaustion.
PR Close#62737
Currently the HTML parser will stop parsing as soon as it hits an end character in the name of an attribute (e.g. `/` or `>`). This ends up being problematic with some third-party packages like Tailwind which uses a wider range of characters for its class names. While the characters are fine when inside the `class` attribute, our current parser behavior prevents users from setting those classes conditionally through `[class.]` bindings.
These changes adjust the parser to handle such cases.
Fixes#61671.
PR Close#62742
Currently if the app has some external resources and it gets bootstrapped in JIT mode, the user will get an error about calling `resolveComponentResources`. These changes add a call to `resolveComponentResources` automatically inside `bootstrapApplication`.
Note that we don't need similar logic for `bootstrapModule`, because it calls into `compileNgModuleFactory` internally which in turn calls `resolveComponentResources`.
PR Close#62758
Currently when testing a component using `TestBed.createComponent`, we always create the component as a `div` which isn't aligned with the runtime. The runtime tries to parse out the tag name from the first selector in `@Component` and only falls back to `div` if there isn't one. This behavior difference can cause components to not behave like they would in production which reduces the usefulness of the tests.
These changes add the `inferTagName` option to `TestBed.createComponent` and `TestBed.configureTestingModule` that allows apps to opt into inferring the tag name from the selector in the same way as the runtime. Currently the new option is set to `false`, but we intend to change it to `true` in a future version.
PR Close#62283
Introduces a new guide for setting up the Angular CLI's Model Context Protocol (MCP) server.
The guide includes:
- Instructions on how to use the command.
- IDE-specific JSON configurations for VS Code, JetBrains, Firebase Studio, and Cursor.
- Clarification on the different JSON structures required by each IDE.
PR Close#62746
Enables configuration of the updateViaCache setting for service worker registration, allowing greater control over caching behavior during updates. Extends tests to cover new option and ensures correct propagation in registration logic.
PR Close#62721
Add transfer state tab, which is taking transfer state script by using APP_ID. Created internal api ɵgetTransferState to retrieve transfer state value from app into devtools app.
PR Close#62465
Allow binding to ARIA attributes using property binding syntax _without_
the `attr.` prefix. For example, `[aria-label]="expr"` is now valid, and
equivalent to `[ariaLabel]="expr"`. Both examples bind to either a
matching input or the `aria-label` HTML attribute, rather than the
`ariaLabel` DOM property.
Binding ARIA properties as attributes will ensure they are rendered
correctly on the server, where the emulated DOM may not correctly
reflect ARIA properties as attributes.
Reuse the DOM schema registry from the compiler to map property names in
type check blocks.
PR Close#62630
By default this is 4 seconds. In CI we have unreliable runtime performance so we this change gives us a bit of wiggle room to validate application behaviour.
PR Close#62726
This was causing some unintended behaviour when paired with our new zoneless configuration. I'm not sure why currentlyMatchedIndex was getting set to -1 here. With this removed it seems like things are working as expected. Previously a select call would reset this index *after* a search filter was applied, which would cause weird behaviour with the "next" and "prev" buttons.
PR Close#62727
One common problem encountered by the devtools content script is that it accepted almost any message send over the message bus. Some websites like `auth.openai.com` were spamming the bus and DDOS the devtools app.
By introducing event tagging and skipping non-devtools events we prevent DDOS of the Angular devtools content script by on forward tagged events.
PR Close#62645
changes code snippet on first-app tutorials (https://angular.dev/tutorials/first-app/09-services) for the step "Add a new file level import for the HousingService:" from
imports: [HousingLocation],
to
import {HousingService} from '../housing.service';
PR Close#62720
When using `hasValue()` I would expect it to behave like any other
reactive value such that changes to the internal `value()` that do not
cause `hasValue()` to return anything different do not trigger change
detection, but this was not the case. This change wraps the value
checking in a `computed` such that it behaves as expected again while
still preserving the type narrowing.
PR Close#62595
This fix also matches the implementation to the jsdoc for `hasDirectiveDependencies` "Whether any of the component's dependencies are directives"
fixes#62573
PR Close#62666
Currently we infer the target of DOM events to be `EventTarget | null` which is consistent with the built-in types for `addEventListener`. This is due to the fact that users can dispatch custom events, or the event might've bubbled. However, this typing is also inconvenient for some other common use cases like `<input (input)="query($event.target.value)">`, because we don't have the ability to type cast in a template.
These changes aim to make some of the cases simpler by inferring the type of `$event.target` if the event is bound on a void element which guarantees that it couldn't have bubbled.
PR Close#62648
When we introduced blocks, we made a deliberate decision to treat the `@` character as a reserved character in case we need to use it for other syntax in the future. This meant that some common cases, like writing out an email address in the template, can be broken.
After some recent discussions we decided to relax the requirement and only treat `@` as a reserve character if it's followed by a character sequence that matches a known block.
PR Close#62644
There were 26 duplicated block tests in `lexer_spec.ts`, likely due to merge conflicts. These changes remove the duplicates while keeping the 6 tests that were different.
PR Close#62644
This commit ensures the application remains unstable during the entire
bootstrap process. This ensures all bootstrap listeners and app
initializers observe the application as being unstable until each one
has gotten a chance to execute the synchronous block (potentially adding
more pending tasks).
Prior to this commit, application initializers or bootstrap
listeners may observe the application as being stable, even though other
initializers/listeners had not yet executed. This created an ordering
issue whereby the hydration bootstrap listener would observe the
application as stable prior to the router performing its initial
navigation.
fixes#62592
PR Close#62631
The `timeout` option is implemented in the different HTTP backends, but the option is not actually passed to the backends. `transferCache` is also missing in one signature. This commit adds both options to `HttpClient`.
Fixes#62581
PR Close#62586
In the Typescript Language Service, these diagnostics are reported as suggestion diagnostics.
This will report the deprecated `Component`, `Directive`, etc.
Fixes https://github.com/angular/angular/issues/59343
PR Close#62054
This commit adds a `.catch()` handler to `transition.ready` from `document.startViewTransition` to prevent `AbortError`s in Safari when `startViewTransition` is called synchronously multiple times.
PR Close#62535
This will spare use the warning logs when the tests run.
```
NG0914: The application is using zoneless change detection, but is still loading Zone.js. Consider removing Zone.js to get the full benefits of zoneless. In applications using the Angular CLI, Zone.js is typically included in the "polyfills" section of the angular.json file.
```
PR Close#62596
Previously these tests would run automatically when Angular DevTools lived in another repo. These files have continued to live here but have not been running automatically on each PR.
Now, these test files have been revived to run properly with our changes since the repo merge. This is a first step to reviving our e2e testing.
Next steps include writing cypress tests for new features like Injector Graph, Router tree, signals visualizations, etc.
PR Close#61972
This commit updates the logic to better handle a situation when there is a cyclic DI dependency detected. Previously, the error message used to contain the name of the token that triggered the problem. With this change, the DI resolution path would also be included, so that it's easier to find and resolve the cycle.
PR Close#50902
The current URL is not correct as it incorrectly includes browsers. We now replace the URL with the comparer provided by baseline which will be available soonish via `web-platform-dx.github.io`
PR Close#62572
Preloaded components were not being activated in certain scenarios when preloading was enabled. This change ensures that components are correctly activated after being preloaded.
PR Close#62502
Currently, this warning is always displayed as the option defaults to false. We update the logic to only display the warning when it's true.
PR Close#62536
Fixes including, but not limited to:
- `visibleLines` values
- all codeblocks normalized to 2 spaces indentation
- lesson 14-http sEverely de-indented
- descriptions and explanations were rewritten to reflect the changes from @Input to input and from ngFor to @for
- missing step added in lesson 11-details-page
- rewritten confusing instructions for adding code that was already added in previous steps
PR Close#62457
The `generateUniqueIdentifier` helper relies on the internal `identifiers` property of a `ts.SourceFile`.
As this is not a public-facing API, it is not included in the externs provided to Closure Compiler.
Consequently, it is susceptible to being renamed during advanced optimizations, which would lead to runtime failures.
To prevent this, the property is now accessed via a string literal (`sf['identifiers']`). This change ensures that
the property name is preserved through the compilation process. An explanatory comment has been added to clarify the
necessity of this approach for future reference.
PR Close#62517
Currently when a diagnostic happens in a template, we always say "Error occurs in ...", however we have other types of diagnostics as well.
PR Close#62479
The mock file system currently relies on some NodeJS logic. This blocks
the convenient use of the mock file system in the browser. The file
system is useful for creating tests to verify e.g. that our transforms
can work in the browser.
PR Close#62493
The static fields may be part of advanced compilations where the
receiver would change as part of the static field collapsing
optimization.
The optimization requires us to use the explicit class name, over
`this` that would change to e.g. `globalThis`.
PR Close#62493
This field defaults to `version`, so there's no need to have it when it's exactly the same. This is one less number to bump during release PRs.
PR Close#62351
The commit introduce the distinction between
- class like decorators (like Component, Interface, NgModule. They are formatted like classes/interfaces, with each attribute being documents.
- function like decorators (Attribute, Host, Optional...)
PR Close#60411
Currently when Tsurge runs in g3, it creates a bare bones Angular
compiler plugin. The tsconfigs from compilation units may set options
like "useHostForImportGeneration", but the Ngtsc logic doesn't enable
because the `fileNameToModuleName` method is not defined on the host.
This can break reference emission for Tsurge analyzers/programs and
result in subtle differences to real `ng_module` compilations. This
commit fixes this by making the method available in 1P Tsurge.
Notably, reference emission can occur during analysis— so even if
migrations aren't "emitting TS -> JS" output.
PR Close#62447
Following some infra changes, DTS files are now splitted over several files, which aren't referenced in the `package.json` but are directly imported in the root dts.
We chose to not use ATA here because it only pulls the latest version from a CDN whereas we prefer to use the local definitions we have in the `node_modules` of the tutorial.
fixes#62374
PR Close#62424
When executing the compiler-cli in the browser, or some parts of it—
modules like `url` are stubbed out with `{}`. This commit accounts for
this.
PR Close#62431
Use the packaged versions of the packages instead of the local ts_project dependencies to prevent multiple versions of the deps to enter test bundles
PR Close#62413
Use the packaged versions of the packages instead of the local ts_project dependencies to prevent multiple versions of the deps to enter test bundles
PR Close#62413
Since we know that DOM properties won't go to an inputs, we can move the remapping logic to the compiler, saving us some processing on the client.
PR Close#62421
The serialization of route data does not support cyclic data objects. We sanitize nested route data object by replacing invalid values with a placeholder string.
PR Close#62339
Abstract the injector tree visualizer so it can be used for both the Injector Tree and Router Tree tabs without having to rely on separate identical implementations.
PR Close#62264
This makes few edits based on feedback and observations from a previous release:
1. Moves `git pull` command before initial `git log` to make sure we're up to date before checking if a release is necessary.
2. Updates both `git log` commands to limit to `fix`, `feat`, and `perf` changes. This ignores more than just `refactor`, such as `build`, `ci`, etc. and should be more meaningful to end users.
* I considered doing something with `Revert` commits, but opted not to. Instead, it will treat this just like their original commit. This does mean we might send a slightly more complicated changelog than it needs to be, but it's not worth making these commands even weirder.
3. Removes install step prior to bumping the version numbers, as its just not needed and we have to reinstall later anyways.
4. Switches PR target from `patch` to `minor`. We only need to merge this to the `main` branch, and it's not worth the effort to keep the `patch` branch in sync.
5. Switches source code zip command to `git archive`. This is more portable than `zip *`, which depends on the shell configuration to determine what is included in `*` (mainly whether or not that includes dotfiles such as `.nvmrc` and `.bazelrc`).
PR Close#62352
Add support for mode and redirect options in Angular's HttpClient based on fech provider to enable control CORS behavior and redirect handling
PR Close#62315
In this commit, the conditional branching around `ɵloadImpl` is removed from client-side code, as `ɵloadImpl` is never defined in client bundles. This makes the logic simpler and improves tree-shaking, allowing the `from()` import to be dropped from the common bundle in browser builds.
PR Close#62191
In this commit, the use of `images.forEach` was replaced with a traditional `for (let i = 0; ...)` loop to ensure compatibility with Domino. Domino may return a custom internal data structure (e.g., a lazily evaluated query result) that does not fully support standard iteration protocols like `forEach` or `for...of`.
Naturally, this would never happen in any browser. It occurs only in unit tests when using `renderApplication()`, because Domino's `querySelectorAll` returns the following:
```js
var nodes = select(selector, context);
return nodes.item ? nodes : new NodeList(nodes);
```
In certain unit tests, it returns an object like:
`{ root: document, filter: function(e) { ... }, lastModTime: 1, done: true, cache: [] }`,
which means that the object does not have a `forEach` method.
As a result, this causes an `afterAll` error: `forEach is not a function`.
PR Close#62290
Your blog post signaled that afterNextRender and afterEveryRender
are now stable:
https://angular.love/angular-20-whats-new#Signal%20related%20APIs
However, only 1 of the overloads of those was marked as stable.
I detected this because angular-eslint errors on calls even to
to the publicApi overload - and while that should probably be
fixed on their end, your announcement wasn't specific about only
one overload being stable, so I assume this was an oversight.
angular-eslint related issue:
https://github.com/angular-eslint/angular-eslint/issues/2534
PR Close#62153
Currently when there's a parser error in interpolated text, the compiler reports an error on the entire text node. This can be really noisy in long strings.
These changes switch to reporting the errors on the specific expressions that caused them.
PR Close#62258
This way, an arbitrary service can implement Angular's service requirements without a hard dependency on @angular/core
ex:
class Foo {
bar = inject(Bar);
}
registerInjectable(Foo);
PR Close#62087
In this commit, the `ngServerMode` check is moved outside the RxJS `pipe()` to ensure that server-only logic is excluded from client bundles. Previously, the `tap()` operator and its closure were always included in the output, even though `ngServerMode` was false on the client and the side effect was never triggered.
By guarding the observable chain earlier, this reduces the RxJS stack frame depth, which simplifies debugging by avoiding unnecessary operator noise in client-side stack traces.
The resulting logic is also easier to reason about and avoids evaluating `HttpResponse` instances where not needed.
PR Close#62238
Adds support for `getEncodedSemanticClassifications` to the language service.
The service now classifies components in a template as the `class` type.
PR Close#60260
1. Fix node coordinates origin – now X and Y represent the exact center of the node
2. Improve links – they now start and end precisely at the nodes' edges
3. Fix node click to zoom/focus/snap (thanks to 1.)
4. Fix vertical orientation links
PR Close#62048
Previously these tests would run automatically when Angular DevTools lived in another repo. These files have continued to live here but have not been running automatically on each PR.
Now, these test files have been revived to run properly with our changes since the repo merge. This is a first step to reviving our e2e testing.
Next steps include writing cypress tests for new features like Injector Graph, Router tree, signals visualizations, etc.
PR Close#61972
This commit prevents lazy injection of the internal `ErrorHandler` from a destroyed injector, as it would result in another "destroyed injector" error.
PR Close#61886
Similar to `DestroyRef`, this adds the `destroyed` property to
`EnvironmentInjector`. It also has the ability to register callbacks with
`onDestroy`, which throws if `destroyed` is already `true`.
This also omits the bit about whether those callbacks have executed
since I realized the property is set to `true` before executing the
callbacks.
PR Close#61951
In this commit, setting `window.history.scrollRestoration` is wrapped in a try-catch block to prevent `SecurityError` exceptions in restricted contexts such as:
- sandboxed iframes
- partially navigated or inactive windows
- test runners, extensions, or content previews
If an error occurs, a runtime warning with error code [2400] is logged to the console. This avoids breaking app initialization and improves cross-browser safety.
Unfortunately, it's not possible to perform any end-to-end testing of this fix.
PR Close#62186
This updates the loader code to run the `loadComponent` and
`loadChildren` functions in the appropriate injection context for the
route.
A primary motiviation for this feature is to bring `loadChildren` with
standalone components and the routes array to
feature-parity with what was possible when using `loadChildren` and a
module that provided routes via the `ROUTES` token and a factory
function (which would have injection context).
fixes#51532
PR Close#62133
Fixes that the logic recognizing initializer APIs didn't account for the expression being wrapped in an `as` expresion or in a parenthesized expression. This was already accounted for in the diagnostic so these changes align the behavior between them.
Fixes#62197.
PR Close#62203
Currently we have a `ParserError` that is used for the expression parser and a `ParseError` that is used everywhere else. These changes consolidate them into the `ParseError` to avoid confusion and make it easier to add more context in the future.
PR Close#62160
Fixes that `getDeferBlocks` wasn't accounting for the case where a component might be injecting `ViewContainerRef`. When that happens, an additional wrapper is introduced that needs to be accounted for when traversing the tree.
Fixes#62047.
PR Close#62156
Adds a field to the directive's metadata tracking whether it has directive dependencies. Knowing this will allow the pipeline to decide whether to produce DOM-only or full instructions.
PR Close#62096
When providing the code action for the directive that is exported by multiple modules
in different files, the directive must save all the TS completion entry data
for every module to compute the module specifier.
When providing a completion item, because the LS only supports displaying one directive
at a time, the first one will be picked.
PR Close#62100
docs: fix reference
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
docs: grammar fix
Co-authored-by: Jeremy Elbourn
docs: update docs reference
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: update docs reference
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: update docs reference
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: update docs reference
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: update route guard title
docs: update route guard types to table
docs: improve phrasing on activated route snapshot description
docs: improve comments to explain how route guard child works
docs: enhance route guards with more explainers and examples
PR Close#62104
This updates the timeouts in a couple flakey router tests. Ideally we can use the jasmine
auto ticking as soon as tests are migrated to web test runner and we are on the latest
version of jasmine
PR Close#62141
Spec updates are in https://github.com/whatwg/html/pull/10919
For the most part, the updates revolve around the deferred commit
handling (with precommitHandler). Updates to redirect allow more
options. A committed promise now exists on the transition since commits
can be delayed. Tests were made zoneless for easier debugging and
timeouts were reduced.
PR Close#62017
Hybrid applications trigger a digest when `onMicrotaskEmpty` emits so
that the AngularJS app can run its lifecycle when the Angular app does. For
ZoneJS applications, this is effectively after every render/app tick. This change
updates the code to use `afterEveryRender` instead.
fixes#61640
PR Close#61660
Fixes: #61900
Previously in DevTools we would read signal values to display preview values in the UI without safely catching any errors thrown in their evaluations.
Now those signal functions are run in a safe context, their errors are caught and handled in the UI as well as replayed in the console.
PR Close#61911
Support to add the missing required inputs into the element and append
after the last attribute of the element.
But it skips the structural directive shorthand attribute. For example,
`<a *ngFor=""></a>`, its shorthand is `<ng-template ngFor>`, the `valueSpan`
of the `ngFor` is empty, and the info is lost, so it can't use to insert
the missing attribute after it.
PR Close#50911
It seems that new jasmine_test runner times out with the larger size shards, by splitting into double the shards the test consistently passes as expected
PR Close#62119
Fixes the following issues with the logic in the unused imports migration that deals with trailing commas:
1. It was generating overlapping text ranges which can break internally.
2. It wasn't handling some cases that produce trailing commas.
PR Close#62118
This commit updates the global error listener to wrap the global ErrorEvent in a new Error with cause
if the error property is undefined.
fixes#62078
PR Close#62081
The value literal table listed tagged template strings as both supported and unsupported. The row under Unsupported literals was removed.
PR Close#62082
docs: update language block
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
docs: enhance redirects function docs
docs: fix future tense usage
docs: update phrasing to be present tense
docs: update redirect guides to use better phrasing and examples
docs: fix typo on code example
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: fix typo in code example
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: update syntax of code snippet
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: update description on redirect function and api docs
PR Close#62005
Adds support for passing in `Binding` objects into `TestBed.createComponent`. This makes it easier to test components by avoiding the need to create a wrapper component. Furthermore, it keeps the behavior consistent between tests and the actual app. For example, given a custom checkbox that looks like this:
```typescript
@Component({
selector: 'my-checkbox',
template: '...',
host: {'[class.checked]': 'isChecked()'}
})
export class MyCheckbox {
isChecked = input(false);
}
```
A test for the `isChecked` input would look something like this:
```typescript
it('should toggle the checked class', () => {
@Component({
imports: [MyCheckbox],
template: '<my-checkbox [isChecked]="isChecked"/>',
})
class Wrapper {
isChecked = false;
}
const fixture = TestBed.createComponent(Wrapper);
const checkbox = fixture.nativeElement.querySelector('my-checkbox');
fixture.detectChanges();
expect(checkbox.classList).not.toContain('checked');
fixture.componentInstance.isChecked = true;
fixture.detectChanges();
expect(checkbox.classList).toContain('checked');
});
```
Whereas with the new API, the test would look like this:
```typescript
it('should toggle the checked class', () => {
const isChecked = signal(false);
const fixture = TestBed.createComponent(MyCheckbox, {
bindings: [inputBinding('isChecked', isChecked)]
});
const checkbox = fixture.nativeElement.querySelector('my-checkbox');
fixture.detectChanges();
expect(checkbox.classList).not.toContain('checked');
isChecked.set(true);
fixture.detectChanges();
expect(checkbox.classList).toContain('checked');
});
```
PR Close#62040
Errors:
- Attempting to translate SVGs when the tab is not on focus (Regression from #61241)
- Null injector node focus error
Extra:
- Improve scoping of the injector-tree component class members
PR Close#62029
In this commit, we request `APP_ID` outside the `onDestroy` callback because the injector might already be in a destroyed state when the callback runs.
PR Close#61885
This seems to be helpful for Mozilla reviewers to reproduce the build without encountering Bazel errors like:
```
Server terminated abruptly (error code: 14, error message: 'Socket closed', log file: '/home/parallels/.cache/bazel/_bazel_parallels/ae710c6507eb251f9511ac4228641059/server/jvm.out')
```
`--local_ram_resources` is also useful, but I'm not sure what to set it to by default or how necessary it is, so let's just start with `--jobs 4` for now. The 4 is arbitrary as I don't have insight into how many jobs are actually appropriate, but we can go with this for now and tweak the number later if it still causes issues.
PR Close#62015
Projected nodes were missing ssrId information and were skipping annotating template information, which caused templates to be destroyed and recreated rather than hydrated.
fixes: #50543
PR Close#61989
Due to a bug that is currently in progress of being resolved in the
`rules_js` toolchain (see:
https://github.com/aspect-build/rules_js/issues/362), we were seeing
subtle differences between `main` and PRs/local builds as RBE is a
strict sandbox environment while the normal linux/darwin sandbox isn't
necessarily.
This commit fixes the issue by avoiding the interop targets that don't
bring in the actual transitive node modules.
PR Close#62027
Temporarily updates the new Node loader to work with `zone.js` `.mjs`
files that are still ending up at runtime due to this package using
`ts_library`.
PR Close#61902
Due to `resource()` not retaining its value while there is a request in progress, the results list flickers. The new `searchResults` signal retains that previous value until the request is completed.
PR Close#61935
Due to `resource()` not retaining its value while there is a request in progress, the results list flickers. The new `searchResults` signal retains that previous value until the request is completed.
PR Close#61935
We defer the update until after rendering
is complete for two reasons: first, to avoid repeatedly calling
`writeValue` on every option element until we find the selected one
(could be the very last element). Second, to ensure that we perform the
write after the DOM elements have been created (this doesn't happen
until the end of change detection when animations are enabled).
This is needed to efficiently set the select value when adding/removing options. The
previous approach resulted in exponentially more `_compareValue` calls than the number
of option elements (issue angular#41330).
Finally, this PR fixes an issue with delayed element removal when using the animations
module (in all browsers). Previously when a selected option was removed (so no option
matched the ngModel anymore), Angular changed the select element value before actually
removing the option from the DOM. Then when the option was finally removed from the DOM,
the browser would change the select value to that of the first option, even though it
didn't match the ngModel (issue angular#18430). Note that this is still
somewhat of an application problem when using `ngModel`. The model value
still needs to be updated to a valid value when the selected value is
deleted or it will be out of sync with the DOM.
Fixes#41330, fixes#18430.
PR Close#61949
This ensures that test functions with arguments (e.g. `it.each` in jest)
are forwarded to the test function. This does not apply to jasmine,
which assumes the only arguments needed would be the `done` function.
fixes#61717
PR Close#61755
Add overrides for the default background colors of some the Material components currently in use by Devtools. Most likely a regression by a recent Material version bump.
PR Close#61969
This commit adds the ability to set the decoding attribute in NgOptimizedImage. It proxies the binding onto the host image element. If no binding is provided, it defaults to "auto", which matches the browser's default behavior. This approach avoids any breaking changes resulting from the update.
PR Close#61905
The reveal answer button accidentally loads files into the embedded
editor that aren't properly relativized. This ends up switching the
currently open file to a different file, unexpectedly.
In addition, due to the incorrect paths, files like `favicon.ico` end up
being loaded in the embedded editor; resulting in a bad experience as
the images are shown as plain text.
PR Close#61925
when marked for traversal the reactive context has to be set to null to avoid inheriting the reactive context of the parent component
PR Closes#61662
PR Close#61663
This commit configures Renovate to automatically apply 'target' labels to pull requests based on their base branch.
- `main` branch will get `target: minor` label.
- Other branches will get `target: patch` label.
PR Close#61894
Migrates the partial compliance tests to `rules_js`. Also as part of
this, we re-enable RBE to see if that fixed the issues, or in case
they are already resolved from the RBE side.
PR Close#61865
For the `rules_js` migration, we are facing the problem where
our current Angular code is shipped as ESM, but we aren't fully
there yet with fully compliant strict ESM during development.
That is because we lack explicit import extensions, and it's also a
different story how this would work in Google3, if we were to add them.
In addition, we cross-import from our packages using npm module names.
This works well for TS, for ESBuild because those can respect path
mappings— but at runtime, when executing native `jasmine_test`'s— such
mappings aren't respected. The options here are:
- avoid module imports in the repo (impossible; undesired)
- use pre-bundling of all NodeJS execution involving npm package code
(slower, extra build action cost)
- wire up a simple NodeJS loader (supported via official APIs) to simply
account for our cases (preferred and similar to what we experimented
with for the last year(s); and worked well)
This commit implements the last option and allows for an easy migration
to `rules_js`, and also is pretty reasonable. Long-term we can resolve
the extension problem if we e.g. migrate to real explicit extensions + a
proper TS module resolution like e.g. `nodenext`.
PR Close#61865
We should remove the `onDestroy` listener once subscription is unsubscribed because components might not be destroyed yet, but they still would capture subscribers.
PR Close#61882
This makes a few changes to try to smooth over the process:
1. Updates changelog commands to filter out `refactor` commits.
2. Tweaks the changelog command to generate a markdown list for easy copy-pasting.
3. Links directly to the store pages to cut down on clicks.
4. Moves the source code section a bove the reviewer note and changelog, to match the ordering of the Firefox Add Ons form.
PR Close#61883
Update the bazel query for finding all releasable packages to look for all targets with the name
`npm_package` that contain the expected tag.
PR Close#61879
This commit unregisters the `onDestroy` listener when `destroy()` is called on the `ResourceImpl`. This prevents memory leaks and ensures that the resource reference is not captured in the destroy callback after it has already been destroyed.
PR Close#61870
In this commit, support for `pushsubscriptionchange` events has been added to the service worker Driver.
When the push subscription changes, the Driver now captures the event and broadcasts a `PUSH_SUBSCRIPTION_CHANGE` message to clients. This ensures the application is aware of push events and can react accordingly.
Unfortunately, it's not possible to perform any end-to-end testing of this feature.
The push subscription change event exists in both Blink and Gecko. It is also supported in the latest version of Chrome, which means we can give users the ability to react to this event in order to gather feedback on whether other components might need updates.
PR Close#61856
In this commit, we mark the `SwPush` and `SwUpdate` classes as root providers. As a result, they are no longer statically referenced in the `provideServiceWorker` providers list, which previously forced them to be explicitly bundled into the main file. These classes might never be used—some consumers may use the service worker only for prefetching and caching assets.
Practically speaking, even if a user injects the `SwPush` class without calling `provideServiceWorker()`, it would result in a DI error because the communication channel dependency is not available. There is no practical reason to keep these classes as non-root providers or to reference them explicitly.
Currently, some users work around this by using `patch-package` to modify the service worker code and remove these classes from the providers list.
PR Close#61670
Since `DestroyRef.onDestroy` throws if the `DestroyRef` is already
destroyed, there is a need to be able to tell if it is already destroyed
before attempting to register a callback.
PR Close#61849
This works for the code actions and completion. When the ls wants to complete
all importable angular metadata in the template, the ls will invoke the function
`ls.getCompletionsAtPosition` and filter the item about the angular. When the
developer selects an item, the ls will get the module specifier from the code action
return by the `ls.getCompletionEntryDetails`.
PR Close#61122
Previously this would throw an error on the assertLView when we try to discover the templateLView.
Now this properly returns null for the template consumer and continues discovering other effects on the injector.
PR Close#60772
Adds fix directly for `takeUntilDestroyed` to unsubscribe when already
destroyed instead of putting
synchronous behavior on `DestroyRef.onDestroyed` callback as in #58008fixes#54527
PR Close#61847
Change the command to execute the migration, because the command stated in the previous version results in the error "Cannot find migration 'control-flow-migration' in '@angular/core'.". The new command is more in line with the docs of other migrations.
PR Close#61816
Refactor createSignal to return a tuple instead of a signal getter. createSignalTuple will be removed in a follow up pr once createSignalTuple usages in google3 are migrated to createSignal.
PR Close#61705
The observable terminates immediately when `error` is called, and no further emissions or completion notifications occur. Thus, we have to remove the listener in both the `error` and `complete` notifications.
PR Close#61596
Implements a compiler transform that attempts to statically analyze variable names and apply them to usages of signal functions like signal, computed, effect, etc.
PR Close#57348
Previously, multiple simultaneous calls to `checkForUpdate()` could result in redundant
fetches and hashing of the update manifest, leading to unnecessary network and CPU usage.
This change introduces a mechanism to track an in-progress update check using a cached
promise (`ongoingCheckForUpdate`). Subsequent calls to `checkForUpdate()` while a check
is in progress will return the same promise instead of triggering a new request.
Once the check completes (successfully or not), the cached promise is cleared,
allowing future update checks to proceed normally.
This improves efficiency and prevents overlapping update logic in applications that
may invoke `checkForUpdate()` from multiple sources (e.g. polling, manual triggers).
PR Close#61443
In this commit, support for `notificationclose` events has been added to the service worker Driver.
When a notification is closed (either by user dismissal or programmatically), the Driver now captures the event, extracts the relevant notification options, and broadcasts a `NOTIFICATION_CLOSE` message to clients. This ensures the application is aware of notification lifecycle events and can react accordingly.
PR Close#61442
The code editor tooltip exhibits some weird bug when there is a margin applied. The root issue is unknown but at least it improves the current situation.
fixes#60923
PR Close#61782
Similarly to the previous change to the expression AST, these changes replace the `WriteVarExpr`, `WriteKeyExpr` and `WritePropExpr` from the output AST with a binary expression. This is closer aligned to TypeScript and makes it easier to translate code between the two.
PR Close#61682
Currently our expression parser produces two different expressions for writes: `PropertyWrite` (e.g. `foo.bar = 123`) or `KeyedWrite` (e.g. `foo[0] = 123`). This is inconsistent with other ASTs, like TypeScript's, where writes are represented as binary expressions with a `=` operator and it makes it difficult to implement more write operators like `??=`, because we'd essentially have to duplicate them.
These changes switch the expression parser over to produce binary expressions instead.
PR Close#61682
This update ensures that the service worker can handle range requests, allowing video seeking to work correctly when videos are delivered by the service worker.
PR Close#60029
The bazel npm package is no longer needed and currently breaks
as we started using a 1P pnpm linked package that would otherwise
end up being pulled into this legacy rule.
PR Close#61826
This commit migrates the remaining pieces of `compiler-cli` to
`ts_project`. This involves a few more things during migration:
- the `ng_module` ngc_wrapped rule broke as part of this change, so we
switched it to `ts_project` too. This logic is soon gone anyway.
- we needed an extra pnpm "package.json" for the linker babel test. This test is
loading from the real compiler-cli npm package. Babel needs a real
node module for this, so this solution seems reasonable. It may be
worth exploring in the future to move this test into an integration
test though.
- the older integrationtest in compiler-cli is removed as the coverage
is much better with the compliance test suite and this test.
PR Close#61826
When the expression parser consumes tokens inside a parenthesized expression, it looks for valid tokens until it hits and invalid one or a closing paren. If it finds an invalid token, it reports and error and tries to recover until it finds a closing paren. The problem is that in such cases, it would produce the `ParenthesizedExpression` and continue parsing **from** from the closing paren which would then produce more errors that add noise to the output and result in an incorrect representation of the user's code. E.g. `foo((event.target as HTMLElement).value)` would be recovered to `foo((event.target)).value` instead of `foo((event.target).value)`.
These changes resolve the issue by skipping over the closing paren at the recovery point.
Fixes#61792.
PR Close#61815
Commit 3e70d64 introduced cdk version 20.0.0-rc2 which introduced a change to how the cdk virtual scroll sets some internal state.
Previously in DevTools we were using a computed incorrectly to respond to changes in the directive forest and apply them to the underlying datasource. With the change to the CDK shown above, this incorrect usage caused us to attempt to update underlying signals in the virtual scroll directive while within a computed callback, throwing an error.
This commit corrects our usage by swapping from a computed to an effect, allowing the underlying signals in the scroll directive to be updated without error.
PR Close#61812
Currently we reuse the same binding parser for all expressions in the template. Under the hood, the parser has a single `errors` array that it passes into all ASTs which means that if there's one binding with an error, those errors will be propagated to all other ASTs in the template.
These changes switch to having a unique `errors` array for each AST so we only report errors once.
Relates to #61792.
PR Close#61793
This ensures that the new optimization rule, and also adev (when we
complete migrating it to `rules_js`) can use the latest compiler-cli
version from HEAD.
PR Close#61810
When defer blocks have a reference-based trigger without a parameter, we infer it from the placeholder block. This requires some validations like ensuring that there's only one element in the placeholder. The validations are currently implemented at the parser level which can affect tools like linters that need to pass `preserveWhitespaces: true` in order to get accurate source mappings.
These changes move the validations into the template type checker so that they still get flagged, but much later in the process. Moving them over involves a bit more work, because the template type checker also sets `preserveWhitespaces: true`.
Fixes#61725.
PR Close#61747
This commit updates runtime logic to produce an error when there are some `@defer` blocks with `hydrate` triggers, but the incremental hydration is not enabled via `withIncrementalHydration()`. Previously the check was only detecting the case when `withIncrementalHydration()` is present on the server, but missing on the client. With the change in this commit, the check would be performed on the server as well.
PR Close#61741
Follow-up to #61674 where we were leaving behind some whitespace, e.g. `[One, Two, Three]` would turn into `[One ]`. These changes only preserve the whitespace if the node is preceded by a newline.
This wasn't caught by tests, because they were stripping away whitespaces before asserting. I've also reworked the tests to be sensitive to formatting changes.
PR Close#61698
Updates the current list of DevTools reviewers to make a few small changes.
1. Adds `hawkgs` and `milomg`.
2. Removes the leading `~` from `JeanMeche` to include him in automatic review requests.
3. Adds `jkrems` for additional Googler coverage in automatic review requests.
4. Removes `mgechev` and `MarkTechson` who haven't been involved in daily DevTools development for a while.
5. Adds the leading `~` to `devversion` and `josephperrott` to remove them from automatic review requests while leaving them with access for "break glass" situations.
Note that the leading `~` means that the individual may approve PRs and satisfy the group's requirement, but PullApprove will not automatically request a review from them. See https://v3-docs.pullapprove.com/config/reviewers/#reviewers-that-dont-want-review-requests.
PR Close#61709
Reworks the `declareTemplate` function, that we use both in the `template` instruction and in other template-based code like control flow and `@defer`, so that it's split up into a function with directive logic and one without. For anything except the `template` instruction we don't need the directive matching and lifecycle hook logic.
Also introduces a DOM-only instruction called `domTemplate`.
PR Close#61718
Adds the new `domElement` and `domElementContainer` instructions that are the equivalent of the `element` and `elementContainer` instructions, but will allow us to skip the following overhead when we know that there are no directives:
* Directive matching.
* Directive instantiation.
* Lifecycle hook management.
* Content query execution.
PR Close#61718
Re-exports the `FileSystem` type since it's used by some tsurge migrations and because internally the barrel export from `ngtsc/file_system` is removed.
PR Close#61697
On clicking a route in the router tree, the route details panel is displayed.
- The panel shows the details of the selected route, including the path, component, providers, guards etc.
- Clicking on a chip will navigate to the corresponding source file in the editor.
- Clicking on the path will navigate to the corresponding route in the router tree.
Demo Application Source: https://github.com/sumitarora/angular-routes-demo
Demo Application Deployed: https://sumitarora.github.io/angular-routes-demo/#/
PR Close#59999
Fixes a typo in the "Lazily loaded components" section of the define-routes.md guide.
The path for the home-page component was incorrectly written as ',' instead of ''.
PR Close#61740
We are dropping the custom ESBuild and Terser pipeline from dev-infra
and instead leverage the Angular CLI directly. This commit adjusts
the benchmarks to use this new rule.
PR Close#61566
Instead of dev-infra maintaining a custom ESBuild + Terser pipeline that
tries to emulate the Angular CLI, we are switching the bundling core
tests to a new rule that really leverages the Angular CLI.
This involves some file renames and small adjustments. In addition, we
leverage the updated symbol tracking rule to output new goldens that can
work with multiple bundle files (as generated by the Angular CLI;
especially with defer and its "lazy" chunks).
PR Close#61566
Since we are going to replace our `app_bundle` rule (custom ESBuild +
Terser pipeline) with the real Angular CLI where shared/lazy/common
chunks may exist, we need to update the symbol extractor to support
multiple files.
We could have just merged all symbols, but this commit tries to do
better by detecting what symbols are loaded eagerly vs. lazily. This
will be very useful for e.g. defer tests or other lazy features we are
introducing in the feature.
PR Close#61566
The `app_bundle` rule does not work after the migration of
`packages/compiler` to `ts_project` because the `.mjs` extensions are
now missing in the non npm-package output.
This causes runtime errors as `.js` is not recognized as ESM. Switching
to the real npm package for usage, fixes this issue.
PR Close#61566
Currently when linking the `@angular/compiler-cli` package, the peer
dependency to `compiler` is not resolved and we are trying to make the
compiler dependency available via `data`. This is unidiomatic and
brittle. This commit fixes this.
PR Close#61566
Compiler now would have `.js` files. Those aren't picked up as ESM,
unless we install the `package.json` with `type: module`. Sounds great
on paper, but doesn't work in reality because the way the compiler
packages are available to `api-gen/` is via the old `rules_nodejs`
linker, so the `packages/package.json` wouldn't work; nor do the
`package.json`s of the e.g. compiler-cli package work- because those
already contain the `exports` of the built npm package.
We fix this in a much more reasonable way, and the whole module
resolution problem by leveraging the pnpm linking here. This works as
expected.
PR Close#61566
Removes the following unused code from the compiler:
* The ICU expander appears to be some really old code converting ICUs into legacy-style control flow directives. It's annoying to keep this one since we need to update it any time the AST changes.
* The `PipeCollector` class wasn't used anywhere.
* The `partitionArray` function wasn't used anywhere.
* The `newArray` function was used only in one test and it can be easily replaced with `new Array().fill`.
PR Close#61668
In this commit, we switch from using the `isPlatformServer` runtime call to the `ngServerMode`.
Note: constructors haven't been touched in order to prevent any breaking changes for the public API.
PR Close#59496
Replaces the `propertyInterpolateX` instructions with calls to `property` and the `interpolate` helper. This allows us to drop the dedicated interpolation instructions and simplify the runtime for future work.
PR Close#61639
Updates the `ɵɵinterpolate` instruction so it doesn't call into `interpolation1` under the hood since it requires a prefix/suffix and we know there isn't one.
PR Close#61639
Replaces the `classMapInterpolateX` instructions with `classMap` plus a call to `interpolate` in order to simplify the runtime. The only difference between `classMapInterpolateX` and `classMap` was that the former passes `keyValueArraySet` into `checkStylingMap` while the latter passes `classKeyValueArraySet`. This doesn't appear to matter, because the interpolation instructions always have a string value which means that the function is never called.
PR Close#61639
Replaces the `styleMapInterpolateX` instructions with the existing `styleMap` and a passed-in interpolated value in order to simplify the runtime.
PR Close#61639
The hardcoded config was introduced because suppressing the diagnostic
via `extendedDiagnostics` in the TS config was unreliable in google3.
This has since been fixed and the workaround is no longer needed.
PR Close#61622
Disables creation of the esbuild meta.json file, which is not utilized in the build process. This streamlines the output and avoids generating unused artifacts.
PR Close#61636
Prevents esbuild generated metadata files from being included in build artifacts. This reduces package size and avoids shipping unnecessary internal build data.
PR Close#61636
This commit removes the direct dependency on TypeScript within the linker, addressing a performance overhead that was adding between 500ms to 1s to compilation times for applications.
The primary cause of this overhead was the linker's direct reliance on TypeScript's which was caused by importing from barrel files. While convenient, barrel files are detrimental to code splitting and code motion. They force the bundling of all exported modules, even if only a subset is actually used.
By removing the usage of this barrel file and restructuring the imports to be more granular, we can avoid unnecessary TypeScript imports.
Furthermore, TypeScript has now been changed to an optional peer dependency as using only the linker does not require TypeScript.
PR Close#61618
An initial guide to use the experimental unit testing system with the
vitest runner has been added. This includes setup instructions for switching
from the karma/jasmine based system.
Additional content for configuration and potential migration of existing
projects may be added in future changes.
PR Close#61483
`fakeAsync` does not work if the zone-testing polyfill is included after
@angular/core/testing is loaded. This allows fakeAsync to work
even if the zone-testing is included later.
PR Close#61375
All usages of the `DtsTransform` interface leave these two methods
`undefined`, so we can remove them, as well as all code invoking them.
PR Close#61610
add a function that we can inspect to jump to the source of a signal, and give every signal a unique id
that devtools can use to match signals across calls to getSignalGraph
PR Close#61541
In this commit, we check whether the application is destroyed before calling `serviceWorker.register(...)`. We should not register the worker because other resources will not be available.
PR Close#61101
When the resource is loading after reloading from the error state reading `Resource.value()` would return the default value instead of throwing an error.
This change prevents `Resource.hasValue()` from throwing an error in such a case.
PR Close#61441
`Resource.error` used to return `unknown`. Now it's `Error | undefined`.
For non-`Error` types they are encapsulated with the `Error` type.
PR Close#61441
This change also decorelate the `reset` type argument from `TValue` by adding a 3rd generic parameter to `AbstractControl`.
This improves the typings overall.
PR Close#55860
The observable terminates immediately when `error` is called, and no further emissions or completion notifications occur. Thus, we have to remove the `abort` listener in both the `error` and `complete` notifications.
PR Close#58306
Updates the `bindingUpdated` function to handle `NO_CHANGE` instead of throwing. This will allow us to reuse instructions across more cases.
PR Close#61557
Replaces the attribute interpolation instructions with `attribute` plus the new `interpolateX` instruction. This allows to reduce our overall instruction footprint.
PR Close#61557
Adds the new `interpolate*` instructions that can be passed into other instructions and used to replace our existing flavors of interpolations.
PR Close#61557
When passing bindings as arguments or storing them before use in
`createComponent`, it's handy to be able to reference this type.
The current workaround is to use `ReturnType<typeof inputBinding>`.
PR Close#61351
Streams left in a pending state (due to `break` without cancel) may continue consuming or holding onto data behind the scenes. Calling `reader.cancel()` allows the browser or the underlying system to release any network or memory resources associated with the stream.
PR Close#61528
This ensures that `TestBed.tick` updates any components created with
`TestBed.createComponent`, regardless of whether autoDetectChanges is
on.
PR Close#61382
In the initial implementation for experimental fast type declaration
emission introduced in e62fb35, external references in host directives
were not supported at all.
This change adds support for direct external references in host
directives. Any other expressions indirectly using external references
are still not supported.
PR Close#61469
In other parts of the code, calls to the `assertInInjectionContext` function are guarded with `ngDevMode`. This change aligns these parts of the code with other implementations that drop such assertions in production.
PR Close#61564
Currently we construct the HMR replacement URL inline by calling into the native `URL` constructor. This can cause conflicts with user code that defines a symbol called `URL`.
These changes resolve the issue by moving the URL construction into a separate function. This has a secondary benefit of making the generated code easier to follow and allowing us to update the URL without changing the compiled code.
Fixes#61517.
PR Close#61550
In other parts of the code, calls to the `assertInInjectionContext` function are guarded with `ngDevMode`. This change aligns these parts of the code with other implementations that drop such assertions in production.
PR Close#61560
enforce content to be fluid until a specific max width, and rollback breakpoints to be applied when 1430px is the current win size
as widths between 1430px and 1431px will be broken
PR Close#61384
The code was not compatible with property renaming so it was always
using _lView. This didn't matter because they're always the same for the
only place the function is used. Casting to any would fix the
renaming problem but introduce a risk of getting "broken" by a refactor
that changes the private variable name. This change removes the
private member access entirely.
PR Close#60918
This change ensures that prior results for all files are retained even when
a request is made such that we only need a shim for a single file. Prior
to this change, any prior results that were not part of the request were discarded.
PR Close#61487
Avoids duplication of the `FactoryTarget` enums. This is necessary
now because we are exposing the previously deeply-imported JIT facade
now via the exports; and the typing integration tests surface a type
conflict due to the different duplicated enums.
PR Close#61472
These helpers are often imported by various tests throughout the
repository, but the helpers aren't exported/exposed from the public
entry-point; even though they confusingly reside in there.
This commit fixes this, and moves the helpers into
`packages/private/testing`. This is a preparation for the `ts_project`
migration where we don't want to leverage deep imports between packages.
PR Close#61472
Use an unstamped version of the compiler when it runs in `ng_project` as it will get stamped appropriately
whenever the generated code gets stamped after its usage."
PR Close#61479
Not sure what changed overnight, but Renovate is now committing .npmrc files that we didn't generate.
Example: https://github.com/angular/angular/pull/61492/files
We should revisit this once we transition away from Yarn.
PR Close#61494
This commit exposes the experimental enableProfiling() API that
enables Angular integration with the Chrome DevTools performance
panel. Previously this integration was exposed on the ng. namespace
only but there are legitimate cases where developers might want to
expose the integration earlier (ex.: bootstrap profiling).
PR Close#61465
Our intention was to remove TestBed.flushEffects() in Angular v20
as it was a developer preview API that doesn't need to follow our
deprecation policy. It turned out, though, that the angular.dev
documentation wasn't displaying the @developerPreview annotation
properly so some of the developers might have been unaware of the
non-stable nature of this API.
This commits re-introduces the TestBed.flushEffects() API. This
API call will delegate to TestBed.tick().
PR Close#61462
Instead of disabling sandbox/workers for every action; which also could
slow-down development turnaround significantly, the flag should only
disable sandboxing for the test actions; allowing for e.g. DevTools to
connect to them, even if they are inside the sandbox.
Arguably, this strategy isn't seemingly necessary in all environments,
but given that we enable network sandboxing in this repo, it seems
reasonable. Ideally we'd also expose `_debug` targets for e.g. Node
tests that have the proper no-sandbox, or requires-network tag.
PR Close#61468
Currently, `yarn ng-dev misc update-generated-files` attempts to update 67 targets, but only 4 actually require updating. Running the full script causes Renovate to slow down significantly, adding around 7 minutes to the process. By replacing it with individual update commands for just the necessary targets, we improve performance and reduce Renovate’s runtime considerably.
PR Close#61467
The logic for the `elementStart` and `elementContainerStart` instructions was identical. These changes consolidate it into a single base instruction.
PR Close#61409
A minor performance improvement for `ɵɵdefineComponent` where the underlying `extractDefListOrFactory` call had a chain of `.map.filter` which meant that we were unnecessarily creating intermediate arrays just to filter out the null values. These changes switch to simple `for` loop to get around it.
PR Close#61445
After nearly a decade of existence, there are 0 uses of
`autoDetectChanges(false)` internally. All uses of
`autoDetectChanges(true)` can be migrated directly to
`autoDetectChanges()` instead.
PR Close#61429
Adds `__PURE__` annotations to non-default `new` expressions to enable tree-shaking, even if they are not referenced. These variables are not dropped when Angular is imported from a module that has `sideEffects` set to `true`.
PR Close#61452
Since the duplication root-cause was solved by the previous commit, we
can revert/drop the logic that was added back then to overcome this
problem with Tsurge.
PR Close#61421
Currently there can be cases, exlusively in 3P, where multiple tsconfig
projects have overlap of source files. This is the default setup of new
CLI applications as well.
When this is the case, Tsurge will treat each tsconfig as an isolated
compilation unit (given the concepts and mental model to support
scalable batching). This is wrong though, and the same `.ts` source file
can appear in two migration invocations; resulting in duplicate
replacements or analysis (depending on the migration).
We've worked around this problem in the past by deduplicating
replacements, or migrating to an ID-based approach with natural
deduplication. This worked, but it's just working around the root cause.
This commit attempts to fix the root cause by adjusting Tsurge to ensure
that no source file ever appears in two compilation units. This is
naively achieved by not adding a source file to a migration unit, if it
was part of a previous one. This is expected to be fine given the nature
of Tsurge migrations that are built to operate on isolated pieces
anyway— so it shouldn't be problematic if e.g. `app.component.ts` ends
up being part of the test tsconfig compilation unit (we avoid this order
though by visiting build targets first).
PR Close#61421
Fixes the `update_all_goldens` script which was throwing, because the query command was also capturing the call into yarn and Bazel which in turn caused it to throw an error. I've also added some validation for the number of targets.
PR Close#61407
* Fixes that the symbol extractor approval script was broken after some recent build changes.
* Fixes the `run_all_symbol_extractor_tests` script which wasn't resolving any targets, because the rule name changed.
PR Close#61407
The commit introduce prettier to format some API entries.
For now we'll do only functions are other are a bit more complex because of the support of deprecation.
fixes#59211
PR Close#61154
Migrates `packages/core/schematics` to `ts_project`. As part of this,
this commit cleans up some of the mixed module types and tsconfigs in
the folder. A single tsconfig (and it's test variant) are now used.
For the shipped schematics, we explicitly use the `.cjs` extension, so
that the bundles are properly recognized as CommonJS; even if they are
part of the `type: module` `@angular/core` package.
The `package.json` with `type: commonjs` is removed from
`packages/core/schematics` as it's no longer needed given the explicit
extension & caused issues as schematics are compiled with ESM but are
only later bundled for shipping & some tests as ESM.
PR Close#61370
As we migrate more and more code to `ts_project`, we are ending up with
`.js` file extensions (ts_library did generate `.mjs` magically).
Since we don't want to get into the business of migrating
`nodejs_binary` targets at this point (in some cases we might)— we
should support pointing to such files.
PR Close#61370
On `19.2` we pass an undefined value to the text-field.
But more generaly, the CVA should protect itself if it doesn't recieve an `undefined` value.
fixes#61299
PR Close#61300
The `getBaseHref` method is called several times per request and currently queries through the entire document. We can speed it up by taking advantage of the fact that the `<base>` can only be a direct child of the `<head>` and is usually defined towards the beginning. Below are some benchmarks for a "Hello world" app before and after this change.
### Before:
```
Running 60s test @ http://localhost:4202
100 connections with 10 pipelining factor
┌─────────┬────────┬────────┬────────┬────────┬───────────┬──────────┬─────────┐
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
├─────────┼────────┼────────┼────────┼────────┼───────────┼──────────┼─────────┤
│ Latency │ 568 ms │ 853 ms │ 901 ms │ 904 ms │ 866.58 ms │ 437.6 ms │ 9915 ms │
└─────────┴────────┴────────┴────────┴────────┴───────────┴──────────┴─────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec │ 490 │ 826 │ 1,006 │ 1,643 │ 1,129.3 │ 234.69 │ 490 │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 10.4 MB │ 17.4 MB │ 21.3 MB │ 34.7 MB │ 23.9 MB │ 4.96 MB │ 10.3 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘
Req/Bytes counts sampled once per second.
# of samples: 60
69k requests in 60.04s, 1.43 GB read
90 errors (90 timeouts)
```
### After
```
Running 60s test @ http://localhost:4202
100 connections with 10 pipelining factor
┌─────────┬────────┬────────┬────────┬─────────┬───────────┬───────────┬─────────┐
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
├─────────┼────────┼────────┼────────┼─────────┼───────────┼───────────┼─────────┤
│ Latency │ 471 ms │ 831 ms │ 889 ms │ 1668 ms │ 835.91 ms │ 467.89 ms │ 9720 ms │
└─────────┴────────┴────────┴────────┴─────────┴───────────┴───────────┴─────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬────────┬─────────┐
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼────────┼─────────┤
│ Req/Sec │ 390 │ 860 │ 1,145 │ 1,572 │ 1,156.77 │ 222.65 │ 390 │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼────────┼─────────┤
│ Bytes/Sec │ 8.24 MB │ 18.2 MB │ 24.2 MB │ 33.2 MB │ 24.4 MB │ 4.7 MB │ 8.24 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴────────┴─────────┘
Req/Bytes counts sampled once per second.
# of samples: 60
71k requests in 60.03s, 1.47 GB read
140 errors (140 timeouts)
```
PR Close#61392
This prevents `core/testing` from throwing an error if ZoneJS is present
but does not patch the test FW APIs such that `fakeAsync` works
automatically. For example, there is currently no patching of the vitest
APIs, so if you try to use Vitest with Zone on the page, it will throw.
PR Close#61376
There were a myriad of problems when using the type: 'cli' for a
tutorial:
* Editor component would flicker the non-cli version first since that
was the default value. Fixed by not showing anything until type is
available
* Editor component still rendered a split screen when there was no
preview. Fixed
* Project initialization was incorrect because the terminal would appear
to be available but really didn't work until dependencies were done
installing. Fixed by sharing initialization with regular project init
and piping the install output to the interactive terminal
* Terminals would not work when going from type: 'cli' to another or
vice versa. This is because the element instance of a terminal cannot
change once it is opened. Fixed by dispoing and recreating terminals
when the element changes
PR Close#61246
This commit implements several enhancements to the adev docs update workflow pipeline:
- **Unify actions:** Merge the workflows into a single one.
- **Optimize Git cloning:** Clone the repo with `--depth=0` only once per push instead of 2 times.
- **Prevent concurrent runs:** Implement concurrency control to automatically cancel in-progress workflow runs for the same branch, ensuring only the latest commit is processed.
PR Close#61253
All entries of the `@angular/platform-browser-dynamic` package are now deprecated.
We now recommend using the `@angular/platform-browser` package instead.
In case a JIT application/testing environment is complaining about missing the compiler also add `import '@angular/compiler'`
DEPRECATED: All entries of the `@angular/platform-browser-dynamic`
PR Close#61043
The Angular class metadata emit structure does not support the use of
private fields. If the class metadata emit is enabled and an ECMAScript
private (i.e., `#` prefixed) member contains a decorator, the member will
now be excluded from the emitting `setClassMetadata` call. This prevents
runtime errors due to invalid syntax.
PR Close#61227
The release process overview is out of date and does not accurately reflect section headers. It's not worth the maintenance effort of keeping it in sync with the rest of the doc.
Added a step 0 to check if there's actually anything to release, reusing the command from later in the doc.
Also makes a few random small corrections to reflect the new release process.
PR Close#60892
This commit adds an import to the `ng_dev_mode.ts` file that augments
`global` to have types for `ngDevMode`.
Notably this change is currently not needed because the file is loaded
by `ts_library` through `tsconfig#files`— but in a separate PR we are
switching the target to `ts_project` which no longer loads all Bazel
dependency files via `tsconfig#files`; resulting in the ambient types no
longer magically being available.
PR Close#61365
In declaration-only emission mode, the compiler extracts the type
declarations (.d.ts) files without full type-checking, which is possible
with sufficient type annotations on exports that can be ensured by the
`isolatedDeclarations` TS compiler option.
This allows us to decouple type declaration emission from the actual
full compilation doing the type-checking, thereby removing the
edge between dependent TS files in the build action graph. In other
words, the compilation of a TS file no longer indirectly depends on the
compilation of all the TS files it imports through its dependency on
their type declarations, because the type declarations themselves no
longer depend on the compilation of their associated TS file.
Without the coupling between type declaration emission and compilation,
compilation time of a TS project is no longer bound dependent on the
depth of the TS dependency tree as we can now build the entire project
with just two entirely parallel phases: 1) emit the type declarations of
all TS files in parallel and 2) compile all TS files in parallel.
Since the Angular compiler adds static metadata fields to components,
directives, modules, pipes and services based on their respective class
annotations, it needs to actively partake in the type declaration
emission in order to provide the types for these static fields in the
declaration.
In this change, we add experimental support for a declaration-only
emission mode based on the local compilation mode, which already
operates without type-checking and access to external type information,
i.e. the same environment as is required for declaration-only emisssion.
Apart from the same restrictions applied in local compilation mode,
there are a few more restrictions imposed on code being compatible with
this initial and experimental implementation:
* No support for `@NgModule`s using external references.
* No support for `hostDirectives` in `@Component`s and `@Directive`s
using external references
* No support for `@Input` annotations with `transform`.
PR Close#61334
Return types for exported functions from the router package have now been
added. This provides preparation for the inclusion of additional linting
rules which will eventually enforce the presence of return types for
functions. It also improves readability and type correctness within the
code.
PR Close#61310
fix new global layout issues, and make other pages adhere to the new centered layout like cli ref page, cli ref details, api ref details pages
PR Close#61256
As we roll out more PRs that migrate to `ts_project`, we need to make
sure that we don't break existing `tsec` targets. This PR copies the
original `tsec` Starlark code and adjusts it to work with the interop.
Note that we don't patch as this would unnecessarily complicate this
file that only exists during migration. Long-term, after migration, we
either need to consider switching to the new ESLint plugin that is being
worked on (I'm in contact with the team), or we send a CL to update the
Tsec Starlark code to keep our changes minimal and avoid scope increase.
PR Close#61275
Follow-up to #61240 that adds renaming support for selectorless components/directives both from the template and from the TypeScript source.
PR Close#61307
Sets up the tests for the selectorless runtime so that we can easily start writing them when we get to it. The tests need to be AoT compiled so they're defined as a separate target from the other `acceptance` tests.
PR Close#61307
Follow-up from https://github.com/angular/angular/pull/61240#discussion_r2084445328. Adds a `isSelfClosing` property on element-like AST nodes so consumers can easily determine if it's self-closing, rather than having to look at the spans. This is useful for migrations and in the language service.
PR Close#61307
Supports arbitrary stats/metrics in Tsurge. This will make
complex analysis easier as we aren't bound to just `Record<string,
number>` counters.
PR Close#61272
The compiler wasn't handling `@let` declarations placed inside i18n blocks. The problem is that `assignI18nSlotDependencies` phase assigns the `target` of i18n ops much earlier than the `@let` optimization. If the `@let` ends up getting optimized because it isn't used in any child views, the pointer in the i18n instruction becomes invalid. This hadn't surfaced so far, because we didn't optimize `declareLet` ops, however once we do, we start hitting assertions that the optimized `declareLet` isn't used anywhere.
These changes resolve the issue by moving the i18n phases after the `@let` optimization.
PR Close#60512
We have some code that avoids `storeLet` calls for declarations only used in the same view, however we didn't previously remove the corresponding `declareLet` calls, because of the following case:
```
@let foo = something$ | async; <!-- First in the template -->
{{foo}}
```
Here we need a `TNode` (created by `declareLet`) in order for DI to work correctly. Since this is only required when using pipes, we can optimize away expressions that do not have pipes.
PR Close#60512
As part of the Bazel toolchain migration we noticed that implicit types
generated by the TypeScript compiler sometimes end up referencing types
from other packages (i.e. cross-package imports).
These imports currently work just because the Bazel `ts_library` and
`ng_module` rules automatically inserted a `<amd-module
name="@angular/x" />` into `.d.ts` of packages. This helped TS figure
out how to import a given file. Notably this is custom logic that is not
occuring in vanilla TS or Angular compilations—so we will drop this
magic as part of the toolchain cleanup!
To improve code quality and keep the existing behavior working, we are
doing the following:
- adding a lint rule that reduces the risk of such imports breaking. The
failure scenario without the rule is that API goldens show unexpected
diffs, and types might be duplicated in a different package!
- keeping the `<amd-module` headers, but we manually insert them into
the package entry-points. This should ensure we don't regress
anywhere; while we also improved general safety around this above.
Long-term, isolated declarations or a lint rule from eslint-typescript
can make this even more robust.
PR Close#61312
Avoid pnpm auto-installing peer dependencies. We want to be explicit about our versions used for peer dependencies, avoiding potential mismatches. In addition, it ensures we can continue to rely on peer dependency placeholders substituted via Bazel.
PR Close#61294
Adds an initial implementation for finding references and renaming to selectorless components/directives.
Finding references should work everywhere, whereas renaming only currently works when initiated from the template.
PR Close#61240
Adds the logic to resolve the template targets for the selectorless component and directive nodes. This is a prerequisite for other functionality.
PR Close#61240
Updates the template type checker to produce symbols for selectorless nodes. This is necessary for integration into the language service.
PR Close#61240
The template symbol builder works by finding the variables referring to template AST nodes with specific offsets and resolving them to directives. Afterwards it goes through the directives and resolves their host directives.
The problem is that host directives are added with the exact same offsets as their host which means they get added once initially and again when resolving host directives.
These changes resolve the issue by de-duplicating them.
PR Close#61240
In the event of an invalid `schemas` field for an Angular module, an
empty schema array will now be used instead of a fatal error occurring.
A build will still fail in this case with the error reported as a
diagnostic. However, for the language service, this allows the module
to exist in the compiler registry and prevents cascading diagnostics
within an IDE due to "missing" modules/components. The originating
schema related errors will still be reported in the IDE.
PR Close#61220
This intends to fix the Angular Language service issues for devtools/adev because it pulls the version from the node_modules and it currently is 14.3.0.
PR Close#61128
take the full width of the page for all the pages that use docs-viewer, also reserve an area for table of contents on-demand
Resolves: #52648
PR Close#58831
This aligns with how angular/components marks their hidden APIs.
`@nodoc` has been broken since the switch to adev, this change should
properly hide the APIs again.
PR Close#61194
Migrates `manual_api_docs` to `rules_js`. Since compiler CLI is ESM
compiled but doesn't have extensions, we can either bundle or simply use
the dependency as type only. This is easier and sufficient for this
use-case.
PR Close#61181
Renovate temporarily modifies the `.npmrc` file during its operations and reverts these changes afterward. However, during `postUpgradeTasks`, the non reverted `.npmrc` will lead to errors when running `yarn bazel sync --only=repo`
See: https://github.com/renovatebot/renovate/discussions/14897
PR Close#61239
Updates the name which accidentally remained unchanged from when I
copied it from the CLI help script
Also marks the PR for merge immediately. The caretaker can sanity check
it, approve it, and merge it.
PR Close#61195
Limits automated cross-repo updates to only follow the 'next' tag when operating on the main branch. This helps avoid unintended updates from other tags and ensures a controlled release process.
PR Close#61215
Replaces incorrect use of GitHub Actions expression syntax `${{CURRENT_BRANCH }}` inside a run block with proper bash variablesyntax `$CURRENT_BRANCH`, preventing 'Unrecognized named-value' errors.
PR Close#61212
This workflow addresses a limitation with Renovate's behavior in fork mode. Renovate does not automatically sync non-default branches in forked repositories.
This workflow automates syncing forked non-default branches with their upstream counterparts. This ensures Renovate can detect and apply updates to these branches, maintaining up-to-date dependencies across all relevant branches.
PR Close#61201
Based on some recent discussions, these changes remove the logic that resolves selectorless references from variables. It also updates the wording so it's clearer where selectorless references are supported.
PR Close#61158
We have several cases where we need a visitor that traverses both the template and expression ASTs fully. Currently we're re-implementing the visitor each time which means that we need to update multiple visitors every time something changes.
These changes add a single base class that we can reuse to simplify such cases in the future.
PR Close#61158
The `RouterLink` href does not depend on the state of the router unless
it uses the `fragment` or `queryParams`. This doesn't bother
unsubscribing from the events if the inputs change in a way to no longer
depend on those values since inputs changing is quite rare (and even
more rare for query params handling or preserveFragment to change).
PR Close#60875
This commit updates the method of setting the href attribute on
`RouterLink` to use built in host binding rather than custom attribute
setting and sanitization. The advantage here would be automatic handling
of the sanitization and avoiding of writing the same value to the DOM
that we had before.
This change does mean that we _always_ write to the href attribute where
before we only wrote to it when the elemnt was known to support `href`.
That said, the implementation attempts to retain behavior that is as
close as possible: the original value of `href` is used and never updated.
PR Close#60875
We don't need this tooling anymore because we are already validating
that there are no circular dependencies via the `ng-dev` tooling that
checks `.ts` files directly.
Also these tests never actually failed to my knowledge.
PR Close#61156
The `false` behavior has existed for a long time but hasn't really
been documented. It's also not _quite_ what the browser would do.
Finally, the page explicitly discourages the implicit `false` way
of preventing default. Biggest motivation (beyond code clarity) are
potential footguns like `(click)="myProp=x()"` which happens to prevent
default behavior iff `x()` happens to return `false`.
Fixes https://github.com/angular/angular.io/issues/2568
PR Close#61184
Dependency updates can no longer be cherry-picked due to hash changes in Aspect lock files. This commit enables Renovate to run directly on the `main` and `20.0.x` branches.
PR Close#61160
Fixes that the runtime was throwing a DI error when attempting to inject a missing `useExisting` provider, despite the call being optional.
The problem was that when the provider has `useExisting`, we do a second `inject` call under the hood which didn't include the inject flags from the original call.
Fixes#61121.
PR Close#61137
Other code may depend on `ngServerMode` and it might have been set
globally / via a bundler. Forcing it to `undefined` in those situations
can lead to hard debug issues where the only symptom is that "suddenly"
browser-specific code paths run on the server and (obviously) break.
PR Close#61106
Fixes that the template binder didn't resolve references to DOM nodes (e.g. `<div #ref></div>` if the matcher being passed in isn't a `SelectorMatcher`.
PR Close#61100
Fixes that we weren't emitting references to selectorless pipes, because we were checking the name of the pipe, rather than the local name of the symbol.
PR Close#61100
These changes connect the dependency analysis data from the previous commits with the template type checker which allows us to fully type check a selectorless component.
Also includes tests for all of the new selectorless behaviors that have been introduced so far.
PR Close#61100
This commit removes the use of the privately exported
PendingTasksInternal everywhere except for Router. A follow-up change
will be done to remove that one as well and delete the private export.
PR Close#61049
There is nothing in the Router that requires ZoneJS and we do not need
`fakeAsync` as a mock clock. We can instead use any mock clock implementation
to speed up test execution.
This removes ZoneJS completely from the bundle of the Router tests.
ZoneJS causes the stacks to be unreadable when combined with the massive
rxjs stack in the router transition.
PR Close#61078
The `ts_project` interop rule that we've built was also used in the
Angular CLI migration, and it allows us to mix `ts_project` and
`ts_library` targets; enabling an incremental migration. Additionally
set up the `ng_project` to replace `ng_module`.
PR Close#61087
This is necessary for an incremental migration to `rules_js` which
requires Bazel v6. Bazel v6 removed the managed directories feature,
which means we no longer can rely on symlinked node modules as the Bazel
repository; but rather need to duplicate dependencies. This is
okay/acceptable to enable the incremental migration.
PR Close#61087
According to the promise specification, promises are not cancellable by default.
Once a promise is created, it will either resolve or reject, and it doesn't
provide a built-in mechanism to cancel it.
There may be situations where a promise is provided, and it either resolves after
the pipe has been destroyed or never resolves at all. If the promise never
resolves — potentially due to factors beyond our control, such as third-party
libraries — this can lead to a memory leak.
When we use `async.then(updateLatestValue)`, the engine captures a reference to the
`updateLatestValue` function. This allows the promise to invoke that function when it
resolves. In this case, the promise directly captures a reference to the
`updateLatestValue` function. If the promise resolves later, it retains a reference
to the original `updateLatestValue`, meaning that even if the context where
`updateLatestValue` was defined has been destroyed, the function reference remains in memory.
This can lead to memory leaks if `updateLatestValue` is no longer needed or if it holds
onto resources that should be released.
When we do `async.then(v => ...)` the promise captures a reference to the lambda
function (the arrow function).
When we assign `updateLatestValue = null` within the context of an `unsubscribe` function,
we're changing the reference of `updateLatestValue` in the current scope to `null`.
The lambda will no longer have access to it after the assignment, effectively
preventing any further calls to the original function and allowing it to be garbage collected.
If Chrome is built with additional flags and run with `--allow-natives-syntax --track-retaining-path`,
we could use `%DebugTrackRetainingPath` to see the distance from the root for `updateLatestValue`
if it's passed directly to async.then, e.g.:
```js
%DebugTrackRetainingPath(updateLatestValue);
// Distance from root 4: 0x123456789abc <JSPromise (sfi = 0x1fbb02e2d7f1)>
```
PR Close#58041
Replaces `PLATFORM_ID` checks with `ngServerMode` within the `HttpXsrfCookieExtractor`. It is not part of the public API, and thus this change should not affect consumers who may have called the constructor directly.
PR Close#59810
This refactor removes the unnecessary `runOutsideAngular` call in the
view transition helper. The resolved promise re-enters the zone in the
transition, so that will trigger the Angular zone anyways. If it didn't do that,
it risks activated the route outside the zone, which is a bigger risk.
Regardless, this function is only run once per navigation, so even if it
_did_ result in an extra promise/timeout inside the zone, this is not
excessive. Using ZoneJS to trigger rendering is known to overreact to events.
Using `OnPush` or zoneless is more effective at mitigating this issue.
PR Close#61068
The inifinite loop test is a real infinite loop and runs until a stack
overflow happens. In addition, all the promise and observable tests are
just duplicates of the other redirects and don't test any additional
logic. Instead, this change updates one test to return an observable and
another to return a promise
PR Close#61076
Adds `__PURE__` annotations to `PROPAGATION_STOPPED_SYMBOL` to enable tree-shaking, even if is is not referenced. This variable is not dropped when Angular is imported from a module that has `sideEffects` set to `true`.
PR Close#61004
The stash event listener is a global function that might be unsafely overridden if multiple microfrontend applications exist on the page.
In this commit, we create a map of `APP_ID` to stash event listener functions. This map prevents conflicts because multiple applications might be bootstrapped simultaneously on the client (one rendered on the server and one rendering only on the client).
I.e., the code that might be used is:
```ts
// Given that `app-root` is rendered on the server
bootstrapApplication(AppComponent, appConfig);
bootstrapApplication(BlogRootComponent, appBlogConfig);
```
Two bootstrapped applications would conflict and override each other's code.
PR Close#59635
As the function in the factory was named `httpResourceRef`, error NG0203 had with the following message:
```
Error: NG0203: httpResourceRef() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`. Find more at https://angular.dev/errors/NG0203
```
PR Close#60022
Currently, the error thrown in `getNgModuleDef` is guarded by `throwIfNotFound`, which is only set to `true` when `ɵɵsetNgModuleScope` is called in production. In all other cases, `throwIfNotFound` is never used in production. This means that if NgModules aren't used, `getNgModuleDef` is never called with the second argument. We can split it into two functions to allow tree-shaking of the error when NgModules aren't used at all.
PR Close#60339
Renderer2 and ElementRef didn't mention the Security-DomSanitizer method, this will add clarity for potential user what to expect. Also swap deprecated "callout" class to docs-alert
Fixes#51208 , #46904
PR Close#60708
This commit wraps the `fn` invocation with `try-finally`, ensuring that the pending task (added in [this commit](https://github.com/angular/angular/commit/d5c6ee432fcd467c09b4d5d5366e731f5c91e8d4)) is always removed.
Prior to this commit, if a subscriber threw an error, it would prevent the application from becoming stable — though this shouldn't happen under normal scenarios because the error should be handled by the RxJS error handler or Angular's error handler.
Errors should not silently prevent the application from being rendered on the server.
PR Close#61028
This commit adds the support for defer block in the Angular DevTools.
@defer block are now visible in the directive tree and give access to defer & hydration details.
This feature also brings support of incrementation hydration.
PR Close#60629
This commit ensures that errors from the `NgZone.onError` subscription
in bootstrap are reported to the internal application error handler.
Practically speaking, this should not affect anything today, as the
application handler goes directly to the `ErrorHandler` from the root.
While TestBed installs an application error handler that rethrows,
`TestBed.createComponent` does not create components through this
bootstrap function.
PR Close#60946
The `ComponentHandler.resolve` method is ~500 lines and is a bit hard to follow due to some very long `if` statements. These changes split the functionality across several smaller methods to make it easier to manage.
PR Close#61018
Currently to create an `R3TargetBinder`, we have to pass some sort of directive matcher, however we also have a couple of use cases where we use the binder to do analysis that's unrelated to directives (e.g. resolving the `@defer` blocks). In these cases having to create a dummy matcher adds some slight overhead and makes the code harder to reason about since it looks like directive matching may be happening.
These changes update the `R3TargetBinder` to allow for `null` to be passed as the directive matcher.
PR Close#61018
An earlier commit that introduced tracking of selectorless directives to the template binder made it so `getDirectivesOfNode` returns _all_ of the matched directives while a new method called `getOwnedDirectives` would return only the ones brought in by the specific node.
In hindsight, this is likely to cause bugs in the future, because it's unclear whether to reach for `getDirectivesOfNode` or `getOwnedDirectives`. These changes remove `getOwnedDirectives` and make it so in selectorless `getDirectivesOfNode` accepts the directive AST node itself.
Another goal of this refactor is that the TCB shouldn't have to check the `selectorlessEnabled` config option.
PR Close#61018
Redirects in the router are handled before `canMatch` guards are evaluated. As a result, `canMatch` will not run for routes that include a redirect. Instead of silently ignoring this misconfiguration, developers should be alerted to help them understand why it doesn't behave as expected.
Closes: #60957
PR Close#60958
Expose `getCleanupHook` as a private export to address integration issues with Vitest. In Vitest, `globalThis.beforeEach` and `globalThis.afterEach` are not available by default. Additionally, these hooks are patched during module evaluation, complicating seamless integration with Vitest.
See: https://github.com/angular/angular-cli/pull/30188
PR Close#61017
Adds a new diagnostic that ensures that a standalone component using custom structural directives in a template has the necessary imports for those directives.
Fixes#37322
PR Close#59443
Add createSignalTuple function to match Wiz array destructuring signal return. This will be the implementation for createSignal once createSignal usages in google3 are migrated to createSignalTuple.
PR Close#60903
This change renames the afterRender to afterEveryRender and marks the
renamed API as stable.
BREAKING CHANGE: afterRender was renamed to afterEveryRender.
PR Close#60999
Setting CSS variables directly is fragile and isn't the officially supported way of override Material styles. Instead the `tabs-overrides` mixin should be used which has validation for the token names.
For future reference, these are the docs for the styling API: https://material.angular.io/components/tabs/styling
PR Close#61008
Adds `__PURE__` annotations to `NOT_SET` and `EMPTY_CLEANUP_SET` to enable tree-shaking, even if they are not referenced. These variables are not dropped when Angular is imported from a module that has `sideEffects` set to `true`.
PR Close#60979
This commit introduces the `TestBed.tick()` method that,
similarly to the `ApplicationRef.tick()`, synchronizes state
with the DOM. It can be used in unit tests to mimic framework's
logic executed in production applications. The `TestBed.tick()`
should be used instead of the removed `TestBed.flushEffects()`.
BREAKING CHANGE: the `TestBed.flushEffects()` was removed - use
the `TestBed.tick()` instead.
PR Close#60993
This commit adds support for the Fetch API's keepalive option when using HttpClient with the withFetch provider.
The change includes:
- Added keepalive to HttpRequestInit interface
- Modified FetchBackend to pass the option
- Added some unit test
PR Close#60621
This commit makes several changes changes to the
`provideExperimentalCheckNoChangesForDebug` API:
* Rename it
* Promote to dev preview
* Apply the exhaustive behavior to _all_ checkNoChanges runs
* Remove `useNgZoneOnStable` option. This wasn't found to be generally
more useful than `interval`
fixes#45612
BREAKING CHANGE: `provideExperimentalCheckNoChangesForDebug` has several
breaking changes:
* It is renamed to `provideCheckNoChangesConfig`
* The behavior applies to _all_ checkNoChanges runs
* The `useNgZoneOnStable` option is removed. This wasn't found to be generally
more useful than `interval`
PR Close#60906
Adds the logic that will generate type checking code in the TCB for the selectorless AST nodes.
Note that we're still missing the logic that determines which symbols are available in the template and exposes them to the template binder. That will come in a future change.
PR Close#60977
Updates the template binder to include information about directives owned by a specific component/directive node and the names of template symbols that don't exist. These will be used when generating the type check block.
PR Close#60977
Updates the `DomSchemaChecker` to require the tag name as a string, rather than the entire DOM node. This makes selectorless a bit easier to intergrate.
PR Close#60977
BREAKING CHANGE:
This commit deprecates `ng-reflect-*` attributes and updates the runtime to stop producing them by default. Please refactor application and test code to avoid relying on `ng-reflect-*` attributes.
To enable a more seamless upgrade to v20, we've added the `provideNgReflectAttributes()` function (can be imported from the `@angular/core` package), which enables the mode in which Angular would be producing those attribites (in dev mode only). You can add the `provideNgReflectAttributes()` function to the list of providers within the bootstrap call.
PR Close#60973
- Highlight only the matched part of the text
- Select the first match by default
- Show the matches count along with the currently selected one
- Minor UI fixes and performance optimizations
PR Close#60672
`ng.getDirectiveMetadata` receives the component instance, not the raw DOM element.
This assumes that `ng.getComponent` is implemented in all environments and that the root element itself is a component.
PR Close#60991
As decided in the Resource RFC, this commit renames `loader` in `rxResource`
to `stream`. Some logic is left in to support gradual rollout of this change
in g3.
PR Close#60919
As decided in the resource RFC, this commit renames the `request` option of
a resource to `params`, including the subsequent argument passed to the
loader. It also corrects the type in the process to properly allow narrowing
of the `undefined` value.
Fixes#58871
PR Close#60919
An outcome of the Resource RFC was that we should use string constants for
communicating the resource status instead of an enum. This commit converts
`ResourceStatus` accordingly.
PR Close#60919
Remove the code related to exposing the response of an HTTP request as a
`Resource` itself, as the final API will not go in this direction.
PR Close#60919
This commit removes the `Compiler` injectee from the `RouterPreloader` constructor. It's unused but was still being referenced in the factory definition: `static ɵfac = ɵɵngDeclareFactory(...)`.
PR Close#60945
This commit wraps the `error` and `unhandledrejection` event listeners so they are installed outside of the Angular zone, because otherwise they trigger change detection whenever the event callbacks are invoked.
PR Close#60944
Adds support for asynchronous redirects in the router, allowing redirect logic to be resolved dynamically (e.g., via API or async function). This enhances routing flexibility and supports more complex navigation scenarios.
BREAKING CHANGE: The `RedirectFn` can now return `Observable` or
`Promise`. Any code that directly calls functions returning this type
may need to be adjusted to account for this.
PR Close#60863
Redirects in the router are handled before `canMatch` guards are evaluated. As a result, `canMatch` will not run for routes that include a redirect. Instead of silently ignoring this misconfiguration, developers should be alerted to help them understand why it doesn't behave as expected.
Closes: #60957
PR Close#60958
This commit moves zoneless from experimental to developer preview.
* Update tag on provider API
* Remove "experimental" from provider name
* Move documentation from "experimental features" to "Best practives ->
Performance" (at least temporarily until there is a better place)
BREAKING CHANGE: `provideExperimentalZonelessChangeDetection` is
renamed to `provideZonelessChangeDetection` as it is now "Developer
Preview" rather than "Experimental".
PR Close#60748
Updates the template binder to account for the new selectorless AST nodes. This is a prerequisite to supporting template type checking of the new syntax.
PR Close#60952
Adds the follow validations to the selectorless template parsing:
* Local references with values are not allowed (e.g. `#foo="bar"`).
* Multiple local references with the same on a component or directive are not allowed.
PR Close#60952
Updates the target binder to allow either a selector-based or selectorless matcher to be passed in. This will allow us to skip some of the overhead when matching directives to nodes.
PR Close#60952
Instead of stabilizing the TestBed.flushEffects() API we intend to
replace it with the tick() method (equivalent of ApplicationRef.tick().
The reasoning here is that we prefer tests running the entire
synchronization process (as in production apps) instead of invoking
parts of the synchronization process in a way that would naver happen
in a running application.
PR Close#60959
This commit adds the support for the `in` keyword as a relational operator, with the same precedence as the other relational operators (<,>, <=, >=)
BREAKING CHANGE: 'in' in an expression now refers to the operator
PR Close#58432
This effectively expands Angular's existing browser support policy to be defined as browsers covered by the "widely available" Baseline (effectively browsers released <30 months ago). Each major version will choose a date shortly before release and pin its version support to the "widely available" Baseline of that date.
For now, I'm arbitrarily picking March 31st as I try to land the general infra and policy change, but we'll likely update the exact date a little closer to the v20 RC.
PR Close#60754
Currently, only forms created with `FormGroupDirective` emit events on
form submission and resetting. This commit extends this behavior to
Template-driven forms also.
Related to #58894
PR Close#60887
The @Attribute decorator will inject null if a host attribute
is missing, but `inject(new HostAttributeToken(...))` will throw
a no provider error. We should set {optional: true} when migrating
an @Attribute decorator. Also allow nonNullableOptional to add
`!` to those declarations.
PR Close#60916
docs: update code snippet
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: update link
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
docs: update syntax highlighting
Co-authored-by: Andrew Scott <atscott01@gmail.com>
docs: correct example links
docs: update load component with more concise syntax
docs: fix link text
docs: fix api docs link formatting
docs: fix callout box types and rendering
docs: truncate properties table
docs: swap constructor routes to use inject instead
docs: add other routing tasks info in subnav and remove duplicate info
docs: fix type conversion param
PR Close#60006
Only require a readonly array as input for router commands instead of a writable array. Router itself does not need writable access to the array of commands. If router requires a writable array somebody on the outside would have to spread a readonly array to a new writable array. We can avoid this by just require what route actually needs.
Fixes#60269
BREAKING CHANGE: Several methods in the public API of the Router which
required writable arrays have now been updated to accept readonly
arrays when no mutations are done.
PR Close#60345
As with `InternalNavigationResult`, this commit adds the `catch` to the
`finished` promise on `InternalNavigationTransition` to avoid unhandled
promise rejections.
PR Close#60816
This adds a page to document the error handling practices, APIs, and features _in the framework_.
It does not contain any application-specific recommendations or
patterns as this information is subjective and domain-specific.
PR Close#60848
If you happen to have node_modules installed for adev tutorials, there would be problems with trying to run adev tests. This excludes those node_modules folders.
PR Close#60872
This moves the commit step to the start of the process and releases after merging it. This has two key benefits:
1. The commit history now reflects the actual release (ex. any DevTools commits before the release commit are actually included in that release). Previously the changes in a release were dictated by the release PR branch, which is an ephemeral target. Other PRs may be merged to `main` before the release PR, and those changes would not be included in that DevTools release.
2. We can now compute a changelog based on this more accurate history.
The downside to this change is that release PRs are now blocking releases in a way they weren't before (which is likely desirable in the grand scheme of things), meaning we need to be more diligent about merging them in a timely manner.
I added a short script for listing DevTools commits since the last release, taking advantage of the more accurate commit history. This should make changelog generation a lot easier, even if there's still a manual process of rewriting the commit message into a line item in release notes.
Also made a few minor cleanup changes such as escaping the markdown in the suggested reviewer note so it can be more easily copy-pasted from the rendered format of this doc.
PR Close#60646
This commit adds a provider that installs listeners on the browser
window to forward unhandled promise rejections and uncaught errors to
the `ErrorHandler`. This is useful for both ZoneJS and Zoneless
applications. For apps using ZoneJS, errors can reach the window when
they happen outside the Angular Zone. For Zoneless apps, any errors not
explicitly caught by the framework can reach the window. Without this
provider, these errors would otherwise not be reported to
`ErrorHandler`.
We will/should consider adding this provider to apps by default in the
cli. In addition, it should be mentioned in the (to be created)
documentation page on error handling in Angular.
relates to #56240
PR Close#60704
This commit exposes the enableProfiling() function which enables
performance data visualisation directly in the Chrome DevTools
performance panel.
PR Close#60789
This commit adds type inference tests for `linkedSignal` usages, to capture their behavior w.r.t.
type inference. Note that there's some situations where type inference doesn't work as you might
expect/hope; these have been included to capture their behavior but may be revisited in the future
if the inference capabilities are expanded for this scenario.
Closes#60423
PR Close#60857
Due to the cyclic nature of `previous`'s type and the computation's return type,
TypeScript isn't able to infer generic type arguments.
Closes#60423
PR Close#60857
Currently, highlighting works only when a directive explorer node is hovered. The change enables this feature on node selection as well.
PR Close#60744
Restructures the examples build rules so that all examples are exposed
through a single file group in adev/src/content/examples.
Also adds a separate filegroup in the same location for just the
embeddable examples and adds it to the APPLICATION_FILES for the docs
app.
This uncovered the fact that some of our examples have broken
non-compiling code. I've excluded these ones from being embeddable for
now, until the breakages can be addressed
PR Close#60778
Restores the ability to have example components rendered alongside the
code. This functionality was broken a while back by #53511.
To enable the embedded preview for an example, add `preview` and
`path=adev/src/content/expamples/component/to/render.ts` attributes to
the `<docs-code>` or `<docs-code-multifile>` tag.
Tested with one of the accessibility examples and it seems to work now.
PR Close#60778
This adjusts code to use `NavigationTrigger` type where appropriate and
moves the `isPublicRouterEvent` next to the private event type union to
make it more obvious that it should be updated along with any updates to
the private type union.
PR Close#60736
The inject tool inserts `const foo = this.foo` if code
in the constructor referenced the constructor parameter `foo`.
If `foo` is a readonly property, we can instead replace `foo` with
`this.foo`. This allows more properties to be moved out of the
constructor with combineMemberInitializers.
For now, it only touches initializers, not all of the code in the
constructor.
PR Close#60713
This is a follow-up to the recent devtools linking change, leveraging
the dedicated package that we are also using in the components
repository; avoiding future duplication.
The latest version of that package contains a fix for an issue where
the linked bundles did not rewrite imports to shared chunks.
Such imports need to also point to their linked variants.
PR Close#60822
Since APF can contain shared chunks, where e.g. `eetemplate` lives, the
`coreHasSymbol` check is no longer reliable. Right now it even prevents
the version range check (that is reliably working) from running because
we detect a `index.d.ts` file but simply don't find the requested
symbol in there (we don't expand exports via type checker).
PR Close#60825
This commit attempts to finally fix the long-standing first-party
package linking issue with the rather tricky `rules_nodejs` toolchain.
I've verified that no version of e.g. `@angular/core` ends up in the
Bazel sandbox. This is achieved by also filtering transitive Angular
deps for first-party linked packages. e.g. `@angular/docs`.
In addition, `@angular/docs` accidentally ended up bundling parts of
Angular core because it relied on an entry-point that was not part of
the "well known externals". As part of the ongoing `ng_package`
update/rewrite, we should look into disabling bundling of ANY external
dependency/module. This is possible because we use relative imports
inside APF packages as of recently!
This commit should allow us to develop and continue new compiler
features, without having to temporarily (or longer) disable all
`angular.dev` unit tests!
Fixes#54858.
PR Close#60825
Currently the HTTP status code and headers are only included if the request succeeded. Given status codes convey more information in case of a request error vs. success, this makes it more useful than inspecting what is contained in `.error()`.
PR Close#60802
Currently when we transpile the HMR update module, we use the project's compiler options verbatim. This appears to break down with some module types, whereas we have to use a native export.
These changes override the compiler options to ensure that the user's options don't end up breaking HMR.
Fixes#60795.
PR Close#60797
When Angular runs application synchronization automatically, animations
are now guaranteed to be flushed, regardless of whether change detection
was run on any components attached to `ApplicationRef`. This most
frequently affects animations related to component removal where the DOM
element for the component would previously not be removed due to
animations not being flushed
BREAKING CHANGE: Animations are guaranteed to be flushed when Angular
runs automatic change detection or manual calls to `ApplicationRef.tick`.
Prior to this change, animations would not be flushed in some situations
if change detection did not run on any views attached to the
application. This change can affect tests which may rely on the old
behavior, often by making assertions on DOM elements that should have
been removed but weren't because DOM removal is delayed until animations
are flushed.
fixes#58075
PR Close#58089
With the changes in #59573, `resource` can now define a `stream` rather than a `loader`.
In the same PR, `rxResource` was updated to leverage this new functionality to handle multiple responses from the underlying observable,
rather than just the first one as it was previously.
This commit renames the `loader` option of `rxResource` into `stream` to be better aligned with its new behavior.
The previous version is temporarily kept and marked as deprecated to help migrating the current usage.
Before
```
usersResource = rxResource({
request: () => ...,
loader: ({ request }) => ...
});
```
After
```
usersResource = rxResource({
request: () => ...,
stream: ({ request }) => ...
});
```
PR Close#59910
This commit changes Tsurge's operation within angular-devkit (i.e. the CLI) to
no longer retain all programs across all migrations. This isn't necessary for
so-called "funnel" migrations so not retaining the programs for those migrations
is a pure performance win. The "complex" migrations may see increased execution time
given that the program is now being recreated for the actual migration phase to run,
although reduced memory pressure may help alleviate this overhead. Since this new
approach should help prevent Node from running out of memory and failing entirely
this is preferred over a potentially increased execution time.
Fixes#59813
PR Close#60774
`bootstrapApplication` always creates the root component in the `NgZone`, however `ApplicationRef.prototype.bootstrap` historically did not, meaning that if users did not go out of their way to call `ngZone.run(() => appRef.bootstrap(SomeComp))`, components would not run change detection correctly.
This commit updates `ApplicationRef.prototype.bootstrap` to _always_ run within `NgZone`, removing this hazard and ensuring components always run CD as expected.
PR Close#60720
This adapter adds an integration with the Navigation API, allowing
SPA Router navigations to be displayed more fully in the browser UI.
With this, site visitors will be able to see that a page is loading via
the loading spinner in the tab. They will also have access to cancel the
navigation with the browser UI via the "stop" button or by pressing the
escape key (only relevant for slower connections).
* https://github.com/WICG/navigation-api
* https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API
PR Close#60722
Currently it's required to pass in the tag name when determining the security context, however with selectorless we might not have a tag name. These changes update the logic to account for it.
PR Close#60724
This commit updates the FakeNavigation implementation to match the
spec's new `precommitHandler` which replaces the old `commit: 'after-transition'`.
PR Close#60652
This commit removes the `@developerPreview` annotation from the `REQUEST`, `RESPONSE_INIT` and `REQUEST_CONTEXT` symbols, making them stable.
PR Close#60717
This commit updates the `HttpClient` internals to use the public
`PendingTasks` API which delays stability until the next
`ApplicationRef.tick` instead of causing the application to become
stable synchronously. This is helpful to resolve unexpected issues where
computations happen as follow-up work to the value coming out of the
response.
fixes https://github.com/angular/angular/issues/59352
PR Close#60656
This is a roll forward of commit d5a8a1c524. Nothing is meaningfully different, as we're trying again to see if the CI failure is reproducible.
PR Close#60622
This PR marks `PendingTasks` as stable, though the `run` function
remains in dev preview. There are still questions around its return
value, error handling, and whether it will be replaced by a different
`task` API that would better track context through the
injector/injection context.
PR Close#60716
In this commit, we unsubscribe the `hasPendingTasks` subject to remove all active observers and enable granular garbage collection, as users may forget to unsubscribe manually when subscribing to `isStable`.
PR Close#59723
Adds the `markAllAsDirty` method to the `AbstractControl` class. This method will mark the control and all its
descendants as dirty.
I pretty much just duplicated the behaviour and tests of `markAllAsTouched`.
Fixes#55990
PR Close#58663
Previously, the order in which root effects were executed was
non-deterministic and relied on the order in which signal graph dirty
notifications were propagated. With this commit, root effects are always run
in creation order.
PR Close#60534
This commit adds the ability to directly abort a navigation through the
`Router.getCurrentNavigation()?.abort()` method. While there are no
feature requests for this, it is a feature that will be necessary for
integration with the navigation API. The API enables better tracking of
an ongoing navigation for SPAs and a site visitor can cancel a
navigation by clicking the stop button in the browser. While this could
technically be done on the transition with an internal jsdoc comment to
hide it from application developers, there's no need.
With this feature, I believe it would be possible to create somewhat of a shim
to integrate with the navigation API even before the router has full support
using the router events to control a deferred navigation that never
commits the URL and always aborts itself on navigation end.
PR Close#60380
In this commit, we introduce the ability to check whether `lView` has already been
destroyed in `NodeInjectorDestroyRef`. If the `lView` is already destroyed, we call
the on-destroy callback immediately, without trying to register it to be called later.
This ensures that any necessary cleanup is handled gracefully and provides better
reliability in managing resources.
One of the use cases is `takeUntilDestroyed`, which aims to replace `takeUntil` in existing
applications. While `takeUntil` can be safely called once the view is destroyed—resulting
in no errors and finalizing the subscription depending on whether a subject or replay
subject is used—replacing it with `takeUntilDestroyed` introduces a breaking change, as
it throws an error if the `lView` is destroyed.
Related issue: #54527
PR Close#58008
This refactor extracts all the logic required to update a single
directive input while running the update pass of a template. It
also adds a number of TODOs that hint on subsequent reqfactorings.
PR Close#60690
In this commit, we reduce the number of imported RxJS symbols since they are redundant.
- We replace `merge` with a manual observable because `merge` internally pulls in `from()`.
- We remove `defer` and `throwError`, replacing them with `new Observable(s => s.error(..))`.
- We replace `toPromise()` with `new Promise`, as `toPromise()` is deprecated.
- We convert `readyToRegister` to a promise to avoid using RxJS operators like `delay`.
PR Close#60657
When a new version of app is available in a service worker, and a client with old version exists, web workers initialized from a client with old version will now be properly assigned with the same version.
Before this change, a web worker was assigned with the newest version.
Fixes#57971
PR Close#58131
The non reactive usage ``httpResource(\`http://test/${myId()}\`` gave the false impression that it was reactive when the signal was invoked. We prevent any possibility of oversight by removing the non reactive signature.
PR Close#60537
Practically speaking, this change ensures that Angular is able to make
decisions about what to do when an uncaught error happens.
For tests, this will mean that, by default, the error either causes the
`fixture.whenStable` promise to reject if there is one or rethrow the
error. This ensures tests do not accidentally ignore errors. Opting out
of this can be done with the `rethrowApplicationErrors: false` option in
`TestBed`.
For SSR, there may be additional behaviors in the future that we want to
add, such as redirecting to an error page or responding with a 500
status code.
BREAKING CHANGE: Uncaught errors in listeners which were previously only reported to
`ErrorHandler` are now also reported to Angular's internal error
handling machinery. For tests, this means that the error will be
rethrown by default rather than only logging the error. Developers
should fix these errors, catch them in the test if the test is
intentionally covering an error case, or use `rethrowApplicationErrors:
false` in `configureTestingModule` as a last resort.
PR Close#60251
This commit updates the `common` package contents test to skip JS chunks, while still making sure that the main entrypoint files are present.
PR Close#60623
This commit updates golden files that got changed after swtiching to relative paths. There are no actual change to the APIs, the golden file updates capture the change in imports.
PR Close#60623
This commit adds a flag `forceSyncFirstEmit` which opts in to the pending
new behavior for `toObservable`, which emits the first value synchronously.
This flag is only really meant for use during a short migration period
while we update g3, and is not meant for prolonged usage. As a result, it's
marked deprecated.
PR Close#60640
This commit re-exports the symbols that are exposed by the `RouterTestingModule` (which re-exports
the symbols from the `RouterModule`. These re-exports are needed for the Angular compiler
to overcome its limitation (on the consumer side) of not knowing where to import import
symbols when relative imports are used within the package.
PR Close#60557
This commit updates the `StateManager` base class to contain common
concrete implementations that would be the same regardless of whether
the state manager is backed by the browser history API or the Navigation
API.
PR Close#60617
Moves the `DOCUMENT` token from `common` into `core` since it's relevant for lots of SSR use cases and users shouldn't have to install `common` for it. The token is still exported through `common` for backwards compatibility.
PR Close#60663
This allows any components individually bootstrapped to inherit from a unique `Injector`. This is useful when bootstrapping multiple root components with different providers.
For now, the function is private while we explore potential designs to consolidate it with the existing `ApplicationRef.prototype.bootstrap` method.
PR Close#60622
This updates `createSignal` to use `signalGetFn` to define the signal getter and exports `signalGetFn` from the shared signal primitives.
PR Close#60497
The previous message would sound like a full sentence when using a signal without `()` (Example: Unsupported styling type function: [Input Signal: neutral]). The new formatting makes it a bit more obvious that the type itself is the problem.
PR Close#59563
This commit updates the OutletInjector and related code to avoid special handling of that injector. The main code that had special handling was refactored to no longer require is in https://github.com/angular/angular/pull/56763, this commit completes the cleanup.
PR Close#58351
This flag is effectively unused in Angular code that we've seen, and is only
serving to complicate the mental model of effects. It could be reintroduced
if needed.
PR Close#60535
Previously the `frameUrl` option in `chrome.devtools.inspectedWindow.eval` would throw errors when used in Firefox, preventing inspect source functionality for firefox users even if they don't need to target a particular frame on the page (they are on the top level frame with Angular DevTools).
Now this behaviour is as follows:
Firefox user that has the top level frame selected -> DevTools inspect functionality works as expected.
Firefox user that has a non-top level frame selected -> DevTools now renders a snackbar message informing the user of the limitation.
PR Close#60430
This commit removes a number of obsolete integration tests and also removes some e2e tests for a few remianing apps, since they are not adding value, but cause extra time to spend on CI.
PR Close#60594
Renames the `hostProperty` instruction to `domProperty` since it's not really host-specific and we can use it for other DOM-specific operations in the future.
PR Close#60608
Includes the following moves.
* Moves the DOM-specific logic from `elementPropertyInternal` into a separate function so we can reuse it.
* Uses the DOM-specific code for the `hostProperty` instruction.
* Removes the `nativeOnly` parameter from `elementPropertyInternal`.
* Renames `elementPropertyInternal` to `setPropertyAndInputs` so it's a bit more clear what the function is doing.
PR Close#60608
This commit removes a few bundling test apps that do not provide any value, but require time on CI and during local development to update golden files.
The functionality that was tested in those apps is covered by various other tests that we have in a repository (either in the same `packages/core/test/bundling` folder or in other unit/integration tests).
PR Close#60591
Note: This is not a deprecation of structural directives, this only about `ngIf`/`ngFor`/`ngSwitch`.
DEPRECATED: `ngIf`/`ngFor`/`ngSwitch` are deprecated. Use the control flow blocks instead (`@for`/`@if`/`@switch`).
PR Close#60492
When the HMR is enabled in Angular, all `@defer` block dependencies are loaded
eagerly, instead of waiting for configured trigger conditions. From the DX perspective,
it might be seen as an issue when all dependencies are being loaded eagerly. This commit
adds a logic to produce a message into the console to provide more info for developers.
PR Close#60533
The inject migration has some logic that treats parameters referenced directly inside of `super` differently. This logic didn't account for the fact that the parameters could be inside of inline functions which have less strict access requirements.
PR Close#60602
Prior to this commit, `hasHttpTransferCacheOptions` was calculated immediately after the `featuresKind` set was declared, which was always defaulted to `false`.
PR Close#60605
This commit removes `'any'` from the type union for router guards and
replaces it with 'string', which will eventually also be removed. This
change allows TypeScript to infer the parameter types of functions when
using functional guards and enables stricter type-checking to ensure the
guard array contains valid values.
BREAKING CHANGE: The guards arrays on `Route` no longer include `any` in
the type union. The union includes functions for the functional guards
as well as a type matching `Injector.get`: `ProviderToken<T>|string`.
Note that string is still deprecated on both the route guards and
`Injector.get`.
PR Close#60378
This updates the DevTools protocol to send Wiz/ACX metadata in addition to Angular metadata. Fortunately we don't need to worry about backwards compatibility here (`framework` is required for example), but the design roughly mirrors `DirectiveDebugMetadata` in `@angular/core`.
Beyond that, this is mostly plumbing through an extra data slice in the form of `props` provided by Wiz. An earlier version implemented `events` as their own slice as well, but was removed as there is currently no generic way to disambiguate events from any other form of callback passed in as a prop. Instead, event callbacks are visualized as functions under the "Props" category.
Working with `DirectiveMetadata` as a union is unfortunately a bit annoying since it requires casting to more specific `{Angular,Acx,Wiz}DirectiveMetadata` types for TS to allow property access, even when the properties are optional anyways.
This commit is mostly for adding Wiz, but does add a bit of ACX functionality which is not fully tested.
PR Close#60475
This type was incorrect, as only components have `encapsulation` and `onPush` values. `ng.getDirectiveMetadata` does not return these properties for directive inputs.
Unfortunately the `| Partial<AngularComponentDebugMetadata>` is necessary to reference these properties or else TypeScript will reject their usage.
PR Close#60475
This allows `ng.getDirectiveMetadata` to be implemented by Wiz and ACX with subtly different shapes to match the nuances of those frameworks.
Existing usage of `{Component,Directive}DebugMetadata` was moved over to `Angular{Component,Directive}DebugMetadata` as appropriate, since the implementation of `ng` in `@angular/core` is specific to Angular. Only the types support Wiz and ACX.
I opted to merge `ComponentDebugMetadata` and `DirectiveDebugMetadata` into a single type of all the frameworks including both components and directives (recall that components extend directives). The reasoning for this is because Wiz does not support directives (you can kind of think of "Wiz Directive" as an abstract class extended by "Wiz Components"). I felt that a `DirectiveDebugMetadata` containing only Angular and ACX types would be a bit of a trap and lead to bugs when used. It's safer to just have the single type containing all the possible results from `ng.getDirectiveMetadata`.
I also chose to leave the `ng` type as is internally, since `@angular/core` implements a specific concrete version of it narrowed to Angular types. Separately I defined an expanded `FrameworkAgnosticGlobalUtils` which redefines `ng.getDirectiveMetadata` to include Wiz and ACX. We want this type to exist in the Angular GitHub repo so it can be referenced as a common primitive across all three frameworks. This is sufficient for now, however longer term we will likely want to actually manually define the function types in this framework-agnostic interface and make Angular's version properly implement it rather than extend and overwrite Angular's type.
PR Close#60475
This change pushes the toString implementation of signal getters
down to the primitives package so it can be shared with other
frameworks.
Closes#59990
PR Close#60365
This commit updates scripts within `packages/platform-browser-dynamic` to relative imports as a prep work to the upcoming infra updates.
PR Close#60559
This regexp accidentally worked. It was splitting by individual character and putting a pipe in rather than splitting by set of event types
PR Close#60592
In this commit, we remove `fromEvent` and replace it with a manually created observable to import fewer symbols from RxJS. Some codebases may not use `fromEvent` at all, but using it in a single place would still include it in the initial bundle.
PR Close#60424
This commit adds a step where we build all found targets in parallel, which speeds up the process of completing public API extractor test/update.
PR Close#60578
This commit adds a step where we build all found targets in parallel, which speeds up the process of completing symbol extractor test/update.
PR Close#60573
This is required to fix
```
adev/shared-docs/testing/testing-helper.ts:100:12 - error TS2416: Property 'on' in type 'FakeWebContainer' is not assignable to the same property in base type 'WebContainer'.
Type '{ (event: "port", listener: PortListener): Unsubscribe; (event: "server-ready", listener: ServerReadyListener): Unsubscribe; (event: "error", listener: ErrorListener): Unsubscribe; (event: "preview-message", listener: PreviewMessageListener): Unsubscribe; }' is not assignable to type '{ (event: "port", listener: PortListener): Unsubscribe; (event: "server-ready", listener: ServerReadyListener): Unsubscribe; (event: "preview-message", listener: PreviewMessageListener): Unsubscribe; (event: "error", listener: ErrorListener): Unsubscribe; (event: "xdg-open", listener: OpenListener): Unsubscribe; (ev...'.
Types of parameters 'event' and 'event' are incompatible.
Type '"xdg-open"' is not assignable to type '"port"'.
100 override on(event: 'server-ready', listener: ServerReadyListener): Unsubscribe;
~~
```
See: https://github.com/angular/angular/actions/runs/14098789522/job/39491059550?pr=60526
PR Close#60581
- Detachment of the navigation from the left window border
- Odd horizontal scroll when there is a URL fragment and the viewport width <900px
PR Close#60583
Extract all colors from the stylesheets, reduce their number by merging the similar ones and organize them into themes represented by CSS variables.
PR Close#60374
Currently the TCB generation code doesn't handle targeted events (e.g. `(document:click)`) which ends up binding to the current element and can have type inference implications. These changes take the event's `target` into account.
PR Close#60561
Moves the logic for parsing event names out into methods on the `BindingParser` so we don't have to duplicate it. Also updates the types to more accurately represent the runtime value.
PR Close#60561
By default, the compiler-cli uses the relative import strategy when
there is no `rootDir` or `rootDirs`. This is expected as everything is
assumed to be somehow reachable through relative imports.
With `rootDirs` that allow for a "virtual file system"-like environment,
the compiler is not necessarily able to always construct proper relative
imports. The compiler includes the `LogicalProjectStrategy` for this
reason. This strategy is able to respect `rootDirs` to construct
relative paths when possible.
This logic currently accidentally triggers when there is a `rootDir`
set. This option is not to be confused with the virtual directory
option called `rootDirs`. The compiler currently confuses this and
accidentally enters this mode when there is just a `rootDir`— breaking
in monorepos that imports can point outside the `rootDir` to e.g. other
compilation unit's `.d.ts` (which is valid; just not `.ts` sources can
live outside the root dir).
This is necessary for our Bazel toolchain migration.
PR Close#60555
Adds a utility type to make it easier to distinguish wrapped and unwrapped listeners. Also adds a type for event callbacks so we don't need to repeat it everywhere.
PR Close#60549
We were duplicating the logic for storing listener-related cleanup functions in a couple of places. These changes consolidate it into one function.
PR Close#60549
We had a special case in the `wrapListener` function that would return the original function if it's invoked with `Function`. This was added for `DebugNode.triggerEventHandler`, but isn't necessary anymore.
PR Close#60549
Node.js v18 will reach End-of-Life on April 30, 2025, and will no longer be supported in Angular v20.
Node.js Release Schedule: https://github.com/nodejs/release#release-schedule
BREAKING CHANGE:
- Angular no longer supports Node.js v18.
- Node.js versions 22.0 to 22.10 are also no longer supported.
Before upgrading to Angular v20, ensure the Node.js version is at least 20.11.1.
For the full list of supported versions, visit: https://angular.dev/reference/versions
PR Close#60545
The version of Node.js used for development and CI jobs is now set to the active LTS version's latest minor and patch. Renovate is also now configured to update the minor and patch versions.
PR Close#60545
The `TemplateLiteralElementExpr` has some logic where it tries to estimate the `rawText` if one isn't provided by looking at the node's source span. The problem with this approach is that we have some long-standing issues with our expression AST parser (see https://github.com/angular/angular/pull/60267#discussion_r1986402524) where it might not produce accurate spans if escape sequences are involved. This in turn can lead to unrecoverable errors, because TypeScript will throw an error if the raw string doesn't match the cooked one when constructing a TypeScript AST node.
These changes remove the logic that depends on the source span and relies purely on the secondary fallback that inserts escaped characters manually.
It's also worth noting that the `rawText` doesn't seem to matter much at this point, because the main usage of it is when downlevelling template literals to ES5 which we no longer support.
Fixes#60528.
PR Close#60529
We can simplify signature of listenToDirectiveOutput by passing less
arguments (some of them can be derived from already passed arguments).
PR Close#60514
This properly cleans up stale control flow branches in the case
that branches change between server and client at the same
timing as NgIf / NgSwitch.
fixes: #58670fixes: #60218
PR Close#60425
This adds a new instruction for dealing with creating conditionals. It ensures flags are set on the TNode for later identification during hydration.
PR Close#60425
This commit fixes the linking of CDK/Material which recently broke
because the CDK/Material package now comes with potential shared FESM
chunks; that our current hard-coded, manual linking process doesn't know
about. This ultimately resulted in duplicate code, breaking
Material/CDK.
This commit fixes that.
In addition to the fix, we simplify our linking significantly and reduce
the rather large complexity around linking, or having to specify every
entry-point manually, by linking the full package and putting it into
a different location. This is also what we conceptually are doing in
Angular Material as part of the `rules_js` migration.
PR Close#60516
`ng add @angular/localize` now also adds the localize polyfill to the configuration of Karma if the `@angular/build:karma` builder is used
(which is the default in Angular CLI v20)
PR Close#60513
This will make the test even more useful, as it ensures that we aren't
accidentally relying on the compiler potentially discovering best
guessed modules from other imports that previously were part of the same
file (importing all modules as part of the test).
PR Close#60503
Removes a link that no longer directs users to the expected documentation. Deleting the line is the recommended solution for issue #60500.
PR Close#60501
Markdown requires code blocks (```) to start without white spaces. With this change we ensure that `@example` blocks with leading spaces are well supported.
fixes#60407
PR Close#60408
Removes logic that was explicitly adding parentheses around ternaries
used as the condition of another ternary. Instead we can just rely on
Typescript to add the parentheses if they are needed to make the code
match the structure of the AST.
Also added a note pointing to the issue that currently prevents us from
removing similar logic pertaining to nullish coalescing
PR Close#60263
Previously, `platformBrowserTesting` did not include any `platformBrowser` providers, causing an inconsistency with `platformBrowserDynamicTesting`.
This update resolves the issue by restructuring platform inheritance to ensure proper provider inclusion:
- `platformCore → platformBrowser → platformBrowserTesting`
- `platformBrowser → platformBrowserDynamic → platformBrowserDynamicTesting`
Now, `platformBrowserTesting` correctly inherits from `platformBrowser`, aligning with the expected behavior.
PR Close#60480
This commit adds a new integration test which will help ensure that all
exported `@NgModule`'s of framework packages can be imported by users
without any errors.
This test is generally useful, but with our upcoming changes with
relative imports, this is a good safety-net. Relative imports could
break re-exported NgModules inside NgModule's. For more details, see:
https://github.com/angular/components/pull/30667
Notably we don't expect any issues for framework package as re-exporting
`@NgModule`'s inside `@NgModule`'s is seemingly a rather rare pattern for
APF libraries (confirmed by Material only having like 4-5 instances).
PR Close#60489
When we switch to relative imports, shared `.d.ts` chunks can be
generated.
We need to also pull these into our mock virtual FS testing
environments. Notably this does not cause a test slow-down because we
are talking about very few extra `.d.ts` chunk files. In our experiments
before, with no dts bundling, we saw test time increase from e.g.
20seconds to 100seconds. The 20s are still the same locally!
In addition, since code for definitions can now reside in shared `.d.ts`
chunks, the language service tests need to be adjusted in cases where
they assert for code definition locations in `@angular/core`. A new
helper prepares for more code to be moved into arbitrary `.d.ts` files;
we should simply assert the definition comes out of
`node_modules/@angular/core`.
PR Close#60487
We've seen these tests regularly, but somewhat rarely to be
stuck/hanging in the remote execution workers. Since the issue was
reproducable locally (via local RBE environment), we can improve
stability for the team until we resolve this with the RBE team.
PR Close#60473
This commit moves `DOMTestComponentRenderer` to `@angular/platform-browser/testing`, allowing the Angular CLI to eliminate its dependency on `@angular/platform-browser-dynamic`, which would no longer be required for new projects.
PR Close#60453
Currently when an incorrect value is in the `imports` array, we highlight the entire array which can be very noisy for large arrays. This comes up semi-regularly (at least for me) when an import is missing.
These changes add some logic that reports a more accurate diagnostic location for the most common case where the `imports` array is static. Non-static arrays will fall back to the current behavior.
PR Close#60455
This uses a fake timer scheduler implementation to ensure timer tests do not cause flakiness, similar to the incremental hydration tests.
PR Close#60461
With the recent changes to the APF bundling rules, we turned on
tree-shaking in rollup to support proper code splitting for FESM bundles.
This resulted in Rollup re-ordering imports in the FESM bundles of
`@angular/platform-browser-dynamic`— highlighting that over the past
years, this package "accidentally" resulted in the side-effects of the
compiler registering itself globally.
This continues to be the case, and our changes generally didn't cause
any issues in CLI applications because the CLI explicitly wires up the
compiler (as expected) before `-dynamic` is even loaded. For custom
setup, like Analog, this order change surfaced a breakage because e.g.
`@angular/common` with its JIT decorators of e.g. directives/services
are triggered before the compiler is actually loaded/made available.
This commit fixes this. The explicit imports in practice are a noop
because our FESM bundling doesn't recognize compiler as side-effects
true; but marking the whole -dynamic package as having side-effects;
prevents rollup from swapping the import order. Long-term, we should
look into improving this by teaching `ng_package` that e.g. the compiler
has side-effects; so that the `import @angular/compiler` statement is
not dropped when constructing FESM bundles.
PR Close#60458
`TestBed.get` isn't type safe and has been deprecated for several years now. These changes remove it from the public API and a follow-up change will add an automated migration to `TestBed.inject`.
BREAKING CHANGE:
* `TestBed.get` has been removed. Use `TestBed.inject` instead.
PR Close#60414
When the browser parses a valid html5 response like this:
```html
<!-- ... -->
<title>My page</title>
</head>
<!--nghm-->
<app-root></app-root>
<!-- ... -->
```
The resulting DOM will only start adding nodes to the body when it
runs into the first non-header tag. E.g.:
```yml
- head
- title "My page"
- comment "nghm"
- body
- app-root
```
This isn't a sign that comments are modified, so it seems worth to
handle it gracefully.
PR Close#60429
The semantics for nullish coalescing (`??`) in Javascript/Typescript
differ slightly from the semantics in Angular templates. Mixing nullish
coalescing with logical and/or without parentheses is an error in
Javascript. This PR adds an extended diagnostic that can be enabled to
treat it as an error in Angular templates as well.
PR Close#60279
This test often (but inconsitantly) timeouts with
```
Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL)
```
We suspect a racing condition within the RouterTestingHarness.
Until this has been investigated, we'll disable this test.
PR Close#60448
Reworks the language service to enable features like quick info and definitions inside host bindings.
**Note:** for the full range of language service features to work, the changes from https://github.com/angular/vscode-ng-language-service/pull/2155 have to be released.
PR Close#60433
Note that this is not a public-facing change because the compiler is not
supposed to be used directly. See `public-api-surface.md`
We are changing this because in the current state, for advanced setups
like our Bazel infrastructure in Material, this peer dependency can
result in a cycle. That is because we may decide to link the
`@angular/core` package using the compiler-cli/compiler; while
transitively the compiler has a dependency on core. That's a cycle
(surfacing in Bazel w/ `rules_js`).
Dropping this optional peer dependency is acceptable because `core`,
since recently, also has an optional peer dependency on the compiler.
This one makes more sense and is also more user-facing (people generally
never install the compiler directly).
Notably the compiler does not have any runtime dependency on `core` and
this was purely added for some safety checking. See:
https://github.com/angular/angular/commit/8c171da29f499648273e61cfb5bffaa4278097e5
PR Close#60437
In TSDoc, we currently handle the `@usageNotes` annotation, but this is not a standard TSDoc tag. Instead, the `@example` annotation is the correct standard, which is used in the Angular CLI repo and on the SSR package.
This change ensures that `@example` is treated the same as `@usageNotes` during the transform process and also handle multiple instances of `@example` on the same tag.
PR Close#60443
Adds a hook in the same style as `postSignalSetFn` for running side effects when a producer has been created. This hook will be passed the reactive node being created.
PR Close#60333
This commit removes the previously added `rejectErrors` option from
`toSignal` which was meant to create similar behavior to what happens
with unhandled errors in `AsyncPipe`.
This option promotes unhandled exceptions and attaches behaviors that we
do not believe are desirable as an option offered by the framework:
* Unhandled errors that are thrown lose the context of where the error
ocurred. Throwing the error where the signal is read allows error
handling to be performed at the signal's usage location
* With this feature, the value of the signal remains set to the initial
value or the previous successful value coming out of the `Observable`.
We do not feel this is appropriate implicit behavior but should be an
explicit choice by the application. Signals are built to represent
state. When an observable stream is converted to a stateful
representation, there should be a choice made about what state should
be presented when an error occurs
* If an error occurs but the signal value is never read in its error
state, this is not an application state error that should result in an
unhandled exception.
* While Angular does not have error boundaries today, there is likely to
be investigation in the near future to address increased risk of
errors thrown from signals such as this in templates. Without
pre-designing any specifics, it is possible that this type of feature
would require the error to be thrown from the signal. We are subsequently
not prepared to commit to stabilizing the `toSignal` API with the
`rejectErrors` option and its current behavior.
Developers that desire similar behavior to `rejectErrors` have several
options, the simplest of which would be something similar to
`toSignal(myStream.pipe(catchError(() => EMPTY)))`.
PR Close#60397
The `renderApplication` and `renderModule` methods currently encapsulate the entire rendering process, making it difficult to intercept key phases from a non-Angular context. This change exports the internal `render` method, allowing us to perform operations such as:
- Flushing headers before hydration preparation
- Handling non static redirects (e.g., 302 responses)
- Intercepting router events for additional processing
This refactor serves as an experimental step toward improving the API for better customization and integration in the future.
PR Close#60416
Angular DevTools now supports mutating objects underneath signals in the property explorer view.
This is done by performing an "immutable update" by recursively copying objects underneath a signal and overwriting the one property specified. For example, if the user attempted to set `foo.bar.baz[2].hello = 'world'` and `bar` was a signal, this would effectively become:
```typescript
foo.bar.set({
...foo.bar(),
baz: [
...foo.bar().baz.slice(0, 2),
{
...foo.bar().baz[2],
hello: 'world',
},
...foo.bar().baz.slice(3),
],
})
```
The motivation for immutable updates is because signals and Angular change detection don't really like interior mutability of signal values. If we didn't do this, any kind of comparison or dirty check would prevent the UI from updating. If an application attempts to change a deeply nested property inside a signal, it doesn't work today. DevTools should generally be limited to operations an application could do itself, and the recommended approach to make such a change like this is an immutable update. Creating entirely new objects intentionally breaks referential equality such that the application can properly react to the change.
Unfortunately, it is not possible to make immutable updates in a truly generic sense. You can't just copy a class for instance `({...new MyFoo()}).doSomething()`. We could do something fancier like manually copying over the prototype or something like that, but there is no way to do this without breaking class semantics (ex. the class might reasonably rely on the constructor being called). Therefore we instead reject any mutations to non-primitive objects. In the future, we might expand the set of "primitives" to include other built-ins and well-known objects like `URL` or `Element`, but those are out of scope for now.
I opted to ban mutating the result of a readonly/computed signal. While the mutation is likely to succeed, a subsequent rerun of the `computed` will immediately drop the change. However, I opted to allow mutating the result of a getter property. This has a similar problem because it might be returning a synthetic object which will be invalidated on the next execution, but it is possible and reasonable for a getter to return the same object multiple times such that a mutation may reasonably survive other updates. DevTools can't easily know whether a getter actually will return the same object on each execution or not, so we optimistically assume the reference is stable. If it isn't, the mutation will be lost whenever the getter is re-executed.
PR Close#60381
Sometimes `forest` can be empty if the provided roots are empty, and was leading to a "Cannot read `resolutionPath` of `undefined`" error. Now we check the forest has a tree in it before looking up `resolutionPath`.
There might be a separate issue with the fact that the backend script likely shouldn't be emitting an empty forest in the first place. However we already check that a resolution path exists at all, so I think it's fair to also check that a tree was provided. We can separately look into making sure the backend is emitting valid data.
PR Close#60403
Improves the partial compliance golden generation to not rely on large
files being transmitted via `stdout`. Instead the files are written
directly as it's done in idiomatic Bazel generation actions.
In addition, we add extra stdout logging for the Bazel action, to see if
the process is actually invoked in RBE workers. Right now those are
occassionally stuck, but neither us, nor the RBE team can see anything
running, and they're occasionally stuck for 1hr.
PR Close#60427
This commit updates the server rendering documentation and merges the prerendering, hybrid, and SSR sections for better clarity and organization.
Closes#52884 and closes#60079
PR Close#60383
Builds on the changes from #60137 to add support for two-way bindings on dynamically-created components. Example usage:
```typescript
import {createComponent, signal, twoWayBinding} from '@angular/core';
const value = signal('');
createComponent(MyCheckbox, {
bindings: [
twoWayBinding('value', value),
],
});
```
In the example above the value of `MyCheckbox` and the `value` signal will be kept in sync.
PR Close#60342
Historically Angular's type checking only extended to templates, however host bindings can contain expressions as well which can have type checking issues of their own. These changes expand the type checking infrastructure to cover the `host` object literal, `@HostBinding` decorators and `@HostListener` with full language service support coming in future commits.
Note that initially the new functionality is disabled by default and has to be enabled using the `typeCheckHostBindings` compiler flag.
PR Close#60267
Sets up the logic that produces the information necessary to type check host bindings of a component. Also introduces a compiler flag for toggling checking of host bindings.
PR Close#60267
Adds the `HostElement` AST node that can be used to represent the host of a directive. Also exposes the `BindingParser` type so it's easier to pass around the return value of `makeBindingParser`.
PR Close#60267
While still being supported because of ngUpgrade, string tokens are not recommended. Developers should use InjectionTokens or classes as tokens instead.
PR Close#60326
This should prevent defer timers from impacting app stability by executing them outside of the zone, similar to other defer triggers.
fixes: #60373
PR Close#60392
Currently when we reuse a Tsurge migration is reused externally, there's some glue code that needs to be executed in a specific order. The code gets copied between the different migrations which is error-prone and means that bugs may have to be fixed several times.
These changes move the common steps out into a separate function so that only the migration-specific logic (mostly instantiation and logging) is left in the schematic.
PR Close#60386
See associated pull request for more information.
Closes#59956 as a pr takeover, `@angular/build-tooling` has been rolled back as due to missing `@aspect_rules_js`.
PR Close#60387
For internal framework values stored in injectors, they are manually
managed and inserted into injectors as needed. Therefore their tokens
don't provide a value or factory. This updates the type to reflect that
and updates the jsdocs a bit.
PR Close#60347
This commit cleans up the transition subject a bit so it doesn't use a dummy
initial value. It also avoids copying over data from the previous
request when a new one is created.
PR Close#60357
The `DowngradeComponentAdapter` adapter was assuming that all outputs are observables, but they can also be `OutputEmitterRef`.
Fixes#60366.
PR Close#60369
The signals primitives package understands the equals option now
so we can pass it to the signal / computed creation methods instead
of manually assigning the equality function on a reactive node.
PR Close#60364
This commit puts in place infrastructure capable of routing
performance-related, internal framework events directly to
the Chrome DevTools performance panel (custom track).
PR Close#60217
This change moves more logic to the primitives package by pushing
the equal configuration on a reactive node to the signal and
computed creation utilities.
PR Close#60300
This should help with network issues of spawned RBE actions. It should
also introduce timeouts when actions couldn't be spawned in a timely
manner.
PR Close#60355
Instead of relying on Microsoft's API extractor for `d.ts` bundling,
we are switching to Rollup-based `.d.ts` bundling.
This allows us to support code spliting, even for `.d.ts` files,
allowing for relative imports to be used between entry-points, without
ending up duplicating `.d.ts` definitions in two files. This would otherwise cause
problems with assignability of types.
It also nicely integrates into our existing rollup configuration, and
overall simplifies the `ng_package` rule even further!
Notably `tsup` also uses this rollup plugin, and it seems to work well.
Keep in mind that Microsoft's API extractor is pretty hard to integrate,
caused many problems in the past, and isn't capable of code splitting.
This aligns our d.ts bundling with the .mjs bundling (great alignment).
PR Close#60321
Replaces all the places where we use `InjectFlags` internally with the `InternalInjectFlags` which has the benefit of being a `const` enum and allowing us to consolidate the flags and object literal eventually.
PR Close#60318
Removes the deprecated `InjectFlags` symbol from the `@angular/core` public API, as well as all the places that accept it. The previous commit includes an automated migration to switch over to the new way of passing in flags.
BREAKING CHANGE:
* `InjectFlags` has been removed.
* `inject` no longer accepts `InjectFlags`.
* `Injector.get` no longer accepts `InjectFlags`.
* `EnvironmentInjector.get` no longer accepts `InjectFlags`.
* `TestBed.get` no longer accepts `InjectFlags`.
* `TestBed.inject` no longer accepts `InjectFlags`.
PR Close#60318
Fixes the link for the commit message guideline in CONTRIBUTING.md
pointing to the building and testing angular guide instead of the
commit message guidelines
Fixes#60925
PR Close#60296
The main goal of this change is to remove `categoryOrder` which effectively hard-codes the supported length of `panels`. Adding another item to `panels` is not rendered unless that is added to `categoryOrder`.
My solution to this is to make the set of categories a signal, with each category able to produce the data inside it. This allow `CdkDragDrop` to rearrange categories but then still produce the correct data in the template without needing a separate array to track order.
Also removed `hidden` and inlined it in the template, since the logic was the same for every panel.
`moveItemInArray` is unfortunately an in-place move, so I needed to manually clone the array to ensure `panels` observes an immutable update which works better with signals and change detection.
PR Close#60286
The HammerJS integration provided by the framework is deprecated
DEPRECATED: HammerJS support is deprecated and will be removed in a future major version.
PR Close#60257
This commit further restricts the deprecated type on injector.get to exclude
all but `string`. Progresses towards #48408
BREAKING CHANGE: The `any` overload has been removed from
`injector.get`. It now only supports `ProviderToken<T>` and (deprecated
since v4) `string`.
PR Close#60202
The server package imports from `rxjs`, but the dependency was not
specified as `peerDependency`, nor `dependency`. This surfaces as an
error in strict dependency environments, like with pnpm's symlinked node
modules structure.
This commit fixes this. It presumably doesn't fail with e.g. Yarn, or
npm because of node modules hoisting.
PR Close#60308
This should keep the existing behavior intact. Right now retrieve never returns back NOT_FOUND. This should not be the case, but tests fail if I do add this behavior so itll have to be later.
PR Close#60192
We had several places where we were trying to get the source file of a class for which we're generating HMR-related code. These calls will fail if the class was transformed so we have to get its source file through the original node.
Fixes#60287.
PR Close#60298
These links aren't that helpful in the context of Angular DevTools for a few reasons:
1. Users of the extension should already have a general understanding of core Angular concepts, inputs and outputs included.
2. The input and output links go to API documentation which isn't useful for someone who doesn't actually understand the core concepts anyways.
3. These links point to signals documentation even though DevTools shows non-signal inputs and outputs.
4. Properties linked to template binding docs, which doesn't *really* have anything to do with the plain JS properties being shown in DevTools anyways.
PR Close#60284
A build will still fail in this case. However, for the language service,
this allows the component to exist in the compiler registry and prevents
cascading diagnostics within an IDE due to "missing" components. The
originating template related errors will still be reported in the IDE.
This case is particularly important when a template file either does
not exist or is inaccessible to the language service.
PR Close#58673
Now that the expression AST contains parenthesized expressions, this
refactors the template pipeline to strip out the ones we don't need.
PR Close#60169
Following up on #60127 which added the concept of a parenthesized
expression to the output AST, this does the same for the expression AST.
PR Close#60169
With Node.js v18 approaching End-of-Life on 2025-04-30, the minimum
supported versions for development have been updated to `^20.11.1 || ^22.11.0`.
This change does not affect published packages.
The custom ESM loader was disabled in several Node.js jasmine tests due
to incompatibilities with the updated custom loader API in newer Node.js
versions. The API in v18 was not considered stable. The rules_js migration
will remove the need for this loader fully in future.
PR Close#60080
This commit changes the text color in terminal light mode to improve
visibility and user experience. The previous color was too light and
made it difficult to read the text.
PR Close#60246
This commit ensures that errors during `ApplicationRef.tick` are
surfaced to the callsite rather than being caught and reported to the
`ErrorHandler`.
The current catch and report approach was originally
added in https://github.com/angular/angular/commit/e263e19a2ae8f7dc6457e5cefb4d27887c111f96
with the goal of preventing automatic change detection crashes due to
the error happening in the subscription. However, this results in hiding
a public API that can hide errors. Callers cannot assume that the tick
was successful and perform follow-up work.
This change now surfaces errors and adds the error handling directly to
the callsites.
BREAKING CHANGE: `ApplicationRef.tick` will no longer catch and report
errors to the appplication `ErrorHandler`. Errors will instead be thrown out of
the method and will allow callers to determine how to handle these
errors, such as aborting follow-up work or reporting the error and
continuing.
PR Close#60102
Previously we never could use relative imports to import e.g. `Component`
in e.g. the `core/tests/bundling` folder. This was necessary because otherwise the
Angular compiler wouldn't process those files as it wouldn't recognize
the Angular decorator as the one from `@angular/core`.
Notably this still isn't a large issue because relative imports still
work for most core tests, that are JIT compiled!
For bundling tests though, or some smaller targets, our new upcoming
guidelines for using relative imports inside the full package; fall
apart. This commit unblocks this effort and allows us to use relative
imports in all tests of `packages/core`. This is achieved by leveraging
the existing `isCore` functionality of the compiler, and fixing a few
instances that were missing before.
PR Close#60268
Usage of the `fast-glob` package has been replaced with the `tinyglobby` package. The change reduces the number of transitive dependencies related to these packages from 17 to 2 while also maintaining equivalent functionality. This was also changed in the Angular CLI packages.
PR Close#60264
This adjusts the tests to have a longer await time and removes the click portion of the test. These tests should only pass if the timer has triggered hydration.
PR Close#60254
To work around the limitation of #54858, this commit removes temporarly the dependency to `core/rxjs-interop` to allow the removal of the microtask effect which was pulled by that entry.
This commit is intented to be reverted once the next patch/next is released.
PR Close#60234
In the case that a route was lazy loaded, some triggers would never properly finish hydrating due to things firing before the route finished resolving.
This will find the topmost parent defer block and ensure the registry knows about it before trying to hydrate.
In the case that the registry does not yet know, just the affected triggers await app stability before initializing.
fixes#59997
PR Close#60203
Currently the language service has some template-specific terminology around type checking, because that's the only place where we had TCB support. These changes make it more generic to accommodate future functionality.
PR Close#60191
Currently only components can have resources, because they're the only symbol kinds being type checked. Since we want to add directives to it, these changes rework the resource handling to accommodate them.
PR Close#60191
Currently the `TemplateSourceManager` is set up to specifically cater to component templates. These changes make it more generic so we can reuse it for directives.
PR Close#60191
Currently a lot of the internal type checking data structures are set up specifically for components, because we only support type checking of templates. Since this will change in future commits, these changes prepare for it by renaming various methods and separating out component-specific data.
PR Close#60191
Currently `R3TargetBinder.bind` gets a set of data back from `DirectiveBinder.apply` and `TemplateBinder.applyWithScope`. This will be annoying if we have multiple sources of data, because we'd have to do merge them at the end.
These changes switch to constructing the various data structures ahead of time and passing them into the binders to populate them instead.
I also extracted some of the less trivial types into type aliases so we don't have to repeat them.
PR Close#60191
Historically we've had to be VERY cautious about the way we import
things between entry-points. That is because the `ng_package` rule
bundling is subject to silently introducing code duplication, breaking
singletons etc. We've had this surface a couple of times already, and
dev-infra tried to help detect such cases by adding safety analysis into
`ng_package`.
Long-term we want to get to an approach where it's easy to simply share
code between chunks. Precisely, with the upcoming `rules_js` migration,
this will be necessary as we will have different import "guidelines"
that would currently, before this commit, result in code duplication, or
trigger our "safety check/lint".
This commit prepares `ng_package` to support relative imports between
entry-points, so that we only need the safety check for cross-package
imports/exports. The result is that `ng_package`/APF is now smartly able
to generate shared chunks for things that are needed between multiple
entry-points. Yay!
Note that those shared chunks still remain private, and are guarded by
our `package.json` "exports"; so no new public API surface is
exposed.
PR Close#60241
In the cases multiple updates with `emitEvent:false` were requests, `shouldHaveEmitted` wasn't passed correctly and and requests updates were trashed.
This commit fixes this.
Fixes#56999
PR Close#57098
Though the plan is to change the default behavior or the router to
instead resolve the navigation promise with `false` to match all other
failed navigations, we should still prevent dangling promise rejections
from navigations triggered internally when developers opt to use the old
(current) behavior.
PR Close#60162
In this commit, we add injector token information to the error message to improve debugging and context awareness, because it is hard to capture the `inject()` stack trace in asynchronous contexts.
PR Close#60009
In this commit, we check whether the application is destroyed before initializing event replay. The application may be destroyed before it becomes stable, so when the `whenStable` resolves, the injector might already be in a destroyed state. As a result, calling `injector.get` would throw an error indicating that the injector has already been destroyed.
PR Close#59789
Note that this does NOT use the retrieve method yet. I believe we need to move the logic for notFoundValue into the inject implementation.
PR Close#60154
Previously, if `ng.getDirectives` was not implemented, Angular DevTools won't throw when attempting to load the component tree. Now it safely ignores the function and assumes no directives exist on the page.
PR Close#60209
In general, we can't assume all applications implement the full `ng` contract as many are older Angular application which pre-date the current interface. As a result, it is safer to type this as a `Partial`.
For now, I just added non-null assertions at all current usage locations, as we do generally feature detect before using these fields. However, hopefully this `Partial` type will make it harder to accidentally call a function which might not be supported.
PR Close#60209
This updates the zoneless documentation to mention that components under
test a required to be onpush compatible. This includes any wrapper
components only used in tests.
fixes#59082
PR Close#59689
Previously Angular DevTools would throw when run on an application which does not support `getInjector`, now it safely ignores it and assumes dependency injection is not supported.
PR Close#60206
Previously this was throwing errors in applications with no Router token.
Now it skips emitting events for the router tree when it is unable to find the Router token.
Note: If these events don't emit, DevTools treats the RouterTree feature as disabled.
PR Close#60221
This commit inlines the `isFactory` function body directly within `getNodeInjectable` because it is only used once. ESBuild does not inline its body within the function, which can be observed when running the build with `NG_BUILD_MANGLE=0`. The results after inlining are as follows:
```
getNodeInjectable x 70,397,377 ops/sec ±3.88% (52 runs sampled)
getNodeInjectable_inlined x 77,834,432 ops/sec ±3.13% (60 runs sampled)
```
PR Close#59824
Previously Angular DevTools would throw if `ng.applyChanges` was not defined. Now DevTools silently ignores the issue, assuming `mutateComponentOrDirective` was sufficient to update the application.
PR Close#60207
This change contains multiple cleanups in the AppComponent:
- remove unused code;
- use router input bindings instead of manual read from
the active route;
- remove isBrowser checks from even handlers (click events
should not be invoked on the server, right?)
PR Close#58897
This fixes an issue with packages managers likes pmpm
that will not link the @angular/compiler package to the @angular/core
package if it is not listed as a peer dependency.
I added it as optional peer dependency as it's only used in special cases.
Fixes#38096
PR Close#55610
This commit updates error reporting of defer blocks to go to the
application root error handler rather than the `ErrorHandler` token that
may be provided by users. This ensures Angular has control over what
happens when these errors are reported.
PR Close#60149
Prior to this change, cyclic injection didn't trigger any error in prod mode, resulting into injecting the `CIRCULAR` object.
This could lead to strange errors where no method would be found on the token.
fixes#60074
PR Close#60118
The PR introduces a few doc content rendering fixes:
- Fix highlighted section heading styles (regression from #59965).
- Convert JSDoc links within 'Usage Notes' sections to HTML and render them.
- Add IDs to doc content headings. This, by itself, makes these headings available in the page ToC.
PR Close#60116
Narrows down the versions of TypeScript we need to support.
BREAKING CHANGE:
* TypeScript versions less than 5.8 are no longer supported.
PR Close#60197
Prior to this commit, the tags from the type definition were dropped.
Tags may include, but are not limited to, deprecation information from
the jsdoc.
PR Close#59524
`AsyncPipe` would previously promise rejections unhandled and
subscription errors uncaught. This is more or less fine in a Zone-based
application because errors inside the Angular Zone are caught be the
Zone's error trap and reported to `ErrorHandler`. However, in zoneless
applications, these errors are never caught or reported by the FW and
can reach the node process in SSR and cause it to shut down.
BREAKING CHANGE: `AsyncPipe` now directly catches unhandled errors in
subscriptions and promises and reports them to the application's
`ErrorHandler`. For Zone-based applications, these errors would have
been caught by ZoneJS and reported to `ErrorHandler` so the result is
generally the same. The change to the exact mechanism for reporting can
result in differences in test environments that will require test
updates.
PR Close#60057
This change introduces a new DI profiler event:
InjectorToCreateInstanceEvent. This new event allows
us to measure DI tokens instantiation time.
PR Close#60158
Reworks the `InputBinding` and `OutputBinding` functionality to be in object literals constructed in functions, rather than classes, because it seems like Terser was having a hard time tree shaking the classes when the functions weren't used.
PR Close#60137
Adds the new `outputBinding` function that allows users to listen to outputs on dynamically-created components in a similar way to templates. For example, here we create an instance of `MyCheckbox` and listen to its `onChange` event:
```ts
interface CheckboxChange {
value: string;
}
createComponent(MyCheckbox, {
bindings: [
outputBinding<CheckboxChange>('onChange', event => console.log(event.value))
],
});
```
Note that while it has always been possible to listen to events like this by getting a hold of of the instance and subscribing to it, there are a few key differences:
1. `outputBinding` behaves in the same way as if the event was bound in a template which comes with some behaviors like forwarding errors to the `ErrorHandler` and marking the view as dirty.
2. With `outputBinding` the listeners will be cleaned up automatically when the component is destroyed.
3. `outputBinding` accounts for host directive outputs by binding to them through the host. E.g. if the `onChange` event above was coming from a host directive, `outputBinding` would bind to it automatically.
Currently `outputBinding` is available only in `createComponent`, `ViewContainerRef.createComponent` and `ComponentFactory.create`, but it will serve as a base for APIs in the future.
PR Close#60137
Calling `setInput` while the component already has an `inputBinding` active can lead to inconsistent state. These changes add an error that will be thrown if that's the case.
PR Close#60137
Adds the ability to bind to inputs on dynamically-created components, either by targeting the component itself or one of its directives. The new API looks as follows:
```ts
const value = signal(123);
createComponent(MyComp, {
// Bind the value `'hello'` to `someInput` of `MyComp`.
bindings: [inputBinding('someInput', () => 'hello')],
directives: [{
type: MyDir,
// Bind the `value` signal to the `otherInput` of `MyDir`.
bindings: [inputBinding('otherInput', value)]
}]
});
```
This behavior overlaps with `ComponentRef.setInput`, with a few key differences:
1. `setInput` sets the value on *all* inputs whereas `inputBinding` only targets the specified directive and its host directives. This makes it easier to know which directive you're targeting.
2. `inputBinding` is executed as if it's in a template, making it consistent with how bindings behave for selector-matched components, whereas `setInput` executes outside the lifecycle of the component.
3. It resolves a long-standing issue with `setInput` where it wasn't possible to set the initial value of an input before the first change detection run.
Currently `inputBinding` is used only for `createComponent`, `ViewContainerRef.createComponent` and `ComponentFactory.create`, however it is going to be base for more APIs in the future.
PR Close#60137
Sets up the symbols used to power the upcoming `inputBinding` functionality.
I also fixed that `setDirectiveInput` was incorrectly only allowing strings for the `value` parameter.
PR Close#60137
Updates `createComponent`, `ViewContainerRef.createComponent` and `ComponentFactory.create` to allow the user to specify directives that should be applied when creating the component.
PR Close#60137
Some upcoming functionality won't work if we can't retrieve a directive definition from a class. These changes add a `throwIfNotFound` to `getDirectiveDef`, similar to `getNgModuleDef`, to avoid duplication in such cases.
PR Close#60137
The check that verifies that there are no duplicates in the directives array was only running after host directive matching since that was the only case when it can happen. After the upcoming changes that won't be the case anymore so these changes move it always run after directive matching.
I also did some additional cleanup by adding comments and by not lazily initializing the `allDirectiveDefs` array when matching host directives. The array is guaranteed to be defined since earlier in the function we verify that there's at least one def with host directives.
PR Close#60137
Moves the tests for `createComponent` into their own file since the `component_spec.ts` was a bit too generic and was accumulating all sorts of tests.
PR Close#60137
Previously, the profiler would only emit the specific template event and context when a template is created/updated, but not the template function related to the event.
This commit emits this function by using the third argument of the profiler function, which previously was only used for lifecycle hooks and output listeners. This commit also renames this arg to eventFn to express that it varies depending on the event type emitting from the profiler.
Note: this change is fully backwards compatible, since previously these template events did not use the third arg of the profiler function.
PR Close#60174
This commit updates the implementation of the fake navigation to more
closely follow the spec. This includes links to spec parts as well as
some reorganization to have the flow of the code more exactly follow the
corresponding steps in the spec. This makes it easier to verify that th
behavior is correct.
PR Close#60028
The navigate event was only ever being cleared when a new navigation
happened. That new navigation would abort the previous one, even if it
had already finished successfully.
PR Close#60028
This commit ensures that rejections of the promise of the async function
passed to `PendingTasks.run` are not dangling and get reported to the
application error handler. This prevents what would likely be a common
dangling promise that could end up crashing the node process.
BREAKING CHANGE: `PendingTasks.run` no longer returns the result of the
async function. If this behavior is desired, it can be re-implemented
manually with the `PendingTasks.add`. Be aware, however, that promise rejections
will need to be handled or they can cause the node process to shut down
when using SSR.
PR Close#60044
This commit fixes a bug where nodes are reused across incremental
compilations. The source file's next template ID is lost because a new
source file is created but nodes may still be retained.
PR Close#60152
This change casts the injector back and forth since all instances of
injector currently don't implement the `retrieve` method. Note that
the retrieve method is seen as optional, so that Angular can revert back to
inject if necessary.
PR Close#60090
The set of inputs and outputs of a component is static, but the getter for the `inputs` and `outputs` property was re-computing them every time which the user might not expect. These changes add a couple of lines to cache them instead.
PR Close#60156
In some rare cases with directives, it is possible that the stash function might be called on a comment node. This actually verifies that the node is an element and exits otherwise.
fixes: #60070
PR Close#60130
This updates the event replay tests to make them share the structure and utility functions used by hydration tests. This also resolves some soft errors in the event replay tests.
PR Close#60130
This commit fixes an issue when ts files are referenced multiple times (and thus analyzed multiple times) for example from a `tsconfig.json` and `tsconfig.spec.json`.
PR Close#60065
Adds a pure annotation to regular expressions because if the animations package is indirectly referenced in the code, it would include regular expressions in the bundle, even if they're unused (since `new` is side-effectful).
PR Close#60095
Instead of using a property on BinaryOperatorExpr / UnaryOperatorExpr,
introduce a ParenthesizedExpr which can be used to parenthesize any
expression.
PR Close#60127
- The token rendered in the first col of the table is now being truncated in favor of the horizontal scroll of the panel which should make the log button accessible/visible all the time
- Introduced a "No such providers" label when a filter is applied
- The icon of the logProvider button has been substituted with `code` (as per the doc)
- The font size and width of the provider type filter have been slightly improved
PR Close#59531
The purpose of this component is purely to encapsulate and offload the styles from `devtools.component.scss` since it wasn't very clear what their scope is.
PR Close#59916
Using `setTimeout` to delay scrolling can result in scrolling in the
next frame and cause noticeable flicker. This commit races rAF and
timeout to ensure scroll happens before the render.
fixes#53985
PR Close#60086
Use the new UI and drop the `InjectorTreeVisualizer` dependency. Additionally, use concrete values for `SerializedInjector.type` type instead of `string`.
PR Close#60011
`HttpClient` has a lot of overloads to achieve proper type checking, however each overload is also very long which makes it hard to read on adev. These changes replace the object literal types with `Record` to make them a bit more concise.
PR Close#59901
This commit updates the resolver execution to ensure that resolvers in
children routes are able to read the resolved data from anything above
them in the route tree. Because resolvers on one level block execution
of those below, it seems more of an oversight in the initial
implementation than anything else that this wasn't already possible.
resolves#47287
PR Close#59860
This change removes the reporting of errors from the
`ChangeDetectorRef.detectChanges` API. The reporting results in the
error being "handled" in two ways, both by reporting to error handler
and rethrowing the error. This rethrown error generally ends up being
caught further up and again reported to the error handler. The error
handler is meant to be for uncaught errors, and since Angular is not at
the top of the stack of the call of `CDR.detectChanges`, it does not
know what is being done with the rethrown error.
Note that for zone-based applications, this will likely have no effect
other than removing duplicate reporting of the error. If the rethrown
error is not already being caught, it will reach the NgZone's error
trap and still be reported to the application `ErrorHandler`.
PR Close#60056
Add support for the `void` operator in templates and host bindings.
This is useful when binding a listener that may return `false` and
unintentionally prevent the default event behavior.
Ex:
```
@Directive({
host: { '(mousedown)': 'void handleMousedown()' }
})
```
BREAKING CHANGE: `void` in an expression now refers to the operator
Previously an expression in the template like `{{void}}` referred to a
property on the component class. After this change it now refers to the
`void` operator, which would make the above example invalid. If you have
existing expressions that need to refer to a property named `void`,
change the expression to use `this.void` instead: `{{this.void}}`.
PR Close#59894
Sets up the infrastructure that will allow to write only to a specific directive and its host directives as a base for future functionality.
I've also renamed `setInputsForProperty` to be a bit more explicit that its sets all inputs.
PR Close#60075
Currently the host directive logic disassembles and re-assembles the array of directive matches, in case there are host directives which in most cases produces an identical array.
These changes add some logic so that we only need to allocate the additional memory if we actually need it.
PR Close#60075
In order to mark a TNode as a component, we need to store the index of the component definition. Currently this happens in the logic that resolves host directives, because the component's host directives can move affect the index.
These changes move the logic out into the directive initialization logic since it doesn't have much to do with host directives.
PR Close#60075
If we want to target an input write to a directive, we have to know the index at which its instance is stored. Technically we can already find this by looking through `TView.data`, but that'll require a linear lookup for each write which can get slow.
These changes introduce the new `TNode.directiveToIndex` map which allows us to quickly find the index of a directive based on its definition, as well as any host directives that its might've brought in.
PR Close#60075
Adjusts the date pipe and formatDate function to detect suspicious usages of the week-numbering year formatter without including the week number, as this is often confused for the calendar year and likely to result in incorrect results near New Years, meaning that those issues aren't typically caught during development. This commit starts throwing a development-only error to reveal this issue right away.
BREAKING CHANGE:
Using the `Y` formatter (week-numbering year) without also including `w` (week number) is now detected as suspicious date pattern, as `y` is typically intended.
PR Close#59798
Instead of centering the dialog, fix the top position in such way that when the results container is full, the dialog looks centered. This prevents the dialog from "jumping" when you type and the results change.
PR Close#60012
By using the `@angular/build` package directly within projects for each
example and tutorial, the total install size can be reduced. This lowers the amount
of time required to be spent setting up the dependencies in browser
before the example is displayed.
The `@angular/build@19.2.0-next.2` package currently has a total unpacked size of ~115 MB.
The `@angular-devkit/build-angular@19.2.0-next.2` package currently has a total unpacked size of ~291 MB.
This also removes the now unneeded `NG_BUILD_PARALLEL_TS=0` environment variable usage.
PR Close#60046
Reworks the `TNode.inputs` and `TNode.outputs` to not store the public names of bindings. The only reason they were stored was for host directive re-aliasing which is handled through a different data structure now.
PR Close#60036
Currently `TNode.inputs`/`TNode.outputs` store all of the available bindings on that node, no matter if they came from a directive that the user applied directly or from a host directive. This has a couple of drawbacks:
1. We need to store more information that necessary. For example, the only reason we have strings in the arrays is to facilitate host directive aliasing.
2. It doesn't allow us to distinguish which host directives belong to which selector-matched directives.
These changes are a step towards resolving both issues by storing the host directive binding information in separate data structures.
PR Close#60036
Reworks the functions that create the `initialInputs`, `inputs` and `outputs` structures to initilize them within the function, instead of returning them to be initialized later. This will simplify future refactors where they'll produce more than one piece of information.
PR Close#60036
This refactoring consolidates logic around detecting ngNonBindable
mode - previously those checks were done in two separate places.
By doing the check in one place we can simplify the directive resolution
logic.
PR Close#60048
There are cases where resources fail to fetch or the DOM has changed due to an if block. This should clean up the remaining promises and any registry references to those blocks in that case.
PR Close#59740
Future changes to initialization order can cause this previously OK code to start having compiler erroring like: `TS2729: Property 'foo' is used before its initialization.`
PR Close#60025
Removes the circular dependencies golden file and cleans up the
associated pullapprove group. All circular dependencies have been
removed and no new ones may be added.
PR Close#60021
This moves the `FakeNavigation` implementation to the primitives folder
so its implementation can be shared with Wiz. This class was initially
copied directly from the Wiz implementation, with some small modifications.
There will still need to be some work done to align the implementations
and fix anything internally that needs adjusting.
PR Close#59857
The refactored version improves the original code by removing the `supports` method from the prototype and inlining the logic directly into the `transform` method. This reduces indirection and simplifies the class, especially since `supports` is not reused elsewhere. ESBuild can directly inline the condition into the `if` statement by removing the variable: `if (!("string" == typeof e || Array.isArray(e))) throw i(s, e);`.
PR Close#59684
In this commit, we remove `_checkFormPresent` because it is a no-op in production. We move its body directly into `ngOnChanges` to eliminate the redundant method from the prototype. Previously, `_checkFormPresent` was being called with no body in production each time `ngOnChanges` was executed.
PR Close#59741
In this commit, we improve branching in the `stringify` function, which is widely used by the framework, and add additional comments for clarification. Benchmark results of the old and new implementations (using `slice` makes it slightly faster) are as follows:
```
stringify (old version) x 117,945,419 ops/sec ±5.25% (55 runs sampled)
stringify (new version) x 136,692,820 ops/sec ±4.82% (56 runs sampled)
```
PR Close#59745
The new version of the function is smaller, eliminating extra bytes. The refactor improves both code size and readability while optimizing the implementation. Benchmark results for the old and new implementations are as follows:
```
stripTrailingSlash_old x 15,446,602 ops/sec ±0.89% (66 runs sampled)
stripTrailingSlash_new x 19,694,523 ops/sec ±1.10% (61 runs sampled)
```
Thus, the new implementation is both smaller and faster.
PR Close#59746
Attempting to write to directive inputs before the directive is created can lead to subtle issues that won't necessarily trigger errors. These changes add an assertion to catch such issues earlier.
PR Close#59980
Currently we resolve the DOM node when writing inputs up-front, because it's necessary for the `ng-reflect-` attributes. Since the attributes are dev-mode-only, we can move the resolution into the function that writes them so we can avoid the resolution when it's not used.
PR Close#59980
Reworks the `InitialInputs` data structure to only store a public name and initial value, resulting in less memory usage and making it easier to work with.
PR Close#59980
Currently the values in `DirectiveDef.inputs` are either strings or arrays, depending if there are flags. This makes it a bit hard to work with, because each time it's read, the consumer needs to account for both cases.
These changes rework it so the values are always an arrays.
PR Close#59980
In this commit, the `urlChanges` subject is completed to release all active observers when the root scope is destroyed. Previously, subscribing to the `urlChanges` subject caused the subscriber to capture `this`, resulting in a memory leak after the root scope was destroyed.
PR Close#59703
This test has 2 async parts, loading the markdown file and the marked parsing.
First attempt to fix the flakiness is by inline the markdown file.
If this test timeouts again in the future it means the timeout is related to marked itself (and the dynamic import of mermaid).
PR Close#59994
`-x dist/` never worked for reasons I don't really understand. Historically I've just deleted `dist/` before zipping. I tried a few different approaches, but all of them lead to some form of "Name not matched" error in `zip` of the `dist/` directory. Instead I just opted to delete `dist/` as part of the zipping command.
The link to recent DevTools commits seems good enough to manually write a changelog. All relevant commits should be using `refactor(devtools)`, so the string "devtools" should definitely be in there.
PR Close#59792
`httpResource` is a new frontend to the `HttpClient` infrastructure. It
declares a dependency on an HTTP endpoint. The request to be made can be
reactive, updating in response to signals for the URL, method, or otherwise.
The response is returned as an instance of `HttpResource`, a
`WritableResource` with some additional signals which represent parts of the
HTTP response metadata (status, headers, etc).
PR Close#59876
Move the initializer into the constructor for instance members that reference identifiers declared in the constructor.
When TypeScript outputs modern language features, the below case throws an TS error.
PR Close#59960
This extends the test timeout for the two timer tests while shortening the actual hydrate on timer. This hopefully should result in more reliable CI.
PR Close#59945
This will be the starting point of the DI package. We will first check in some interfaces and then make sure the existing DI package implements that interface. Afterwards, we'll slowly start moving injector implementation.
PR Close#59921
Updates the signature of the `throwInvalidWriteToSignalError` to take the signal node in question and pass it along to the throwInvalidWriteToSignalErrorFn handler function. This allows the handler to e.g. include the signal name in error messaging.
PR Close#59600
The CLI uses the `ts.transform` API to apply the Angular compiler's transformers
on the source files when `isolatedModules` is true (and various other constraints)
instead of going through a full `ts.Program.emit` operation. This results in the
transformers to operate in an environment where no emit resolver is available, which
was not previously accounted for. This commit reflects the possibility for the emit
resolver to be missing and handles this scenario accordingly.
Fixes#59837
PR Close#59869
The `transferCacheInterceptorFn` injects dependencies in itself; the `TransferCache` and cache options are redundant in the `deps` list.
PR Close#59819
The new version of the function is smaller, eliminating extra bytes. The refactor improves both code size and readability while optimizing the implementation. Benchmark results for the old and new implementations are as follows:
```
concatStringsWithSpace_old x 149,225,311 ops/sec ±8.54% (50 runs sampled)
concatStringsWithSpace_new x 160,206,834 ops/sec ±5.72% (54 runs sampled)
```
Thus, the new implementation is both smaller and faster.
PR Close#59820
1. The WebGL animation on the home page is completely removed.
2. A new animation processor/player is implemented and added to `adev` web app.
3. A new CSS+JS-based animation substitutes the existing WebGL one.
PR Close#59865
We should probably have our own authoritative documentation here, but Tailwind's doc is pretty decent, so this is a good starting point.
PR Close#59765
- Move all styles to ng-devtools/src/styles.
- Create a BrowserService that detects the browsers and adds it as a class to the body. Move global browser styles.
- Create theme mixins that incorporate the browser type into them.
- Refactor some of the affected code along with the introduced changes.
PR Close#59589
Currently when we generate the tracking expression for a `@for` block, we process its expression in the context of the creation block. This is incorrect, because the expression may require ops of its own for cases like nullish coalescing or safe reads. The result is that while we do generate the correct variable, they're added to the creation block rather than the tracking function which causes an error at runtime.
These changes address the issue by keeping track of a separate set of ops for the `track` expression that are prepended to the generated function, similarly to how we handle event listeners.
Fixes#56256.
PR Close#58520
This commit solves two cases
Bug: When a directive of the same name is selected, the property view tab would not update properly. This was caused by a signals refactor that changed the behaviour of a string input property to not re-render because the underlying signal did not change (string equality). This is fixed by converting this input into an object.
Bug: When a selected element is removed from the component tree, DevTools would not rerender the component tree properly and deselect that component. Now if DevTools detects that a component is removed, it re-renders the tree and deselects the component.
PR Close#59873
When the compiler analyzes the defer blocks in a component, it generates two sets of dependencies: ones specific for each block and others from all the deferred blocks within the component. The logic that combines all the defer block dependencies wasn't de-duplicating them which resulted in us producing `setClassMetadataAsync` calls where the callback can have multiple parameters with the same name. This was a problem both in full and partial compilation, but the latter was more visible, because Babel throws an error in such cases.
These changes add some logic to de-duplicate the dependencies so that we produce valid code.
Fixes#59922.
PR Close#59926
Adjusts the code we generate for HMR so that it passes in the HMR ID and `import.meta` to the `replaceMetadata` call. This is necessary so we can do better logging of errors.
PR Close#59854
The refactoring of `resource()` to use `linkedSignal()` introduced the
potential for a race condition where resources would get stuck and not update
in response to a request change. This occurred under a specific condition:
1. The request changes while the resource is still in loading state
2. The resource resolves the previous load before its `effect()` reacts to the
request change.
In practice, the window for this race is small, because the request change in
(1) will schedule the effect in (2) immediately. However, it's easier to
trigger this sequencing in tests, especially when one resource depends on the
output of another.
To fix the race condition, the resource impl is refactored to track the request
in its state, and ignore resolved values or streams for stale requests. This
refactoring actually makes the resource code simpler and easier to follow as
well.
Fixes#59842
PR Close#59851
This change waits until the end of `tick` to clear the tracing snapshot.
This ensures that if we notify the scheduler during `tick` the correct
tracing snapshot is used.
PR Close#59796
Previously, using `Validators.required`, `Validators.minLength` and `Validators.maxLength` validators don't work with sets because a set has the `size` property instead of the `length` property. This change enables the validators to be working with sets.
PR Close#45793
I assume that the link text should read "Try it now" instead of "Try it not". The latter is funnier, but also implies that this migration is not a recommended one.
PR Close#59816
When we generate an HMR replacement function, we determine which locals from the file are used and we pass them by reference. This works fine in most cases, but breaks down for const enums which don't have a runtime representation.
These changes work around the issue by passing in all the values as an object literal.
Fixes#59800.
PR Close#59815
Fixes that the partial evaluator was interpreting initializer-less enum members as undefined. In this case the value is the same as the index.
PR Close#59815
This change removes some code and logic duplication by
re-using the existing functionality. It also pulls some
code into separate methods for clarity.
PR Close#59806
In this commit, we wrap `initCanvas` in an observable to prevent executing any code, such as `getViews()`, if the view is destroyed before the canvas becomes ready.
PR Close#59732
Fixes example of programmatically rendering of components using dynamic import, as calling dynamic import returns module namespace object rather than component instance
PR Close#59768
Removes the hard dependency between `platform-server` and `platform-browser/animations` since now the animations module will disable itself automatically.
PR Close#59762
Uses `ngServerMode` to automatically disable browser animations on the server. This allows us to decouple `platform-server` from the animations package.
PR Close#59762
Implemented functionality to prepend the baseHref to `sourceMappingURL` in CSS content. Added handling to ensure external sourcemaps are loaded relative to the baseHref. Corrected sourcemap URL behavior when accessing pages with multi-segment URLs (e.g., `/foo/bar`). Ensured that when the baseHref is set to `/`, maps are requested from the correct path (e.g., `http://localhost/comp.css.map` instead of `http://localhost/foo/bar/comp.css.map`).
Closes#59729
PR Close#59730
In this commit, we check whether the application is destroyed before printing hydration stats. The application may be destroyed before it becomes stable, so when the `whenStableWithTimeout` resolves, the injector might already be in a destroyed state. As a result, calling `injector.get` would throw an error indicating that the injector has already been destroyed.
PR Close#59716
Add @bazel/ibazel to the ignored deps list for renovate to prevent us from updating to a version that
is incompatible with our repository.
PR Close#59761
The merge tool is currently hard-coded to only check `lint` as a
required status. This was added because at some point the old GitHub
robot was replaced with a so-called `unified-statuses` check GitHub
action; but that one never worked/impacted productivity of the team.
I've added support to the merge tool to require specific jobs/checks to
run, before allowing merge (can be forcibly ignored). We are using this
ability now to enforce a few "common" required jobs, as a safety measure
when GitHub didn't trigger CI runs (e.g. for new contributors).
This recently became a more prominent issue as the GitHub org enforces
that CI doesn't run for e.g. first time contributors.
PR Close#59749
`hasValue` attempts to narrow the type of a resource to exclude `undefined`.
Because of the way signal types merge in TS, this only works if the type
of the resource is the same general type as `hasValue` asserts.
For example, if `res` is `WritableResource<string|undefined>` then
`.hasValue()` correctly asserts that `res` is `WritableResource<string>` and
`.value()` will be narrowed. If `res` is `ResourceRef<string|undefined>`
then that narrowing does _not_ work correctly, since `.hasValue()` will
assert `res` is `WritableResource<string>` and TS will combine that for a
final type of `ResourceRef<string|undefined> & WritableResource<string>`.
The final type of `.value()` then will not narrow.
This commit fixes the above problem by adding a `.hasValue()` override to
`ResourceRef` which asserts the resource is of type `ResourceRef`.
Fixes#59707
PR Close#59708
When a resource first starts up, even if it transitions immediately to
`Loading` it should report a `previous.state` of `Idle`. It was reporting
`Loading` as the previous state in such a case because of an oversight in
the migration to `linkedSignal` which this commit addresses.
PR Close#59708
In this commit, we're using the `from()` in the `adev-home` component, which allows us to invert a dependency and avoid memory leaks. Because an `async` function would be executed even if the component is already destroyed.
PR Close#59683
In this commit, we're using the `from()` in the `adev-tutorial` component, which allows us to invert a dependency and avoid memory leaks. Because `then()` would be executed even if the component is already destroyed.
PR Close#59675
Updates the docs since we'll have support for template strings in 19.2. Also mentions that tagged template string aren't supported.
Fixes#59160.
PR Close#59710
In this commit, we tree-shake the `PreloadLinkCreator` for client bundles because it's targeting only server code. We use the pending tasks service to contribute to app stability by waiting for the module to load.
PR Close#59431
The new version is 2x smaller in the reduced code size; as thus this eliminates extra bytes. Refactors `joinWithSlash` function to reduce code size and improve readability. Added checks to handle leading and trailing slashes more concisely and provided comments for clarity.
PR Close#59484
We already have a function called `isDetachedByI18n` which checks whether a `tNode` is in `isDetached` state; as thus, there's no reason to apply those checks manually.
PR Close#59668
Before `resource()` resolves, its value is in an unknown state. By default
it returns `undefined` in these scenarios, so the type of `.value()`
includes `undefined`.
This commit adds a `defaultValue` option to `resource()` and `rxResource()`
which overrides this default. When provided, an unresolved resource will
return this value instead of `undefined`, which simplifies the typing of
`.value()`.
PR Close#59655
In this commit, we remove the separate `a === undefined` and `a === null` checks and replace them with `a == null`. Using `a == null` is better and more concise because it checks for both `null` and `undefined` in a single operation. The loose equality `==` is specifically designed to treat `null` and `undefined` as equivalent. This change only reduces some bytes in the code and simplifies it, with no performance impact, as modern JavaScript engines handle `a == null` efficiently. Additionally, comments have been added for clarification.
PR Close#59696
The `_checkParentType` bodies are wrapped with `ngDevMode`, meaning they act as no-ops in production. We can wrap the actual calls to `_checkParentType` with `ngDevMode` to prevent calling no-op functions in production
PR Close#59489
The `type_checks` module already exposes a utility function that checks whether `TNode.componentOffset` is greater than -1. There is no need to check that property manually in other places, as we can reuse the helper function.
PR Close#59611
Drops some bytes by moving `Accept` into a variable, which is then minified to something like `var a="Accept"` and reused in all the places.
PR Close#59546
In this commit, we prevent error handling when the root injector is already destroyed. This may happen when the observable completes before emitting a value, which would trigger a `catchError` block that attempts to call `runInInjectionContext` on a destroyed injector.
PR Close#59457
The `type_checks` module already exposes a utility function that checks whether `LView` is marked as a root view. There is no need to check flags in other places, as we can reuse the helper function.
PR Close#59614
If a file ends up in multiple programs, the unused imports migration was counting it twice. This was fine since the string replacements were handling it correctly, but it was printing out incorrect data.
These changes rework the migration to de-duplicate the replacements and produce the data from the de-duplicated results.
PR Close#59656
This commit updates a flaky test to increase the amount of work (more `for` loop iterations) to minimize the chance of getting the same timestamp after that work.
PR Close#59653
Makes the following cleanups in the output AST:
* The `TemplateLiteral` and `TemplateLiteralElement` nodes have been renamed to `TemplateLiteralExpr` and `TemplateLiteralElementExpr` respectively for consistency and to avoid overlaps with the expression AST nodes.
* The `TemplateLiteralExpr` and `TemplateLiteralElementExpr` have been refactored to be `Expression`s for correctness. This involves updating some existing code.
* The `TaggedTemplateExpr` has been renamed to `TaggedTemplateLiteralExpr` for consistency.
PR Close#59230
Reworks the lexer's scanner to produce more than one token at a time. This can be useful for the cases where one token means the end of another one.
Also cleans up the scanner by making all non-essential methods private and using strict equality everywhere.
PR Close#59230
Updates the HMR dependencies extraction logic to handle conditional expressions.
For example, `providers: [condition ? providersA : providersB]`.
PR Close#59637
The component ID collision check tries to account for components being replaced by checking for the `type`, however that might not work during SSR.
These changes disable the warning since it's primarily useful on the browser anyways.
PR Close#59625
This commit adds support for creating `resource()`s with streaming response
data. A streaming resource is defined by a `stream` option instead of a
`loader`, with `stream` being a function returning
`Promise<Signal<{value: T}|{error: unknown}>>`. Once the streaming loader
resolves to a `Signal`, it can continue to update that signal over time, and
the values (or errors) will be delivered to via the resource's state.
`rxResource()` is updated to leverage this new functionality to handle
multiple responses from the underlying Observable.
PR Close#59573
Fixes that the async animations renderer didn't have the logic to clean up its style cache during HMR. This is identical to #59393.
Fixes#59640.
PR Close#59644
Fixes that we were filtering out the component itself from the set of dependencies when HMR is enabled, breaking self-referencing components.
Fixes#59632.
PR Close#59644
Currently during HMR we swap out the entire module definition (e.g. `MyComp.ɵcmp = newDef`). In standalone components and most module-based ones this works fine, however in some cases (e.g. circular dependencies) the compiler can produce a `setComponentScope` call for a module-based component. This call doesn't make it into the HMR replacement function, because it is defined in the module's file, not the component's. As a result, the dependencies of these components are cleared out upon replacement.
A secondary problem is that the `directiveDefs` and `pipeDefs` fields can save references to definitions that later become stale as a result of HMR.
These changes resolve both issues by:
1. Performing the replacement by copying the properties from the new definition onto the old one, while keeping it in place.
2. Preserving the initial `directiveDefs`, `pipeDefs` and `setInput`.
Fixes#59639.
PR Close#59644
Both `:host` and `:host-context` work by looking for a specific character sequence that is terminated by `,` or `{` and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for `:host`, because each `:host` produces one scoped selector which doesn't affect any child selectors, however it breaks down with `:host-context` which replaces each instance with two selectors. For example, if we have a selector in the form of `:host-context(.foo) a:not(.a, .b)`, the compiler ends up determining that `.a,` is the end selector and produces `.foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}`.
These changes resolve the issue by splitting the CSS alogn top-level commas, processing the `:host-context` in them individually, and stiching the CSS back together.
PR Close#59276
When a component is created with shadow DOM encapsulation, we attach a shadow root to it. When the component is re-created during HMR, it was throwing an error because only one shadow root can be attached to a node at a time.
Since there's no way to detach a shadow root from a node, these changes resolve the issue by making a shallow clone of the element, replacing it and using the clone for any future updates.
Fixes#59588.
PR Close#59597
When HMR is enabled, we need to capture the dependencies used in a template and forward them to the HMR replacement function. One half of this process is static, meaning that we can't change it after the initial compilation. Tree shaking becomes a problem in such a case, because the user can change the template in a way that changes the set of dependencies which will start matching with the static part of the HMR code.
These changes disable the tree shaking when HMR is enabled to ensure that the dependencies stay stable.
Fixes#59581.
PR Close#59595
If a component injects `ViewContainerRef`, its `LView` gets wrapped in an empty `LContainer` and the container's host becomes the `LView`. The HMR logic wasn't accounting for this which meant that such components wouldn't be replaced.
Fixes#59592.
PR Close#59596
In this commit, we clean up the reference to the function set by the environment initializer, as the function closure may capture injected elements and prevent them from being properly garbage collected.
PR Close#59598
This change refactor how the dynamically created component
deals with attributes in order to reuse the existing
setupStaticAttributes logic (instead of having specific
and similar code).
PR Close#59572
This commit updates a test setup to define a global `ngServerMode` correctly for a test that was emulating client-only behavior. The flag could've been set by prior tests and depending on its state, the test was acting differently.
PR Close#59584
This commit updates testing setup logic to apply correct `document` reference, which should be used by the runtime. Previously, the timing of that operation was less predictable and in some cases led to reusing document state from previous tests.
PR Close#59579
In this commit, we delete `_ejsa` when the app is destroyed, ensuring that no elements are still captured in the global list and are not prevented from being garbage collected.
PR Close#59492
In this commit, we switch from decorators (which also produce redundant metadata, such as in the `declareFactory`
instruction) to the `inject` function to drop the `ROUTER_FORROOT_GUARD` token in production. This token factory function is only in development mode but is still referenced in the constructor due to the `@Inject(ROUTER_FORROOT_GUARD)` decorator.
PR Close#59458
These changes aim to resolve the issue that prompted #59514. The animations module is a bit tricky for HMR, because it schedules the destruction of its renderer after the currently-running animations are done. If there are no running animations, the renderer gets destroyed next time around. This is a problem, because it means that the styles can stay around for a long time.
These changes resolve the issue by:
1. Moving the cleanup of the renderer to after the destruction of the old view. This ensures that the usual clean up flow has been kicked off.
2. Flushing the animations when a component is replaced to ensure that the renderer is cleaned up in a timely manner.
PR Close#59574
When the reactive `request` of a resource() notifies, it transitions to the
Loading state, fires the loader, and eventually transitions to Resolved.
With the prior implementation, a change of the `request` will queue the
effect, but the state remains unchanged until the effect actually runs. For
a brief period, the resource is in a state where the request has changed,
but the state has yet to update.
This is problematic if we want to use resources in certain contexts where we
care about the state of the resource in a synchronous way. For example, an
async validator backed by a resource might be checked after an update:
```
value.set(123);
if (validator.value()) {
// value is still valid, even though the resource is dirty and will soon
// flip to loading state (returning value(): undefined) while revalidating
}
```
To address this timing concern, `linkedSignal()` is used within the
`resource()` to synchronously transition the state in response to the
request changing. This ensures any followup reads see a consistent view of
the resource regardless of whether the effect has run.
This also addresses a race condition where `.set()` behaves differently on a
`resource()` depending on whether or not the effect has run.
PR Close#59024
Originally the `T` in `Resource<T>` represented the resolved type of the
resource, and `undefined` was explicitly added to this type in the `.value`
signal. This turned out to be problematic, as it wasn't possible to write a
type for a resource which didn't return `undefined` values. Such a type is
useful for 2 reasons:
1. to support narrowing of the resource type when `Resource.hasValue()`
returns `true`.
2. for resources which use a different value instead of `undefined` to
represent not having a value (for example, array resources which want to
use `[]` as their default).
Instead, this commit changes `resource()` and `rxResource()` to return an
explicit `ResourceRef<T|undefined>`, and removes the union with `undefined`
from all types related to the resource's value. This way, it's trivially
possible to write `Resource<T>` to represent resources where `.value` only
returns `T`.
`hasValue()` then actually works to perform narrowing, by narrowing the
resource type to `Exclude<T, undefined>`.
PR Close#59024
Prevent leaking signal reads and exceptions from a custom `equal`
function of a producer `computed()` to a consumer.
Upstream https://github.com/tc39/proposal-signals/pull/90 with a notable
change: Angular does **not** track reactive reads in custom `equal`
implementations.
PR Close#55818
Fixes that in some cases the HMR replacement function was being run outside the zone which meant that change detection would break down after a replacement.
Fixes#59559.
PR Close#59562
Rolls back the changes from #59514 because they ended up being breaking in 1P. We can revisit the internal fix in a different way.
Fixes#59558.
PR Close#59557
Drops some bytes by moving `Content-Type` into a variable, which is then minified to something like `var b="Content-Type"` and reused in all the places.
PR Close#59518
This is first of a series of refactorings that moves code
around such that logic from the shared instruction file
is dispatched to the relevant functional parts.
PR Close#59453
Adds a new diagnostic that ensures that a standalone component using custom structural directives in a template has the necessary imports for those directives.
Fixes#37322
PR Close#59443
This commit introduces an update to the official recommendations when it comes to class & styles bindings.
`[class]` & `[style]` bindings are now recommended for basic uses cases.
`[ngClass]` and `[ngStyle]` allow more advanced bindings (like space separated keys) or keys with units (for `ngStyle`) which are not supported by the native bindings. They still require the dedicated directives.
PR Close#59240
The input tags written within the flowcharts in the document were not being escaped, so we did that.
This change will ensure that the flowcharts in the document are properly displayed.
PR Close#59517
Fix issues related to scrolling in the API reference:
- Scroll to the top of the page when navigating to the API details page
- Preserve scroll position when navigating back from the API details page
PR Close#59207
Prior to this commit, the `this.lcpObserver?.updateImage` expression was still preserved in the production code because it wasn't wrapped with `ngDevMode`. The observer is injected only in development mode. Additionally, we moved the logic from `ngOnDestroy` to avoid having an empty method in production.
PR Close#59481
In this commit, we replace `isPlatformServer` runtime call with the `ngServerMode` in the `transferCacheInterceptorFn` in order to make the functionality tree-shakable between client and server bundles.
PR Close#59439
The set of profiler events was recently extended. This commit plugs
newly created events dispatch into the approriate places
of the Angular core.
PR Close#59233
Several profiler calls don't have any meaningful instance when
producing a profiling event. This commit changes the default
instance value to null to sreamline profiler invocations.
PR Close#59233
Currently when we swap out the component during HMR, we remove the renderer from the cache, but we never destroy it which means that its styles are still in the DOM. This can cause the old styles to leak into the component after they're replaced. These changes add a `destroy` call to ensure that they're removed.
PR Close#59514
Generate the `NavigationItem`-s as part of adev/shared-docs pipeline and use the output JSON files instead of the hardcoded objects in the `sub-navigation-data.ts`.
PR Close#59355
As of 19.1, component HMR for both styles and templates is considered
stable and enabled by default. This includes support for both inline
and file-based component styles/templates.
PR Close#59503
It looks like this height property was redundant prior to upgrading to angular/material 19.1.0-rc.0. An interaction between this property and that update caused elements inside of material expansion panels to be hidden.
This PR removes this unnecessary height assignment entirely.
PR Close#59493
Note: this enums are not a part of the public API.
Prior to this commit, the compiler produced:
```js
var DateType;
(function (DateType) {
DateType[DateType["FullYear"] = 0] = "FullYear";
DateType[DateType["Month"] = 1] = "Month";
DateType[DateType["Date"] = 2] = "Date";
DateType[DateType["Hours"] = 3] = "Hours";
DateType[DateType["Minutes"] = 4] = "Minutes";
DateType[DateType["Seconds"] = 5] = "Seconds";
DateType[DateType["FractionalSeconds"] = 6] = "FractionalSeconds";
DateType[DateType["Day"] = 7] = "Day";
})(DateType || (DateType = {}));
```
With these changes, we allow objects to be dropped entirely and inlined.
PR Close#59468
We change the `enum` to a plain `const` to eliminate extra bytes, as `enum` is not really required. We might not be able to switch to `const enum` due to single-file compilation restrictions.
PR Close#59469
The set of profiler events was recently extended. This commit plugs
newly created events dispatch into the approriate places
of the Angular core.
PR Close#59233
Several profiler calls don't have any meaningful instance when
producing a profiling event. This commit changes the default
instance value to null to sreamline profiler invocations.
PR Close#59233
In this commit, we lazy-load `EmbeddedTutorialManager` in the home editor component via `injectAsync` as done in other parts of the code.
PR Close#59491
docs: Adjust lines of server.ts example in ssr docs
The server.ts excerpt used in the server-side-rendering docs
(https://angular.dev/guide/ssr#configure-server-side-rendering)
does not fully encapsulate the commonEngine code-block.
It begins too early in line 31, leading to the inclusions of lines
from another codeblock that is not intended to be shown here:
```
);
// All regular routes use the Angular engine
```
It should be beginning with the line
`// All regular routes use the Angular engine`.
It also ends too soon, cutting off these parts of the code-block:
```
.catch((err) => next(err));
});
```
PR Close#59490
We previously did count forcibly ignored queries as incompatible. This
resulted in incorrect migration stats that are printed upon migration
completion.
See: #58657
PR Close#59463
This ensures the migration works for these TypeScript versions. The
migration is very sensitive to the TS version and its internals; so it
makes sense to test all of these.
PR Close#59463
In this commit, we switch from decorators (which also produce redundant metadata, such as in the
`declareFactory` instruction) to the `inject` function to drop the `BROWSER_MODULE_PROVIDERS_MARKER`
token in production. This token is actually provided only in development mode but is still
referenced in the constructor due to the `@Inject(BROWSER_MODULE_PROVIDERS_MARKER)` decorator.
PR Close#59412
The URL that is dynamically imported to fetch a potential component update
for HMR is now based on the value of `import.meta.url`. This ensures that
the request is sent to the same location that was used to retrieve the
application code. For some development server setups the HTML base HREF
may not be the location of the Angular development server. By using the
application code location which was generated by the development server,
HMR requests can continue to work as expected in these scenarios. In
most common cases, this change will not have any effect as the HTML base
HREF aligns with the location of the application code files.
PR Close#59459
The `X-Request-URL` string is duplicated in multiple places. It is worth moving it to a shared constant that would be minified to something like `const a = "X-Request-URL"` and referenced in all the used places.
PR Close#59420
Prior to this commit, functions that issued warnings were not wrapped with `ngDevMode` at the point
of invocation but had the `ngDevMode` check inside. This meant they acted as no-ops in production.
In this commit, we wrap them externally with `ngDevMode`, so they are entirely removed.
PR Close#59408
Injecting the `Console` is redundant because it directly calls the global `console` object.
There is no reason to reference this class in Hammer gestures, as it is only used in development
mode. We can safely call the `console` object directly.
PR Close#59409
This commit updates the code of the HTTP code to make the `FetchBackend` class tree-shakable. The class is only needed with `withFetch()` is called and it should not be included into bundles that do not use that feature.
PR Close#59418
In this commit, we replace the `isPlatformBrowser` runtime call with the `ngServerMode` in order to drop the `NullViewportScroller` for client bundles.
PR Close#59440
Fixes that the HMR dependency extraction logic wasn't handling some node types. Most of these are a bit edge-case-ey in component definitions, but variable initializers and arrow functions can realistically happen in factories.
PR Close#59445
Prior to this commit, the compiler produced:
```js
No = (function (e) {
return (
(e[(e.None = 0)] = "None"),
(e[(e.HasTransplantedViews = 2)] = "HasTransplantedViews"),
e
);
})(No || {});
```
Changing to `const enum` allows it to be entirely dropped and inline values.
PR Close#59416
Prior to this change, a scheduled root effect, even if destroyed instantly, would still run at least once.
This commit fixes this.
fixes#59410
PR Close#59415
For `afterRender`/`afterNextRender` calls associated with a particular
view, ensure that they are not registered until after the first time the
view is rendered.
Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>
PR Close#58250
This is helpful as it allows us to set `type: module` in the checked-in
package files, useful for the hybrid mode of `rules_js` and
`rules_nodejs`, where the package.json files can control the execution
format.
PR Close#59406
In this commit, we're replacing the `async-await` style in the `home-editor` component with the `from()`
observable, which allows us to invert a dependency and avoid memory leaks. Because an `async` function
has a closure, just like any other function in JavaScript, using `await` captures `this` until the
promise is resolved.
PR Close#58164
`new` expressions are not dropped by default because they are considered side-effectful,
even if they are not referenced anywhere in production mode.
PR Close#59381
In this commit, we manually complete the `events` subject to remove all active observers and enable
granular garbage collection, as users may forget to unsubscribe manually when subscribing to `router.events`.
PR Close#59327
The `type_checks` module already exposes a utility function that checks whether `LView` is marked
as destroyed. There is no need to check flags in other places, as we can reuse the helper function.
PR Close#59387
When we replace a component during HMR, we clear it from the cache of the renderer factory, however when using animations, there's an animation-specific renderer factory that wraps the base DOM one and was preventing the cache from being cleared.
These changes rework the logic that clear the cache to go through a method so we can forward the call to the delegated factory.
PR Close#59393
In this commit, we're replacing the provided injector in `afterNextRender` with a node injector
because it was previously mistakenly passing an `EnvironmentInjector` in the `ReferenceScrollHandler`.
PR Close#58640
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.
fixes#56144
PR Close#56489
Currently the `ɵEmptyOutletComponent` is very prone to generating ID collision warnings with user code, because it only has one child and no other metadata. This shows up some of our tests as well. While users can resolve it on their end, it can be confusing since they won't have any references to `ɵEmptyOutletComponent` in their own code.
These changes add an `exportAs` to it to make its component ID unique. This doesn't affect the public API of the component since users can't use it directly anyways.
PR Close#59300
`ts_project` interop does not emit `.mjs` files. We could achieve this
in the interop rule, but it's better to just fallback look for `.js`.
In addition, `ng_package` currently fails because there is no
`module_name` retrievable from the interop rule; hence causing in
incorrect packaging and safety errors being thrown.
PR Close#59325
In this commit, we replace `private warnIfDestroyed` with a `warnIfDestroyed` function that can
be completely removed in production. This change is necessary because, with `private warnIfDestroyed`,
the empty method is still retained in production, even though it has no body.
PR Close#59269
Fixes that the compiler wasn't capturing defer block dependencies correctly when `supportTestBed` is disabled. We had tests for this, but we didn't notice the issue because the dependencies ended up being captured because of the `setClassMetadata` calls. Once they're disabled, the dependencies stopped being recorded.
Fixes#59310.
PR Close#59313
During the HMR dependency analysis we need to check if an identifier is top-level or not. We do this by looking at each identifier and its parent, however we didn't account for some cases. These changes expand our logic to cover more of the common node types.
Related to https://github.com/angular/angular/issues/59310#issuecomment-2563963501.
PR Close#59323
Some time ago we narrowed down the expressions we support in two-way bindings, because in most cases any apart from property reads doesn't make sense. This ended up preventing users from using `$any` in the binding since it's considered a function call.
These changes update the validation logic to allow `$any`.
Fixes#51165.
PR Close#59362
In v19 we added a warning about unused standalone imports, however we didn't do anything about existing code which means that users have to clean it up manually. These changes add the `ng g @angular/core:cleanup-unused-imports` schematic which will remove the unused dependencies automatically.
There isn't any new detection code since all the manipulations are based on the produced diagnostics, but there's a bit of code to remove the import declarations from the file as well.
Fixes#58849.
PR Close#59353
This commit updates the timeout used in the incremental hydration tests from `101` -> `10` ms, which allows to speed up tests by ~20% (12.5 -> 10 seconds locally).
PR Close#59275
'parameter' was spelled as 'paramater'.
Fix spelling error in Update r3_control_flow.ts
'parameter' was spelled as 'paramater'.
Fix spelling error in r3_template_transform_spec.ts
'parameter' was spelled as 'paramater'.
PR Close#59289
In this commit, we're replacing the `async-await` style in the playground component with the `from()`
observable, which allows us to invert a dependency and avoid memory leaks. Because an `async` function
has a closure, just like any other function in JavaScript, using `await` captures `this` until the
promise is resolved.
PR Close#58040
Fix visibility issue with text inside polygon nodes in mermaid diagrams when using dark mode theme to ensure proper contrast and readability
PR Close#59285
Currently the module mapping aspect fails when it transitively discovers
a node module target managed by `rules_js`. That is because the targets
don't have a `deps` attribute as part of their rule definition.
PR Close#59316
In https://github.com/angular/components/pull/30179 the CDK overlay started depending on the `Renderer2Factory`. Since the overlay is used in the `MatSnackbar` which is commonly used in error handlers, `Overlay` can end up being injected as a part of the app initialization. Because `AsyncAnimationRendererFactory` depends on the `ChangeDetectionScheduler`, it may cause a circular dependency.
These changes inject the `ChangeDetectionScheduler` lazily to avoid the error.
Note: this will also be resolved by #58984, but I decided to send it out, because:
1. #58984 seems to be stuck on some internal cleanup.
2. The `AsyncAnimationRendererFactory` doesn't need the `scheduler` eagerly anyway so the change is fairly safe.
Fixes#59255.
PR Close#59256
This change was originally proposed by @alxhub. We should all be comfortable reviewing and approving any and all code in the repo. This consolidation removes the barriers for that to happen.
PR Close#59080
This commit extends the set of events understood by the
profiler integrated with the Angular time. The set got
extended to account for the recently added functionality
and mark entry point to the code execution points.
The new set of events can be visualised by the Angular
DevTools or other profiler integrations.
PR Close#59183
We recently introduced a custom error to allow us to catch certain types
of errors. Unfortunately it doesn't work as expected in G3 because the
Node execution seems to run with ES5.
PR Close#59219
Introduced the `ENABLE_ROOT_COMPONENT_BOOTSTRAP` token to control the bootstrapping of components during application initialization. This token is utilized by the Angular CLI in the `@angular/ssr` package, particularly during server-side rendering (SSR) when extracting routes.
When set to `false`, this token prevents the root component from being bootstrapped during SSR's route extraction phase, which is crucial for efficiently extracting routes without triggering component initialization. This mechanism separates the concerns of route extraction and component bootstrapping during SSR rendering, optimizing performance.
If not provided or set to `true`, the default behavior of bootstrapping the root component(s) during initialization is maintained.
Context: https://github.com/angular/angular-cli/issues/29085
PR Close#59133
Adds the `getDeferBlocks` function to the global `ng` namespace which returns information about all `@defer` blocks inside of a DOM node. This information can be useful either directly in the browser console or to implement future functionality in the dev tools.
PR Close#59184
Adds a field on the `TDeferBlockDetails` where we can track debugging information about the defer block. Also uses it to store text representation of the different triggers which can be shown to the dev tools.
PR Close#59184
This commit updates defer block logic to avoid triggering `on idle` and `on timer` on the server for regular SSR mode (when incremental hydration is not enabled). Triggering the mentioned condition resulted in invoking `setTimeout` calls, which delayed serialization on the server during SSR (the process was waiting for the timeouts to clear).
PR Close#59177
The handwritten entries are now included as part of `//packages/core:core_docs_extraction` it seems. So, they are no longer needed. On the contrary, they are causing duplicated entries in the generated manifest which are then reflected in the A.dev API reference.
Fixes#59165
PR Close#59169
Since code lines are wrapped in `<button>`-s, the native font styles overrides the parent's one which results in the font-family and font-size (esp. Safari) difference. This change fixes that.
PR Close#59072
Switches the goldens for the symbol tests to be an array of strings, rather than an array of objects where each object only has a `name` property. This makes more compact, easier to read and easier to avoid merge conflicts.
PR Close#59147
There were type mismatches and or unintended any types that were preventing nested timers from accessing the delay value during hydration annotation processing.
PR Close#59173
- Remove trailing slash redirect (e.g., /overview no longer redirects to /overview/).
- Update static file matching: Resolves an issue where hashed files were being cached for up to 1 hour.
PR Close#59170
This adds a few helper functions and ensures we call complete fns when error state is rendered. It also eliminates serialized views from being copied.
PR Close#59032
This can happen if server providers are provided more than twice. We detect it on the state transfer phase by flagging app id as transferred in a set.
Resolves#58531
PR Close#58935
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
Creates a debug api that returns an arrays of nodes and edges that represents a signal graph in the context of a particular injector.
Starts by discovering the consumer nodes for each injector, and then traverses their dependencies to discover each producer.
PR Close#57074
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
In the past two-way bindings used to be interpreted as `foo = $event` at the parser level. In #54065 it was changed to preserve the actual expression, because it was problematic for supporting two-way binding to signals. This unintentionally ended up causing the TCB to two-way bindings to look something like `someOutput.subscribe($event => expr);` which does nothing. It largely hasn't been a problem, because the input side of two-way bindings was still being checked, except for the case where the input side of the two-way binding has a wider type than the output side.
These changes re-add type checking for the output side by generating the following TCB instead:
```
someOutput.subscribe($event => {
var _t1 = unwrapSignalValue(this.someField);
_t1 = $event;
});
```
PR Close#59002
The `isSplitTwoWayBinding` function was a bit misleading, because it has side effects. Renames the function make it a bit more explicit.
PR Close#59002
Adds the implementation of the `ɵɵattachSourceLocations` instruction that will add the `data-ng-source-location` attribute to nodes to indicate where they were defined.
PR Close#58982
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
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 folder contains configuration files that can be used to opt into working on this repository in a [Docker container](https://www.docker.com/resources/what-container) via [VSCode](https://code.visualstudio.com/)'s Remote Development feature (see below).
Info on remote development and developing inside a container with VSCode:
- [VSCode: Developing inside a Container](https://code.visualstudio.com/docs/remote/containers)
- [VSCode: Remote Development FAQ](https://code.visualstudio.com/docs/remote/faq)
## Usage
_Prerequisite: [Install Docker](https://docs.docker.com/install) on your local environment._
@@ -15,6 +15,7 @@ _Prerequisite: [Install Docker](https://docs.docker.com/install) on your local e
To get started, read and follow the instructions in [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers). The [.devcontainer/](.) directory contains pre-configured `devcontainer.json` and `Dockerfile` files, which you can use to set up remote development with a docker container.
In a nutshell, you need to:
- Install the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension.
- Copy [recommended-Dockerfile](./recommended-Dockerfile) to `Dockerfile` (and optionally tweak to suit your needs).
- Copy [recommended-devcontainer.json](./recommended-devcontainer.json) to `devcontainer.json` (and optionally tweak to suit your needs).
@@ -23,7 +24,6 @@ In a nutshell, you need to:
The `.devcontainer/devcontainer.json` and `.devcontainer/Dockerfile` files are ignored by git, so you can have your own local versions. We may occasionally update the template files ([recommended-devcontainer.json](./recommended-devcontainer.json), [recommended-Dockerfile](./recommended-Dockerfile)), in which case you will need to manually update your local copies (if desired).
## Updating `recommended-devcontainer.json` and `recommended-Dockerfile`
You can update and commit the recommended config files (which people use as basis for their local configs), if you find that something is broken, out-of-date or can be improved.
description="Researches part of the codebase and creates a skill for it"
prompt="""
## Role
You are an experienced senior developer specializing in reverse engineering and understanding
complex code, prompt engineering, and context engineering.
Your task is to build a complete understanding of the mental model and architecture of the code,
and to create an efficient context file that allows a coding agent to understand and work with the
code.
## Guiding Principles
1. **Deep Analysis:** Understand the _why_ behind the code. Not just a surface level listing of
files and classes.
2. **Curiosity:** Be curious. If something is unclear, confusing, or unexpected you _MUST_
investigate further until you fully understand.
3. **Efficient Token Use:** The final output will be directly included into the context of the
coding assistant, so be sure to make efficient use of tokens. Think deeply, but only capture the
most important information for the coding agent in the final output
## Procedure
1. Fully explore the code before first, with a focus on understanding the architecture and how all
of the pieces fit together.
2. Develop an understanding of the mental model behind the architecture. _Why_ is the code is
architected this way? How should developers think about the system?
3. Document your findings using the given output format described in the next section.
## Output Format
Note the following placeholders below:
- `[package]`: is a unique identifier for the current code package (for example if you're looking at
code under `packages/forms/signals` you might use `signal-forms` as the `[package]`)
- `[code-location]`: is the location of the current code within the larger repository
- `[context]`: is the context to add to the coding agent when it is working with this code.
With those placeholders in mind, write a file create a new directory under `.gemini/skills` with the
name `reference-[package]/`, and under that directory add a `SKILL.md` file with the following
content:
```md
---
name: reference-[package]
description: Explains the mental model and architecture of the code under `[code-location]`. You MUST use this skill any time you plan to work with code in `[code-location]`
---
[context]
```
## Additional User Instructions
The user may have additional instructions.
- The user should indicate what package to research
- The user may indicate that they want to update a package that has already been researched. In this
case, read the existing skill and make any required updates based on your research
- The user may request supplemental information be added to the skill (if so, add this to the
existing skill in a new markdown file under a `references` directory within the skill. Add a
section to the main `SKILL.md` that mentions what supplemental information is available)
description: Comprehensive writing guide for Angular documentation (adev). Covers Google Technical Writing standards, Angular-specific markdown extensions, code blocks, and components. Use when authoring or reviewing content in adev/src/content.
---
# Angular Documentation (adev) Writing Guide
This skill provides comprehensive guidelines for authoring content in `adev/src/content`. It combines Google's technical writing standards with Angular-specific markdown conventions, components, and best practices.
## I. Google Technical Writing Guidelines
### Tone and Content
- **Be conversational and friendly:** Maintain a helpful yet professional tone. Avoid being overly casual.
- **Write accessibly:** Ensure documentation is understandable to a diverse global audience, including non-native English speakers.
- **Audience-first:** Focus on what the user needs to do, not just what the system does.
- **Avoid pre-announcing:** Do not mention unreleased features or make unsupported claims.
- **Use descriptive link text:** Link text should clearly indicate the destination (e.g., avoid "click here").
### Language and Grammar
- **Use second person ("you"):** Address the reader directly.
- **Prefer active voice:** Clearly state who or what is performing the action (e.g., "The system generates a token" vs "A token is generated").
- **Standard American English:** Use standard American spelling and punctuation.
- **Conditional clauses first:** Place "if" or "when" clauses before the instruction (e.g., "If you encounter an error, check the logs").
- **Define terms:** Introduce new or unfamiliar terms/acronyms upon first use.
- **Consistent terminology:** Use the same term for the same concept throughout the document.
- **Conciseness:** Aim for one idea per sentence. Keep sentences short.
### Formatting and Organization
- **Sentence case for headings:** Capitalize only the first word and proper nouns in titles and headings.
- **Lists:**
- **Numbered lists:** Use for sequential steps or prioritized items.
- **Bulleted lists:** Use for unordered collections of items.
- **Description lists:** Use for term-definition pairs.
- **Serial commas:** Use the Oxford comma (comma before the last item in a list of three or more).
- **Code formatting:** Use code font for code-related text (filenames, variables, commands).
- **UI Elements:** formatting user interface elements in **bold**.
- **Date formatting:** Use unambiguous formats (e.g., "September 4, 2024" rather than "9/4/2024").
- **Structure:** Use logical hierarchy with clear introductions and navigation. Headings should be task-based where possible.
### Images and Code Samples
- **Images:** Use simple, clear illustrations to enhance understanding.
- **Captions:** Write captions that support the image.
- **Code Samples:**
- Ensure code is correct and builds without errors.
- Follow language-specific conventions.
- **Comments:** Focus on _why_, not _what_. Avoid commenting on obvious code.
### Reference Hierarchy
1. Project-specific style guidelines (if any exist in `CONTRIBUTING.md` or similar).
2. Google Developer Documentation Style Guide.
3. Merriam-Webster (spelling).
4. Chicago Manual of Style (non-technical).
5. Microsoft Writing Style Guide (technical).
---
## II. Angular Documentation Specifics
### Code Blocks
Use the appropriate language identifier for syntax highlighting:
- **TypeScript (Angular):** Use `angular-ts` when TypeScript code examples contain inline templates.
- **HTML (Angular):** Use `angular-html` for Angular templates.
- **TypeScript (Generic):** Use `ts` for plain TypeScript.
- **HTML (Generic):** Use `html` for plain HTML.
- **Shell/Terminal:** Use `shell` or `bash`.
- **Mermaid Diagrams:** Use `mermaid`.
#### Attributes
You can enhance code blocks with attributes in curly braces `{}` after the language identifier:
-`header="Title"`: Adds a title to the code block.
-`linenums`: Enables line numbering.
-`highlight="[1, 3-5]"`: Highlights specific lines.
-`hideCopy`: Hides the copy button.
-`prefer`: Marks code as a preferred example (green border/check).
-`avoid`: Marks code as an example to avoid (red border/cross).
description: Explains the mental model and architecture of the code under `packages/compiler-cli`. You MUST use this skill any time you plan to work with code in `packages/compiler-cli`
---
# Angular Compiler CLI (`ngtsc`) Architecture
## Overview
The `packages/compiler-cli` package contains the Angular Compiler (Ivy), often referred to as `ngtsc`. It is a wrapper around the TypeScript compiler (`tsc`) that extends it with Angular-specific capabilities.
The core goal of `ngtsc` is to compile Angular decorators (like `@Component`, `@Directive`, `@Pipe`) into static properties on the class (Ivy instructions, e.g., `static ɵcmp = ...`). It also performs template type checking and ahead-of-time (AOT) compilation.
## Mental Model
The compiler is designed as a **lazy, incremental, and partial** compilation pipeline.
1.**Wrapper Pattern**: `NgtscProgram` wraps the standard `ts.Program`. It intercepts calls to act as a drop-in replacement for standard tooling.
2.**Traits System**: Every class with an Angular decorator is considered a "Trait". The compiler manages the state of these traits through a state machine:
- **Resolved**: Dependencies (directives/pipes in template) resolved, import cycles handled.
- **Skipped**: Not an Angular class.
3.**Lazy Analysis**: Analysis only happens when necessary (e.g., when diagnostics are requested or emit is prepared).
4.**Output AST**: The compiler generates an intermediate "Output AST" (`o.Expression`) for the generated code, which is then translated into TypeScript AST nodes during the emit phase.
## Key Subsystems
### 1. Core Orchestration (`ngtsc/core`)
- **`NgtscProgram`**: The public API implementing `api.Program`. It manages the `ts.Program` and the `NgCompiler`.
- **`NgCompiler`**: The brain of the compiler. It orchestrates the compilation phases (Analysis, Resolution, Type Checking, Emit). It holds the `TraitCompiler`.
### 2. Trait Compilation (`ngtsc/transform`)
- **`TraitCompiler`**: Manages the lifecycle of "Traits". It iterates over source files, identifies decorated classes, and delegates to the appropriate `DecoratorHandler`.
- **`Trait`**: A state container for a class, holding its handler, analysis results, and resolution results.
### 3. Decorator Handlers (`ngtsc/annotations`)
- **`DecoratorHandler`**: An interface for handling specific decorators.
- **`ComponentDecoratorHandler`**: The most complex handler. It:
- Extracts metadata (selector, inputs, outputs).
- Parses the template.
- Resolves used directives and pipes (`R3TargetBinder`).
- Generates the `ɵcmp` instruction.
- **`DirectiveDecoratorHandler`**, **`PipeDecoratorHandler`**, **`NgModuleDecoratorHandler`**: Handle their respective decorators.
### 4. Template Type Checking (`ngtsc/typecheck`)
- **`TemplateTypeChecker`**: Generates "Type Check Blocks" (TCBs). A TCB is a block of TypeScript code that represents the template's logic in a way `tsc` can understand and check for errors.
- **`TypeCheckBlock`**: The actual generated code that validates bindings, events, and structural directives.
- **`MetadataReader`**: Reads Angular metadata from source files (using `LocalMetadataRegistry`) and `.d.ts` files (using `DtsMetadataReader`).
- **`ScopeRegistry`**: Determines the "compilation scope" of a component (which directives/pipes are available to it), handling `NgModule` transitive exports and Standalone Component imports.
### 6. Emit & Transformation (`ngtsc/transform`)
- **`ivyTransformFactory`**: A TypeScript transformer factory.
- **`IvyCompilationVisitor`**: Visits classes, triggers compilation via `TraitCompiler`, and collects the Output AST.
- **`IvyTransformationVisitor`**: Translates the Output AST into TypeScript AST, injects the `static ɵ...` fields, and removes the original decorators.
## Compilation Phases
1.**Construction**: `NgtscProgram` creates `NgCompiler`, which sets up all registries and the `TraitCompiler`.
2.**Analysis** (`analyzeSync`):
- The `TraitCompiler` scans files.
-`DecoratorHandler`s extract metadata and parse templates.
- No cross-file resolution happens here (allowing for parallelism and caching).
3.**Resolution** (`resolve`):
-`TraitCompiler` resolves traits.
- Components link their templates to specific Directives and Pipes (found via `ScopeRegistry`).
- Import cycles are detected and handled (e.g., via "remote scoping").
4.**Type Checking**:
-`TemplateTypeChecker` creates TCBs for all components.
- TypeScript diagnostics are retrieved for these TCBs.
5.**Emit** (`prepareEmit`):
-`ivyTransformFactory` is created.
- TS `emit` is called.
- The transformers run, injecting the compiled Ivy instructions into the JS/DTS output.
## Important File Locations
-`packages/compiler-cli/src/ngtsc/program.ts`: Entry point (`NgtscProgram`).
description: Explains the mental model and architecture of the code under `packages/core`. You MUST use this skill any time you plan to work with code in `packages/core`
---
# Angular Core (`packages/core`) Mental Model
This document outlines the architecture and mental model for `packages/core`, the heart of the Angular framework.
## 1. High-Level Architecture
`packages/core` contains the runtime logic for Angular. Its primary responsibilities are:
1.**Rendering (Ivy/Render3)**: Transforming templates into DOM updates.
2.**Dependency Injection (DI)**: Managing object creation and lifetime.
3.**Change Detection**: Synchronizing the model with the view.
4.**Reactivity**: Signals and Zone.js integration.
## 2. Rendering Engine (Ivy / Render3)
The rendering engine (located in `packages/core/src/render3`) uses an **instruction-based** approach.
### Key Concepts
- **Instructions**: The Angular compiler transforms templates into a sequence of instruction calls (e.g., `ɵɵelementStart`, `ɵɵtext`, `ɵɵproperty`). These instructions are executed at runtime to create and update the view.
- **TView (Template View)**: An array containing the _static structure_ of a view. It is shared across all instances (`LView`s) of the same component/template. It holds:
- Configured via `@Component.providers` or `@Directive.providers`.
- **Not a class**, but a data structure embedded in the `LView` ("Expando" section).
- Uses **Bloom Filters** (`TView.data`) to quickly check if a token is present at a specific node index before traversing up the tree.
- Resolves tokens starting from the current node, walking up the view tree (Element Injector hierarchy), and falling back to the Module Injector if not found.
## 4. Change Detection
- **Dirty Checking**: Angular checks if values bound in templates have changed.
- **Strategies**:
-`Default`: Checks everything.
-`OnPush`: Checks only if inputs change, events fire, or signals update.
- **Signals**: The new reactivity primitive. Signals notify the scheduler when they change, potentially allowing for fine-grained updates (Zoneless).
## 5. Key Directories to Know
-`src/render3`: The Ivy rendering engine.
-`instructions`: The runtime instructions called by compiled code.
-`src/signal`: Signals implementation (if present in this version, otherwise likely in `primitives`).
## 6. Conventions & Gotchas
- **Prefixes**: Private/Internal exports often start with `ɵ`.
- **Global State**: Ivy relies heavily on global state (e.g., `getLView()`) during instruction execution to avoid passing context arguments everywhere. This is for performance and code size.
- **Performance**: The code is highly optimized for performance and memory. You will see arrays used instead of objects, bitmasks, and manual memory management patterns. **Respect these patterns.**
## 7. How to Modify Core
1.**Understand the Instruction**: If modifying runtime behavior, find the corresponding instruction in `src/render3/instructions`.
2.**Check `LView`/`TView` Impact**: If adding state, understand where it fits in the `LView` array.
3.**Tests**: Core has extensive tests. Run them using Bazel.
description: Explains the mental model and architecture of the code under `packages/forms/signals`. You MUST use this skill any time you plan to work with code in `packages/forms/signals`
---
# Signal Forms Architecture
The `packages/forms/signals` directory contains an experimental, signal-based forms API for Angular.
This system differs significantly from the existing Reactive and Template-driven forms.
## Mental Model
1.**Model-Driven**: The system is built around a `WritableSignal<T>` which serves as the **single source of truth**.
Unlike Reactive Forms where the `FormControl` holds the value, here the `Signal` holds the value.
The form is merely a _view_ or _projection_ of that signal, adding form-specific state (validity, dirty, touched).
2.**Proxy-Based Traversal**: The form API (`form(signal)`) returns a `FieldTree`. This object is a **Proxy**.
It allows accessing nested fields (e.g., `myForm.user.name`) without manually creating control groups.
Accessing a property on the proxy lazily resolves or creates the corresponding `FieldNode`.
3.**Schema-Based Logic**: Validation, disabled state, and other metadata are defined separately via **Schemas**.
Schemas are applied to the form structure using functions like `apply`, `applyEach` (for arrays), and `applyWhen`.
This separates the _structure_ of the data from the _rules_ governing it.
4.**Directives as Glue**: The `[formField]` directive binds a DOM element (native input or custom control) to a `FieldNode`.
It handles:
- Syncing the value between the DOM and the Signal.
- Reflecting state (valid, touched, etc.) to the UI.
- Handling user interaction events (blur, input).
## Key Components
### 1. `FieldNode` (`src/field/node.ts`)
The central internal class representing a single field in the form graph. It aggregates several state managers:
-`structure`: Manages parent/child relationships and signal slicing.
This document explains how the Signal Forms system hooks into the Angular compiler and runtime to provide seamless type-checking and efficient updates.
## 1. Compiler-CLI Integration (Type Checking)
The `packages/compiler-cli` package contains specific logic to support `[formField]`. This is primarily handled in `src/ngtsc/typecheck/src/ops/signal_forms.ts`.
### Key Mechanisms:
- **Detection**: The compiler identifies a directive as a "Field Directive" if it has the `ɵNgFieldDirective` property or comes from `@angular/forms/signals`.
- **Synthetic Binding Expansion**: When you write `<input [formField]="mySignal" />`, the type checker doesn't just check `formField`. It synthetically expands this into a set of bindings for validation:
-`[value]="mySignal()"` (or `checked` for checkboxes)
-`[disabled]="mySignal.disabled()"`
-`[required]="mySignal.required()"`
- ...and so on.
- This ensures that `mySignal` (the `FieldNode`) has all the necessary properties to drive the form control.
- **Conflict Detection**: It actively prevents "double binding". If you bind `[formField]`, you are _banned_ from also binding `[value]`, `[disabled]`, `[required]`, etc., as the signal form should be the single source of truth.
- **Element Type Validation**:
- **Native Elements**: Checks that the signal's value type matches the element type (e.g., `<input type="checkbox">` requires a `boolean` signal).
- **Custom Controls**: Detects if a custom component is a "Form Value Control" (has a `value` input/output) or "Form Checkbox Control" (has a `checked` input/output) and validates against that.
### Relevant Files:
-`packages/compiler-cli/src/ngtsc/typecheck/src/ops/signal_forms.ts`: The core logic for `TcbNativeFieldOp` and `SignalFormFieldOp`.
## 2. Core Runtime Integration
The `packages/core` package provides the low-level instructions that power the `FormField` directive. This allows it to do things normal directives cannot, like efficiently syncing state without change detection overhead for every property.
### Key Mechanisms:
- **`ɵngControlCreate` Hook**: The `FormField` directive defines a special method `ɵngControlCreate`.
- **`ɵɵcontrol` Instructions**: When the compiler sees `ɵngControlCreate`, it emits:
-`ɵɵcontrolCreate`: Called during the creation phase.
-`ɵɵcontrol`: Called during the update phase.
- **`ControlDirectiveHost`**: These instructions provide the directive with a `ControlDirectiveHost`. This is a privileged interface that allows the `FormField` directive to:
- **Access the Element**: Get direct access to the native element or component instance.
- **Set Inputs**: Write directly to inputs of _other directives_ on the same node (e.g., setting the `value` input of a custom control).
- **Listen to Outputs**: Subscribe to outputs of other directives (e.g., `valueChange`).
- **Bypass Templates**: It effectively acts as a "meta-directive" that manages the bindings for you, bypassing the need for explicit template syntax for every property.
### Relevant Files:
-`packages/core/src/render3/instructions/control.ts`: Implementation of `ɵɵcontrol` instructions.
-`packages/forms/signals/src/directive/form_field_directive.ts`: The directive that implements the hook.
# - We trust that people do the right thing and won't approve changes they don't feel confident reviewing
# - We enforce that only approved PRs are merged ensuring that unreviewed code isn't accidentally merged
# - We distribute approval rights as much as possible to help us scale better
# - Groups have one or two global approvers groups as fallbacks:
# - @angular/fw-global-approvers: for approving minor changes, large-scale refactorings, and emergency situations.
# - @angular/fw-global-approvers-for-docs-only-changes: for approving minor documentation-only changes that don't require engineering review
# - A small number of file groups have very limited number of reviewers because incorrect changes to the files they guard would have serious consequences (e.g. security, public api)
#
# Configuration nuances:
@@ -37,27 +34,10 @@
# See reviewer list under `required-minimum-review` group. Team member names and
This is the source code for the Angular framework. This guide outlines standard practices for AI agents working in this repository.
## Environment
- Use `pnpm` for package management.
- Use `pnpm bazel test //target` to run tests.
## Key Documentation
- [Building and Testing](contributing-docs/building-and-testing-angular.md): definitive guide for running targets.
- [Coding Standards](contributing-docs/coding-standards.md): style guide for TypeScript and other files.
- [Commit Guidelines](contributing-docs/commit-message-guidelines.md): format for commit messages and PR titles.
## Testing
- **Zoneless & Async-First:** Assume a zoneless environment where state changes schedule updates asynchronously.
- **Do NOT** use `fixture.detectChanges()` to manually trigger updates.
- **ALWAYS** use the "Act, Wait, Assert" pattern:
1.**Act:** Update state or perform an action.
2.**Wait:**`await fixture.whenStable()` to allow the framework to process the scheduled update.
3.**Assert:** Verify the output.
- To keep tests fast, minimize the need for waiting:
- Use `useAutoTick()` (from `packages/private/testing/src/utils.ts`) to fast-forward time via the mock clock.
- When waiting is necessary, use real async tests (`it('...', async () => { ... })`) along with:
-`await timeout(ms)` (from `packages/private/testing/src/utils.ts`) to wait a specific number of milliseconds.
-`await fixture.whenStable()` to wait for framework stability.
## Pull Requests
- Use the `gh` CLI (GitHub CLI) for creating and managing pull requests.
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.