Remove `_shadowDOMSelectorsRe` and `_convertShadowDOMSelectors` from `shadow_css.ts` so that `::shadow`, `::content`, `/shadow-deep/`, and `/shadow/` are no longer treated specially or stripped from user CSS. Instead, they are naturally scoped like standard selectors. Also remove the legacy failing test from `shadow_css_spec.ts`.
(cherry picked from commit 6de4955124)
Completely remove support for `polyfill-next-selector`, `polyfill-unscoped-rule`, and `polyfill-rule` from `shadow_css.ts`, along with their associated methods and regular expressions. Also delete `polyfills_spec.ts` entirely.
(cherry picked from commit 23f0898edb)
Update the regular expression in `_scopeAnimationRule` to prevent absorbing and deleting leading commas after `animation:`. Also remove the corresponding legacy test case from `keyframes_spec.ts`.
(cherry picked from commit 770e505f78)
Modify `_colonHostContextRe` and `_hostContextPattern` to strictly process `:host-context` only when parentheses containing at least one non-whitespace argument character are present. Update `_colonHostRe` to explicitly NOT match `:host` when followed by a hyphen. When invoked without parentheses or with empty parentheses, the selector is completely ignored and treated as a standard CSS pseudo-class in the source text. Also update the legacy test case from `host_and_host_context_spec.ts`.
(cherry picked from commit 338bf7d46f)
The `readFileBuffer` method in `node_js_file_system.ts` was wrapped in
`@ts-ignore` to suppress a TS2322 Buffer/Uint8Array typing error that
was fixed in the TypeScript 5.9.2 upgrade. The minimum supported
TypeScript is now 6.0, so the suppression is dead.
(cherry picked from commit e0593ecc8b)
Marks `HttpResourceRequest`, `HttpResourceOptions`, and `HttpResourceRef` as public APIs following the stabilization of the Resource API in https://github.com/angular/angular/pull/68253
(cherry picked from commit a617967d90)
This change moves `RouterState` creation to _before_ the `afterPreactivation` step,
which is the step that pauses until bootstrap listeners are complete. It is used for
'enabled blocking' initial navigation and destructive hydration. After this stage,
activation is expected to be (more or less) synchronous.
More importantly than above (since enabled blocking and destructive hydration are
essentially deprecated), this also oves the state creation before the view transition
creation.
These are done to accomodate features in the future that would depend on the RouterState
(e.g. ones which need to know which `ActivatedRoute` instances are new and which are reused).
These features may include additional async blocks/waits, which should not happen after view
transition creation (which freezes the UI until resolved).
(cherry picked from commit 1f287b9ba7)
Convert four `.forEach()` calls in `private_export_checker.ts` and
`reference_graph.ts` to `for...of`, matching the iteration style used
elsewhere in the compiler. The TODOs that forced these workarounds are
obsolete.
(cherry picked from commit e661f4d255)
WebMCP is still an experimental standard and going through frequent changes in the Chrome implementation and the standards process. As a result, we should be clear about the support status of this API and its overall stability guarantees.
(cherry picked from commit 38e26f0759)
The getters and setters for jsDocParsingMode in `host.ts` and
`ts_create_program_driver.ts` were suppressed with @ts-ignore to
support TypeScript 5.2, which lacked the property on `ts.CompilerHost`.
The minimum supported TypeScript is now 6.0, and `jsDocParsingMode`
is part of the public TypeScript API, so the suppressions can go.
(cherry picked from commit 7a146238ba)
This allows us to show the API docs when the jsdoc block is at the top of a overloaded function (and not on the implementation signature).
eg: `injectAsync`
(cherry picked from commit 7360c1da68)
Errors thrown by BEFORE_APP_SERIALIZED callbacks were previously logged
via console.warn and silently ignored. This meant failures such as
TransferState.toJson() encountering a circular reference would go
unreported in apps that use a custom ErrorHandler (e.g. Sentry).
Errors are now forwarded to the application's ErrorHandler, making them
visible through whatever reporting mechanism the app has configured.
The render continues to completion after the error is reported.
Closes#65811
(cherry picked from commit 7623580378)
In server-side rendering (SSR) setups, passing request URLs directly to the lower-level rendering APIs `renderModule` or `renderApplication` can expose applications to Server-Side Request Forgery (SSRF) or Host Header Injection attacks via absolute-form request URLs.
To mitigate these vulnerabilities at the framework layer, this commit introduces the `allowedHosts` option to `PlatformConfig` (supporting exact hostnames, wildcards like `*.example.com`, or `*` to allow all).
During platform initialization inside `createServerPlatform`, the hostname of the request `url` is validated against the `allowedHosts` list. If the hostname is not authorized, bootstrap immediately throws a host validation error, preventing unauthorized rendering and silent SSRF bypasses.
Closes#68436
(cherry picked from commit 60552a73e8)
These tests happened to use garbage "{c}" declaration lists which caused
the parser to choke. Given that we already have tests demonstrating
similar behavior and that's not what these tests were meant to
demonstrate, I've updated them to use empty declaration lists.
(cherry picked from commit b1699da827)
Moves the event attribute validation check outside of `ngDevMode` in the `elementAttributeInternal` instruction to ensure that bindings to event attributes like `on*` are always blocked at runtime.
(cherry picked from commit 5b421c61cd)
Rather than requiring TS AST in the indexer API, this update makes it generic with adapters to provide necessary information. This allows other analysis pipelines that don't use TS AST to work with the indexer.
(cherry picked from commit bc655d006f)
Several user-facing docs, tooltips, and tutorial code samples used
non-canonical spellings of product names. This normalizes them to
the form each project uses for its own brand.
(cherry picked from commit ed333c3992)
Removes the @angular/compiler import from the safe optional chaining migration. This import is not needed as the compiler package import is side-effectful and has no functional use here.
(cherry picked from commit f1738b5032)
This is an ergonomic wrapper around `declareWebMcpTool`, allowing a user to define multiple tools directly on an injector's providers, rather than needing to find an injection context.
Example:
```typescript
import {bootstrapApplication, provideWebMcpTools} from '@angular/core';
await bootstrapApplication(RootComp, {
providers: [
provideWebMcpTools([
{
name: 'hello',
description: 'Says hello',
inputSchema: {type: 'object', properties: {}},
execute: async () => ({content: [{type: 'text', text: 'Hello, World!'}]});
},
]),
],
});
```
The `execute` function is invoked in the injection context of the `Injector` it is provided to, meaning you can easily `inject` dependencies and invoke them.
This also works particularly well with route `providers` and `withExperimentalAutoCleanupInjectors`, registering the tools when the router is navigated to and then automatically unregistering them when navigating away. Note that `withExperimentalAutoCleanupInjectors` is required for unregistration to work.
```typescript
import {provideWebMcpTools} from '@angular/core';
import {provideRouter} from '@angular/router';
provideRouter(
[
{
path: '',
component: Home,
providers: [
provideWebMcpTools([
{
name: 'hello',
description: 'Says hello',
inputSchema: {type: 'object', properties: {}},
execute: async () => ({content: [{type: 'text', text: 'Hello, World!'}]}),
},
]),
],
},
],
withExperimentalAutoCleanupInjectors(),
);
```
This uses the injection context the tool is registered in for the `execute` callback and makes it a little more ergonomic to inject and use services in this context.
This exports `declareWebMcpTool`, a mechanism for registering WebMCP tools and tying them to Angular's `Injector` lifecycle. This function immediately registers the given tool and automatically unregisters it once the associated `Injector` is destroyed.
This exports the function and all transitively reachable types *except* for JSON Schema types as there are quite a lot and we don't want to couple to this particular implementation will likely be obsoleted by built-in types as the standard develops. If users want to leverage those, they should add their own dependency on `@mcp-b/webmcp-types`.
This is a relatively light wrapper around `navigator.modelContext.registerTool` which ties tool registration to the lifecycle of an `Injector`. When the `Injector` is destroyed, the tool is automatically unregistered. This makes it easier to create WebMCP tools without having to worry about managing unregistration.
I went a little off-spec by providing the `AbortSignal` to the `execute` function. I suspect something like this will be added eventually and there are some early discussions of that, but AFAICT, this behavior is not defined yet so I'm making something up instead so the `execute` function can observe a cancellation based on the `Injector` being destroyed.
This uses `@mcp-b/webmcp-polyfill` for testing, as it provides a small `modelContextTesting` utility for listing and invoking WebMCP tools. Unfortunately it is slightly out of date of the current Chrome spec (it requires `modelContext.unregisterTool` to be called, whereas the spec recently removed this option and expects you to provide an `AbortSignal` to `registerTool`). My slightly hacky solution for the moment is to both trigger the `AbortSignal` and also call `unregisterTool` safely. In production, only the `AbortSignal` happens, but in testing the `unregisterTool` code path is used. Hopefully this will get smoothed out as the spec matures and `@mcp-b/webmcp-polyfill` updates over time.
This copies WebMCP types into `@angular/core` and redistributes them. Ideally this would just be a regular dependency, but we need to do this vendoring for API extractor to properly process the types, since they will inform `@angular/core` public API.
One downside of this approach is that the dependency is not visible in Intellisense, breaking type inference.
This commit removes runtime console warnings and uses TypeScript overloads with JSDoc @deprecated annotations to handle backward compatibility for conditional rules.
This commit updates the signal forms API to use a consistent 'when' parameter for conditional rules and validators, replacing direct function arguments.
Replaced `@experimental` tags with `@publicApi 22.0` across all Signal Forms APIs under `packages/forms/signals` to mark them as ready for general use in v22.
TAG=agy
CONV=0af6c644-225a-4212-a49a-5843d17ec638
* Test that `minDate`/`maxDate` binds to `min`/`max` on date and time inputs
* Test that `min`/`max` attribute can be set directly on date and time inputs
* Relax type checker to allow `min`/`max` bindings on date and time inputs
PR Close#68001
- Added `minDate()` and `maxDate()` for validating constraints on `Date` inputs.
- `ReadonlyFieldState.min` and `.max` now return
`Signal<NonNullable<TValue>`. This ensures that `min` and `max` inputs
on custom controls can accept a reliable type (matching their value
type).
- Made the `TWrite` type parameter of `MetadataKey` contravariant to
properly indicate that it's writable.
- Added `LimitKey` as a convenience type for defining validation limit
metadata (e.g. `MAX_NUMBER`, `MIN_DATE`).
- Added `LimitSelectionKey` which can be used to bind a `LimitKey` with
value-specific aggregation logic, to a generic metadata key (e.g. use
`MAX_NUMBER` to aggregate numbers for `MAX`).
PR Close#68001
The `min` and `max` validation rules previously handled `string` values
to accommodate numbers bound to text inputs. However, this is no longer
necessary as the control binding itself handles the conversion.
This change removes string support from these rules, simplifying the
types to `number | null`. The validation logic has been updated to use
concrete checks (`value === null || Number.isNaN(value)`) to ensure safe
TypeScript narrowing.
Associated tests have been updated to:
- Remove string-specific validation checks.
- Add coverage for text input bindings.
- Add coverage for empty input handling (standard behavior where empty
sets model to null and skips validation).
BREAKING CHANGE: `min` and `max` validation rules no longer support
string values. Bound values must be numbers or null.
PR Close#68001
Introduce a highly decoupled FVC and CVA custom control reset mechanism, and implement the framework-wide automatic `transformedValue` and native controls clearing bridge for both new Signal Forms and legacy forms (Template-driven and Reactive).
1. Custom Control Reset Propagation (Bug #2):
- Establish agnostic custom control resetting via `FormFieldBindingOptions.reset` in `FormField`.
- Ensure that `FieldNode.reset()` unconditionally triggers `writeValue` updates on CVA custom controls.
- Protect against duplicate writes during subsequent change detection updates in `control_cva.ts` by verifying and tracking previous written values in the local bindings cache.
2. Unified Framework-wide FormControl Integration:
- Introduce a monorepo-wide private InjectionToken `ɵFORM_CONTROL_INTEGRATION` and `ɵFormControlIntegration` interface to act as the single, decoupled bridge for hooking up FVC parse errors and receiving control resets across both Signal and legacy forms architectures.
- Simplify Signal Forms: make `FormField` implements `ɵFormControlIntegration` directly, removing the intermediate context object and reducing DI boilerplate down to a clean `useExisting: FormField` provider. Triggers the `onReset` callback directly inside `FormField.reset()`.
- Upgrade Legacy Forms: `NG_CONTROL_INTEGRATION_PROVIDER` provides the renamed token. `NgControl` handles the event subscription internally (`set onReset(callback)`) to recursively listen to `control.events` (`FormResetEvent`) lazily only when assigned, resolving all `FormControl` swapping timing and lifecycle cleanup races automatically.
3. Automatic `transformedValue` and Native Controls Utility Clearing:
- Make `Parser.reset()` method required in the interface for a cleaner and non-defensive execution.
- Wire `transformedValue` into the new integration token `ɵFORM_CONTROL_INTEGRATION` to clear validation parsing states on resets.
- Lazily resets the UI-facing `rawValue` linked signal utilizing the original native `linkedSignal.set` callback (`originalSet`), correctly bypassing the UI-to-model parser loopback and preventing redundant model writes during `reset()`.
- Wire up Native Controls (`control_native.ts\Device`): Hook `parent.onReset` inside native element creation to automatically trigger the native `parser.reset()` and force DOM writes (`setNativeControlValue`) back down to the DOM input value during resets, ensuring native elements with pending parsing validation errors are successfully cleared and synced on form resets.
TAG=agy
CONV=8b4cee1e-2117-42a4-b242-c8ec7bf01752
Synchronize `controlValue` with the model `value` following `reset()`. This
ensures the UI will reflect the form model in cases where a control had a
pending change–delayed by debouncing–at the time it was reset.
Updates the supported Node.js engine versions to include Node.js 26.
This allows running the CLI on Node.js 26.0.0 and above while continuing to support active LTS versions.
The time has come.
Note: #67382 introduced a breaking change where you could notice some sublte timing change on how `value` is set when using `rxResource` or a `stream` on a `resource`
- Short-circuit `FieldNode.debounceSync()` if the node is orphaned right
before calling `this.sync()`, preventing unhandled promise rejections
on dead state reads.
- Include `this.node.structure.isOrphaned()` in `shouldSkipValidation`
computed signal in `ValidationState`. This safely shields the entire
validation layer (sync and async errors) from executing on dead nodes during
in-flight async validator resolutions.
- Append robust reproduction specs to `orphan_repro.spec.ts` for both the
`debounceSync` and `validateAsync` async race conditions. Include an intentional
promise resolution workaround for an experimental Angular `core/resource`
`PendingTasks` leak deadlock bug uncovered during testing.
TAG=agy
CONV=054e0185-f5f0-40e3-9c9b-413309f36cf6
Explain the race condition: when an item is deleted from a model array, its
DOM element is removed during change detection, which fires a `blur` event
synchronously. The `blur` handler tries to mark the field as touched,
navigating up to `keyInParent` which throws because the item is already gone
from the array in signals state.
Fix by introducing an `isOrphaned` check that short-circuits `markAsTouched`
early, backed by a reactivity-insulated `childrenMap` poll to avoid double
scans and prevent unhandled exceptions.
TAG=agy
CONV=054e0185-f5f0-40e3-9c9b-413309f36cf6
Fixes#66711
Co-Authored-By: Matthieu Riegler <kyro38@gmail.com>
"AngularJS" is the official product name for the v1.x line and is
written as a single word. A few places in the docs and package
READMEs used "Angular JS" with a space. This normalizes those
references to the canonical spelling.
Prohibit concurrent submits in signal forms to prevent duplicate actions and side effects when a submission is already in progress.
If `submit()` is called while a prior submit is in progress for the same field or any of its parents, it returns `false` immediately without running the action again.
This commit also updates the documentation in `form-submission.md` to reflect this behavior.
Fixes#68317
The i18n sub-system has the `changeMask` and `changeMaskCounter` flags which are set by i18n-related instructions and reset once the state is applied. The problem is that if something throws within the application logic, the flags would never be reset. This is currently causing flakes in our CI runs.
These changes resolve the issue by adding a try/finally around the flags.