Commit Graph

6437 Commits

Author SHA1 Message Date
SkyZeroZx d7f70616a0 fix(core): reject dynamic script host elements
The previous fix for GHSA-692r-grfm-v8x7 was incomplete because it rejected script tags only when locating an explicit host element. Dynamic component instantiation can also infer the host element from the component selector.

Move the script-host rejection to the point where ComponentFactory has resolved the host element for either path, so createComponent rejects script hosts consistently.
2026-06-30 17:29:36 -07:00
Andrew Scott a7bde662c3 refactor(core): allow AnimationClassBindingFn to return undefined or null
The AnimationClassBindingFn type was too restrictive, only allowing `string | string[]`. However, the runtime (`getClassListFromValue`) safely handles `undefined` and `null` values by treating them as no animation.

This change updates the type to allow `undefined` and `null`, which is consistent with other class/style bindings in Angular and avoids requiring workarounds (like empty strings) in host bindings.

Added a compliance test case to verify that `[animate.enter]` with a potentially `undefined` value compiles correctly.
2026-06-30 17:27:59 -07:00
leonsenft a720094deb refactor(core): format @content blocks consistently (#69502)
`@content(name)` -> `@content (name)` to align with other block syntax.

PR Close #69502
2026-06-29 17:34:27 -07:00
leonsenft 555fc20af0 refactor(core): add context support for foreign components (#69502)
Enable foreign components to receive and propagate contextual data
across framework boundaries.

Previously, foreign render functions only accepted component properties,
and foreign content projection instructions (`ɵɵforeignContent` /
`ɵɵforeignContentFn`) did not provide any mechanism to expose foreign
framework context to projected Angular embedded views.

With this change:

- Update `ForeignRenderFn` and `ForeignComponent` interfaces to accept
  an optional context parameter and an optional `GET_CONTEXT` symbol
  method.

- Introduce `FOREIGN_CONTEXT` injection token and
  `provideForeignRootContext` helper to configure root context in
  Angular's DI hierarchy.

- Update `ɵɵforeignComponent` instruction to resolve `FOREIGN_CONTEXT`
  from the injection tree and pass it to the foreign component's render
  function.

- Update `ɵɵforeignContent` and `ɵɵforeignContentFn` instructions to
  wrap embedded view creation with a `ForeignContextInjector` when
  `GET_CONTEXT` is present.

Furthermore, foreign render functions are no longer run inside an
Angular injection context, since it's expected they use the foreign
context support directly.

PR Close #69502
2026-06-29 17:34:27 -07:00
leonsenft 4847c0e07b refactor(core): enable foreign components to render content lazily
Transition parameterless `@content` projection in foreign components
from eager DOM creation to lazy evaluation. Previously, projecting
content into a foreign component eagerly instantiated the embedded view
and created DOM nodes, causing unnecessary resource consumption if the
content was hidden or unmounted.

With this change, runtime content instructions (`ɵɵforeignContent` and
`ɵɵforeignContentFn`) pass lazy producer callbacks directly through the
foreign component's configured `contentAdapter`. View creation and
teardown registration occur lazily when the external framework evaluates
the adapted producer.

`foreignImport` now requires a third argument, `contentAdapter`,
specifying how Angular content producer callbacks are adapted for the
target external framework.
2026-06-29 14:22:48 -07:00
tmpln 74638cab84 fix(core): improve input writes migration in best effort mode
Currently, signal migration schematics in best effort mode doesn't do a very good job migrating input writes when there is a nested property access in templates.

In event handlers, no attempt is made to migrate a nested access in the left-hand-side of assignments or anything in their right-hand-side. E.g., nothing will happen here:

`(ngModelChange)="inputD.prop = $event + inputF"`.

Additionally, when a migration attempt is made, parentheses are often incorrectly placed on the parent, both in event handlers and two-way bindings:

`(ngModelChange)="inputC = $event"` is migrated to `(ngModelChange)="inputC = $event()"`.

`[(ngModel)]="inputB.prop.prop"` is migrated to `[(ngModel)]="inputB.prop().prop"`.
2026-06-26 10:30:57 -07:00
aparziale 26b0c719ef fix(migrations): resolve migration failure when tsconfig specifies rootDir
When `rootDir` was set in a project's tsconfig (e.g. `rootDir: "src"`),
tsurge-based migrations would fail because `projectRoot` was derived from
`rootDir`, causing `rootRelativePath` to be computed relative to `src/`
instead of the workspace root. This produced paths like `app/app.ts`
instead of `src/app/app.ts`, which the DevKit tree could not resolve.

Fix by overriding `info.projectRoot` to `absoluteFrom(info.program.getCurrentDirectory())`
immediately after program creation, ensuring workspace-relative paths are
used for all tree updates.
2026-06-26 09:14:46 -07:00
JoostK ecd047578e fix(compiler): account for NgModule dependencies in JIT-compiled partial declarations
When partial declarations are not preprocessed to AOT by the linker, the `ngDeclareComponent`
call causes them to be compiled ad-hoc. In this mode, NgModule imports in standalone components
would be dropped, deviating from the linker. This commit changes the ad-hoc compilation of
component declarations to pass the NgModule imports along just like the linker does.

Fixes #69451
2026-06-24 14:46:43 -04:00
Matthieu Riegler 4744bab38e refactor(core): Tree shake the SimpleChanges & co.
Any application that doesn't use the `ngOnChanges` hook shouldn't pull its code.
2026-06-24 13:04:35 -04:00
Saurabh Singh 7057b1257f docs(core): document resource chaining with chain() in params context
Adds a 'Chaining resources' section to the resource guide covering:
- Basic usage of chain() to depend one resource on another
- Status propagation for all ResourceStatus values (idle, loading,
  reloading, error, resolved, local)
- Chaining vs reading .value() directly, shown as an avoid example
- Guidance on passing the chained value directly as params

Also adds an @see link from ResourceParamsContext to the new section.

Closes #69329
2026-06-24 11:23:49 -04:00
Angular Robot 295dad7389 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-06-24 10:48:36 -04:00
Kristiyan Kostadinov 91d168e74b fix(core): avoid uncaught promise errors in injectAsync prefetching
Fixes a minor issue where the `preload` function in `injectAsync` might cause an uncaught promise error.

I also fixed that in `onIdle` we were passing the wrong function into `assertInInjectionContext`.
2026-06-23 12:57:26 -04:00
Kristiyan Kostadinov 792edaba48 refactor(migrations): account for inheritance in service migration
Updates the `@Service` migration to account for inheritance when determining if a class can be migrated.
2026-06-22 16:34:50 -04:00
Kristiyan Kostadinov c75ff0255c feat(migrations): add migration from injectable to service
Sets up an automated migration to convert `@Injectable` usages to `@Service`.
2026-06-22 16:34:50 -04:00
Jessica Janiuk a849b6fbfd Revert "fix(core): escape overlapping comment delimiters in escapeCommentText"
This reverts commit ea1a3ed64c.
2026-06-18 12:34:25 -04:00
Cameron Smick ae6d8dae75 refactor(core): add childSignalProp to ReactiveNodeKind
Add `childSignalProp` to `ReactiveNodeKind` in order to consolidate `ReactiveNodeKind` types and enable Client-Only Wiz to use it.
2026-06-17 13:03:13 -07:00
arturovt 8cf7731468 fix(core): guard against DOM clobbering in declareExperimentalWebMcpTool
Previously, the modelContext truthiness check could be bypassed via DOM
clobbering (e.g. `<form id="modelContext">`), causing a truthy HTMLElement
to pass the guard and then throw when `registerTool` was called on it.

Replace the truthiness check with a duck-type check that asserts
`registerTool` is a function, rejecting both absent and clobbered values.
2026-06-17 13:02:10 -07:00
Andrew Scott 1e79dd3140 refactor(router): Add handling for ActivatedRoute-scoped injector
Add handling in navigation for creating and destroying injectors scoped
to `ActivatedRoute` life.
The code for creating the injectors is certainly more complicated
than it _could_ be since there's no actual feature built around this yet.

Keeps as much implementation code tree-shakeable as possible:
Raw size: +764 bytes
Gzipped size: +182 bytes
2026-06-17 11:39:13 -07:00
Joost Koehoorn 327744ac17 perf(core): detect existing signal dependency without checking all producer links
This commit addresses a scaling issue in the signal dependency graph where
the detection of duplicate dependency links would perform a linear scan across
all consumer links of all producers. The linear scan is replaced with a version
comparison of the dependency edge against the current epoch; if they are
equal the existing dependency edge is known to be valid in this epoch. This means
that the link won't be eligible for removal and therefore doesn't have to be
recreated.
2026-06-17 11:38:04 -07:00
rootvector2 ea1a3ed64c fix(core): escape overlapping comment delimiters in escapeCommentText
`COMMENT_DISALLOWED` is matched globally, so overlapping delimiter
sequences are skipped: `<!-->` only escapes the leading `<!--` and
leaves a live `-->` that can close a programmatically created comment
node early. Drop the `^` anchors so a standalone `>`/`->` is escaped
wherever it appears, which neutralizes the trailing delimiter left
behind by an earlier match.
2026-06-17 11:37:08 -07:00
SkyZeroZx 0152e3cbdf fix(core): treat iframe credentialless as security-sensitive
Mark the iframe `credentialless` attribute as security-sensitive so dynamic
bindings are handled consistently with other iframe attributes that affect the
initial navigation, such as `sandbox`, `allow`, `referrerPolicy`, `csp`, and
`fetchPriority`.

Because `credentialless` must be present before the iframe starts loading to
affect the navigation’s credential mode, late dynamic updates can leave the final
DOM looking correct while the initial request was not loaded credentiallessly.
2026-06-16 09:05:53 -07:00
Kristiyan Kostadinov 28cb15a2bb fix(core): prevent unsubscribe during emit from throwing off other listeners
Fixes that when a listener unsubscribes from an `output` within its own callback, it was preventing subsequent listeners from running.

These changes fix the issue by not mutating the array while the emit loop is running, but replacing the listener with `null` and coming back later to remove it.

Fixes #69325.
2026-06-16 08:29:32 -07:00
SkyZeroZx 98f42eaaae fix(core): avoid caching missing locale data
Only cache locale data loaded from the global locale registry when an actual locale entry is found.

This prevents attacker-controlled missing locale identifiers from being retained indefinitely in SSR when locale lookup falls back to a parent locale or the built-in English locale, avoiding unbounded process memory growth in locale-aware pipes and formatters.
2026-06-15 10:53:08 -07:00
Alan Agius 417a4071a7 fix(compiler): restrict possible event handler check to property names longer than 2 characters
Previously, the compiler disallowed translation of any attribute starting with 'on' for security reasons. This incorrectly disallowed translation of the 'on' attribute itself, which is not an event handler.

This commit introduces `isPossibleEventHandler` to verify that the property name has a length greater than 2 in addition to starting with 'on'. This allows attributes like 'on' to be translated while still correctly disallowing actual event handlers like 'onerror', 'onclick', etc.
2026-06-15 09:23:49 -07:00
Andrew Scott 2112edefe1 refactor(core): ɵɵgetInheritedFactory should accept abstract type
An abstract component or directive can extend another class, meaning
ɵɵgetInheritedFactory needs to allow abstract
2026-06-15 09:22:35 -07:00
aparziale 58efd86c78 fix(migrations): migration skip any target are not build or test
Fix migration behaviout that skip any target are not build or test

Fixes #66865
2026-06-12 09:24:44 -07:00
Alan Agius 32d7315094 refactor: optimize dom security schema lookups
Restructure the security schema map to index by property name instead of tag name, improving lookup efficiency.
2026-06-12 09:20:36 -07:00
Andrew Scott 8984c59626 refactor(core): ComponentDef should allow abstract types too
d1539a8513 incorrectly assumed components wouldn't be abstract but
it is still possible (though probably should be an abstract directive instead).
2026-06-11 13:08:09 -07:00
Jessica Janiuk dcc4fe06b9 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-06-11 13:04:18 -07:00
Kai Guo 6b5616b2c7 fix(core): preserve leave animation for sibling instances sharing a TNode
`animate.leave` was skipped — the element was removed from the DOM
synchronously instead of running its leave animation — whenever a
sibling instance of the same template entered in a different DOM parent
during the same change-detection tick (e.g. an exclusive-expansion
accordion or nav where opening section B collapses section A).

`leavingNodes` is keyed by `TNode`, which is shared by every instance of
a template. When a node was inserted, `cancelLeavingNodes` force-removed
any tracked leaving node whose DOM parent differed from the entering
node's parent (the `leavingParent !== newParent` branch added to
de-duplicate a dynamic component re-rendered into a fresh overlay pane).
For two distinct live sibling instances that merely share a `TNode`,
"different parent" is the normal situation, so the still-animating
sibling was ripped out.

Track the declaration view of each leaving element alongside it, and
only perform the cross-parent removal when the entering element belongs
to the same declaration view as the leaving one — i.e. the same logical
view re-rendered, the case the branch was written for. Two distinct
instances of a shared template have different declaration views, so
their `animate.leave` is now left to run to completion.

This preserves the dynamic-component/overlay de-duplication (#67032) and
the drag-and-drop node-move rescue (#67361), which are unchanged.

Fixes #69291
2026-06-11 10:38:57 -07:00
Andrew Scott d25d2e1524 refactor(core): Update registerNgModuleType to support codegen typechecking
Updates types and adds test for source->source transformation with tsc downstream
2026-06-10 10:52:55 -07:00
Doug Parker 492e3a2a1f test(core): fix AI tools test flake
This test flakes occasionally because it is called in production when a platform is created and unregistered when a platform is destroyed. However, not all tests properly clean up their platforms, meaning we can accidentally leak platforms between tests. If this happens, we end up have an event listener created from the production code path and a second event listener from the test. When the test emits the event, both listeners respond and it causes too many responses which fails the test.

Ideally, all tests would clean up the platforms correctly, but this seems difficult to guarantee for all Angular tests and is likely to break over time. The simplest solution is just destroy any leaked platform before the test starts. It's a bit elegant, but the safest option.
2026-06-10 10:29:00 -07:00
SkyZeroZx e640692452 fix(core): validate lowercase SVG animation attribute names
Normalize SVG animation attributeName lookup to also recognize lowercase attributename before allowing dynamic animation value bindings.

Add runtime and platform-server SSR regression coverage for lowercase attributename retargeting.
2026-06-10 10:22:29 -07:00
Hexix23 6c41f5ca01 fix(compiler): disallow i18n event attributes
Reject translated event-handler attributes so localization cannot bypass Angular event-attribute validation.
2026-06-10 10:21:33 -07:00
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
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
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
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
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
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
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