The `@property` atrule allows users to define custom CSS variables. These changes update the compiler to account for when namespacing variables.
(cherry picked from commit 9b80d4ce9e)
The static `ɵprov` field emitted on `@Injectable()` classes uses `ɵɵInjectableDeclaration<T>`.
When a subclass extends a generic `@Injectable()` base class with contravariant parameters
(such as callback/transformer methods depending on generic type parameters), TypeScript's
static side inheritance check (`typeof Sub extends typeof Super`) fails with `TS2417` because
`ɵɵInjectableDeclaration<Sub>` is not assignable to `ɵɵInjectableDeclaration<Super<any>>`.
Using `any` (`o.DYNAMIC_TYPE`) in `createInjectableType` avoids strict variance checks on
static inheritance for internal Ivy definitions and aligns with other Ivy declaration types.
(cherry picked from commit caeab598c9)
Make the SVG animation security context depend on the tag name instead of the namespace the element was created in. An animation element declared outside an `<svg>` is created in the HTML namespace, but still animates once it ends up inside an SVG subtree, so to and `attributeName` bindings were reaching the DOM unvalidated.
Fixes #70490
(cherry picked from commit 7168bed663)
Foreign components imported via foreignImports and created by the
ɵɵforeignComponent instruction were previously rendered eagerly in the
creation phase (rf & 1) of the template. This restricted which
properties could be passed to foreign component props, as parent-bound
inputs (@Input(), input(), input.required()), properties initialized in
ngOnInit(), and pull-based view queries (viewChild()) were not yet
initialized at creation time.
This change defers foreign component rendering to run as a view effect
during the update pass:
- Update ɵɵforeignComponent in core to schedule component rendering via
createViewEffect (executed in runEffectsInView during refreshView),
executed with setActiveConsumer(null) to prevent reactive context
leakage and destroyed immediately upon first execution.
- Update ɵɵforeignComponent to strictly accept props as a factory function
(() => props) or null.
- Update the compiler template pipeline to wrap foreign component props
in an arrow function closure (() => ({ ... })).
- Hoist creation-time foreign content projection instructions
(ɵɵforeignContent, ɵɵforeignContentFn) into creation-phase variable
declarations before ɵɵforeignComponent so creation-time context is
captured safely.
(cherry picked from commit 34817da735)
The semantics of optional chaining changes when there are extra parenthesis. We need to make sure that we do not introduce some unnecessary ones.
fixes#70143
(cherry picked from commit e9ba39d671)
The regular expressions in `_scopeAnimationRule` expect an `animation` or `animation-name` property to be preceded by whitespace or a semicolon, and its value to end at a semicolon. Minified CSS breaks both assumptions. Inside an at-rule the property follows a `{`, and the last declaration of a block has no trailing semicolon, so the closing `}` lands inside the captured value. The keyframe name is then left unscoped while the `@keyframes` rule itself is renamed, so the animation does nothing in a production build.
Accept `{` as a leading boundary and stop the value at `}`. The prefix is written back unchanged, and a declaration value cannot contain an unescaped `}`.
Fixes#70316
(cherry picked from commit 58b0cb4735)
`findConnectedBlocks` scans siblings after an `@if` to collect connected
`@else`/`@else if` blocks. Whitespace-only text nodes encountered during
the scan were eagerly added to `processedNodes`, marking them as "do not
emit", before confirming whether a connected block actually followed.
By the time `findConnectedBlocks` runs, `WhitespaceVisitor` has already
converted `&ngsp;` (and ` `) into a plain space character, making
them indistinguishable from insignificant whitespace via `.trim().length`.
When the next sibling was a second, unrelated `@if` instead of `@else`,
the scan stopped but the text node was already silently dropped.
Fix by deferring the `processedNodes` insertion into a pending buffer and
only committing those nodes once a connected block is confirmed to follow.
Fixes#55791
(cherry picked from commit 53fc371142)
We keep getting PRs that target single usages of `hasOwnProperty` and we have ~100 of them. These changes aim to address the issue centrally by swapping out all the instances and adding a lint rule against introducing new ones.
(cherry picked from commit 732e505018)
Treat MathML-namespaced script elements as scripts during template preprocessing. This prevents scripts nested in MathML HTML integration points from surviving template compilation.
(cherry picked from commit 107f6fa49d)
Optional chaining was generating expressions with included an extra pair of parenthesis which changed the semantics of the expression and threw an unexpected error from the optional chain non nullable extended diagnostic.
fixes#70085
(cherry picked from commit d7b03f5523)
- r3_factory: use `in` operator instead of `as any` property probing
in isDelegatedFactoryMetadata / isExpressionFactoryMetadata type guards
- r3_deferred_triggers: narrow assignment to
`DeferredBlockTriggers[typeof name]` instead of `as any`
- defer_resolve_targets / reify: drop unnecessary `as any` on
`op.trigger` — `DeferTriggerBase.kind` is present on all union members
- pipe_creation: replace double `as any` with `as {target?: ir.XrefId}`,
and reuse the already-narrowed `slotHandle` variable for the call
- extractor_merger: replace legacy `<any>console` guards with a proper
`typeof console !== 'undefined'` check
(cherry picked from commit 5d76720e06)
Make runtime URL sanitizer selection namespace-aware so SVG and MathML host bindings match the security schema.
Cover SVG href/xlink:href and MathML href host binding cases, including dynamic hostElement resolution.
PR Close#69558
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
Store the trigger kind before each switch and assign the value to `never` in the fallback branch.
This removes the `any` casts and makes the switches exhaustive. Adding a new `DeferTriggerKind` without handling it in either phase now produces a TypeScript compilation error.
Runtime behavior and error messages remain unchanged.
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.
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
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
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 support for namespacing css variables in style properties. Behaves
as you'd expect following the implementation for stylesheets generally.
This change also moves the error message into a util function since we
now need to produce the same error in three places.
PR Close#68846
Using `--global-foo` is now prohibited. We suspect these cases will
likely be typos of `--global--foo` in the future, so we blanket ban them
and direct users to the expected syntax.
PR Close#68846
Adds logic to inject symbols into CSS variables for runtime namespacing.
The runtime now replaces instances of `%NS%` with a namespacing
variable, limiting reach of CSS variables to the current app. An opt-out
syntax of a `--global` prefix allows users to avoid this behavior.
PR Close#68846
Previously I intentionally kept the lexer as generic as possible so that block detection can happen later. However, since #62644 we detect blocks in the lexer so we might as well normalize them there so all the upstream code doesn't have to account for things like whitespace.
Transition parameterless `@content` projection in foreign components
from eager DOM creation to lazy evaluation. Previously, projecting
content into a foreign component eagerly instantiated the embedded view
and created DOM nodes, causing unnecessary resource consumption if the
content was hidden or unmounted.
With this change, runtime content instructions (`ɵɵforeignContent` and
`ɵɵforeignContentFn`) pass lazy producer callbacks directly through the
foreign component's configured `contentAdapter`. View creation and
teardown registration occur lazily when the external framework evaluates
the adapted producer.
`foreignImport` now requires a third argument, `contentAdapter`,
specifying how Angular content producer callbacks are adapted for the
target external framework.
When partial declarations are not preprocessed to AOT by the linker, the `ngDeclareComponent`
call causes them to be compiled ad-hoc. In this mode, NgModule imports in standalone components
would be dropped, deviating from the linker. This commit changes the ad-hoc compilation of
component declarations to pass the NgModule imports along just like the linker does.
Fixes#69451
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.
Previously, the compiler disallowed translation of any attribute starting with 'on' for security reasons. This incorrectly disallowed translation of the 'on' attribute itself, which is not an event handler.
This commit introduces `isPossibleEventHandler` to verify that the property name has a length greater than 2 in addition to starting with 'on'. This allows attributes like 'on' to be translated while still correctly disallowing actual event handlers like 'onerror', 'onclick', etc.
This limit breaks ts-ignore comments when using this for our source->source transform.
Rather than overridding it there, it's just removed here since we don't care about the limit
Apply schema-derived sanitizer resolution to TwoWayProperty ops so native two-way DOM bindings emit the same sanitizer as one-way property bindings.
Add compiler compliance coverage for innerHTML, srcdoc, URL, resource URL, and security-sensitive attribute cases.
Coordinate template lifecycle events between Angular and foreign components to
allow clean teardown of nested Angular views inside a foreign container.
Previously, when Angular content was projected into a foreign component (for
instance, via render props), Angular had no way to receive destruction
notifications from the foreign component. If the foreign component unmounted
or conditionally removed its children, the nested Angular views remained active,
leading to memory leaks and incomplete lifecycle teardowns.
This change introduces the `ON_DESTROY` symbol and a new registration mechanism
(`ForeignOnDestroyFn`) on the `ForeignComponent` interface. The `foreignImport`
helper now takes an additional `onDestroy` callback function where the foreign
component can register to receive Angular's view-destruction callback.
During the creation phase, `ɵɵforeignContentFn` resolves the foreign component
from the constant pool using a new constant pool index and invokes the
`onDestroy` function. This registers a callback that destroys the corresponding
embedded view from the container.
In the compiler, `ForeignComponentOp` is modified to track the target constant
pool index, and `ForeignContentExpr` reification is updated to pass this index
to `ɵɵforeignContentFn`.
Currently, the template pipeline directly emits the raw expression for foreign
component definitions (such as `frameworkImport(MyComponent)`) directly into
the body of the generated template function. If a foreign component is defined
inside a local scope or is non-exported (e.g. nested inside a test block), the
emitted template function may not have access to that variable because
`ɵɵdefineComponent` and its template functions are emitted at the top-level
module scope. This previously caused reference errors during template
compilation.
This commit updates the compilation pipeline to instead ingest foreign
component references into the component's `consts` pool. The
`ɵɵforeignComponent` runtime instruction is updated to accept an index into the
constant pool rather than a raw expression. By routing the references through
the `consts` pool, block-scoped classes and variables are appropriately
captured by `ngtsc` without scoping errors, properly supporting nested/local
foreign component usage.
Previously, foreign component `@content` blocks were rendered eagerly by
Angular and could only project a list of nodes. With this change, `@content`
can be used to declare a function (e.g. `@content(renderItem; let item)`) that
is passed as a callback prop to the foreign component, allowing the foreign
component to invoke it with context arguments at its leisure.
Implementation details:
- Introduces a new runtime instruction `ɵɵforeignContentFn` which wraps the
template function so it can be called on demand with arguments by the foreign
component.
- Extends the compiler AST to parse and validate `@content` parameters.
- Maps `@content` parameters to the corresponding positional arguments of the
calling foreign component function property.
Adds validation to verify that `@content` blocks are only used as direct
children of foreign components.
Specifically:
- Defines a new compile diagnostic code `INVALID_CONTENT_PLACEMENT = 8026`.
- Updates `ForeignComponentFeatureAnalyzer` to traverse content blocks and
report `INVALID_CONTENT_PLACEMENT` diagnostics if they are placed
incorrectly.
- Removes the raw error thrown during ingestion in
`packages/compiler/src/template/pipeline/src/ingest.ts`.
- Adds integration tests in `template_typecheck_spec.ts`.
Add `@content(propName)` blocks for passing template content to foreign
component properties by name. Previously, only a single set of direct children
could be passed to a foreign component via the default `children` property.
With this change, developers can project distinct template content to multiple
specific properties on the foreign component:
```html
<FancyButton [label]="title">
@content(icon) {
<span>Icon</span>
}
@content(description) {
<span>Description text</span>
}
<span>Other children</span>
</FancyButton>
```
Specifically:
- Add support to the HTML lexer for `@content` blocks.
- Introduce `ContentBlock` AST node to represent `@content` blocks.
- Implement validation ensuring `@content` blocks have exactly one parameter
representing a valid JS identifier.
- Throw an error during ingestion if a `@content` block is placed anywhere
other than as a direct child of a foreign component.
- Map `@content` blocks to properties of the props object passed to
`ɵɵforeignComponent`.
- Update compliance and unit tests to cover these changes.
```
Previously, any children nested inside a foreign component were ignored
during template ingestion. With this change, the compiler now:
1. Identifies when a foreign component has children in the template AST.
2. Compiles these children into a separate template view (using the
standard TemplateOp).
3. Passes a `ɵɵforeignContent` expression under the `children` prop
inside the foreign component's `props` object.
At runtime, the new `ɵɵforeignContent(index)` instruction instantiates the
template at the specified slot index in memory (detached from the DOM),
extracts its root DOM nodes, and returns them. These root nodes are then
passed directly to the foreign component's `props.children` so they can
be rendered by the foreign framework.
The instantiated children view is registered in the parent LView's
child tree, ensuring its change detection and destruction are managed
automatically as part of the standard Angular view tree lifecycle.