Commit Graph

15623 Commits

Author SHA1 Message Date
Doug Parker e041f9483e refactor(core): pass AbortSignal to WebMCP tools to handle cancellation
This forwards the `AbortSignal` natively supplied by Chrome 153.0.8009.0's update to `registerTool` executions down into the Angular context. This helps tools gracefully handle execution cancellations initiated by agents or users, preventing unnecessary background work and leaking resources.

We combine the injector/component destruction abort signals with the native WebMCP execution cancellation signals so the underlying tools correctly cancel long-running requests without producing invalid states.

Justification:
https://groups.google.com/a/chromium.org/g/chrome-ai-dev-preview/c/9291sjhIRz0/m/RFuyRrs5AAAJ
2026-08-19 12:41:09 -07:00
Andrew Scott 80a04eba52 refactor(router): add support for non-blocking router resources (#70211)
Introduces support for route-level resources via the `resources` property on route definitions, enabled with `withRouterResources()`.

Router resources provide a reactive, signal-based alternative to resolvers, allowing routes to declare resources tied to route parameters and route lifecycle:
- The `resources` function executes during navigation transitions within an injection context scoped to the route (`_localInjector`).
- It receives a `ResourceContext` containing signals for `params`, `queryParams`, `fragment`, and `data`, alongside the static `snapshot`.
- For newly created routes, `resources` runs once and attaches to `ActivatedRoute.resources`. For reused routes, parameter signals update reactively to trigger new data fetches while keeping resource references stable.
- Wrapped resources (`routerResource`) provide transactional stability: snapshots are frozen during active navigations to prevent UI jitter, unfreezing on `NavigationEnd`.
- On cancelled navigations or errors, rollback recovery retains the frozen snapshot until reverted signals settle, avoiding flashes of loading state. Manual reloads are rejected while frozen.
- Local injectors are automatically cleaned up if navigations are cancelled or rolled back.

Note that this commit only implements non-blocking resources (marked with `nonBlocking()`), deferring blocking resource resolution to future work to keep the initial changeset smaller and less complex.

PR Close #70211
2026-08-19 15:28:08 +00:00
Andrew Scott 99c0f593c4 refactor(router): rename activated route injector feature to resource feature (#70211)
Activated Route Injector feature was developed for resources. This moves the internal
naming (files and vars) to reflect this now that we have landed the core bits of plumbing
and are ready to implement router resources.

PR Close #70211
2026-08-19 15:28:08 +00:00
Matthieu Riegler c819880b91 fix(forms): report forbidden 2way bindings on when FormField is applied
We were already reporting regular bindings but not 2way.

fixes #70219
2026-08-18 17:08:02 -07:00
Jessica Janiuk da9f3e2118 Revert "fix(compiler): preserve &ngsp; between sibling control flow blocks"
This reverts commit 53fc371142.
2026-08-18 17:03:06 -07:00
arturovt 53fc371142 fix(compiler): preserve &ngsp; between sibling control flow blocks
`findConnectedBlocks` scans siblings after an `@if` to collect connected
`@else`/`@else if` blocks. Whitespace-only text nodes encountered during
the scan were eagerly added to `processedNodes`, marking them as "do not
emit", before confirming whether a connected block actually followed.

By the time `findConnectedBlocks` runs, `WhitespaceVisitor` has already
converted `&ngsp;` (and ` `) into a plain space character, making
them indistinguishable from insignificant whitespace via `.trim().length`.
When the next sibling was a second, unrelated `@if` instead of `@else`,
the scan stopped but the text node was already silently dropped.

Fix by deferring the `processedNodes` insertion into a pending buffer and
only committing those nodes once a connected block is confirmed to follow.

Fixes #55791
2026-08-18 15:52:42 -07:00
arturovt c2b14b7ab4 fix(core): prevent orphaned requestIdleCallback handle from re-entrant scheduling
Defer blocks that ask to run during browser idle time with the same
options get grouped into one batch ("bucket") and processed together
the next time the browser is idle. While that batch runs, if one
callback (or the change-detection check right after it) asks to
schedule more idle work for that same batch, Angular used to register
a second idle-callback handle instead of reusing the one already in
flight.

That second handle became orphaned. By the time the batch finished
running, its queue was empty, so Angular threw away the bookkeeping
for it — including the only reference that could have cancelled the
handle. If the app was destroyed before the browser got around to
calling it, it fired anyway, against a scheduler that no longer
existed.

The root cause was a marker (idleId) that IdleScheduler uses to know
"I already have a browser callback pending for this batch, don't
request another one." That marker was being cleared to null right at
the start of processing a batch, before any of its callbacks had
actually run. So a callback that re-entrantly asked to schedule more
work mid-batch saw "nothing pending" and requested a redundant handle.

The fix: leave the marker set for the entire batch instead of clearing
it up front. Only clear it once every callback in the batch has run —
at that point, if there's leftover work, it's safe to request a fresh
handle for it.

Added a test for the basic re-entrant scenario, plus five more for
edge cases: a re-entrant add() into a different batch, and re-entrant
remove() of a sibling callback that hasn't run yet versus one that
already has.
2026-08-18 15:52:07 -07:00
Aleksander Bodurri 0ddbc47e7f fix(core): expose debuggableFn for non-computed signal graph nodes
Before: getSignalGraph only exposed debuggableFn on computed and template
nodes, preventing DevTools from linking to source code for other node types.

After: debuggableFn is also populated for linkedSignal, effect, and
afterRenderEffectPhase nodes.
2026-08-18 15:51:26 -07:00
arturovt f1a4c85212 fix(router): pass correct component to canDeactivate for named outlets in componentless parent routes
When a componentless parent route has children rendered into a named outlet
(e.g. `outlet: 'inner'`), the `canDeactivate` guard received `null` as the
component argument instead of the actual component instance.

The bug was in `deactivateRouteAndItsChildren`: for componentless routes,
each child was passed the same `context` inherited from the parent lookup,
which was `null` when the parent component only registered a named outlet.
The children's actual outlet contexts were never consulted.

The fix adds a `parentContexts: ChildrenOutletContexts | null` parameter so
that for componentless routes, each child is looked up by its own outlet name
in `parentContexts` (e.g. `parentContexts.getContext('inner')`). For
component routes, `context.children` is passed as the new `parentContexts`
on recursion, ensuring correct context resolution across component boundaries.

This re-addresses #34614. A previous fix (#36302) was reverted because it
passed `parentContexts` unchanged through component boundaries; this fix
updates `parentContexts` to `context.children` when descending into a
component route, preventing the wrong contexts from propagating into deeper
componentless levels.

Fixes #34614
2026-08-18 15:04:56 -07:00
brysonbw 2720362818 feat(router): add containsTree as public API
Export containsTree from @angular/router to enable direct UrlTree subset matching.
2026-08-18 12:08:17 -07:00
Kristiyan Kostadinov 732e505018 fix(core): replace all hasOwnProperty usages with Object.hasOwn
We keep getting PRs that target single usages of `hasOwnProperty` and we have ~100 of them. These changes aim to address the issue centrally by swapping out all the instances and adding a lint rule against introducing new ones.
2026-08-18 09:17:18 -07:00
Angular Robot 48a0fd6e8a feat(compiler): allow template to access private props
To allow this we'll catch the errors during typechecking and discard it.

As context, when setting `isolatedDeclarations: true` this requires developers to explicitly type every property but the `private` ones. By allowing private properties to be used in templates we discard the actually for explicit typing for template only properties.
2026-08-18 09:01:25 -07:00
arturovt c658d73210 fix(core): stop running further effects once one destroys the view mid-flush
When a view has more than one effect scheduled to run, and one of them
destroys the view (e.g. by calling `componentRef.destroy()`), the
remaining effects in that same flush could still run afterward,
against a view that no longer exists. In some cases this crashed
outright with `TypeError: view[EFFECTS] is not iterable`.

Here's why: `runEffectsInView` walks a view's effects in a `for...of`
loop, wrapped in an outer `while` loop that re-checks for any effects
that became dirty as a side effect of ones that already ran. When an
effect destroys its view, `view[EFFECTS]` gets set to `null` as part
of tearing the view down.

First attempt checked for that inside the `for...of` loop, before each
effect runs. That covers a sibling effect later in the *same* pass,
but misses a second case: if the effect that destroys the view *also*
dirties another effect on that same view in the process (e.g. by
writing a signal the sibling depends on), the outer `while` loop sees
`HasChildViewsToRefresh` set and tries to restart — and immediately
crashes re-entering `for (const effect of view[EFFECTS])` on a
now-null value, before the in-loop check ever gets a chance to run.

Reproduced that exact crash with a test first: two effects on one
view, the second one writes a signal the first depends on and then
destroys the view in the same call — confirmed it throws before
touching the fix.

Fixed by checking right after `effect.run()` instead of before it,
covering both cases in one place: the remaining effects in the current
pass, and the loop trying to restart afterward. As soon as one effect
destroys the view, nothing else runs against it again.

This is intentionally narrow in scope. An earlier version of this fix
also tried to guarantee that `onCleanup()` callbacks still ran even
when registered after an effect destroyed its own view. That's been
dropped — destroying your own view and then continuing to register
more work for it isn't something the framework should have to paper
over. If you need to do both, register `onCleanup` first, then
destroy.
2026-08-18 08:59:13 -07:00
Alon Mishne 292991e2df Revert "fix(router): limit protocol-relative URL handling to serialization"
This reverts commit 435f8b2b8b.
2026-08-18 08:58:13 -07:00
arturovt 46d2cb7ff0 fix(common): preserve literal key union in KeyValuePipe.transform()
Previously, when you passed an object typed like
Record<'a' | 'b', number> into the `keyvalue` pipe, TypeScript would
"forget" that the keys could only ever be 'a' or 'b', and just tell
you the key was a plain `string` instead. So code like this used to
fail to compile, even though it's correct:

```ts
  const input: Record<'a' | 'b', number> = {a: 1, b: 2};
  const result = pipe.transform(input);
  const key: 'a' | 'b' = result[0].key; // error: string is not 'a' | 'b'
```

This happened because the pipe has multiple overloaded versions of
transform(), and TypeScript checks them top to bottom, using the
first one that matches. The "number keys" overload was listed first,
and it happened to also match string-keyed objects by accident, so
it "won" before the correct "string keys" overload ever got a
chance to run.

The fix just reorders those two overloads so the string-keys one is
checked first. Nothing about runtime behavior changes — objects with
actual numeric keys (e.g. Record<1 | 2, string>) still correctly
report their keys as plain `string`, matching what Object.keys()
really returns at runtime.
2026-08-17 15:01:24 -07:00
Jaime Burgos 6f9a6bea50 fix(platform-browser): disallow event handler attributes in Meta
Prevent arbitrary MetaDefinition properties from writing on* handlers directly to meta elements. Browser events can execute these handlers, including on meta elements rendered in the document body.
2026-08-17 14:59:50 -07:00
Nikita Barsukov 182c371d82 docs: use transformedValue in Forms | Custom Controls | Value transformation section
The "Value transformation" section taught readers to hand-roll
transformation with `linkedSignal()` and a manual parse method, even
though `@angular/forms/signals` ships `transformedValue()` for exactly
this case. Readers ended up with a weaker version of a feature the
framework already provides — notably, no parse error reporting.

Rewrite the section around `transformedValue()` and document the parts
the manual pattern could not cover: returning `{error}` from `parse` to
surface parse errors on the field's `errors()`, and `reset()` clearing
them. This also makes good on the cross-reference from the validation
guide, which pointed here for parse error details the section never
covered.

Fixes #70206

Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
2026-08-17 14:58:14 -07:00
splincode d35c17d393 refactor: correct typos in comments, docs, and error messages
Fix misspellings found across multiple packages:

- `paramters` → `parameters` (utils.spec.ts)
- `directve` → `directive` (typecheck/context.ts)
- `subscriper` → `subscriber` (zone.js rxjs test)
- `swich` → `switch` (adev animation parser test)
- `subscribtion` → `subscription` (forms/abstract_model.ts)
- `lifecyle` → `lifecycle` (ng-devtools-backend hooks)
- `compatability` → `compatibility` (tree-visualizer.ts)
- `indentifier(s)` → `identifier(s)` (compiler-cli shared.ts, i18n_helpers.ts, declaration_only_emission_spec.ts)
- `identifer` → `identifier` (platform-browser shared_styles_host.ts)
- `prcess` → `process` (standalone-migration to-standalone.ts)
2026-08-17 14:57:04 -07:00
splincode b10021c79b refactor(localize): replace any with unknown in messages and translations utils
Replace unsafe `any` type annotations with `unknown` across the localize
utility layer to improve type safety and catch potential type errors at
compile time rather than at runtime.

Changes in `messages.ts`:
- `ParsedMessage.substitutions`: `Record<string, any>` → `Record<string, unknown>`
- `parseMessage` parameter `expressions`: `readonly any[]` → `readonly unknown[]`
- Local `substitutions` variable: `{[key: string]: any}` → `Record<string, unknown>`

Changes in `translations.ts`:
- `isMissingTranslationError` parameter: `any` → `unknown`, with proper
  narrowing (`typeof e === 'object' && e !== null`) before property access
- `MissingTranslationError.type` visibility: `private` → `readonly` to allow
  access through the narrowed `unknown` type in the type guard
- `translate` parameter and return type: `readonly any[]` → `readonly unknown[]`
- `makeTemplateObject` cast: `cooked as any` → `cooked as unknown as TemplateStringsArray`

Fix in `mock_message.ts` (test helper):
- `substitutions: []` → `substitutions: {}` — the array literal was only
  assignable because the field was typed as `any`; the correct empty value
  for a `Record<string, unknown>` is an object literal
2026-08-17 14:56:31 -07:00
arturovt 38d093232c fix(forms): warn in dev mode when ngModel cannot reach parent NgForm across component boundary
NgModel injects ControlContainer with @Host(), which stops the injector at
the component host element boundary. When NgForm lives in a parent component
and ngModel lives in a child component, the injection returns null silently
and the control acts standalone — never registering with the form.

To surface this invisible failure, emit a dev-mode warning (NG01354) when
ngModel's @Host() injection finds nothing but the element Injector can still
reach a ControlContainer further up the hierarchy. The warning identifies the
cross-boundary issue and points developers to the viewProviders fix or the
standalone option.

Adds the NG01354 reference page explaining why the warning fires and providing
two remediation paths: bridging ControlContainer via viewProviders, or opting
out with [ngModelOptions]="{standalone: true}".

Fixes #47580
2026-08-17 13:59:40 -07:00
Vincent 70b252cac3 test(core): Add test to ensure Angular correctly detects paths when served from file system
This test makes sure that when Angular is served from Electron or just from the file system that the router works correctly.
2026-08-17 13:58:54 -07:00
Jaime Burgos 45ebb127e3 refactor(compiler-cli): add error guide links to diagnostics
Add the error guide URL when a compiler diagnostic uses a negative
marked error code.
2026-08-17 13:58:11 -07:00
arshiya tabasum c73a001fbf fix(animations): detect object trigger values with Object.hasOwn
StateValue and AnimationTransitionNamespace.trigger detect the {value,
params} object form of a trigger binding by calling hasOwnProperty on the
bound value. When that value is an object from untrusted data (for example
a parsed JSON payload) carrying an own hasOwnProperty key, the shadowed
property is called as a method and throws, breaking the animation flush.
Use Object.hasOwn for the check so a shadowing key no longer matters.
2026-08-17 13:53:17 -07:00
SkyZeroZx 1a006a8f97 fix(http): cancel oversized fetch response bodies
Cancel the unread response body before reporting NG02825 when its declared Content-Length exceeds the configured buffer limit. Without cancellation, SSR can finish while the underlying connection remains open.

Add regression coverage for the declared-length rejection path.
2026-08-17 13:52:12 -07:00
Matthieu Riegler ed3373868d refactor(language-service): adapt strict template suggestion
In v22, `strictTemplates` is true by default. We need to adapte the LS to online report the suggestion when the option is explicitly `false`
2026-08-17 13:51:43 -07:00
Aleksander Bodurri 2a2585708a fix(devtools): clarify disabled View Source tooltip and update demo app
Before: The View Source button tooltip in signal details static ('View source') even when disabled.

After: The tooltip explains 'Source location is not available for this node' when disabled.
2026-08-17 13:28:27 -07:00
Aleksander Bodurri a1fd3c45f9 fix(core): expose debuggableFn for non-computed signal graph nodes
Before: getSignalGraph only exposed debuggableFn on computed and template
nodes, preventing DevTools from linking to source code for other node types.

After: debuggableFn is also populated for linkedSignal, effect, and
afterRenderEffectPhase nodes.
2026-08-17 13:28:27 -07:00
arturovt c6e4a36be1 fix(core): throw a descriptive error instead of crashing when a hydration node is missing
locateOrCreateElementNodeImpl looks up the DOM node for an element
during hydration and immediately checks its nodeType. If the
client-rendered DOM has fewer nodes than the server-rendered HTML,
the lookup returns null, and in production that null flows straight
into the nodeType check and crashes with a raw, uncoded
"Cannot read properties of null (reading 'nodeType')" TypeError.

The dev-mode check that would normally catch this (validateMatchingNode)
already handles a missing node, but it's compiled out of production
builds, so the crash only shows up outside of dev mode.

Add a null check ahead of the nodeType check that throws a coded
RuntimeError using the existing HYDRATION_MISSING_NODE (NG0502) code,
with a descriptive message in dev mode and a cheap fallback in
production. Also add a regression test that removes a server-rendered
element before hydration runs and asserts a coded RuntimeError is
thrown instead of a raw TypeError.
2026-08-14 08:30:49 -07:00
arturovt 1cb3d606bf fix(platform-browser): throw a descriptive error when insertBefore reference node is missing
Angular's internal LView/TNode bookkeeping can get out of sync with the
real DOM: manual DOM manipulation, a browser extension, or an edge case in
Angular's own view-insertion/reordering code can all leave Angular believing
a node is still attached at a given position when it isn't. The next time
Angular's renderer calls `insertBefore` relative to that stale reference
node, the native DOM API throws an opaque `NotFoundError` with no indication
of which node or component was involved, making these errors effectively
undebuggable in production:

    NotFoundError: Failed to execute 'insertBefore' on 'Node': The node
    before which the new node is to be inserted is not a child of this node.
        at Node.insertBefore (native)
        at DefaultDomRenderer2.insertBefore (packages/platform-browser/src/dom/dom_renderer.ts)
        at nativeInsertBefore (packages/core/src/render3/dom_node_manipulation.ts)
        at nativeAppendOrInsertBefore (packages/core/src/render3/dom_node_manipulation.ts)
        ... (called while Angular inserts or moves a view during change detection)

Check the reference node's actual parent against the expected parent before
calling the native `insertBefore`, and throw a descriptive `RuntimeError`
(NG05106) instead, following the same pattern already used for hydration
node mismatches.
2026-08-14 08:29:59 -07:00
Edu 6bfbfcc3a1 refactor(core): expose debuggableFn for effects in signal debug graph
Exposes the internal fn reference of effect reactive nodes on DebugSignalGraphNode as debuggableFn. This allows Angular DevTools to inspect and set breakpoints on effect callbacks.
2026-08-14 08:26:55 -07:00
Kristiyan Kostadinov 262fba7f7d build: resolve CI failures
Resolves some e2e failures that only happened on CI.
2026-08-14 08:22:34 -07:00
Kristiyan Kostadinov 7b74bee5b4 build: switch adev tests away from protractor
Reworks the tests in adev not to depend on Protractor.
2026-08-14 08:22:34 -07:00
Kristiyan Kostadinov 204265f9a3 build: switch examples away from protractor
Reworks the `examples` tests not to depend on Protractor.
2026-08-14 08:22:34 -07:00
Kristiyan Kostadinov 413c79c10b build: switch core tests away from protractor
Reworks the tests under `core` not to depend on Protractor.
2026-08-14 08:22:34 -07:00
Angular Robot d3d3bc62ea build: update cross-repo angular dependencies
See associated pull request for more information.
2026-08-13 13:35:29 -07:00
Alex Rickabaugh dc65e3656f fix(core): accept readonly arrays for setClassMetadata decorators
When reflection metadata is emitted via setClassMetadata, passing readonly arrays or const tuples for the decorators parameter causes TypeScript type checking errors because setClassMetadata previously expected decorators to be a mutable any[] or null.

This change updates the setClassMetadata type signature to accept decorators as readonly any[] or null and casts the parameter internally when mutating the class metadata property.
2026-08-13 13:33:07 -07:00
Alex Rickabaugh eee9ef4d09 fix(core): allow readonly arrays in RawScopeInfoFromDecorator
When components pass  arrays or readonly tuples to decorator metadata fields (such as ), typechecking generated decorator reflection metadata causes a TS2322 type mismatch error because  previously only accepted mutable .

This change updates  to accept , allowing  arrays and readonly tuples to be assigned without TypeScript compilation errors.
2026-08-13 13:33:07 -07:00
arturovt 4560f4fdcd fix(core): throw NG0500 instead of a raw TypeError on element hydration mismatch
When hydration locates the DOM node for an ɵɵelementStart/ɵɵdomElementStart
instruction, locateOrCreateElementNodeImpl assumed the located node was
always an Element and called hasSkipHydrationAttrOnRElement(native), which
does native.hasAttribute(...). The check that would normally catch this
class of mismatch, validateMatchingNode, is gated behind `ngDevMode &&` and
is compiled out of production builds. So when a real SSR/hydration
structural mismatch located a Text or Comment node instead of the expected
Element, production builds hit .hasAttribute on a node type that doesn't
have it and crashed with a raw, uncoded TypeError instead of a coded
hydration-mismatch RuntimeError.

Add a cheap, always-on nodeType check ahead of that call. On mismatch it
throws RuntimeError(HYDRATION_NODE_MISMATCH, ngDevMode && '...'), the same
pattern used elsewhere in the codebase, so the descriptive message is only
built in dev mode and production keeps throwing just the bare NG0500 code
without pulling validateMatchingNode's DOM-printing machinery into the
production bundle (verified via the bundling/hydration golden-symbols test,
which is unchanged).
2026-08-13 13:32:34 -07:00
Andrew Scott e8aa222e7d fix(compiler-cli): correctly resolve symbol for SafePropertyRead in chained optional navigation
When resolving template symbols for SafePropertyRead in TCBs emitted with optional chaining (strictSafeNavigationTypes: true), SymbolBuilder falls back to finding a TS node matching the AST expression's nameSpan. It then traverses up through parent nodes to find the enclosing expression.

Previously, the traversal loop checked isAccessExpression(node.parent) without verifying whether node was the accessed member name or the expression receiver. When multiple optional navigation expressions are chained (e.g. route?.data?.['icon']), the parent of ((route)?.data) is an access expression where ((route)?.data) is the receiver. Because isAccessExpression was true, the loop continued ascending into the outer access expression, causing symbol resolution for data to erroneously return the symbol and TCB location of icon.

This commit refines the parent traversal condition so that it only climbs into a parent PropertyAccessExpression if node is the accessed name (node.parent.name === node), preventing escape into outer receiver expressions.
2026-08-12 16:11:23 -07:00
SkyZeroZx a26fbfa641 refactor(core): distinguish animations that share a name
animate.leave waits for the longest-running animation before removing an element. When multiple animations use the same keyframe name, their animationend events have the same animationName, so a shorter animation can be mistaken for the longest one and remove the element too early.

Track the longest animation duration returned by getAnimations() and compare it with the duration from event.animation when available. Keep the existing name/property checks as a fallback for older browsers and computed-style detection.

Allow a 1ms tolerance for rounding differences between CSSOM and Web Animations and add a regression test using values equivalent to fractional calc() durations.
2026-08-12 16:09:27 -07:00
Andrew Scott c111f3fb0c refactor(router): Create transactional router resource
This commit adds an implementation of a router resource (not currently exposed for public use) which
defines the behavior of a resource dependent on the Router navigation lifecycle.
2026-08-12 16:07:05 -07:00
SkyZeroZx 870a525bd3 test(platform-server): clean up viewport hydration observer
Trigger routed viewport hydration so its cached observer is removed before later randomized specs run.
2026-08-12 11:04:40 -07:00
Matthieu Riegler f1c0c405c9 refactor(compiler): remove explicit strict: true
This flag is set by default in TS 6.0
2026-08-12 11:03:53 -07:00
SkyZeroZx 435f8b2b8b fix(router): limit protocol-relative URL handling to serialization
Preserve createUrlTree command semantics, including custom serializer inputs, while keeping the single-leading-slash guarantee at the default serialization boundary.

Expand coverage for command forms, public UrlTree values, secondary outlets, and preserved query parameters and fragments.

Fixes #69700
2026-08-11 12:07:31 -07:00
Andrew Scott b65dea4f03 feat(router): allow throwing RedirectCommand to trigger redirects
This allows developers to throw a `RedirectCommand` directly from guards and resolvers to trigger a redirect.

The primary benefit is that we no longer need to pollute the return type of functions that redirect. For example, a deeply nested helper function or a resolver can now simply throw a `RedirectCommand` to short-circuit and redirect, instead of having to return the `UrlTree` or `RedirectCommand` all the way up the call stack.

This aligns with prior art in other modern framework routers (such as Next.js, Remix, and SvelteKit), which commonly use thrown exceptions or special redirect responses to abort execution and trigger immediate redirection.
2026-08-11 10:03:43 -07:00
Alex Rickabaugh 8925a4ee49 fix(core): ensure i18n_util hasOwnProperty checks are safe for property renaming
`getTIcu` and `setTIcu` performed `hasOwnProperty` checks with string
literals (`'currentCaseLViewIndex'` and `'tView'`). Under Closure Compiler
property renaming optimizations, these properties are minified but the
string literals are not, causing property lookups and type discriminations
to fail.

This commit defines closure-safe property constants using
`getClosureSafeProperty` so the property names are renamed consistently.
2026-08-10 15:35:38 -07:00
Angular Robot b95f9e2691 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-08-10 08:57:16 -07:00
Kristiyan Kostadinov 565dbb2fe5 fix(core): incorrect loop in defer blocks
Fixes that we were running a `for in` loop on an array and silently doing the wrong thing.

Fixes #70113.
2026-08-07 16:35:03 -07:00
Ady Elouej 107f6fa49d fix(compiler): remove namespaced MathML script elements
Treat MathML-namespaced script elements as scripts during template preprocessing. This prevents scripts nested in MathML HTML integration points from surviving template compilation.
2026-08-07 16:32:57 -07:00
SkyZeroZx 4631a6e479 refactor(forms): modernize Signal Forms tests
replace change detection calls with whenStable for async tests
2026-08-07 16:22:59 -07:00