Decouple `SymbolBuilder` from the full `BoundTarget` interface by introducing a purpose-built `SymbolBoundTarget` interface containing only the 4 methods required for symbol resolution. This eliminates the need for the large, pass-through `BoundTargetAdapter` and further isolates `SymbolBuilder` from compiler-internal implementation details.
Also minimize `TypeCheckableDirectiveMetaAdapter` by redefining `SymbolDirectiveMeta` to not extend `DirectiveMeta`, exposing only the properties actually used by `SymbolBuilder`.
Removed dead code `getDirectiveMeta` in `template_symbol_builder.ts` which was unused.
These changes improve maintainability and ensure a cleaner architecture by strictly defining the boundaries of what `SymbolBuilder` needs from the rest of the system.
By limiting the required inputs to only what's necessary for the implementation, we make it easier to re-use
the implementation between different compiler architectures
Since WebKit commit 67a62d98 (merged for iOS 13), WebKit no longer restricts
click event bubbling to interactable nodes like `div` or `body`. The
`cursor: pointer` hack polyfill is therefore obsolete and can safely be
removed without breaking JSAction behavior.
(cherry picked from commit a24179e125)
removing ts.typechecker in a prior refactor caused some regressions, particularly when multiple directives
appear on a single elemnt. this is now addressed by using an id for directives and storing that in the tcb comment
(cherry picked from commit 30c950f133)
This updates the SymbolBuilder to no longer use ts.TypeChecker internally to
build symbols for the language service. These lookups are deferred/done later
using the newly expanded template type checker API.
Moves the `ClassPropertyMapping` into the compiler, rather than having to pass around the limited `InputOutputPropertySet` interface that is only implemented by `ClassPropertyMapping`.
Simplify the hydration regression test by removing conditional early-return branches and relying on direct Jasmine expectations while keeping strict typing and OnPush configuration.
(cherry picked from commit 77f1ca08e4)
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.
(cherry picked from commit ab061a7610)
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.
(cherry picked from commit 2ce0e98f79)
The `HttpClient` tests in `client_spec.ts` were failing intermittently in Node/Domino environment because `MockPlatformLocation` defaults to `http://_empty_/`. This valid URL satisfied the URL parser in `xsrfInterceptorFn`, causing it to proceed to cookie extraction which throws `NotYetImplemented` in Domino.
To fix this:
1. Disabled XSRF protection in `client_spec.ts` using `withNoXsrfProtection()`, as these tests are not for XSRF.
2. Provided `ɵprovideFakePlatformNavigation` to remove state leakage effects and ensure consistency.
(cherry picked from commit 1ef503e18e)
The test was using a brittle fixed timeout of 10ms to wait for change detection to run in Zoneless mode. This failed in CI sometimes presumably because CI can execute slower based on resource constraints. This commit replaces it with a polling approach which checks until the expected content is rendered.
(cherry picked from commit 4a174b89c8)
This test appears to be flakey in CI, presumably because resource constrained environments can run unexpected slower and exceed the timeout. This switches to a polling approach, waiting for the queue to drain.
(cherry picked from commit b4a3abd095)
Document that FormArray.value includes only enabled child controls when the array is enabled, but includes all child values when the FormArray itself is disabled.
Fixes#67759
(cherry picked from commit 789c2cd9fb)
This commit addresses review comments from AndrewKushnir regarding conditional formatting of error messages and updating tests.
(cherry picked from commit 30f63fc1c2)
This adds a bit more context to the NG0750 error message to provide details about which module failed to load when executing the dependencyResolverFn. This can help with debugging a failed lazy load in a defer block.
(cherry picked from commit 8218d2e34a)
Previously, the Language Service fetched Quick Info and definitions for template variables (such as `@let` declarations) using mapping to their `initializerLocation` (the right-hand side expression). This aggressively bubbled the type, JSDoc, and definition identity of the initializer backwards onto the variable itself.
This approach had two flaws:
1. It broke type narrowing because the LS read the original un-narrowed type from the source expression rather than the type of the narrowed intermediate variable in the Type Check Block.
2. It deviated from native TypeScript semantics, where a local `let` binding (`let address = hero.address`) does not inherit the docstrings or `(property)` kind of its initializer, acting solely as a local inferred variable.
By using `localVarLocation` rather than `initializerLocation` for LetDeclaration Quick Info and Type Definitions, these intermediate variables now properly preserve type narrowing within templates and flawlessly match the standard behavior expected of TypeScript block variables. `VariableSymbol.initializerLocation` is retained solely to map the value spans of structural directive contexts (e.g., `exportAs` strings).
fixes#65491
(cherry picked from commit 75ac120493)
The `split` helper function in `packages/router/src/utils/config_matching.ts` was blind to the current outlet being processed. When encountering an empty path named outlet in the config, it would assume it needed to pull it in as a synthetic empty group, even if we were already in the process of resolving that very outlet!
When navigating to `/(secondary:component-copy)` with this config:
```typescript
{
path: '',
component: MainLayout,
children: [
{ path: '', outlet: 'secondary', component: SecondaryComponent, children: [{path: 'component-copy'}] }
]
}
```
The router uses `MainLayout` as a pass-through and calls `split` on its children with segments `['component-copy']`.
`split` uses the `containsEmptyPathMatchesWithNamedOutlets` helper to determine if there are any candidate empty path named outlets to pull in. Because of this, it sees `{ path: '', outlet: 'secondary' }` and says: "Ah, an empty path named outlet! I must pull it in!"
Rather than falling through to standard segment matching, it returns `UrlSegmentGroup(segments: [], children: {secondary: emptyGroup})`.
The router then tries to process `primary` (with `[]` segments) and fails because the config only has `secondary`. It also tries to process `secondary` with the `emptyGroup`. While `{ path: '', outlet: 'secondary' }` matches the empty group, its child `{ path: 'component-copy' }` fails to match because the `emptyGroup` has no segments! So both branches fail, resulting in a `NoMatch` error for the entire navigation!
Pulling in empty path named outlets IS desired when they act as siblings to segments we are matching. This has worked before and continues to work!
```typescript
{
path: 'a',
children: [
{ path: 'b', component: ComponentB },
{ path: '', component: ComponentC, outlet: 'aux' }
]
}
```
When navigating to `a/b`, `split` sees segments `['b']` and the `aux` empty path. It pulls in `aux` so it gets instantiated alongside `b`. This is correct!
If we have a named outlet with a non-empty path under an empty path parent:
```typescript
{
path: '',
component: MainLayout,
children: [
{ path: 'component-copy', outlet: 'secondary', component: ComponentE }
]
}
```
When we navigate to `/(secondary:component-copy)`:
- `split` uses `containsEmptyPathMatchesWithNamedOutlets` to see if there are any empty path named outlets. Since it only sees `path: 'component-copy'`, it returns `false`.
- It falls through to standard segment matching, which finds `component-copy` in the segments array and activates it flawlessly!
This worked perfectly before the fix because it didn't use `containsEmptyPathMatchesWithNamedOutlets`.
The fix passes the **current active outlet context** into `split`. If `split` finds an empty path named outlet that matches the outlet we are already processing, it ignores it as a pull-in candidate.
When evaluating `MainLayout` children for `secondary`:
- URL Segments left to process: `['component-copy']`
- Current Outlet: `secondary`
- `childConfig`: `[{ path: '', outlet: 'secondary' }]`
Previously, `split` saw the empty path and pulled it in as a synthetic empty group, breaking matching. Now, since `getOutlet(r) === outlet` (both are `secondary`), the fix ignores it. Instead of returning empty segments, it **falls through to standard segment matching**, which successfully find the `component-copy` segment!
When evaluating `ComponentA` children for `primary`:
- URL Segments left to process: `['b']`
- Current Outlet: `primary`
- `childConfig`: `[{ path: 'b' }, { path: '', outlet: 'aux' }]`
Since `getOutlet(aux) !== primary`, the fix **does not ignore it**. `split` pulls in `aux: emptyGroup` as a sibling, instantiating `ComponentC` alongside `ComponentB`. This preserves correct behavior for auxiliary outlets!
fixes#67708
(cherry picked from commit daa9b2a9d6)
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
Previously, the `data` attribute of the `<object>` tag was being sanitized as a regular URL instead of a `ResourceURL`, which is security-sensitive.
This commit updates the runtime sanitization logic to correctly identify `object[data]` as a `ResourceURL` context. Additionally, the sanitizer lookup logic has been refactored to use a more efficient lookup map (`RESOURCE_MAP`) instead of multiple `Set` lookups, providing better performance and maintainability.
Added tests to verify the correct sanitization of `object[data]` and its behavior with trusted values.
PR Close#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
Avoid substring matching on importClause.getText() which caused suffix collisions (e.g., BarComponent vs FooBarComponent). Use AST-based matching for default and named (including aliased) imports to reliably resolve the correct import path when generating loadComponent.
(cherry picked from commit 8fa6617352)
The `pending` getter in `AbstractControl` used loose equality (`==`)
while all other status getters (`valid`, `invalid`, `disabled`) use
strict equality (`===`). Both sides are strings so behavior is
identical, but this inconsistency would fail strict linting rules.
(cherry picked from commit ef7679b7a5)
The `localize-translate` CLI tool uses the `locale` field from translation files to expand the `{{LOCALE}}` placeholder in the output directory. It failed to sanitize `locale` input, allowing malicious translations to write files outside of the configured output directory.
This change mitigates this issue by combining.
Closes#67906
(cherry picked from commit 7871093822)
Replaced testing constructions of `Date` objects from `formatDate` tests from plain ISO strings over to 'new Date(year, month, date)'.
Instantiating 'new Date("2024-01-01")' parses the string strictly as UTC midnight ("2024-01-01T00:00:00.000Z"). When local operations execute (such as calculating `getThursdayThisIsoWeek` boundaries), the UTC date shifts relative to the executing machine's timezone. For example, in PST (GMT-8), that date translates exactly to 'December 31st 16:00:00', pushing week boundaries backwards.
By wrapping date constructs explicitly as 'new Date(2024, 0, 1)', it natively guarantees local midnight execution and prevents boundaries shifting on global CI Remote Build Execution (RBE) workers.
Example (from a machine in PST):
```javascript
> new Date('2024-01-01')
Sun Dec 31 2023 16:00:00 GMT-0800 (Pacific Standard Time)
> new Date(2024, 0, 1)
Mon Jan 01 2024 00:00:00 GMT-0800 (Pacific Standard Time)
```
(cherry picked from commit 61ee183fa7)
Removes the 'America/New_York' timezone string test case from `formatDate` tests because the underlying `Date.parse` API does not support IANA timezone strings. This caused the timezone calculation to silently fall back to the local executing machine's timezone, leading to non-deterministic test flakiness on Remote Build Execution (RBE) workers operating in varying geographic locations.
(cherry picked from commit a1385ad977)
Move the domino bundling logic and related shims into a centralized third_party directory within packages/platform-server. This avoids duplication of the bundling logic and ensures consistent shimming across the platform-server package and its entry points.
Following a conversation with OSS licensing, this change also includes the domino LICENSE file in the generated npm package to comply with licensing requirements for bundled third-party code.
```
├── fesm2022
│ ├── init.mjs
│ ├── init.mjs.map
│ ├── platform-server.mjs
│ ├── platform-server.mjs.map
│ ├── _server-chunk.mjs
│ ├── _server-chunk.mjs.map
│ ├── testing.mjs
│ └── testing.mjs.map
├── LICENSE
├── package.json
├── README.md
├── third_party
│ └── domino
│ ├── bundled-domino.d.ts
│ ├── bundled-domino.mjs
│ ├── bundled-domino.mjs.map
│ └── LICENSE
└── types
├── init.d.ts
├── platform-server.d.ts
└── testing.d.ts
```
(cherry picked from commit b40d11eec4)
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.
(cherry picked from commit 5a712d42d1)
PATCH PR for #67765
This fixes a regression bug that resulted in reordered elements not getting properly removed from the DOM. Reused nodes were not being cleared out in this situation.
fixes: #67728
prevents browsers from re-fetch image during DOM teardown
when using `sizes="auto"` with lazy loading.
Fixes angular#67055
(cherry picked from commit c1312da183)
Fix inject migration in multi-project workspace. The inject migration doesn't work when targeting one of the projects due to either not finding any files in other projects or considering them external thus it throws a SchematicsException
Fixes: #66074
(cherry picked from commit a73b4b7c30)