Host binding sanitization previously used the declaring directive or component selector to choose a compile-time security context. The same host binding can execute on a different concrete element through hostDirectives, inherited host bindings, dynamic directives, or createComponent hostElement usage.
Compute host binding security contexts against possible concrete hosts and defer URL versus ResourceURL selection to runtime when necessary. Resolve dynamic root host TNodes to their native tag before sanitizer and security-sensitive attribute checks.
Fixes angular#69550
PR Close#69558
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.
(cherry picked from commit 0ae6d81ed2)
This reverts commit 9b9b0e93c9.
This broke g3. Not sure yet why it didn't break externally. We can
investigate and fix following this revert.
(cherry picked from commit 1fb4678207)
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.
(cherry picked from commit 9b9b0e93c9)
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.
(cherry picked from commit eb2a8ff63f)
the toSignal function received a debugName option in 0812ac3bec,
but was not covered by the signalMetadataTransform which sets the debugName in dev mode
automatically.
(cherry picked from commit 165995285c)
`parseHostBindings` throws plain `Error`s for malformed host bindings
(e.g. a property binding with a non-static value, as can happen while
editing in the language service). These were uncaught during directive
analysis, crashing the compiler and the Angular Language Service.
Wrap the call and surface the error as a `FatalDiagnosticError` so it
becomes a diagnostic and analysis can complete normally.
Fixes#69106
(cherry picked from commit 8b2785b597)
Adds support for `@Input` transform functions in isolated declarations mode (`emitDeclarationOnly: true`), allowing components and directives to specify `transform` functions without triggering fatal compiler errors.
Synthesizes the `ngAcceptInputType_` write type syntactically:
- For referenced functions (`transform: booleanAttribute`), emits `Parameters<typeof booleanAttribute>[0]`, relying on downstream template type checking to resolve the type.
- For inline functions (`transform: (v: string) => boolean`), extracts `parameters[0].type` directly from the local TypeScript AST.
(cherry picked from commit 86ade07de6)
Removes restrictions around using external references and local directives in `hostDirectives` under isolated declarations mode (`emitDeclarationOnly: true`).
By wrapping the host directive reference in a `WrappedNodeExpr`, TypeScript's declaration emitter seamlessly emits `typeof hostReference.node`, preserving existing imports or local identifiers exactly as authored. Also adds support for translating `PropertyAccessExpression` inside `WrappedNodeExpr` into `QualifiedName` for `.d.ts` emission, ensuring namespace imports (`import * as n from './dir'`) are preserved correctly.
(cherry picked from commit 5d2b1c4100)
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.
(cherry picked from commit 0152e3cbdf)
Ensures that namespaced <script> elements (such as :svg:script) are correctly classified as PreparsedElementType.SCRIPT by the template preparser and stripped during compilation to prevent potential XSS vulnerabilities. Consequently, obsolete security schema mappings and runtime sanitization checks for <script> attributes have been removed since these elements are never present in compiled template outputs.
(cherry picked from commit 90494cd909)
Currently if a `@for` loop doesn't have a `track` expression we don't produce an AST for it at all which means no type checking and language service support for it.
These changes make it so we produce the AST anyways since it gives the user more tools to resolve the issue (e.g. autocompletion when writing the `track` expression).
(cherry picked from commit 06f6dec7aa)
This allows us to show the API docs when the jsdoc block is at the top of a overloaded function (and not on the implementation signature).
eg: `injectAsync`
(cherry picked from commit 7360c1da68)
* Test that `minDate`/`maxDate` binds to `min`/`max` on date and time inputs
* Test that `min`/`max` attribute can be set directly on date and time inputs
* Relax type checker to allow `min`/`max` bindings on date and time inputs
PR Close#68001
This commit updates `@defer` logic related to incremental hydration to be tree-shakable.
If hydrate triggers are used in a `@defer` block, the compiler emits a single top-level call to `ɵɵenableIncrementalHydrationRuntime`, placed once per create block before the first `ɵɵdefer` that requires it.
As a result, the incremental hydration runtime is only included in the bundle when hydrate is explicitly used.
Removes the `checkTwoWayBoundEvents` flag since the code it generates is quite breaking and we never got the chance to enable it. Also it caused our tests to misrepresent how the compiler behaves for actual users.
These changes introduce the new `@Service` decorator which is a more ergonomic alternative to `@Injectable`. The reason we're adding a new decorator is that `@Injectable` has been around since the beginning of Angular and it has a lot of baggage that adds unnecessary overhead for users that generally want to define a singleton service, available in their entire app. The key differences between `@Service` and `@Injectable` are:
1. `@Service` is `providedIn: 'root'` by default. You can opt into providing the service yourself by setting `autoProvided: false` on it.
2. `@Service` doesn't allow constructor-based injection, only the `inject` function.
3. `@Service` doesn't support the complex type signature of `@Injectable` (`useClass`, `useValue` etc.). Instead it supports a single `factory` function.
Example:
```ts
import {Service} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {AuthService} from './auth';
@Service()
export class PostService {
private readonly httpClient = inject(HttpClient);
private readonly authService = inject(AuthService);
getUserPosts() {
return this.httpClient.get('/api/posts/' + this.authService.userId);
}
}
```
The commit updates the TCB for safe navigation expressions to allow for correct narrowing of nullables.
This will trigger the `nullishCoalescingNotNullable` and `optionalChainNotNullable` diagnostics on exisiting projects.
You might want to disable those 2 diagnotiscs in your `tsconfig` temporarily if you want to update your project without having to fix all the issues at once.
Narrowing can be disabled altogether with `strictSafeNavigationTyes: false`.
fixes#37619
BREAKING CHANGE: This change will trigger the `nullishCoalescingNotNullable` and `optionalChainNotNullable` diagnostics on exisiting projects.
You might want to disable those 2 diagnotiscs in your `tsconfig` temporarily.
Fixes an error that was heppning when a generic param has type parameters of its own. There were a few different issues going on:
1. In #67707 I had changed a bit how we pass the `genericContextBehavior` which ended up ignoring the `useContextGenericType` option from the environment.
2. All directives depend on themselves, but we were overridding the `genericContextBehavior` for the directive being processed.
3. The type translator wasn't handling type parameter declarations. Technically we shouldn't be able to hit a code path that has a type parameter, however it's also easy enough to handle so we might as well.
Relates to #67704.
Implements the logic at the compiler level that will de-duplicate host directives and merge them together. It will also report if a conflict is detected during merging.
The default change detection strategy is now OnPush.
BREAKING CHANGE: Component with undefined `changeDetection` property are now `OnPush` by default. Specify `changeDetection: ChangeDetectionStrategy.Eager` to keep the previous behavior.
Add NG8023 extended diagnostic to report duplicate component selectors
during compilation.
This replaces the former NG0300 runtime error, ensuring the failure
occurs at build time instead of runtime.
Closes angular#48377
BREAKING CHANGE: Elements with multiple matching selectors will now throw at compile time.
`<input type="number">` often does not provide the desired user experience when editing numbers in
a form. MDN even [describes](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/number#using_number_inputs)
how text inputs should be used in many cases instead, via `<input type="text" inputmode="numeric">`
or similar configurations. Previously, this did not work with Signal Forms without a custom input
component/directive.
This PR builds support for binding `number|null` models directly to `<input type="text">` native
controls via `[formField]`. When a model has a number or `null` value, signal forms will preserve
that status when the user makes edits/changes. Empty string values are converted to `null`, other
values are parsed as numbers, and a parse error is raised when a non-numeric value is entered.
Note that it's up to the UI developer to configure additional UI affordances such as setting an
appropriate `inputmode`, rejecting non-numeric keypresses, etc.
Fixes#66903Fixes#66157
Fixes a regression caused by the recent TCB changes where we moved the type parameter processing earlier in the pipeline and stopped properly accounting for the `TcbGenericContextBehavior`.
Fixes#67704.
In some cases the `debugName` transform generates a spread into the signal function parameters. This can cause compiler errors, because the functions don't have rest parameters.
These changes work around it by adding a `@ts-ignore` above it.
The Angular compiler unconditionally adds a debug name transform for signals
which generates a conditional on `ngDevMode` (e.g., `ngDevMode ? { debugName: "xyz" } : []`).
During testing, `ngDevMode` is true, so the true branch executes but the
false branch is never executed. Consequently, coverage tools report the
false branch as an untested line/branch, preventing 100% test coverage.
This commit adds a synthetic `/* istanbul ignore next */` comment to the
generated false branch so that Istanbul ignores it. We only include the
istanbul comment (instead of additionally including c8) to focus on the
established standard for Angular CLI/Karma coverage while maintaining
compatibility with modern Vitest setups, since @vitest/coverage-v8 now
natively respects the fallback istanbul comment.
Fixes#64583
inputs & outputs cannot be binded to 2 different directives/components properties
Eg
```
data = model();
dataChange = output(); // throws because model already emits on the `dataChange` output
userSomething = input({alias 'user'});
user = input(); // throws because userSomething already binds to the `user` input
````
fixes#65844
BREAKING CHANGE: The compiler will throw when there a when inputs, outputs or model are binding to the same input/outputs.
Wrap `@defer` trigger expressions (`when`, `prefetch when`, `hydrate when`)
in a conditional context within the TCB to enable TypeScript's TS2774
diagnostic for detecting functions used without invocation.
Previously, signals and functions passed to `when` triggers without
parentheses would silently evaluate to truthy, causing unexpected behavior.
Now the compiler reports an error when a function is used as a condition
without being called.
`FieldTree` was an unnecessarily specific type for the `[formField]`
input. It forced the directive to care about what _kind_ of `FieldTree`
was bound–specifically whether it was Reactive Forms compatible or not.
This made it difficult to author forms system-agnostic components with
passthrough `[formField]` inputs.