38441 Commits

Author SHA1 Message Date
Matthieu Riegler 3927a5b271 fix(compiler): sanitize href/xlink:href attributes of any element of the MathML namespace
The ensures that future, present and past (and precated) elements of that namespace get sanitized.
2026-06-10 10:13:48 -07:00
arturovt 6cc54e5ede fix(forms): remove animationstart listener on component destroy to prevent memory leak
The `watchValidity` method in `AnimationInputValidityMonitor` was registering
an anonymous arrow function via `addEventListener` with no corresponding
`removeEventListener` call.

In V8, each closure is represented as a `JSFunction` holding a strong pointer
to a heap-allocated `Context` object containing captured variables
(`VariableLocation::CONTEXT` slots, decided at parse time by
`Scope::MustAllocateInContext`). In Blink, DOM event listeners are stored in
the element's `EventTargetData::event_listener_map` as `JSEventListener`
wrappers backed by a `v8::Persistent<JSFunction>` handle — a strong cross-heap
reference that keeps the function alive as long as the element is alive.

Because the callback passed to `watchValidity` closes over the calling
component/directive (which itself holds a reference back to the element), this
produced a cross-heap reference cycle:

```
  HTMLInputElement (Blink/Oilpan)
    └── EventTargetData → JSEventListener → v8::Persistent<JSFunction>
          └── Context → callback closure
                └── component → HTMLInputElement  ← cycle
```

Neither V8's nor Blink's GC could independently break this cycle because it
crosses the V8/Oilpan heap boundary. The element was therefore never collected
after being removed from the DOM.

The fix stores the listener in a named local variable and registers its removal
via `DestroyRef.onDestroy`, tying cleanup to the lifetime of the component that
owns the element. This ensures `removeEventListener` is called with the exact
same `JSFunction` reference, causing Blink to drop the `v8::Persistent` handle
and allowing both the function and the element to become GC-eligible.
2026-06-10 09:56:12 -07:00
Kristiyan Kostadinov 158307cd63 refactor(core): add internal utility
Sets up a utility function that we need for an internal project.
2026-06-10 09:54:35 -07:00
Matthieu Riegler f06b96d181 fix(forms): harden FormGroup control lookups against prototype shadowing
Guard FormGroup control-map presence checks with safe own-property checks to avoid inherited/prototype collisions from reserved keys such as hasOwnProperty and toString.

This prevents:
- crashes from shadowed hasOwnProperty access paths
- incorrect early-return and existence behavior for prototype-named controls

Adds regression tests for prototype-shadowed keys covering:
- register/add with toString
- contains/get with hasOwnProperty
- setControl/removeControl with toString
- FormRecord behavior with hasOwnProperty
2026-06-09 19:27:56 -07:00
Matthieu Riegler 6b0150faad refactor(migrations): Improve safeNavigationMigration heuristic
There is no need to migrate expressions with a nullish comparison.

fixes #69274
2026-06-09 17:11:55 -07:00
Andrew Scott d1539a8513 refactor(core): Fix DirectiveDefinition interface to allow abstract classes
Interface should permit abstract classes since directives can be abstract
2026-06-09 16:21:04 -07:00
Angular Robot 7541f3012f build: update pnpm to v11.5.2
See associated pull request for more information.
2026-06-09 14:55:56 -07:00
Jad Chahed 248e9c146d docs: add Signal Forms and v22 guidance to AI best-practices and llms.txt
Update the AI codegen resources for Angular v22:
- best-practices.md: OnPush is the default in v22+ (don't set it explicitly),
  recommend Signal Forms, and recommend the @Service decorator.
- llms.txt: add a Signal Forms reference, the httpResource guide, and an
  Accessibility section linking the Angular Aria overview.
2026-06-09 13:59:56 -07:00
Andrew Scott 2e4ed8027d fix(language-service): prevent external template inlay hints from appearing in TS files
Inlay hints from external templates were being incorrectly applied to
TypeScript files because the compiler was processing all templates
associated with components found in the TS file, regardless of whether
the template was inline or external. This resulted in misplaced hints
due to mismatched offsets.

This change filters the templates and host bindings processed in
getInlayHintsForTemplate to only include those that belong to the
target file being queried.

Fixes #69224
2026-06-09 13:33:15 -07:00
Kam 86cd166141 fix(docs-infra): load cross-origin video embeds under COEP credentialless
adev is cross-origin isolated (COOP same-origin + COEP require-corp) so the
embedded WebContainer editor can use SharedArrayBuffer. Under require-corp the
cross-origin YouTube iframe in `<docs-video>` only loaded in Chromium, leaving
the player blank in Safari.

Switch COEP from `require-corp` to `credentialless`. The page stays cross-origin
isolated, so the editor keeps working, but cross-origin frames are now allowed
to load, which restores the inline player in Safari as well.
2026-06-09 13:26:18 -07:00
Kristiyan Kostadinov 5829177729 fix(core): update comment for Default change detection
Updates the comment on `ChangeDetectionStrategy.Default` to mention that it's the same as `Eager`.

Fixes #69253.
2026-06-09 13:09:58 -07:00
Andrew Scott 0e16bb701f fix(core): Handle synchronous errors in PendingTasks.run function
catches synchronous errors coming out of the function passed to PendingTasks.run
2026-06-09 12:24:20 -07:00
Angular Robot 390af258bb build: update cross-repo angular dependencies
See associated pull request for more information.
2026-06-09 11:23:48 -07:00
Andrew Scott fe721868a6 fix(router): use native URL object for navigation boundary and comparison
Previously, `NavigationStateManager` relied on string-based comparisons and `.substring()` to match `NavigateEvent` URLs against internal router transitions or the application root boundary. This was brittle against trailing slashes, query parameter order variations, and sibling application URLs.

This commit updates the logic to:

- Use the native `URL` object to strictly compare `origin` and `pathname` for `appRootURL` boundaries.

- Sort `searchParams` and use `Location.stripTrailingSlash()` to robustly compare the router destination against the event destination.

- Pre-compute and store `appRootUrl` as a `URL` object to avoid redundant parsing on every navigation.
2026-06-09 11:15:15 -07:00
Angular Robot 0a9ff4ea47 build: update all non-major dependencies
See associated pull request for more information.
2026-06-09 11:07:34 -07:00
arturovt 3dd35c242c fix(common): escape CSS string-terminating characters in escapeCssUrl
The `escapeCssUrl` helper used by `NgOptimizedImage` to sanitize placeholder URLs for use in the `background-image` CSS property previously escaped only backslashes and double quotes. However, several characters that can terminate a CSS quoted string according to the CSS Syntax Level 3 specification were left unescaped, allowing a crafted placeholder URL to break out of the `url("...")` context and inject arbitrary CSS.

This change additionally escapes the following characters using CSS hex escapes:

* `U+000A` (LINE FEED) → `\A `
* `U+000D` (CARRIAGE RETURN) → `\D `
* `U+000C` (FORM FEED) → `\C `
* `U+0000` (NULL) → `\0 `

For example:

```text id="1w5vkp"
x.com/img\nx.jpg  →  x.com/img\A x.jpg
x.com/img\rx.jpg  →  x.com/img\D x.jpg
x.com/img\fx.jpg  →  x.com/img\C x.jpg
x.com/img\0x.jpg  →  x.com/img\0 x.jpg
```

The trailing space is required by the CSS tokenizer to terminate the escape sequence and prevent the following character from being interpreted as part of the escape.

The backslash replacement remains first in the chain to avoid double-escaping the backslashes introduced by subsequent replacements.
2026-06-09 10:40:20 -07:00
cexbrayat c121407c0d fix(core): require WebMCP tool descriptions
The WebMCP ModelContextTool dictionary marks description as required: https://webmachinelearning.github.io/webmcp/#modelcontexttool-dictionary
2026-06-09 10:29:11 -07:00
Matthieu Riegler bff084f203 refactor(core): harden change store access
This prevents any attack through prototype polution.
2026-06-09 10:05:53 -07:00
Kam 7d92cc8b46 fix(docs-infra): improve version picker dropdown positioning
Drops `position: absolute` from the version picker `<ul>` and tightens `max-height` to `70dvh` so the cdk-overlay-pane fits the viewport and the inner scroll reaches the last versions on mobile and desktop.
2026-06-09 09:58:21 -07:00
Alan Agius 8446e46f8b refactor(platform-server): deprecate ServerXhr
XHR support in `@angular/platform-server` is deprecated because the underlying `xhr2` library does not safely handle redirects. Specifically, it can forward `Authorization` headers on cross-origin redirects (which leaks credentials) and is susceptible to denial-of-service (DoS) via redirect loops.

DEPRECATED: XHR support in `@angular/platform-server` is deprecated. Use standard `fetch` APIs instead.
2026-06-09 09:54:16 -07:00
Matthew Beck 547d85addf ci: run benchmark comparison in isolated worktree and harden security
- Run comparison benchmark in an isolated git worktree to prevent workspace pollution and local branch conflicts.
- Harden security by passing benchmark target and SHA as environment variables to prevent shell injection, and adding '--' to bazel query and git rev-parse.
- Optimize workflow by removing pnpm caching to mitigate cache poisoning risks.
- Improve robustness of benchmark log parsing, supporting both ZIP outputs and raw directories, and safely checking for JSON reports.
- Centralize git command execution on the dev-infra GitClient for consistency.
- Add tslib to benchpress dependencies to prevent module resolution failures.
2026-06-09 09:48:50 -07:00
SkyZeroZx cd771d3712 fix(http): preserve empty referrer option in HttpRequest
Preserve `referrer: ''` when constructing and cloning HttpRequest.

An empty string is a valid Fetch referrer value and is documented by
Angular as the way to omit referrer information for sensitive requests.
The previous truthy checks treated it as if the option was not provided,
causing requests to fall back to the browser default referrer behavior.
2026-06-09 09:41:19 -07:00
Angular Robot e6ae250802 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-06-08 15:40:04 -07:00
SkyZeroZx 47d68dcb26 fix(service-worker): Strips sensitive headers on cross-origin redirects
Removes `Authorization`, `Cookie`, and `Proxy-Authorization` headers when a request is redirected to a different origin. This aligns with the Fetch API's redirect algorithm to prevent sensitive information from being sent to third-party origins.
2026-06-08 14:49:29 -07:00
Kam a82f822057 docs: fix CurrencyPipe locale override example
The "Override current locale for CurrencyPipe" example used `{{ amount | currency: 'en-US' }}`, but the first `CurrencyPipe` argument is the currency code, not the locale, so `'en-US'` was treated as an invalid currency code (rendered literally as the symbol) and the locale was never overridden. Since `locale` is the fourth positional argument, the example now passes a valid currency code, display, and digits before it (`'USD' : 'symbol' : '1.2-2' : 'en-US'`), matching the parameter order shown on the CurrencyPipe API page.
2026-06-08 14:36:17 -07:00
KirtiRamchandani b7cb5844cf fix(docs-infra): avoid code copy button overlap
Reveal code copy controls on hover and focus so long code snippets stay readable while keyboard access and copy state feedback remain intact.
2026-06-08 14:19:49 -07:00
SkyZeroZx 3c70270c96 fix(compiler): sanitize two-way properties
Apply schema-derived sanitizer resolution to TwoWayProperty ops so native two-way DOM bindings emit the same sanitizer as one-way property bindings.

Add compiler compliance coverage for innerHTML, srcdoc, URL, resource URL, and security-sensitive attribute cases.
2026-06-08 13:12:22 -07:00
Bhuvansh855 422e6893e4 docs: fix malformed prettier-ignore comment in whitespace guide 2026-06-08 12:59:24 -07:00
aparziale dc8165e253 docs: close menù with click outside container
close menù with click outside container

Fixes #69222
2026-06-08 12:57:59 -07:00
Matthieu Riegler 9cfd3f52e1 docs: mention required behavior for booleans
fixes #68509
2026-06-08 12:54:40 -07:00
Aleksander Bodurri 06db706238 feat(devtools): improve transfer state tab
- promote to default-on (remove opt-in setting and gear-menu toggle)
- replace the <pre> value cell with a collapsible JSON tree
- add key filter and column sort (size sorts by raw bytes)
- show an educational empty state when the app has no transfer state
- iterate every root in the directive forest and merge their state
- guard size calculation against undefined and circular references
- register listener once with DestroyRef cleanup; add a loading timeout
- distinguish array/string badge colors via theme-aware tokens
- responsive value cell width; flex-based table scroll
- add a component spec; seed the harness fixture with more demo data
2026-06-08 12:47:13 -07:00
Georgi Serev fe50a7ea94 perf(devtools): optimize signal graph nodes value inspection
This change is based on the presumption that a signal graph can be significantly large memory-wise sometimes. This is the reason why we don't send the full graph to the FE but rather serialize its values and then lazy load them when they are needed, that is, during value inspection.
2026-06-08 12:34:03 -07:00
leonsenft b3748e9fe4 fix(core): correct container anchor collection order to match DOM layout
Historically, `collectNativeNodes` collected the container's anchor comment
node (`LContainer[NATIVE]`) before descending into the views contained inside
the `LContainer`. While this worked logically, it did not match the actual
physical layout of the DOM tree, where dynamic view content is inserted before
the container anchor. This discrepancy was particularly visible in projected
`@content` blocks where the anchor comment ended up rendered at the beginning
instead of the end of the content block.

This commit refactors `collectNativeNodes` to collect container nodes in the expected order:

1. Push the host element for dynamic containers where where `lContainer[NATIVE]
   !== lContainer[HOST]` (e.g., a `ViewContainerRef` injected on a `div` element).
2. Collect nodes in the container.
3. _Unconditionally_ push the container anchor comment.

Associated acceptance tests in `template_ref_spec.ts` are updated to match the
physically correct DOM order.
2026-06-08 12:13:12 -07:00
Matthieu Riegler 51724b48d2 ci: add myself to size-tracking
I feel confortable reviewing those
2026-06-08 11:52:20 -07:00
hawkgs a7d684517f refactor(devtools): use ng-filter for the router tree search
Use the reusable `ng-filter` for the router tree search.
2026-06-08 11:19:47 -07:00
Edu a816848373 ci: update devtools reviewers list
Update the Angular DevTools reviewers list in .pullapprove.yml. Add eduhmc and csmick, remove hybrist, and change milomg to approval-only.
2026-06-08 10:59:00 -07:00
SkyZeroZx c3207dc6b3 docs: add best practices for model and linkedSignal usage in components 2026-06-08 10:57:27 -07:00
leonsenft 11b206b919 fix(core): introduce disposal mechanism for Angular views in foreign @content
Coordinate template lifecycle events between Angular and foreign components to
allow clean teardown of nested Angular views inside a foreign container.

Previously, when Angular content was projected into a foreign component (for
instance, via render props), Angular had no way to receive destruction
notifications from the foreign component. If the foreign component unmounted
or conditionally removed its children, the nested Angular views remained active,
leading to memory leaks and incomplete lifecycle teardowns.

This change introduces the `ON_DESTROY` symbol and a new registration mechanism
(`ForeignOnDestroyFn`) on the `ForeignComponent` interface. The `foreignImport`
helper now takes an additional `onDestroy` callback function where the foreign
component can register to receive Angular's view-destruction callback.

During the creation phase, `ɵɵforeignContentFn` resolves the foreign component
from the constant pool using a new constant pool index and invokes the
`onDestroy` function. This registers a callback that destroys the corresponding
embedded view from the container.

In the compiler, `ForeignComponentOp` is modified to track the target constant
pool index, and `ForeignContentExpr` reification is updated to pass this index
to `ɵɵforeignContentFn`.
2026-06-08 10:17:40 -07:00
leonsenft 25c744c4d0 fix(compiler): support foreign components defined outside top-level scope
Currently, the template pipeline directly emits the raw expression for foreign
component definitions (such as `frameworkImport(MyComponent)`) directly into
the body of the generated template function. If a foreign component is defined
inside a local scope or is non-exported (e.g. nested inside a test block), the
emitted template function may not have access to that variable because
`ɵɵdefineComponent` and its template functions are emitted at the top-level
module scope. This previously caused reference errors during template
compilation.

This commit updates the compilation pipeline to instead ingest foreign
component references into the component's `consts` pool. The
`ɵɵforeignComponent` runtime instruction is updated to accept an index into the
constant pool rather than a raw expression. By routing the references through
the `consts` pool, block-scoped classes and variables are appropriately
captured by `ngtsc` without scoping errors, properly supporting nested/local
foreign component usage.
2026-06-08 10:17:40 -07:00
leonsenft b399f78c34 refactor(compiler): support passing @content blocks as functions
Previously, foreign component `@content` blocks were rendered eagerly by
Angular and could only project a list of nodes. With this change, `@content`
can be used to declare a function (e.g. `@content(renderItem; let item)`) that
is passed as a callback prop to the foreign component, allowing the foreign
component to invoke it with context arguments at its leisure.

Implementation details:
- Introduces a new runtime instruction `ɵɵforeignContentFn` which wraps the
  template function so it can be called on demand with arguments by the foreign
  component.
- Extends the compiler AST to parse and validate `@content` parameters.
- Maps `@content` parameters to the corresponding positional arguments of the
  calling foreign component function property.
2026-06-08 10:17:40 -07:00
Angular Robot 21e8ad37d9 build: update jasmine dependencies to v6
See associated pull request for more information.
2026-06-08 10:13:32 -07:00
SkyZeroZx 255151a413 fix(http): Rejects non-HTTP(S) URLs in JSONP requests
Prevents JSONP requests from using URLs with unsupported protocols
for improved security.

Fixes #68832
2026-06-05 15:09:37 -07:00
leonsenft 79e5d5d75f refactor(compiler-cli): validate @content block names for conflicts
Ensures `@content` blocks on foreign components have unique names and do not
conflict with static attributes or input property bindings.

Specifically, this commit introduces two new template diagnostics:
1. `CONFLICTING_CONTENT_DECLARATION` (8028): Raised when multiple `@content`
   blocks with the same name are defined under the same foreign component.
2. `CONFLICTING_CONTENT_AND_PROPERTY` (8029): Raised when a `@content` block's
   name matches an attribute or input property binding on the parent foreign
   component.

Both diagnostics include related information pointing to the location of the
conflicting declaration or property.
2026-06-05 12:46:32 -07:00
leonsenft 337442453b refactor(compiler-cli): disallow @content (children) in favor of implicit children
Defining a `@content (children)` block explicitly is unnecessary because
children should always be passed implicitly as direct nested content of the
foreign component. Using an explicit block could also lead to conflicts and
silent template rendering issues where implicit content (like whitespace)
accidentally overwrote the explicit block in the compiler's template
representation.

This change introduces a compilation error
(`FOREIGN_COMPONENT_CONTENT_UNNECESSARY_FOR_CHILDREN`) when an explicit
`@content (children)` block is detected, guiding developers to pass children
implicitly instead.
2026-06-05 12:46:32 -07:00
leonsenft 1f6e843648 refactor(compiler-cli): validate @content block placement
Adds validation to verify that `@content` blocks are only used as direct
children of foreign components.

Specifically:
- Defines a new compile diagnostic code `INVALID_CONTENT_PLACEMENT = 8026`.
- Updates `ForeignComponentFeatureAnalyzer` to traverse content blocks and
  report `INVALID_CONTENT_PLACEMENT` diagnostics if they are placed
  incorrectly.
- Removes the raw error thrown during ingestion in
  `packages/compiler/src/template/pipeline/src/ingest.ts`.
- Adds integration tests in `template_typecheck_spec.ts`.
2026-06-05 12:46:32 -07:00
leonsenft daa47b4aad refactor(compiler-cli): validate foreign component bindings during analysis
Refactors the unsupported bindings validation for foreign components from the
template semantics checker phase (during type-checking) to the component
analysis phase. Surfacing this check during component analysis means it will be
correctly reported during local compilation (which skips full template
type-checking).

Specifically:
- Creates a new helper `analyzeForeignComponentFeatures` in
  `foreign_component.ts` that traverses template elements and checks for
  unsupported outputs, references, and non-property inputs on foreign components.
- Removes the legacy validation from `template_semantics_checker.ts`.
- Invokes the validation during component analysis in
  `ComponentDecoratorHandler.analyze()`.
2026-06-05 12:46:32 -07:00
leonsenft 56607967db fix(core): introduce logical-only containers for foreign content
This commit introduces a logical-only container flag (`LContainerFlags.LogicalOnly`)
to support Angular features (like change detection and queries) on projected content
within foreign components, while relinquishing control over their placement in the DOM.

When content is projected into a foreign component via `ɵɵforeignContent`, the foreign
component receives the native DOM nodes directly and assumes control over their DOM
placement. Therefore, Angular must skip all platform-level view operations (insert,
move, delete) on these projected views.

To achieve this:
1. Introduce Logical-Only Containers:
   - Added `LContainerFlags.LogicalOnly` to represent view containers whose nodes are
     managed logically (by the consuming foreign component) rather than by the renderer.
   - Flagged `ɵɵforeignContent` containers with the `LogicalOnly` annotation.
   - Updated `applyContainer` in `node_manipulation.ts` to return early and skip platform
     DOM manipulations (insert, detach, destroy) on containers marked as logical-only.

2. Guard `collectNativeNodes`:
   - Updated `collectNativeNodes` in `collect_native_nodes.ts` to skip descending into
     logical-only containers. This prevents nested projected child elements (which are
     already claimed and placed inside nested foreign components) from being re-collected
     at the parent component's projection root level.

3. Unit and Acceptance Tests:
   - Added a comprehensive set of categorized acceptance tests in `foreign_component_spec.ts`
     covering nested foreign projections, projecting foreign components into Angular components,
     Signal-based view queries (`viewChildren`), event handlers, and change detection.
2026-06-05 12:46:32 -07:00
leonsenft f19bbe59dd refactor(compiler): support passing content to specific foreign component props
Add `@content(propName)` blocks for passing template content to foreign
component properties by name. Previously, only a single set of direct children
could be passed to a foreign component via the default `children` property.
With this change, developers can project distinct template content to multiple
specific properties on the foreign component:

```html
<FancyButton [label]="title">
  @content(icon) {
    <span>Icon</span>
  }
  @content(description) {
    <span>Description text</span>
  }
  <span>Other children</span>
</FancyButton>
```

Specifically:
- Add support to the HTML lexer for `@content` blocks.
- Introduce `ContentBlock` AST node to represent `@content` blocks.
- Implement validation ensuring `@content` blocks have exactly one parameter
  representing a valid JS identifier.
- Throw an error during ingestion if a `@content` block is placed anywhere
  other than as a direct child of a foreign component.
- Map `@content` blocks to properties of the props object passed to
  `ɵɵforeignComponent`.
- Update compliance and unit tests to cover these changes.
```
2026-06-05 12:46:32 -07:00
leonsenft f89d0e4c8f refactor(compiler): support passing children to foreign components
Previously, any children nested inside a foreign component were ignored
during template ingestion. With this change, the compiler now:
1. Identifies when a foreign component has children in the template AST.
2. Compiles these children into a separate template view (using the
   standard TemplateOp).
3. Passes a `ɵɵforeignContent` expression under the `children` prop
   inside the foreign component's `props` object.

At runtime, the new `ɵɵforeignContent(index)` instruction instantiates the
template at the specified slot index in memory (detached from the DOM),
extracts its root DOM nodes, and returns them. These root nodes are then
passed directly to the foreign component's `props.children` so they can
be rendered by the foreign framework.

The instantiated children view is registered in the parent LView's
child tree, ensuring its change detection and destruction are managed
automatically as part of the standard Angular view tree lifecycle.
2026-06-05 12:46:32 -07:00
Alan Agius 5f36274da3 fix(common): use cryptographically secure SHA-256 for transfer cache key generation
Replace the custom 64-bit non-cryptographic combined DJB2 hashing implementation in HttpTransferCache with a robust, pure JavaScript, synchronous SHA-256 algorithm.
2026-06-05 11:18:12 -07:00