Commit graph

14453 commits

Author SHA1 Message Date
arturovt
bb0061ba63 refactor(core): wrap operationsCounter calls with ngDevMode checks
Wrap operationsCounter method calls (recordCreate, recordDestroy, reset)
with ngDevMode guards to ensure they are tree-shaken in production builds.

This aligns with the existing pattern where operationsCounter is only
initialized in development mode, and eliminates unnecessary method call
overhead in production.

The optional chaining (?.) is retained as TypeScript doesn't narrow types
based on ngDevMode checks, but the entire expression will be removed during
production builds.

(cherry picked from commit 80dbd74ae8)
2025-12-09 10:38:44 -08:00
Matthieu Riegler
ffad78360f refactor(core): add dedicated deprecated signatures for providedIn: any / NgModule.
Those were deprecated by #47616 back in v15.

fixes #65923

(cherry picked from commit 8199945637)
2025-12-09 10:38:14 -08:00
Miles Malerba
f254ff4f2e feat(forms): expose element on signal forms Field directive
This allows for easier focusing of the relevant element based on the
`field` property of a `ValidationError`

(cherry picked from commit aff8b248b3)
2025-12-09 09:47:56 -08:00
Kristiyan Kostadinov
f901cc9eb3 perf(compiler): chain query creation instructions
We always emit the query creation instructions in a group which makes them good candidates for chaining.

(cherry picked from commit ae1c0dc490)
2025-12-09 09:24:41 -08:00
Miles Malerba
5880fbc73c feat(forms): redo the signal forms metadata API
This PR makes a number of changes to the metadata API to address design
flaws in the previous API. Some of the changes include:

- Replaces the previous `MetadataKey` and `AggregateMetadataKey` with a
  single unified `MetadataKey` that is used for all metadata.
- The new `MetadataKey` is only defined for fields that explicitly set
  it in their schema logic
- All metadata now has reducer / aggregate behavior
- The new `MetadataKey` has an option to create a managed key which
  wraps the result of its computed aggregate into some other structure
  such as a `Resource` or `linkedSignal`
- There are now two APIs to create metadata keys
  - `createMetadataKey` for pure computed metadata
  - `createManagedMetadataKey` for metadata that manages its computation
    internally

(cherry picked from commit ebc5c2b083)
2025-12-09 09:21:45 -08:00
Joey Perrott
53f752e7a3 build: update repository to use node 22.21.1 in bazel
The repository was updated to use node 22.21.1 via nvm, but bazel had not been updated to match

(cherry picked from commit 349133374f)
2025-12-09 09:19:19 -08:00
cexbrayat
55fc677cef fix(forms): add signals for dirty, hidden, and pending states in custom controls
FormUiControl states that hidden, pending and dirty will be bind in custom controls, but this is currently not the case.

Fixes #65575

(cherry picked from commit 9fe9566581)
2025-12-08 10:30:48 -08:00
Anuj Chhajed
288238abef refactor(core): correct all typeof ngDevMode comparison patterns introduced by #63875
This change replaces all remaining occurrences of `typeof ngDevMode !== undefined`
with the correct `typeof ngDevMode !== 'undefined'` form. This aligns the codebase
with JavaScript typeof semantics and maintains consistency with other Angular code.

(cherry picked from commit 96b79fc393)
2025-12-08 10:30:06 -08:00
Miles Malerba
a4c436a058 refactor: followup cleanup for #65758 fallout
Fixes some issues left behind by recent refactor

(cherry picked from commit efde94a525)
2025-12-08 10:28:04 -08:00
Shuaib Hasan Akib
55709c1de6 refactor(core): use proper type for stringifyTypeFromDebugify parameter
Replace the 'any' type with ClassDebugInfo for the debugInfo parameter in
stringifyTypeFromDebugInfo function. This removes the TODO comment that was
tracking the need for proper typing without creating circular dependencies.

The change improves type safety while avoiding circular imports since
stringify_utils.ts doesn't export anything that definition.ts imports.

(cherry picked from commit 5fd75410a9)
2025-12-08 10:23:21 -08:00
Joey Perrott
ed7db0e0a2 build: update to bazel version 8.4.2
Update bazel to use version 8.4.2

(cherry picked from commit aa92f19307)
2025-12-08 10:22:04 -08:00
Matthieu Riegler
10bdae9098 build: enable angular formatting on all html files
This should also be safe on any html file that isn't an angular template

(cherry picked from commit 9d1d742f1b)
2025-12-08 10:19:50 -08:00
SkyZeroZx
71568e069c docs: add documentation HOST_TAG_NAME
(cherry picked from commit 6f2ef918e3)
2025-12-08 09:08:55 -08:00
SkyZeroZx
56418b108e docs: add documentation for HTTP_TRANSFER_CACHE_ORIGIN_MAP
(cherry picked from commit 7e1e396a00)
2025-12-08 09:00:13 -08:00
Matthieu Riegler
bd4cfc88ef docs(docs-infra): expose VERSION from @angular/upgrade
The missing src was responsible for not exposing the symbols during the doc extraction.

fixes #65916

(cherry picked from commit 81cf319534)
2025-12-08 08:41:40 -08:00
Kirill Cherkashin
7de8558219 refactor(forms): Break logic.ts into separate files
This would make it easier to navigate

(cherry picked from commit 5be33048cc)
2025-12-04 11:33:26 -08:00
Nakul Sharma
d40a517c0f refactor(core): use getComponentDef in stringify_utils
- Use getComponentDef in debugStringifyTypeForError to clean up TODO
- Remove outdated comment from stringify_utils

(cherry picked from commit 0bb8924ab6)
2025-12-04 11:32:17 -08:00
Joey Perrott
c3bd22d10d
build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-04 11:26:14 -08:00
Alex Rickabaugh
bf1c12cd93 fix(forms): memoize reads of child fields in signal forms (#65802)
Previously, navigating a `FieldTree` in signal forms involved reactive reads
of the value of the parent field(s), both directly and via `.childrenMap()`.

This meant that on _any_ change to the value of a field, reactive
notifications would trigger updates of computeds, reruns of effects, etc.
So for example, this effect would run on every change to the form:

```ts
const f = form(signal({data: 'abc', unrelated: 0}));
effect(() => {
  // accessing f.data incurs a dependency on f().value() which changes
  // on every change in the whole form
  console.log(f.data().value());
});
```

This is deeply counterintuitive and troublesome when attempting to write
effect logic, and also results in `computed`s unnecessarily updating.

This change introduces the concept of a "reader" computed, which memoizes
the access of a field at a given key via the reactive graph. With this, the
same `f.data` access above now depends on the `data` reader in `f` only,
which is effectively a constant computed. As a result, the effect only
reruns on changes to `data`'s value, as intended.

PR Close #65802
2025-12-03 12:52:43 -08:00
Alex Rickabaugh
2c12661620 refactor(forms): simplify child field creation (#65802)
Previously, several values were being passed into the creation of
`FieldNodeStructure`s that were only used in the creation of child nodes.
Separately, we also passed a `createChildNode` function which these values
were passed back into.

Instead, this moves the small bit of logic from structure.ts behind the
`createChildNode` callback, which reduces the passing of values back-and-
forth and gives `createChildNode` a much more suitable signature.

PR Close #65802
2025-12-03 12:52:43 -08:00
SkyZeroZx
6b4ab876e8 feat(forms): Allows transforms on FormUiControl signals
Extends the `FormUiControl` interface to allow `InputSignalWithTransform` in addition to `InputSignal` for its properties.

Fixes #65756

(cherry picked from commit 7d1e502345)
2025-12-03 15:13:06 +01:00
Leon Senft
609699ae17 perf(core): tree shake unused dynamic [field] binding instructions (#65599)
Move the instructions used to dynamically bind a `Field` directive to a
form control onto the `Field` itself. This way the instructions are only
retained if the app uses the `Field` directive.

PR Close #65599
2025-12-03 15:10:50 +01:00
Leon Senft
a5dbd4b382 fix(forms): support dynamic [field] bindings (#65599)
Support binding a `Field` directive to a component created dynamically
with `createComponent()`.

Fix #64632

PR Close #65599
2025-12-03 15:10:49 +01:00
Kristiyan Kostadinov
4bb085311e fix(core): unable to inject viewProviders when host directive with providers is present
When registering providers, the DI system assumes that `viewProviders` are registered before plain `providers`. This was reinforced by components always being first in the array of directive matches, only one component being allowed per node and the fact that only components can have `viewProviders`.

This breaks down if there are host directives with `providers` on the component, because they'll execute earlier, throwing off the order of operations.

These changes fix the issue by separating out the resolvers for `viewProviders` and plain `providers` and explicitly running the component's `viewProviders` resolver before any others. This also has the benefit of not attempting to resolve `viewProviders` for directives which are guaranteed not to have them.

Fixes #65724.

(cherry picked from commit 886cf6c452)
2025-12-03 15:09:53 +01:00
Alan Agius
20474d3f0f fix(http): enable XSRF protection for same-origin absolute URLs
Previously, the XSRF interceptor only added the XSRF token to requests with relative URLs.
This commit updates the interceptor to also add the token to requests with absolute URLs, provided they match the current origin.

(cherry picked from commit 0659d11c85)
2025-12-03 12:19:46 +01:00
Kristiyan Kostadinov
1f1856e897 fix(compiler-cli): check that field radio button values are strings
Adds some type checking code which verifies that the bound `value` on a `Field` radio button is a string.

Fixes #65726.

(cherry picked from commit 6773d3b97d)
2025-12-03 12:19:01 +01:00
arturovt
48b89f9fbe fix(router): handle errors from view transition finished promise
This commit adds a `.catch()` handler to `transition.finished` from `document.startViewTransition` to prevent unhandled promise rejections. The finished promise can reject with `TimeoutError` or `InvalidStateError` when transitions fail during or after the animation phase.

Based on the Blink source code, the `finished` promise can reject with:
* `TimeoutError`: "Transition was aborted because of timeout in DOM update"
* `InvalidStateError`: "Transition was aborted because of invalid state"

This may happen when the DOM update phase exceeds the browser's internal timeout threshold.

(cherry picked from commit b74a0693f2)
2025-12-03 12:17:02 +01:00
Andrew Scott
c2a8934d12 Revert "refactor(router): compress synchronous end to router navigation to single operator"
This reverts commit 71362733cf.
2025-12-02 19:13:07 +01:00
Andrew Scott
71362733cf refactor(router): compress synchronous end to router navigation to single operator
The end of the Router navigation is a block of synchronous logic that
can be compressed into a single operator rather than splitting it across
several, making it harder to step through. The only benefit from the
split is automatic unsubscribe/cancellation, which we can replicate
with an additional 'shouldContinue' check before proceeding.

(cherry picked from commit b7d21e209a)
2025-12-02 16:44:06 +01:00
Kristiyan Kostadinov
5a80a48e96 fix(compiler-cli): avoid allocating an object for signals in production mode
Currently when the signal debug name transform sees something like `const foo = signal(0);`, it transforms the signal into `signal(0, {...(ngDevMode ? { debugName: 'foo' } : {})})`. After minification this becomes `signal(0, {})` which will allocate memory for the empty object literal.

These changes rework the logic to produce `signal(0, ...(ngDevMode ? [{ debugName: 'foo' }] : []))` which will be fully tree shaken away to `signal(0)`.

(cherry picked from commit e30e61b789)
2025-12-02 15:06:55 +01:00
Jessica Janiuk
8c3304c766 fix(core): run animation queue in environment injector context
In the case that a component injector is destroyed before the animation
queue runs, the animation queue would fail to run because it was using a
destroyed injector. This commit changes the animation queue to run in the
context of the EnvironmentInjector, which is not destroyed until the app
is destroyed.

fixes: #65628
(cherry picked from commit d8ab83ca82)
2025-12-02 15:05:21 +01:00
Matthieu Riegler
017672f742 refactor(compiler): Generate the controlCreate instruction after the native element has been created
This is necessary to exclude a race condition where the MutationObserver initialized by the instruction fired before the inputs are binded.

fixes #65678

(cherry picked from commit f35b2ef47c)
2025-12-02 12:59:53 +01:00
Matthieu Riegler
8e0df4083d docs(docs-infra): Show examples on function overloads
(cherry picked from commit a784995a98)
2025-12-02 12:13:16 +01:00
Tim Deschryver
efe4b72abb docs: fix documentation link for currentNavigation method
(cherry picked from commit 680de24c3c)
2025-12-02 12:02:28 +01:00
Angular Robot
706d7620e8 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-01 19:36:18 +01:00
SkyZeroZx
b7ccb308b8 docs(docs-infra): Improves symbol linking for Angular Aria selectors
Improves the symbol linking logic to handle Angular component selectors (e.g., ngCombobox). It attempts to convert Angular selector patterns to their corresponding class names, improving navigation to Angular API documentation.

(cherry picked from commit 2d854e01bc)
2025-12-01 18:47:23 +01:00
Alan Agius
78fd159b78 fix(compiler): prevent XSS via SVG animation attributeName and MathML/SVG URLs
This commit implements a security fix to prevent XSS vulnerabilities where SVG animation elements (`<animate>`, `<set>`, etc.) could be used to modify the `href` or `xlink:href` attributes of other elements to `javascript:` URLs.

(cherry picked from commit 1c6b0704fb)
2025-12-01 10:27:00 +01:00
Matthieu Riegler
a4084154f2 refactor(migrations): don't migration the server bootstrapApplicaiton on zoneless apps.
With the change we specifically analyse `boostrapApplication` with a config that uses `mergeApplicationConfig`.

fixes #65408

(cherry picked from commit c1dfd9cde6)
2025-11-26 15:58:57 -05:00
Matthieu Riegler
151616dd7c refactor(core): show error message on signal error
When a signal throws an error on read. The formatter will show the error message.

(cherry picked from commit 5b720aa2eb)
2025-11-26 13:11:10 -05:00
Leon Senft
0ae14cb746 test(core): test bundling of dynamic component creation and bindings
Add test coverage for bundling dynamic component creation API like
`createComponent()` and `inputBinding()`. This will be used to test that
Signal Forms related features for #64632 can be tree-shaken when unused.

(cherry picked from commit add8c41e5b)
2025-11-26 11:57:18 -05:00
Alan Agius
3240d856d9 fix(http): prevent XSRF token leakage to protocol-relative URLs
The XSRF interceptor previously failed to detect protocol-relative URLs (starting with `//`) as absolute URLs. This allowed requests to such URLs to include the XSRF token, potentially leaking it to external domains.

This change updates the interceptor to correctly identify protocol-relative URLs as absolute and exclude them from receiving the XSRF token.

(cherry picked from commit 40790ef980)
2025-11-25 13:47:29 -05:00
Alan Agius
908b5a41a3 refactor: replace getDocument() with inject(DOCUMENT)
This replaces `getDocument()` with `inject(DOCUMENT)` across hydration and transfer state logic.

(cherry picked from commit 400fc82c43)
2025-11-25 13:05:01 -05:00
Kristiyan Kostadinov
6b20adff62 refactor: add mark for signal forms
Adds a mark for signal forms so we can track adoption. Also moves the call for `@let` into `declareLet` since we don't need it to fire as often as in `storeLet`.

(cherry picked from commit c994267f17)
2025-11-25 13:03:46 -05:00
Alan Agius
49ad7c6508 fix(core): use injected DOCUMENT for CSP_NONCE
This ensures that the right document is used and that `CSP_NONCE` can be used in `provideAppInitializer` and `provideEnvironmentInitializer`.

Closes #65624

(cherry picked from commit 3b1fa8235b)
2025-11-25 11:39:23 -05:00
AntonChesnokov
8d3a89a477 fix(compiler-cli): escape angular control flow in jsdoc
Escape @-prefixed template control flow constructs during doc extraction so JSDoc parsing keeps description text intact. Add regression coverage for @for snippets.

(cherry picked from commit 5bfa027d41)
2025-11-25 11:33:29 -05:00
kirjs
e3f5f34732 refactor(forms): Make reset take value
Now you can do form.reset({name: 'cat', age: 4});

(cherry picked from commit dec222d4d7)
2025-11-25 10:51:38 -05:00
Miles Malerba
7d5c7cf99a feat(forms): add DI option for classes on Field directive
Adds a DI configuration option for signal forms that allows the
developer to specify CSS classes that should be automatically added
by the `Field` directive based on the field's status.

(cherry picked from commit c70e246c23)
2025-11-25 10:33:41 -05:00
SkyZeroZx
477df38d17 docs: improve core package API documentation with additional reference links
(cherry picked from commit 67d41e9bcc)
2025-11-25 10:19:39 -05:00
Leon Senft
8acf5d2756 fix(forms): allow dynamic type bindings on signal form controls
The type checker will no longer prohibit binding the Signal Forms `[field]`
directive to an input with a dynamic `[attr.type]` or `[type]` binding.

(cherry picked from commit 3a1eb07c46)
2025-11-25 09:16:01 -05:00
Andrew Scott
0e458c7e12 refactor(core): Remove toggles used for zoneless by default migration
this migration is complete both internally and externally

(cherry picked from commit 51ebe9a4fc)
2025-11-24 16:57:52 -05:00