Bind spyOn explicitly to Window so Jasmine uses the DOM setTimeout signature that returns a number instead of the Node.js Timeout type. Remove the unsafe any cast and the obsolete TODO.
If a directive has an input declared as `dismissible = input<boolean>(true, {transform: booleanAttribute});` then the following templates were not compiling:
```
<div directiveName dismissible="true"></div>
<div directiveName dismissible></div>
```
This commit fixes the issue, without breaking contravariant consumers.
The NAMED_FORMATS and DATE_FORMATS caches were plain objects read with a
truthy check keyed by a token from the format string, so a token matching
an inherited Object member (e.g. `__proto__`) resolved to a prototype
value. Create both caches with a null prototype so only real entries are
returned.
Native text `<input type="text">` controls do not support `null` values.
When a Signal Forms model bound to a text input is set to `null`, the value
is silently coerced to an empty string.
Updates the template parser to detect and ignore processing instruction syntax (e.g. `<? foo ?>` or `<? foo >`). Currently it is being printed out as text.
Fixes#34371.
Move the DebugSignalGraph, DebugSignalGraphEdge, and DebugSignalGraphNode interfaces from packages/core/src/render3/util/signal_debug.ts into the packages/core/primitives/devtools/src package. This decouples the signal graph debug types from runtime render3 utilities and allows devtools and internal core tooling to import them directly from primitives as type-only exports.
Replace the lazy quantifier (.+?) with a negated character class
([^\s*]+) that excludes whitespace and asterisks. Source map URLs
never contain these characters, so the fix is semantically
equivalent while eliminating the O(n²) backtracking path triggered
by unclosed /*# sourceMappingURL= fragments.
Fixes: polynomial ReDoS in addBaseHrefToCssSourceMap
When `HttpClient` is called from within an `effect()` or other reactive
context, any signal reads performed inside HTTP interceptors were
inadvertently tracked by that context. This caused the effect to
re-execute whenever those signals changed, regardless of whether the
signal was semantically related to the HTTP call.
The fix wraps the interceptor chain invocation in `untracked()` so that
signal reads inside interceptors — both functional (`withInterceptors`)
and class-based (`withInterceptorsFromDi`) — are invisible to the
calling reactive context. This matches the precedent set by the resource
API, which also wraps its loader in `untracked()` for the same reason.
Fixes#58682
TypeScript reuses SourceFile objects between old and new programs, so untagging the old program also untags shared files in the new program. Re-apply shim tags on the new program to prevent getSemanticDiagnostics() crashes with TS 5.5+.
Remove the obsolete @types/babel__core dependency from packages/compiler-cli and packages/localize. This dependency is no longer needed as Babel v8 ships with its own built-in TypeScript definitions.
In the WebMCP specification, tools are unregistered by aborting the `AbortSignal` provided in `registerTool(tool, {signal})`. The deprecated `unregisterTool` method on `ModelContext` is no longer needed or part of the standard, and is now removed from the TypeScript interface definition.
`translate()` looked up substitutions with `message.substitutions.hasOwnProperty(placeholder)`. A message whose placeholder is named `hasOwnProperty` stores that key on the plain substitutions object, shadowing the method, so the lookup calls the substitution value and throws a TypeError. Use `Object.hasOwn` instead, which resolves through `Object` and is unaffected by the shadowed key, matching the recent `I18nSelectPipe` fix.
Use controlValue() instead of value() when synchronizing
ControlValueAccessor instances.
When debounce is active, value() can still contain the
previous model value while controlValue() reflects the
latest user-entered value. This prevents stale values
from being written back to the CVA before the debounce
is flushed.
Adds a regression test covering the debounce scenario.
This is a follow-up to #67997, which allowed explicit read generics with input transforms, such as `input<boolean>(false, {transform: booleanAttribute})`.
That fixed the declaration, but static template attributes like `dismissible="true"` and bare `dismissible` were still checked as strings against the read type. Allow the fallback write type to include static attribute strings so these template forms compile.
Add a dedicated error reference page for NG05703 (suspicious URL origin
change during SSR) and update the error to use RuntimeError with a
negative code so the error message automatically includes a link to the
docs page in both dev and production builds.
Update affected tests in url_spec.ts, platform_location_spec.ts, and
integration_spec.ts to match the new NG05703-prefixed error message
format.
Fixes: #69667
Even if we have an `EmptyExpr`, add that expression to the expressions array when a literal is parsed.
The lack of the expression results in a discrepancy in the sizes of the `elements` and the `expressions`
arrays of a `TemplateLiteral`, that result in an error when we visit that same literal due to the missing
expression.
Fixes#69699
loadTranslations stores parsed translations into the shared global
$localize.TRANSLATIONS keyed by message id. Those ids come verbatim from
the translations map (typically parsed from a translation file), so a
translation whose id is __proto__ assigns through the inherited __proto__
setter, reparenting the map rather than storing the entry (and throwing
under --disable-proto=throw). Create the map with Object.create(null) in
loadTranslations and clearTranslations so __proto__ is an ordinary key.
When a parent form element defines an async validator, its resource's `params` function needs to evaluate `syncValid()`, which causes unvisited child form nodes to be lazily instantiated. If any of these lazily instantiated child nodes also define an async validator, their resource is initialized while the parent's `params` function is still evaluating. This incorrectly triggers Angular core's `NG0992` guard (`Cannot create a resource inside the params of another resource`).
This commit exports `ɵsetInParamsFunction` and `ɵisInParamsFunction` from `@angular/core` and uses them in `FieldMetadataState.runMetadataCreateLifecycle` to explicitly detach the lazy creation of form metadata from the parent's reactive `params` context.
fixes#69620
Prepend generated view scope variables to `view.create` in addition to
`view.update` so that expressions evaluated during creation (such as
foreign component property bindings) can resolve context variables from
parent views when nested inside control flow blocks (`@if`, `@switch`,
`@for`). This is necessary to support binding properties to foreign
components inside control flow blocks.
reflect this broader behavior.)
PR Close#69674
When a control flow block (`@if`, `@switch`, `@for`) contains a single
root element that is a foreign component, do not treat its name as a tag
name for the template container (`conditionalCreate`, `repeaterCreate`).
PR Close#69674
Adds build-time validation to catch broken, stale, or miscased internal documentation links in both JSDoc and markdown, including `/api/` and `/guide/` URLs and their fragments. Updates the documentation pipeline to share the canonical route manifest, ensuring that all references are checked against the current navigation structure.
Transform assumed `.required` functions always take options as the first argument.
This is true for `input` and `model`, but not for `viewChild` and `contentChild`,
which take the same arguments as non-required versions.
Change the code to put options for signal queries in the right position,
causing debugName to be correctly generated for signal queries.
Extract the AI tool definition interfaces from the core debug module to the devtools primitives module. This relocates ToolDefinition, ToolGroup, and DevtoolsToolDiscoveryEvent to the primitives folder, exposing them cleanly via "export type" in the devtools entry point, improving module organization and readability.
`parseQueryParam` and the AngularJS-compat `parseKeyValue` accumulate query params into a plain object and check key presence with `obj.hasOwnProperty`, so a `hasOwnProperty` query key clobbers the method and the next lookup throws `TypeError`. Switch both to `Object.hasOwn`, which can't be shadowed by a query key.
Replaces the `node.keySpan.toString().startsWith('attr.')` string allocation in the `suffixNotSupported` extended template check with an O(1) `node.type === BindingType.Attribute` enum comparison.
The diagnostic message string is also extracted to a module-level constant so it is created once at module load time instead of on every diagnostic emit.
Additionally, this change adds missing test coverage for the `.%` and `.em` suffixes, as well as for a plain `attr.` binding without a style suffix.
Measured with a 100-iteration microbenchmark before and after the change (MacBook Pro 2018, Intel CPU):
```ts
const start = performance.now();
for (let i = 0; i < 100; i++) {
new ExtendedTemplateCheckerImpl(templateTypeChecker, program.getTypeChecker(),
[suffixNotSupportedFactory], {}).getDiagnosticsForComponent(component);
}
console.log((performance.now() - start) / 100, 'ms/iter');
```
Before: `~0.24 ms/iter`
After: `~0.14 ms/iter` (~40% faster)
Extend the interpolated signal extended diagnostic to inspect ternary-bound expressions and report uninvoked signal reads in bound bindings.
```
<div [style.width]="width() ? 1 : width"></div>
```
where the false branch should invoke the signal as `width()`.
Three small, behavior-neutral cleanups to maybeRemoveStaleArrayFields:
1. Avoid allocating an empty Set when prevData.byTrackingKey is
undefined. new Set(undefined) previously created an unused empty
Set on every call for parents with no tracking keys.
2. Guard the per-element tracking-key check on `oldTracking` being
defined, skipping the isObject/hasOwn check entirely when there's
nothing to track.
3. Replace childValue.hasOwnProperty(identitySymbol) with
Object.hasOwn(childValue, identitySymbol). hasOwnProperty throws
on null-prototype array elements (Object.create(null)), which
would crash computeChildrenMap. Object.hasOwn is null-prototype-safe
and preserves "own property" semantics (does not match inherited
identitySymbol values).
4. Replace `data.byTrackingKey?.delete(id)` with
`data.byTrackingKey!.delete(id)`. The optional chaining was dead:
if oldTracking.size > 0, prevData.byTrackingKey (and therefore
data.byTrackingKey, same Map reference via the spread) is always
defined. The `?.` masked this invariant; `!` documents it and
would surface a runtime error instead of a silent no-op if the
invariant is ever violated.
Verified via performance.mark/measure instrumented directly inside
the function (count=1 call for a single-field edit in both cases).
Total duration dropped from ~0.7ms to ~0.1ms, consistent with the
avoided Set allocation in (1) and (2).
Remove `isIterable` from `util/iterable.ts` and
`newTrustedFunctionForDev` from `util/security/trusted_types.ts`
as they are no longer referenced anywhere in the codebase.
Previously, extracting foreign component imports relied on the partial
evaluator and semantic import resolution to locate declaration
references across files. This resolver-based approach is incompatible
with isolated declarations and local compilation, where cross-file type
information and full semantic resolution are unavailable.
Replace the resolver-based foreign import evaluation with a lightweight,
AST-based extraction mechanism (`extractForeignImportsFromAst`). This
allows the compiler to extract foreign component names and raw AST
expressions directly from syntax trees during the analysis phase without
requiring full type checking.
Additionally, simplify the `ForeignComponentMeta` interface by removing
the obsolete reference property and implement granular AST diagnostics
that provide actionable error messages and usage examples when invalid
expressions are passed to `foreignImports`.
Adds a reference page for `NG05200`, thrown by `DomSanitizer` when a value is bound to a `<script>` element without being marked trusted via `bypassSecurityTrustScript`. Covers why Angular rejects script content outright, how to reproduce the error, the escape hatch, and the XSS caveat.
When a parent form element defines an async validator, its resource's `params`
function needs to evaluate `syncValid()`, which causes unvisited child form
nodes to be lazily instantiated. If any of these lazily instantiated child
nodes also define an async validator, their resource is initialized while the
parent's `params` function is still evaluating. This incorrectly triggers
Angular core's `NG0992` guard (`Cannot create a resource inside the params
of another resource`).
This commit exports `ɵsetInParamsFunction` and `ɵisInParamsFunction` from
`@angular/core` and uses them in `FieldMetadataState.runMetadataCreateLifecycle`
to explicitly detach the lazy creation of form metadata from the parent's reactive
`params` context.