Commit graph

1957 commits

Author SHA1 Message Date
Alan Agius
6f525245cd fix(core): disallow event attribute bindings in host bindings unconditionally
Moves the event attribute validation check outside of `ngDevMode` in the `elementAttributeInternal` instruction to ensure that bindings to event attributes like `on*` are always blocked at runtime.

(cherry picked from commit 5b421c61cd)
2026-05-07 15:19:27 -07:00
Leon Senft
1f30aacbe5 refactor(forms): bind formatted date string to min/max for minDate/maxDate (#68001)
* 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
2026-05-06 11:59:18 -07:00
Kristiyan Kostadinov
b225a5d902 fix(compiler): invalid type checking code if field name needs to be quoted
Fixes that we were producing invalid TypeScript if an input with an unsafe name (e.g. `aria-label`) is coerced.
2026-05-05 09:34:26 -07:00
Kristiyan Kostadinov
39806360da refactor(compiler): add utility to check if property name needs to be quoted
Consolidates the places where we check if a property name should be quoted so we can reuse the logic.
2026-05-05 09:34:26 -07:00
SkyZeroZx
11721509b0 refactor(core): Makes @defer(hydrate ...) runtime tree-shakable
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.
2026-05-01 15:54:55 -07:00
Alex Rickabaugh
a4145dea06 Revert "fix(language-service): Add support for @Input with transforms"
This reverts commit dc9c72da9b. Reason: breaking
targets in g3.
2026-05-01 11:05:56 -07:00
Matthieu Riegler
dc9c72da9b fix(language-service): Add support for @Input with transforms
Prior to this change @Input with transforms were not linked by language service and you couldn't navigate on it.
2026-04-30 15:51:48 -07:00
Matthieu Riegler
37ec63e745 refactor(compiler): introduce default constant for legacyOptionalChaining flag
This will help patch the value in G3 to help land this change.
2026-04-29 10:01:13 -07:00
Matthieu Riegler
2896c93cc1
feat(compiler): Angular expressions with optional chaining returns undefined
To mitigate this breaking change,  this behavior can be disabled by wrapping expressions with the `$null` magic function.
: `$null(foo?.bar?.baz)`
2026-04-28 15:26:53 -07:00
Kristiyan Kostadinov
72be5be9c1 refactor(compiler-cli): remove checkTwoWayBoundEvents flag
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.
2026-04-28 10:31:42 -07:00
Kristiyan Kostadinov
6bd1721662 fix(compiler): let declaration span not including end character
Fixes that the span for `@let` declarations didn't include the end token.
2026-04-27 17:09:14 -07:00
SkyZeroZx
70c011e879 refactor(compiler): Removes unused compiler utility functions
Remove helper functions and constants across the compiler, as they are no longer required by current logic.
2026-04-27 17:00:44 -07:00
Kristiyan Kostadinov
8f3d0b9d97 feat(core): introduce @Service decorator
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);
  }
}
```
2026-04-22 11:01:01 -07:00
Kristiyan Kostadinov
7fa274510f refactor(compiler): move TCB generation logic into compiler
Moves the logic for generating type check blocks into the compiler since it isn't coupled to TypeScript anymore.

Note: the tests haven't been moved over, because they depend on the environment that's currently in `compiler-cli` and it still has some dependencies on TypeScript.
2026-04-15 19:43:29 +03:00
Matthew Beck
2c5aabb9da fix(compiler): don't escape dollar sign in literal expression
Removes the escape for `$` in literal expressions. I don't think this is
required with our output.
2026-04-10 09:23:50 +03:00
Kristiyan Kostadinov
2ce0e98f79 fix(compiler): handle nested brackets in host object bindings
Fixes that we were parsing bindings in the `host` object with a regex that didn't account for nested brackets which may come up with something like Tailwind.

Fixes #68039.
2026-04-06 13:21:50 -07:00
Andrew Scott
0a7f4ddf93 refactor: export symbols for external use
export symbols for sharing in environments outside of angular monorepo
2026-04-06 13:16:19 -07:00
Kristiyan Kostadinov
57432f1b6a refactor(compiler-cli): merge duplicate directive matches and report conflicts
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.
2026-04-03 09:44:39 -07:00
Kristiyan Kostadinov
22f9ee1be6 refactor(compiler): require a reference in DirectiveMeta
Requires the `DirectiveMeta` to have a `ref` so that we can find duplicates easily.
2026-04-03 09:44:39 -07:00
Kristiyan Kostadinov
d15ceff617 refactor(compiler-cli): move ClassPropertyMapping into compiler
Moves the `ClassPropertyMapping` into the compiler, rather than having to pass around the limited `InputOutputPropertySet` interface that is only implemented by `ClassPropertyMapping`.
2026-04-03 09:44:39 -07:00
Kristiyan Kostadinov
927ae3abc8 refactor(compiler): move matchSource into base metadata
Moves the `matchSource` into the base metadata so the binder can use it.
2026-04-03 09:44:39 -07:00
Alan Agius
e84e35cdd6 fix(core): prevent binding unsafe attributes on SVG animation elements (#67797)
SVG animation elements (`animate` and `set`) can be used to animate sensitive attributes like `href` or `xlink:href`. Binding to these animation attributes (like `to`, `from`, or `values`) with a sensitive target creates an XSS vector.

This change mitigates this risk by:
1. Classifying `to`, `from`, and `values` on `<animate>` and `<set>` elements as `ATTRIBUTE_NO_BINDING` in the DOM security schema to prevent standard dynamic bindings.
2. Adding runtime validations in `ɵɵvalidateAttribute` to verify that `attributeName` is not a sensitive attribute (such as `href` or `xlink:href`) when processed by a set of `SECURITY_SENSITIVE_ATTRIBUTE_NAMES`. If it is, a runtime error `UNSAFE_ATTRIBUTE_BINDING` is thrown.
3. Adding regression tests in `integration_spec.ts` to ensure unsafe bindings throw an error while safe ones pass correctly.

PR Close #67797
2026-04-01 11:43:58 +02:00
Alan Agius
08d36599d7 fix(compiler): register SVG animation attributes in URL security context (#67797)
This change is a security hardening measure to prevent potentially unsafe attribute value manipulation through SVG animations. By mapping `animate|to`, `animate|from`, `animate|values`, and `set|to` to the `SecurityContext.URL`,  Angular will now automatically sanitize these attributes.

PR Close #67797
2026-04-01 11:43:58 +02:00
Matthieu Riegler
eae8f7e30b feat(core): Set default Component changeDetection strategy to OnPush
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.
2026-03-24 16:25:02 -07:00
Matthieu Riegler
8bc31a515f feat(core): Allow other expression for exhaustive typechecking
When the switched expression is nested within a union, exhaustive typechecking needs to know which expression to check.
This change adds the possibility of specifying the expression to check:

```
@Component({
  selector: 'app-root',
  imports: [],
  template: `
    @switch (state.mode) {
      @case ('show') { {{ state.menu }}; }
      @case ('hide') {}
      @default never(state);
    }
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
  state!: { mode: 'hide' } | { mode: 'show'; menu: number };;
}
```

fixes #67406
2026-03-24 14:42:28 -07:00
Kristiyan Kostadinov
96be4f429b fix(compiler): abstract emitter producing incorrect code for dynamic imports
Fixes that the abstract emitter wasn't adding quotes around the URL of a dynamic import.
2026-03-20 15:18:29 -07:00
Matt Lewis
5a712d42d1 fix(compiler): prevent shimCssText from adding extra blank lines per CSS comment
The comment placeholder restoration in `shimCssText` appended an unconditional
`+ '\n'` to each non-hash comment replacement. Because `_commentRe` does not
consume the newline that follows a comment in the source, that newline already
remains in `cssText`. The extra `'\n'` was therefore inserted on top of the
existing one, shifting every line after each comment down by one. In files with
many comments (e.g. large SCSS preambles) this shifts all subsequent CSS rules
far enough that the CSS sourcemap — generated before `shimCssText` runs —
points to completely wrong source locations in browser DevTools.

The fix is to drop the `+ '\n'`; internal newlines within a multi-line comment
are still preserved via `_newLinesRe`, and the trailing newline that follows the
comment in `cssText` is already present without any extra injection.
2026-03-20 15:17:31 -07:00
Matthieu Riegler
e850643b1b feat(compiler): Support comments in html element.
```
      <div
        // comment 0
        /* comment 1 */
        attr1="value1"
        /*
           comment 2
           spanning multiple lines
        */
        attr2="value2"
      ></div>
```
2026-03-19 15:25:17 -07:00
Kristiyan Kostadinov
468874d6e0 refactor(compiler): emit types from abstract emitter
Adds an opt-in flag to emit type information through the base abstract emitter.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov
a946e26850 refactor(compiler): move more logic into abstract emitter
Moves the logic for constructing more AST nodes into the `AbstractEmitterVisitor` so it's easier to implement.

Also cleans up the visitor a bit.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov
71cee58e89 refactor(compiler): add opt out for printing comments
Allows for consumers of the `AbstractEmitterVisitor` to determine whether comments should be printed.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov
a3fb4a5f70 refactor(compiler): clean up unused parameter
Cleans up the `escapeDollarInStrings` parameter in various places since it isn't passed anywhere.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov
c457b9b5b4 refactor(compiler): add ts-ignore comment on factory functions
Adds a `ts-ignore` comment to thew instantiation expressions in factories, because in some compilation modes we can't guarantee that they'll compile.
2026-03-18 14:05:18 -06:00
yogeshwaran-c
75560ce43d fix(compiler): parse named HTML entities containing digits
The lexer's isNamedEntityEnd function stopped scanning entity names
when encountering a digit character, causing 24 valid HTML named
entities with digits in their names (e.g. &sup1;, &frac12;, &blk34;)
to be treated as plain text instead of decoded to their corresponding
Unicode characters.

Fixes #51323
2026-03-17 13:54:41 -06:00
Alex Rickabaugh
c4ce3f345f feat(forms): template & reactive support for FVC
Implement support for `FormUiComponent`s in both Reactive and Template-driven
forms. This allows components that use the new signal-based form control
architecture to be used seamlessly within existing Angular form paradigms.

Key changes:
- Integrated `ɵngControlCreate` and `ɵngControlUpdate` lifecycle hooks into
  `NgModel`, `FormControlDirective`, and `FormControlName`.
- Implemented branching logic to choose between the traditional `ControlValueAccessor` (CVA) path and the new FVC path based on the host element's capabilities.
- Added comprehensive unit tests for FVC integration in both Reactive (`reactive_fvc.spec.ts`) and Template-driven (`template_fvc.spec.ts`) forms, covering:
    - Value synchronization (model -> view and view -> model).
    - Status synchronization (touched, dirty, valid, invalid, pending, required).
    - Error propagation and `parseErrors` support.
    - Fallback behavior to native DOM properties (disabled, required) when FVC inputs are missing.
    - Graceful fallback to CVA when no FVC pattern is detected.
- Refined `NgModel` to correctly handle `required` validation via its existing `RequiredValidator` directive while supporting FVC for other properties.
2026-03-17 13:18:26 -06:00
Alex Rickabaugh
5fe0b6d269 refactor(compiler): match control instruction on attributes
Previously we were only adding the `ɵɵcontrol` instruction on property bindings. This commit
fixes that bug by adding matching on attributes as well.
2026-03-17 13:18:26 -06:00
Kristiyan Kostadinov
4154e7db70 refactor(compiler): add ts-ignore in pipeline
Adds `@ts-ignore` comments to same places in the pipeline where we can't produce code that passes all type checks.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
40c0f53d8b refactor(compiler): add type annotations to generated code
Adds explicit type annotations to the generated code so it's able to compile.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
4b80227efa refactor(compiler): allow leading comments on expressions
Updates the output AST to allow leading comments to be attached to expression nodes.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
d99ab0e040 fix(compiler): stop generating unused field
Fixes that the compiler was generating an `attrs` field on the definition which isn't used anywhere.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
412788fac9 fix(compiler): ensure generated code compiles
Initial pass to make sure some common cases produce code that compiles.
2026-03-13 11:13:03 -06:00
Kristiyan Kostadinov
78dea55351 fix(compiler): disallow translations of iframe src
Fixes that the compiler was allowing translations of `src` attributes in iframes which can be a security issue.
2026-03-12 11:01:26 -06:00
Andrew Scott
72a17afaf3 fix(compiler): prevent mutation of children array in RecursiveVisitor
RecursiveVisitor.visitIfBlockBranch was permanently mutating the children array by pushing the expressionAlias into it. This change clones the array before pushing to avoid this side effect.
2026-03-04 14:41:32 -08:00
SkyZeroZx
98eb24cea0 feat(core): Support optional timeout for idle deferred triggers
Allows specifying a timeout parameter for idle-based deferred triggers, enabling more granular control over when deferred actions are executed.

Closes angular#67187
2026-03-04 07:57:30 -08:00
Matthieu Riegler
786ef8261f fix(compiler): throw on invalid in expressions
`{{in}}` are not interpreted as `'in'` string expressions anymore.

```
<input #in /> // OK
{{in}} // throws
```

fixes #65244

BREAKING CHANGE: `in` variables will throw in template expressions.
2026-02-23 13:35:07 -08:00
Matthieu Riegler
488d962bc7 fix(compiler): Don't bind inputs/outputs for data- attributes
This is to improve consistency and match developer expectations. This syntax was already deprecated a long time ago.
If you want to bind a data attribute, use the `attr.` prefix (which was already supported).

BREAKING CHANGE: data prefixed attribute no-longer bind inputs nor outputs.

fixes #26406
2026-02-23 13:23:58 -08:00
Matthieu Riegler
95b3f37d4a feat(compiler): Exhaustive checks for switch blocks
`@switch` blocks can now enable exhaustive typechecking by adding `@default(never);` at the end of a `@switch` block.
2026-02-17 10:25:31 -08:00
Kristiyan Kostadinov
9c5658adb1 refactor(compiler): clean up pipeline compatibility distinction
Removes the switch for compatibility mode from the template pipeline since we never got around to removing it and at this point it causes a bunch of runtime errors.
2026-02-17 08:30:04 -08:00
Matthieu Riegler
6e0d783e5b refactor(compiler): Add info about unclosed element.
We chose to throw 2 errors here because we can't assume the intention of the developer and the span we target are different.

fixes #57032
2026-02-13 09:41:37 -08:00
Matthew Beck
06d94ac0ca Revert "refactor(compiler): Add info about unclosed element."
This reverts commit 097208454b.
2026-02-12 09:30:57 -08:00