Commit Graph

2217 Commits

Author SHA1 Message Date
Kristiyan Kostadinov ccb7d427e4 fix(compiler): type check invalid for loops
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)
2026-05-13 11:26:46 -07:00
Matthew Beck 7dc1017e51 fix(compiler): simplify handling of colon host with a selector list
Update `_convertColonHost` to extract and use only the first argument from a `:host(...)` selector list, ignoring subsequent arguments instead of splitting and duplicating the selector list. Also remove the obsolete test cases from `host_and_host_context_spec.ts`.

(cherry picked from commit 1d3bf59f9a)
2026-05-12 14:25:49 -07:00
Matthew Beck 194f723f66 fix(compiler): remove dedicated support for legacy shadow DOM selectors
Remove `_shadowDOMSelectorsRe` and `_convertShadowDOMSelectors` from `shadow_css.ts` so that `::shadow`, `::content`, `/shadow-deep/`, and `/shadow/` are no longer treated specially or stripped from user CSS. Instead, they are naturally scoped like standard selectors. Also remove the legacy failing test from `shadow_css_spec.ts`.

(cherry picked from commit 6de4955124)
2026-05-12 14:24:32 -07:00
Matthew Beck 4c25a42e98 fix(compiler): remove deprecated shadow CSS encapsulation polyfills
Completely remove support for `polyfill-next-selector`, `polyfill-unscoped-rule`, and `polyfill-rule` from `shadow_css.ts`, along with their associated methods and regular expressions. Also delete `polyfills_spec.ts` entirely.

(cherry picked from commit 23f0898edb)
2026-05-12 14:24:06 -07:00
Matthew Beck 8a1533c9ad fix(compiler): preserve leading commas in animation definitions
Update the regular expression in `_scopeAnimationRule` to prevent absorbing and deleting leading commas after `animation:`. Also remove the corresponding legacy test case from `keyframes_spec.ts`.

(cherry picked from commit 770e505f78)
2026-05-12 14:23:00 -07:00
Matthew Beck c7aef8ec5d fix(compiler): enforce parentheses containing arguments for :host-context
Modify `_colonHostContextRe` and `_hostContextPattern` to strictly process `:host-context` only when parentheses containing at least one non-whitespace argument character are present. Update `_colonHostRe` to explicitly NOT match `:host` when followed by a hyphen. When invoked without parentheses or with empty parentheses, the selector is completely ignored and treated as a standard CSS pseudo-class in the source text. Also update the legacy test case from `host_and_host_context_spec.ts`.

(cherry picked from commit 338bf7d46f)
2026-05-12 14:22:23 -07:00
Matthew Beck 932458c6b5 test: remove invalid css that was causing issues with the postcss parser
These tests happened to use garbage "{c}" declaration lists which caused
the parser to choke. Given that we already have tests demonstrating
similar behavior and that's not what these tests were meant to
demonstrate, I've updated them to use empty declaration lists.

(cherry picked from commit b1699da827)
2026-05-07 15:20:21 -07:00
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
Alan Agius b8d3f36ed9 feat(compiler-cli): add support for Node.js 26.0.0
Updates the supported Node.js engine versions to include Node.js 26.

This allows running the CLI on Node.js 26.0.0 and above while continuing to support active LTS versions.
2026-05-06 09:55:38 -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