This stamping is interfering with publishing to the Firefox addons store by brining in the entirety of the `.git` directory as part of the source code necessary for a reproducible build, which Firefox requires as part of it's approval process.
In it's place, we are now using the extension version pulled from the manifest.
PR Close#55694
Related to #51131, this change ensures that the router navigation exits
the current event loop before rendering the route when the view transition
feature is enabled, when the browser does not support view transitions.
PR Close#55327
Prior to this change, `NgZone` was provided by default in TestBed in a
location that would override anything configured in
`TestBed.initTestEnvironment`. This change moves the default `NgZone`
provider to the `RootScopeModule` and these providers can be overridden
by the ones in `additionalModuleTypes`, which are assigned from the
first argument of `initTestEnvironment`. This makes it possible to
configure Zone globally for all tests as opposed to needing to repeat it
in `configureTestingModule` of each suite.
PR Close#55226
Previously, multiline selectors were being converted into single lines, resulting in sourcemap disruptions due to shifts in line numbers.
Closes#55508
PR Close#55509
Closure compiler optimizations in g3 require `.then` to be present for a dynamic import (or an import should be `await`ed) to detect the set of imported symbols. Currently, the `.then` is located at a later stage in the file, which confuses static code analysis. This change adds the `.then((m) => m)` workaround to satisfy Closure compiler constraints.
PR Close#55686
This commit addresses a warning in Renovate regarding a deprecated behavior that will be phased out in the future.
```
WARNING: To prevent future issues, replace the usage of matchPackagePatterns with matchDepPatterns (repository=angular/angular, baseBranch=main)
"packageRule": {
"matchPackagePatterns": ["^@bazel/.*", "^build_bazel.*"],
"groupName": "bazel setup",
"schedule": ["at any time"]
},
"packageName": "bazelbuild/rules_nodejs",
"depName": "build_bazel_rules_nodejs"
```
PR Close#55683
This commit removes the 'stopUpdatingLabel' option from Renovate settings. This option caused pull requests to not automatically rebase when conflicting.
PR Close#55683
This commit addresses dependency injection defects when using the `withFetch` API. Formerly, utilizing `withFetch` led to the automatic setting of `HttpBackend` to `FetchBackend`, which proved problematic in certain scenarios. Notably, conflicts arose when integrating `withRequestsMadeViaParent` and manually overriding tokens, as observed in instances like `InMemoryWebApiModule`.
PR Close#55652
This commit handles two cases that were breaking applications when using the new migration:
- tests using `HttpClientModule` in `TestBed.configureTestingModule` were broken as the import was removed, but the module is still present in the test configuration. It now properly adds `provideHttpClient(withInterceptorsFromDi())` and related imports to the test.
- tests using `HttpClientTestingModule` were migrated to use `provideHttpClient(withInterceptorsFromDi())` but the necessary imports were not added. They are now added by the migration.
PR Close#55640
This will allow a multi-app application to listen to early events from different elements and place them
on a separate field on the window.
PR Close#55586
Prior to this change, MathML element were created with the wrong namespace resulting in regular DOM `Element`.
This commit fixes this.
Related to #55608 (but doesn't fix it entirely).
PR Close#55622
This commit updates the list of Node.js `fs` APIs to be patched because
they haven't been updated for a long time. It adds `opendir,lutimes,writev`.
For example, the `opendir` method was added to Node.js in version 12.12.0 in
2019, causing some of the APIs to potentially be always called within the
`<root>` context.
**Note:** There are missing unit tests for these changes because in unit tests,
`fs` is patched by Bazel's Node.js rules and its `node_patches.cjs`. However,
the APIs are successfully patched in the real production code and are called
with the correct context.
PR Close#54396
This key comes from the release build of the Chrome extension. Setting it here configures the extension ID of a local build to match the extension ID of the public release. This makes Chrome recognize that local builds are the same extension leading to more intuitive behavior. It's also useful for allowlists of extension IDs to keep the local ID consistent.
PR Close#55639
Rather than attempting to use the native timing functions, this commit
simplifies the logic significantly by using the global timer functions
as they are, either patched or unpatched. When Zone is defined, we run
the timers in the root zone. This has more predictable behavior and
timing than (a) using both patched and unpatched versions of timers in
different places (b) trying to get an unpatched timer and failing due to
environment specifics and patches that aren't ZoneJS.
PR Close#55366
This commit removes the `@developerPreview` annotation from the `@defer` APIs, effectively promoting them (and the entire feature!) to stable.
PR Close#55625
All usages in google3 have been deleted so this should be a no-op. Next I'll clean up all the configurations turning this off and then delete the option entirely.
PR Close#55598
Fixes that we didn't have the MathML elements in the schema. Note that we can't discover which tag names are available by looking at globally-available classes, because all MathML elements are `MathMLElement` rather than something like `SVGCircleElement`. As such, I ended up having to hardcode the currently-available tags.
Fixes#55608.
PR Close#55631
This also adds a test to make sure that the event contract is still listening to other events, especially in the case where we may want partial hydration in the future.
PR Close#55549
This reverts commit 7e89753eef.
Running render hooks inside the zone is specifically problematic for
`afterRender` hooks. If the callback has async task, it would cause an
infinite change detection. In addition, updating state in render hooks
is generally discourages and certainly should update state in a way that
notifies Angular of the change (either via signal or with `markForCheck`) rather
than relying on ZoneJS to pick it up (which would only work if the
change is done inside an async task).
PR Close#55624
This commit fixes an error in the looping logic of `ApplicationRef.tick`
when the tick skips straight to render hooks. In this case, if a render
hook makes a state update that requires a view refresh, we would never
actually refresh the view and just loop until we hit the loop limit.
PR Close#55623
Currently we add global extra imports to all the files in the compilation unit. However not all the files need extra imports. For example non-Angular files definitely do not need such extra imports, and in some cases these extra imports causes problems as the file is meant to be run the Node but it has Angular dependencies which are not compatible with Node. This change tries to limit extra import generation to a subset of files. Wit hthis change we create extra imports only for the files that contain at least one component whose NgModule is in a different file. This is because all other files do not need extra imports since they are either not Angular files or they already have all the imports that the components need.
PR Close#55548
Fixes that even though we weren't rendering the deferred block the server, we were still triggering the timeout which can delay the response.
Fixes#55475.
PR Close#55605
This define has been removed at head, and now legacy stop propagation
behavior can be opted into at the LegacyDispatcher level, if necessary.
PR Close#55582
This commit ensures we flush animations by calling renderFactory
begin/end in cases where the ApplicationRef._tick happens in a mode that
skips straight to the render hooks.
PR Close#55564
These lines were not tree shakable by Closure Compiler because `.toString()` is special cased as a "pure" function eligible to eliminated if it's return value is unused. However `.toString.call` circumvents this and makes Closure Compiler think the function may have side effects. Switching to `.toString()` should be fine here as `process.toString()` in Node outputs `[object process]` so this should be safe. Presumably the original motivation for this roundabout approach was for type safety reasons which no longer apply as `_global` is `any`.
PR Close#55412
The docs-viewer loads asynchronously and can happen after the scroll
event has happened and the Router has attempted to scroll to the
requested position/anchor. This commit saves the scroll event and
handles it again if the cards are loaded after scrolling happens.
PR Close#55566
Currently whenever a compliance test case TS file is modified, all
compliance tests in repository are rebuilt in partial compilation mode.
This is inefficient and also slows down local development where one may
use a wildcard to run all test targets inside `/test/compliance/...`.
This commit fixes this.
PR Close#55594
This commit adds detailed description for the errors NG0955 and NG0956.
Those errors correspond to the check introduced in the built-in for loop.
PR Close#55591
Using `setTimeout` to delay scrolling can result in scrolling in the
next frame and cause noticeable flicker. This commit scrolls as soon as
the next render happens (or in `setTimeout` if a render does not happen
before then).
fixes#53985
PR Close#55105
The caveat here is that this needs to be done before creating the
fixture. There are some technical issues to overcome with disabling it
after it was already enabled, related to detaching from `ApplicationRef`
without other side effects.
PR Close#55494
Fixes several issues with the `HttpClient` migration that showed up after I tried updating the Material docs site to the latest v18 release. Includes:
* The migration was assuming that all Angular decorators have at least one argument. This led to a null pointer error that broke the v18 update process when I was testing it.
* The migration incorrectly reimplemented the detection of classes with Angular decorators. This can cause code to be migrated incorrectly and doesn't handle cases like import aliases. I've switched it to use the existing tooling for detecting decorated classes.
* The migration was trying to migrate directives, even though they don't support the `imports` field.
* The migration was detecting `TestBed.configureTestingModule` calls using a raw string match which is very fragile and can be broken by the user's formatting.
* There were syntax errors in the unit tests.
* There were type checking errors in the unit tests, for example none of them were importing the Angular decorators that they were migrating.
There's more room for improvement, but this should resolve the most glaring issues without having to rewrite too much.
PR Close#55557
In some cases the height of the viewport wasn't calculated correctly because of extension tabs quirks. This commit fixes this issue.
Fixes#53704
PR Close#54912
This commit prevents doubling change detections when the zoneless
scheduler is notified first, followed by the zone becomeing unstable
(effectively "scheduling" zone-based change detection). When run
coalescing is enabled, this would otherwise result in the zoneless
scheduler running change detection first and then change detection
running again because of the run coalescing since both scheduler use the
same timing function (and then it would be FIFO).
PR Close#55403
In Angular today, a bound listener automatically marks the view for
check. When using ZoneJS, these listeners are most often executed in the
Angular Zone as well, so synchronization (`ApplicationRef.tick`) will
eventually happen. _However_, developers can opt out of zone-patching
for events in several ways, and often do this for very frequent
listeners like `mousemove`, `resize`, and `scroll`. We do not want to
break existing expectations that these are now "safe" events to have
listeners for by automatically scheduling change detection regardless of
whether the listener executed inside or outside the Angular zone.
In contrast, in order for developers to more easily transition to zoneless,
we need to be able to ensure that components which are using `OnPush`
are, for the most part, compatible with zoneless as well. Because listeners
automatically mark the component for check, developers using `OnPush`
did not/do not need to also call `ChangeDetectorRef.markForCheck` or a
similar API. Unfortunately, this means that we need to consider the
listener callbacks as a notification to schedule a `tick` when Zoneless
is enabled. In the future, we would like to have an opt-out for this
(i.e. signal components) since it's not really how we _want_ things to work.
Also includes the fix for #54919 that got reverted only because it was
easier to revert the set of conflicting commits
PR Close#55525
This commit modifies the setup of the injector profiler to occur solely when the application is running in a browser context. This adjustment is made because the injector profile serves no purpose when the application is running on the server.
PR Close#55530
The timing of render hook execution is almost entirely identical to
`ngZone.onMicrotaskEmpty`. Developers working towards zoneless
compatibility will need to migrate `onMicrotaskEmpty` calls to use
`afterNextRender`/`afterRender` instead. This, however, would lead to
confusing issues if there are promises in the callbacks because
`onMicrotaskEmpty` emits inside the Angular zone while render hooks
execute outside today. This is problematic because it's not documented
and does not produce any notification or error message when async work
is done inside the hooks that requires change detection. Instead, change detection
simply does not run, and this behavior has proven to be surprising to
developers who are used to ZoneJS change detection behavior.
fixes#55299
PR Close#55399
Currently fallback content for `ng-content` gets declared and rendered out in one go. This breaks down if multiple instances of the same component are used where one doesn't render the fallback content while the other one does, because the `TNode` for the content has to be created during the first creation pass.
These changes resolve the issue by always _declaring_ the template, but only rendering it if the slot is empty.
Fixes#55466.
PR Close#55478
This PR sets a default state for cookie consent of 'denied'. The other part of the PR exists in the angular/dev-infra repo which will grant permission when the user accepts the cookie banner.
PR Close#54574
The ExperimentalPendingTasks service was accidently exposing one of its
internal fields as a public one. This commit fixes this by marking the
field in question as private.
PR Close#55516
In Angular today, a bound listener automatically marks the view for
check. When using ZoneJS, these listeners are most often executed in the
Angular Zone as well, so synchronization (`ApplicationRef.tick`) will
eventually happen. _However_, developers can opt out of zone-patching
for events in several ways, and often do this for very frequent
listeners like `mousemove`, `resize`, and `scroll`. We do not want to
break existing expectations that these are now "safe" events to have
listeners for by automatically scheduling change detection regardless of
whether the listener executed inside or outside the Angular zone.
In contrast, in order for developers to more easily transition to zoneless,
we need to be able to ensure that components which are using `OnPush`
are, for the most part, compatible with zoneless as well. Because listeners
automatically mark the component for check, developers using `OnPush`
did not/do not need to also call `ChangeDetectorRef.markForCheck` or a
similar API. Unfortunately, this means that we need to consider the
listener callbacks as a notification to schedule a `tick` when Zoneless
is enabled. In the future, we would like to have an opt-out for this
(i.e. signal components) since it's not really how we _want_ things to work.
PR Close#55492
The new ExperimentalPendingTasks API lets developers to add and remove
tasks that control applications stability: a pending task prevents
application from being stable.
This API is important for all the use-cases that depend on the concept
of stability and SSR serialization is a notable example.
Closes#53381
PR Close#55487
This change ensures that `ApplicationRef.tick` flushes animations by
calling `rendererFactory2.end`. This might not have happened before if
there were no views that needed to be refreshed.
This is also likely to fix a potential regression caused by #53718 even
in zone apps where animations don't get flushed when no views attached
to ApplicationRef are dirty.
PR Close#55132
This commit fixes an issue where event contract init script was injected into the page before the inlined event dispatch script. That resulted in runtime exceptions, since event contract relies on some code being present on a page already.
PR Close#55502
This commit updates the logic to take into account a situation when Event Replay feature is enabled (using `withEventReplay()` method), but there were no events configured in an application. In this case, there is no need to setup an event dispatcher and trigger event replay.
PR Close#55502
This commit updates Terser config to disable property renaming for the event delegation script (that we later inline into the HTML during SSR). The problem is that event dispatcher relies on some functions on the EventContract class to have original names after after minification, we loose an ability to call those functions.
PR Close#55502
This will enable refactoring existing usages of the Dispatcher that use
APIs that we do not intend to support, like registerGlobalHandler and
registerEventInfoHandlers to use the LegacyDispatcher.
PR Close#55372
When a formControlName is used without a parent formGroup, an error is
logged in the console. Before this commit, there was no information
about which control had the issue. Now, it's reported and the
troubleshoot is much faster.
PR Close#55397
The `DeferBlockFixture.render` function should not await the
`whenStable` promise of the fixture. This does not allow developers to
test any intermediate states that might occur between rendering the
initial content and the full app stability.
fixes#55235
PR Close#55271
Remove the `async` function in favor of using `waitForAsync` instead.
BREAKING CHANGE: `async` has been removed, use `waitForAsync` instead.
PR Close#55491
The previous example had an incomplete code snippet that would not work if copied and pasted as is. There were two missing closing parentheses, one for the `inject` function, and the other for the `waitForAsync` function.
PR Close#55407
Adds a check that disables the timer scheduling for `placeholder` and `loading` blocks on the server since the underlying timer will delay the server response.
Fixes#55475.
PR Close#55480
BREAKING CHANGE: Deprecated `StateKey`, `TransferState` and `makeStateKey` have been removed from `@angular/platform-browser`, use the same APIs from `@angular/core`.
PR Close#55474
Mozilla requires add-ons to have reproducible builds and this is managed directly by human reviewers and need to understand how to build Angular DevTools correctly. This commit defines a reproducible way of building Angular DevTools which is useful for reviewers and contributers.
The actual changes I made include:
1. Moving local development content into `devtools/README` (deleting `devtools/DEVELOPING.md`) and explicitly stating the Node version as well as global Yarn install to be clear about the correct way to build the extension. This should make it easier for reviewers to understand and reproduce builds.
2. Moving release instructions to a separate doc to reduce noise as well as making some minor clean ups there.
I briefly considered pointing reviewers at a new `devtools/docs/reviewers.md` doc, but decided against it because I want these instructions to be maintained in a single location where contributors and reviewers use the same content. This way any changes don't miss one of these sets of users. If reviewers have trouble with this format (dev builds isn't useful to reviewers and some content is repeated from other docs for contributors) then we can consider splitting out to a separate `reviewers.md` file. But until then, I'd like to try sharing this content and see how it works out in practice.
PR Close#55406
Partial revert of #54891. Webcontainers do not support node ^18.19.1 which is required by the v18 CLI.
Until this is solved by the stackblitz team, we're stucked with v17 based tutorials
PR Close#55437
Ahead of delegating the i18n subsystem to the `Intl` API, this commit introduce the intention to remove those functions from the public API.
DEPRECATED: `getCurrencySymbol`, `getLocaleCurrencyCode`, `getLocaleCurrencyName`, `getLocaleCurrencySymbol`, `getLocaleDateFormat`, `getLocaleDateTimeFormat`, `getLocaleDayNames`, `getLocaleDayPeriods`, `getLocaleDirection`, `getLocaleEraNames`, `getLocaleExtraDayPeriodRules`, `getLocaleExtraDayPeriods`, `getLocaleFirstDayOfWeek`, `getLocaleId`, `getLocaleMonthNames`, `getLocaleNumberFormat`, `getLocaleNumberSymbol`, `getLocalePluralCase`, `getLocaleTimeFormat`, `getLocaleWeekEndRange`, `getNumberOfCurrencyDigits`
PR Close#54483
This migration will allow developers to migrate the deprecated `HttpClientModule`, `HttpClientJsonpModule` & `HttpClientXsrfModule` to their respective provider functions.
PR Close#54020
This commit deprecates the `HttpClientModule` and other related http modules. Those can be replaced by provider function only.
Angular is an opinionated framework, feature guidance will help developer choose the recommended way to enable feature (like Http requests here).
Note: This is not an indication of deprecation for `NgModule`. The deprecated module's only purpose here was to define providers. This can be done directly by the provide function pattern.
DEPRECATED: `HttpClientModule`, `HttpClientXsrfModule` and `HttpClientJsonpModule`
As mentionned, those modules can be replaced by provider function only.
PR Close#54020
The change in the index is to allow the framework to add a type to the object that is passed from the contract to the dispatcher. ie
registerDispatcher(contract, (eventInfo: EventInfoWrapper) => ...).
The latter is to return the event contract so that tests can clean it up.
PR Close#55411
`RouterOutlet` uses a unique injector logic that returns a value that correspond to the `ActivatedRoute` token dynamically. This logic breaks when a component/directive/pipe that injects the `ActivatedRoute` is located within a `@defer` block, because defer creates an `EnvironmentInjector` instance, which doesn't have that dynamic logic.
We've added some special handling of the `OutletInjector` in one of the previous commits, but it was incomplete and it was not covering cases when different routes use the same component. This commit updates defer logic to re-establish this dynamic behavior for `ActivatedRoute` by creating an instance of the `OutletInjector` when a parent injector was also an instance of `OutletInjector`.
This fix is a short-term solution and longer term we should find a way to achieve the dynamic behavior that Router relies on, but without adding a special case logic into defer.
Resolves#54864.
PR Close#55374
Removes the warning about performance from the directive composition API docs since some recent benchmarks have snown that their effect is negligible.
PR Close#55448
This breaks renovate
```
### ⚠ Artifact update problem
Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.
♻ Renovate will retry this branch, including artifacts, only when one of the following happens:
- any of the package files in this branch needs updating, or
- the branch becomes conflicted, or
- you click the rebase/retry checkbox if found above, or
- you rename this PR's title to start with "rebase!" to trigger it manually
The artifact failure details are included below:
##### File name: packages/zone.js/test/typings/yarn.lock
```
error Package "zone.js" refers to a non-existing file '"/tmp/renovate/repos/github/angular/angular/dist/bin/packages/zone.js/npm_package"'.
```
PR Close#55433
PR #51670 removed the usage of `const enum`. As a consequence HttpStatusCode that were previously inlined now pull and retains the (fairly large) `HttpStatusCode` enum.
By intermediate constants, we prevent the framework from pulling this big enum by default.
PR Close#55434
JSAction script is inlined into the HTML by the build process to avoid extra blocking request. The script looks like this:
```
<script type="text/javascript" id="ng-event-dispatch-contract">...</script>
```
This commit updates the logic to remove JSAction if event replay feature is disabled or if there are no events to replay.
PR Close#55428
Expose `HTTP_TRANSFER_CACHE_ORIGIN_MAP` injection token in public api. This is useful when different origins are used to access the same APIs between server and browser.
Fixes#53702
PR Close#55274
Angular DevTools depends on many modern Angular features in order to function. As a result, at present the last officially supported version is v12. Angular DevTools may function for some Angular 9, 10 and 11 applications, but they are not officially supported.
This commit fixes an issue where DevTools would not inject a backend script into an Angular application if it detected it was below version 12. This backend script is important because it's used to inform the DevTools panel that the inspected application is in fact Angular, but that it is not on a supported version.
Angular 9, 10 and 11 applications that successfully have Angular DevTools initialize will now have a red highlight and tooltip on their version number, informing the user that they are using Angular DevTools on a version of Angular that is no longer supported.
Angular DevTools for applications that are below version 9 will continue to display the "Angular Devtools supports Angular versions 12 and above" message.
PR Close#55233
This commit introduces a check plus an associated warning for situations where
the combination of the collection change and the tracking expression resulted
in the entire view structure managed by @for to be re-created.
The check uses the following conditions before raising a warning:
- the entire collection was re-created and there were no other operations (ex.: move);
- views in a collection are considered "expensive" to re-create;
- a developer is using tracking by identity.
The last condition tries to capture cases where changes to immutable data
collections can cause significent performance and / or corectness problems.
Note that this warning might be "overreacting" and report cases where
the collection re-creation is the intended behavior. Still, the assumption is that
most of the time it is undesired.
PR Close#55314
This commit fixes an error in a previous commit which attempted to read
`data` from the first item in the apply args array, even if it was not
defined.
PR Close#55465
This commit removes of migrations introduced in version 17, along with the relocation of a migration from 17.3 to version 18. This ensures that this is ran for users who may have updated from one minor to another without executing `ng update`
PR Close#55391
Angular only checks the contents of template nodes in full type checking mode. After v17, the new control flow always had its body checked, even in basic mode, which started revealing compilation errors for apps that were using the schematic to automatically switch to the new syntax.
These changes mimic the old behavior by not checking the bodies of `if`, `switch` and `for` blocks in basic mode. Note that the expressions of the blocks are still going to be checked.
Fixes#52969.
PR Close#55360
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
This commit adds helpful stack information for the case when change
detection continues to be triggered in the event loop and would cause
the browser to freeze.
PR Close#55231
There is an existing pattern that zone-based applications use to avoid
`ExpressionChangedAfterItHasBeenCheckedError` which is also used in
`NgModel`: update the state in a microtask instead of doing it
synchronously. This defers the state update to another round of change
detection, and with ZoneJS, also still executes in the same event loop.
These types of changes across multiple rounds of change detection were
still executed before the browser paint.
This update allows the `NgModel` workaround to continue working in
Zoneless. This may not be permanent and is certainly still not
advisable. Render hooks (`afterNextRender`/`afterRender`) will execute between these
rounds of change detection when they are intended to be run after all
DOM updates completed.
PR Close#55231
This update modifies the transfer cache logic to prevent caching of HTTP requests that require authorization. To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`
BREAKING CHANGE: By default we now prevent caching of HTTP requests that require authorization . To opt-out from this behaviour use the `includeRequestsWithAuthHeaders` option in `withHttpTransferCache`.
Example:
```ts
withHttpTransferCache({
includeRequestsWithAuthHeaders: true,
})
```
Closes: #54745
PR Close#55034
This commit adds the ability to return `RedirectCommand` from the error
handler provided by `withNavigationErrorHandler`. This will prevent the
error from being surfaced in the `events` observable of the Router and
instead convert the error to a redirect. This allows developers to
have more control over how the Router handles navigation errors. There
are some cases when the application _does not_ want the URL to be reset
when an error occurs.
resolves#42915
PR Close#55370
This commit ensures we correctly handle the exit from the zone.run in
the zoneless scheduler. Run coalescing would delay the `onMicrotaskEmpty` event
until after we have exited the change detection triggered by the
zoneless scheduler and mean that the subscription cannot determine if
`ApplicationRef.tick` should be skipped.
PR Close#55352
For ideal DOM usage, you would not unwrap an ElementRef outside of the browser. However, it's reasonable to want to find the tag name of the host node on the server, and so this introduces a HOST_TAG_NAME token that can be injected to read this value.
PR Close#54751
Flip `stopPropagation` constructor parameter default to `false` for
`EventContract` and `EventContractMultiContainer`. Change type for
`EventContract` to `false` to indicate that no values besides `false`
should be passed. This enables removing all usages of `stopPropagation`
in `EventContract` and leaving only usages of `stopPropagation = true`
for `EventContractMultiContainer`.
PR Close#55351
When `cleanUp` is called `containerManager` is set to null. Currently
the `EventContract` API assumes that users know not to call further
methods on `EventContract`, but this lead to a bug in a downstream app,
b/333750059. So instead, this makes a defensive check to make sure it's
not null.
PR Close#55353
This commit integrates the JSA contract binary into the NPM package and ensures its accessibility by including it in the package exports. This adjustment is essential for enabling Angular CLI to effectively access and inject the script. Additionally, sourcemaps are removed from the minified bundle to prevent their inclusion in the HTML page.
PR Close#55361
This commit loosens the restrictions on calling `ComponentFixture.detectChanges`
when using the zoneless scheduler. While we don't necessarily think it's
a good idea, the thought is that it's unnecessary mental overhead to
diverge behaviors in the API when zoneless is enabled versus when it is
not. Instead, these opinionated restrictions can be considered when we
look at new testing APIs.
PR Close#55325
BREAKING CHANGE: The deprecated `isPlatformWorkerUi` and `isPlatformWorkerApp` have been removed without replacement, as they serve no purpose since the removal of the WebWorker platform.
PR Close#55302
When Angular receives a clear indication that change detection should
run again, this should not be ignored, regardless of what Zone it
happened in. This change updates the default change detection scheduling
approach of Zone-based applications to ensure a change detection will
run when these events happen outside the Angular zone (which includes,
for example, updating a signal that's read in a template, setting an
input of a `ComponentRef`, attaching a view marked for check, calling
`ChangeDetectorRef.markForCheck`, etc.).
This does not apply to applications using `NoopNgZone` or those which
have a custom `NgZone` implementation without ZoneJS.
The impact of this change will most often be seen in existing unit tests. Tests
execute outside the Angular Zone and this can mean that state in the
test is not fully recognized by Angular. Now that Angular will ensure
change detection _does_ run, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior. Often, this should be seen
as more correct and the test should be updated, but in cases where it is
too much effort to debug, the test can revert to the old behavior by adding
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the `TestBed` providers.
fixes#55238fixes#53844fixes#53841fixes#52610fixes#53566fixes#52940fixes#51970fixes#51768fixes#50702fixes#50259fixes#50266fixes#50160fixes#49940fixes#49398fixes#48890fixes#48608fixes#45105fixes#42241fixes#41553fixes#37223fixes#37062fixes#35579fixes#31695fixes#24728fixes#23697fixes#19814fixes#13957fixes#11565fixes#15770fixes#15946fixes#18254fixes#19731fixes#20112fixes#22472fixes#23697fixes#24727fixes#47236
BREAKING CHANGE:
Angular will ensure change detection runs, even when the state update originates from
outside the zone, tests may observe additional rounds of change
detection compared to the previous behavior.
This change will be more likely to impact existing unit tests.
This should usually be seen as more correct and the test should be updated,
but in cases where it is too much effort to debug, the test can revert to the old behavior by adding
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the `TestBed` providers.
Similarly, applications which may want to update state outside the zone
and _not_ trigger change detection can add
`provideZoneChangeDetection({schedulingMode: NgZoneSchedulingMode.NgZoneOnly})`
to the providers in `bootstrapApplication` or add
`schedulingMode: NgZoneSchedulingMode.NgZoneOnly` to the
`BootstrapOptions` of `bootstrapModule`.
PR Close#55102
Rather than attempting to use the native timing functions, this commit
simplifies the logic significantly by using the global timer functions
as they are, either patched or unpatched. When Zone is defined, we run
the timers in the root zone. This has more predictable behavior and
timing than (a) using both patched and unpatched versions of timers in
different places (b) trying to get an unpatched timer and failing due to
environment specifics and patches that aren't ZoneJS.
We will try to update the coalescing behavior of ZoneJS in a future PR
to also just use the patched version of the timers instead of the
"fakeTopEvent" workaround with the native timers.
PR Close#55367
This commit ensures that manually calling ApplicationRef.tick will
result in any scheduled change detections being canceled. There is no
need for the scheduled one to run because it was manually done by the
`tick` already.
PR Close#55290
This commit updates the implementation of `ngswAppInitializer` to configure
the `controllerchange` event listener outside of the Angular zone. This adjustment
is made to prevent unnecessary change detections, as the `controllerchange` event
is unrelated to view updates.
**NOTE**: This change may result in breaking unit tests that implicitly rely on a
specific number and sequence of change detections for their assertions to pass.
PR Close#54222
Two-way bindings are meant to represent a property binding to an input and an event binding to an output, e.g. `[(ngModel)]="foo"` represents `[ngModel]="foo" (ngModelChange)="foo = $event"`. Previously due to a quirk in the template parser, we accidentally supported unassignable expressions in two-way bindings.
In #54154 the quirk was fixed, but we kept support or some common expression because of internal usages. Now the internal usages have been cleaned up so the backwards-compatibility code can be deleted.
Externally a migration was added in #54630 that will automatically fix any places that depended on the old behavior.
BREAKING CHANGE:
Angular only supports writable expressions inside of two-way bindings.
PR Close#55342
Right now this binary sits at 9.5kb. Additional changes to the library will
be done to reduce the binary size, such as converting event_type from
an enum to an object, and other code size reductions.
PR Close#55319
When we started fixing the version mismatch with local 1st-party
packages, we also re-routed all dependencies like `@lezer/javascript`
into `adev/node_modules`. This works fine, but results in a different
version mismatch because the codemirror dependencies may resolve the
Angular version from `/node_modules`- causing some subtle complex
runtime error.
This commit fixes this by only re-routing dependencies that have
dependency on e.g. `@angular/core` into `adev/node_modules`.
Fixes#55298.
PR Close#55349
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
This commit removes the long-deprecated Testability methods that track
pending tasks. This is done by NgZone today and will be done by other
APIs in zoneless.
BREAKING CHANGE: Testability methods `increasePendingRequestCount`,
`decreasePendingRequestCount` and `getPendingRequestCount` have been
removed. This information is tracked with zones.
PR Close#53768
This commit adds a configuration option to zone-based change detection
which allows applications to enable/disable the zoneless scheduler.
When the zoneless scheduler is enabled in zone-based applications,
updates that happen outside the Angular zone will still result in a
change detection being scheduled. Previously, Angular change detection
was solely based on the state of the Angular Zone.
PR Close#55252
An implementation of a TypeScript server plugin module factory has
been added to the main plugin code which minimizes the amount of
infrastructure code necessary to directly setup the Angular plugin.
This is not yet used externally but can be integrated in the future.
PR Close#55264
Expect that the number of template executions is `===` to a number, rather than expect that it
does not contain a number. As they were, these expectations would pass regardless of the expected
value.
PR Close#55294
1: Remove USE_EVENT_PATH, which has no users.
2: Create a new `EventActionInfo` object to represent actions, update all `EventInfoWrapper` users.
3: Fix `stopPropagation` behavior in JSAction Dispatcher - it should only `stopPropagation` if an action is found, which is only known during normal dispatch rather than global.
PR Close#55182
Similar to what we did for aio, we should not clear the architect CLI
output in Bazel. This messes up with the output and makes debugging
hard.
PR Close#55282
There is quite some trickery going on with the adev build related to
local packages:
- Adev builds using npm packages from `/node_modules`
- At runtime, we are adding `HEAD` packages for e.g. `@angular/core` to
the bundles.
- At build time, the CLI, or Angular devkit may accidentally resolve to
`@angular/core` from `/node_modules/`— which is the core version from
npm, transitively installed via `@angular/docs`.
This causes a version mismatch, leading to issues like:
- CLI throwing because of a mismatch. https://github.com/angular/angular/issues/54858#issuecomment-2047188739
- Compiler changes not being picked up. https://github.com/angular/angular/issues/54858#issuecomment-2041322427
This commit attempts to fix this by:
- Linking all Angular `HEAD` packages into `adev/node_modules`. The
current logic attempts to link into `/node_modules`, but this does not
override existing `@angular/core`!
- Linking all direct external NPM packages, like
`@angular_devkit/build-angular` into `adev/node_modules` without their
transitive deps. This allows proper resolution of e.g. compiler as
node looks in `adev/node_modules` first, and falls back for the rest
to the execroot `node_modules`, or symlink target destination (if
`preserveSymlinks=false`).
Note: This is still not 100% ideal because a direct external NPM
dependency may have a transitive dependency that has another transitive
dependency on `@angular/core`. In those cases, the may be a conflict
that is not resolvable until we switch to a Bazel toolchain with better
first party resolution support.
PR Close#55282
This commit a new check that warn users about duplicated keys detected given
a tracking expression and a collection iterated over with @for. Duplicated keys
should be avoided as those are more expensive to manage and can result in
incorrect UI display.
PR Close#55243
`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests (https://github.com/angular/angular/commit/28c68f709cdc930e12bac51a266e7bf790656034).
Today, `PendingTasks` contribute to `ApplicationRef.isStable` but do not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended and we plan to make these two
stability indicators the same again, like they were when it was solely
based on the state of the Zone.
By aligning the two behaviors again, this would include all pending
tasks in the stability of fixtures. After investigation, this seems
likely to be a pretty large breaking change. Tests appear to quite often use
`await fixture.whenStable` when there are unfinished requests that have
not been mocked or flushed.
This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` automatically but only when using
`HttpClientTesting`. In this scenario, requests need to be expected and
flushed manually for them to resolve. When the test backend and controllers
aren't used, requests should resolve on their own so `await fixture.whenStable`
shouldn't be particularly affected or problematic.
PR Close#54974
The `getDefinitionAtPosition` function may be called by consumers instead
of `getDefinitionAndBoundSpan` with the later of which already implemented.
The `getDefinitionAtPosition` result is a subset of what `getDefinitionAndBoundSpan`
returns and currently delegates to that function.
PR Close#55269
Within the language service, the Angular compiler instance can provide
access to the current TypeScript program via `getCurrentProgram`. By
using the compiler, the need to pass around the program driver is no longer
required and can also be removed as an instance field of the Angular language
service class. This change also provides a higher assurance that the correct
program is being used throughout each language service request.
PR Close#55097
Keep theme constants in sync betwee index.html file and theme manager. Move versions config static data to their own file, and replace the deprecated toPromise() api with the new firstValueFrom() api
PR Close#55234
Previously located in the `aio` directory, the commit moves the docs file into `adev` and also moves the `script` used to generated them from the `angular-cli` repo.
PR Close#55242
Prior to this change, `NgZone` was provided by default in TestBed in a
location that would override anything configured in
`TestBed.initTestEnvironment`. This change moves the default `NgZone`
provider to the `RootScopeModule` and these providers can be overridden
by the ones in `additionalModuleTypes`, which are assigned from the
first argument of `initTestEnvironment`. This makes it possible to
configure Zone globally for all tests as opposed to needing to repeat it
in `configureTestingModule` of each suite.
PR Close#55226
Now that #55092 has merged, we now consistently get the `setTimeout` and
`rAF` implementations that are not patched by zone. There's no longer a
need to run them in the root zone.
PR Close#55230
PR #55099 updated zoneless behavior to treat all views attached to
`ApplicationRef` as `OnPush`. Put another way, Zoneless change detection
will only refresh view trees that notified Angular of a change. This
generally works as expected but there was one situation where it did
not.
Some views are logically linked to their declaration locations and
should refresh when the declaration refreshes. These views are called
"transplanted views" and work correctly when inserted into another view
container. This change updates the logic to also work when they are
attached directly to `ApplicationRef`.
PR Close#55154
Previously the input flags were being generated as a reference to an enum member for better readability and under the assumption that minifiers would inline the values. That doesn't appear to be the case so these changes switch to using the literal values instead.
PR Close#55215
This commit introduces a new method to subscribe to on every `AbstractControl` subclass.
It allows to track value, pristine, touched and status changes on a given control.
Fixes#10887
PR Close#54579
The fix from PR #55079 introduced a configuration of the injector chain, which wasn't properly handled by the injector debug utils, thus resulting in JS exceptions in DevTools. This commit updates injector debug utils logic that calculates injector resolution path to also handle `ChainedInjector`s.
Resolves#55137.
PR Close#55144
In #52110 we had to use `if` statements to represent `switch` blocks, because TypeScript had a bug when narrowing the type of parenthesized `switch` statements. Now that it has been fixed by TypeScript and we don't support any version that has the broken behavior, we can go back to generating `switch` statements in the TCB which are simpler and better represent the user's code.
PR Close#55168
Grabbing and saving the references to global `setTimeout` and `rAF`
implementations at a certain point in time can be problematic, espcially
in tests. Tests might call something like `jasmine.clock().install();`
and `jasmine.clock().uninstall();`. If the install happens before we
grab the implementation and then the uninstall happens after, our
scheduling function will be broken because it would have saved a reference to
the jasmine `setTimeout` implementation, which would have since been
cleaned up and will throw an error when attempting to access `delayedFunctionScheduler`.
There are other scenarios that may apply, not even just for tests, when
patches are applied and removed to the globals.
PR Close#55124
This commit ensures components in the route config predictably always
get their providers from the hierarchy available to routes rather than
sometimes being dependent on where they are inserted.
fixes#53369
BREAKING CHANGE: Providers available to the routed components always
come from the injector heirarchy of the routes and never inherit from
the `RouterOutlet`. This means that providers available only to the
component that defines the `RouterOutlet` will no longer be available to
route components in any circumstances. This was already the case
whenever routes defined providers, either through lazy loading an
`NgModule` or through explicit `providers` on the route config.
PR Close#54265
Returning a `RedirectCommand` from a resolver can be interpreted as
distinctly different from regular resolved data. When a resolver returns
`RedirectCommand` we can interperet this as an intention to redirect in
the same way as other guards.
resolves#29089
PR Close#54556
Fix scrolling experience in API Reference:
- set correct margin top for members container (right side) which is aligned with tabs (left side)
- prevent scroll on focus
- remove redundant blur calls
PR Close#55133
The control flow migration was using a couple of Greek letters as placeholders. This ended up conflicting with templates authored in Greek.
These changes use a more obscure placeholder to make conflicts less likely. It also moves the placeholder generation to a centralized function so it's easier to make changes if we decide to update the pattern again.
Fixes#55085.
PR Close#55113
To display the image correctly, swap the image from the folders
Fixes #54778
feat(docs-infra): change path for correct ADEV
Changing path for correctly displaying in adev
PR Close#54795
This reverts commit 367b3ee6e9.
The search element is not a void element but existing components may use
the same selector and be used as a void element.
PR Close#55127
This change treats all views attached to `ApplicationRef` as `OnPush`,
meaning that they have to be explicitly marked for check in order to be
refreshed when a tick happens. This prevents "accidentally" refreshing
views which have `Default` change detection as a side effect of running
change detection from an unrelated notification.
In addition, this change helps us achieve one of the big goals of the
project: that we can provide a testing experience which gives developers
more confidence that a component is zoneless-compatible. Because
`ComponentFixture` change detection is run through `ApplicationRef`
instead of `ChangeDetectorRef` when zoneless is enabled, this ensures
that the component under test has correctly been marked for check in
order to be updated. Without this, calling
`ComponentFixture.detectChanges` would allow a test to _force_ change
detection on a view when Angular would have otherwise not known that it
needed to be updated. Calling `ComponentFixture.detectChanges` on a component
which is not marked for check will now omit refreshing component view.
PR Close#55099
It is not enough to use provideHttpClientTesting() for HTTP Client Testing, it will throw a dependency injection error. Update the docs to include both provideHttpClient() and provideHttpClientTesting()
Fixes#53390
PR Close#53716
Rework the i18n cleanup behavior to more closely match that of containers. Specifically, we assume that nodes are going to be claimed unless they are part of a branching ICU block.
During hydration, we then track which ICU case was active at serialization time, and which was active during hydration. Any remaining cases that weren't used during hydration are then cleaned up.
PR Close#54823
Add support for hydrating i18n blocks. This is accomplished by serializing information about selected ICU cases for a block during server-side rendering.
During hydration, this data is read and is used to traverse both an AST of the translated message and the DOM, in parallel, to map each LView with an RNode.
Finally, this mapping is used while nodes are being created (either via i18n or their respective instructions) to locate existing nodes.
PR Close#54823
This commit updates the internal resolve value of the navigation promise
to use `false` instead of `null` when a navigation is skipped. The
navigation promise type requires `boolean` so the correct resolution to
match the truthy/falsiness of the currently resolved value, `null`, is
`false` instead.
PR Close#55068
This commit moves the call to the error handler to the location where
the error event emits instead of having it indirectly work through the
events subscription. This change would also allow the handler to return
a value which can be handled by the navigation transition.
PR Close#55068
This commit fixes the types on the error handler resolve and reject
functions and also ensures that the resolve value matches the API type
(`boolean`, not "any random value returned from `errorHandler`"). This
could be considered a breaking change but I would argue instead that
relying on the return value of the error handler is API misuse because
the promise returned by the router navigation _does not_ include `any`
in its type.
PR Close#55068
This commit fixes the internal types for the resolve and reject
functions used for the router navigation Promise. These are currently
typed as `any`.
PR Close#55068
Angular recently gained a local compilation mode (see commit 345dd6d).
This is intended to be used with the TypeScript compiler option isolatedModules, which bans imports of const enums.
PR Close#55103
While we do want to discourage `fixture.detectChanges`, it is yet to be
determined how this should be accomplished (warning, documentation, etc.). At
the moment, not being able to disable the error at all is entirely
prohibitive for existing test suites to use zoneless change detection in
tests. We would much rather allow existing test suites to disable the
error and use the zoneless change detection than prevent them from using
it entirely until all the `detectChanges` calls have been fixed.
Calling `detectChanges` manually can hide errors related to change
detection timing, but it is even worse when the "PseudoApplication"
fixture used (since it runs change detection _only_ on the component
rather than through `ApplicationRef`).
PR Close#55098
Angular's template files are not valid TypeScript. Attempting to get syntactic
diagnostics from the underlying TypeScript language service will result in
a large amount of false positive errors. Only actual TypeScript files should
be analyzed by the underlying TypeScript language service for syntactic errors.
PR Close#55091
Fixes that the control flow migration was throwing an error if the `imports` of a component are initialized to an identifier.
Fixes#55080.
PR Close#55081
This commit updates the `@defer` logic to establish proper injector resolution order. More specifically:
- Makes node injectors to be inspected first, similar to how it happens when `@defer` block is not used.
- Adds extra handling for the Router's `OutletInjector`, until we replace it with an `EnvironmentInjector`.
Resolves#54864.
Resolves#55028.
Resolves#55036.
PR Close#55079
Allows for `SourceFileValidatorRule.checkNode` to produce a single diagnostic. The most common case should be one diagnostic per node so this allows us to save some array allocations.
PR Close#54993
Adds the new `SourceFileValidator` that will be used to check for file-level issues that may prevent Angular from working, like invoking the `input()` function outside of an initializer. Currently only one check is planned, but this setup will allow us to easily add more in the future.
PR Close#54993
`Object.getPrototypeOf(obj)` returns `null` if `obj` is an empty object. `Object.getOwnPropertyDescriptors` throws on `null`/`undefined`
PR Close#55061
This commit makes the zoneless scheduler (privately) available to applications that
have ZoneJS-based change detection. This would catch any changes of
interest (signal updates, `markForCheck` calls, attaching `Dirty` views)
that happen outside the Angular Zone.
See #53844 for additional information about why this is important.
More details to come in the a future commit that makes this a public option.
PR Close#54952
Add a sentence to the `@loading` block documentation that emphasizes more that the `@loading` block will replace the `@placeholder` block once the deferred view starts loading.
PR Close#54779
This change aligns the stability of `ComponentFixture` with that of
`ApplicationRef`, preventing confusing differences between the two as
more APIs start using the `PendingTasks` that may not be tracked by
`NgZone`.
BREAKING CHANGE: `ComponentFixture.whenStable` now matches the
`ApplicationRef.isStable` observable. Prior to this change, stability
of the fixture did not include everything that was considered in
`ApplicationRef`. `whenStable` of the fixture will now include unfinished
router navigations and unfinished `HttpClient` requests. This will cause
tests that `await` the `whenStable` promise to time out when there are
incomplete requests. To fix this, remove the `whenStable`,
instead wait for another condition, or ensure `HttpTestingController`
mocks responses for all requests. Try adding `HttpTestingController.verify()`
before your `await fixture.whenStable` to identify the open requests.
Also, make sure your tests wait for the stability promise. We found many
examples of tests that did not, meaning the expectations did not execute
within the test body.
In addition, `ComponentFixture.isStable` would synchronously switch to
true in some scenarios but will now always be asynchronous.
PR Close#54949
This commit will fix the issue of the setting of NavigationExtras.replaceUrl being lost when
returning a urlTree from a CanActivateFn.
Fixes#53503
BREAKING CHANGE: When a a guard returns a `UrlTree` as a redirect, the
redirecting navigation will now use `replaceUrl` if the initial
navigation was also using the `replaceUrl` option. If this is not
desirable, the redirect can configure new `NavigationBehaviorOptions` by
returning a `RedirectCommand` with the desired options instead of `UrlTree`.
PR Close#54042
Previously, `RouterLinkActive` would only add or remove the active classes when
its active state changed. This means that if you accidentally add one of
the active classes to the static class attribute, it won't get removed
until the link becomes active and then deactives (because the class is
added at creation time and never removed until the `RouterLinkActive`
state changes from active to inactive).
fixes#54978
PR Close#54982
The custom flatMap implementation can now be removed as Array contains a
native implementation that is available for all supported Node.js versions.
PR Close#55011
When the `angularOnly` option is disabled, the underlying TypeScript language service
was previously used for all files including `.html` template files. This can result in
incorrect responses including a large amount of invalid diagnostics for a template file.
Checks have now been added to only use the Angular Language service for template files
which can properly handle template files. Additionally, the check for a TypeScript file
name has now been expanded to encompass all current file extension forms.
PR Close#55003
For `FatalDiagnosticError` we are currently hiding the `message` string
field in favor of the actual TS `diagnosticMessage`.
This works as expected, but makes these errors hard to debug in certain
environments (e.g. Jasmine). That is because `null` is the value of
`message` at runtime. We fix this by just overriding the type, like we
originally intended to do.
In addition, we properly render message chains in the `Error#message`
field— so that these errors, when uncaught, are somewhat reasonable and
can be useful.
PR Close#54981
This commit ensures that the new APIs like `input`, `model`, `output`,
or signal-based queries are not accidentally used on fields that have a
problematic visibility/access level that won't work.
For example, queries defined using a private identifier (e.g. `#bla`)
will not be accessible by the Angular runtime and therefore _dont_ work.
This commit ensures:
- `input` is only declared via public and protected fields.
- `output` is only declared via public and protected fields.
- `model` is only declared via public and protected fields.
- signal queries are only declared via public, protected and TS private
fields (`private` works, while `#bla` does not).
Fixes#54863.
PR Close#54981
An initializer API like `input`, `output`, or signal queries may not be
compatible with certain access levels. E.g. queries cannot work with ES
private class fields.
This commit introduces a check for access levels into the initializer
API recognition— enforcing that every initializer API *clearly*
specifies what type of access is allowed.
PR Close#54981
This commit changes the TypeScript reflection host to:
* inspect / process ES private fields. e.g. `#someField` — those are
ignored right now and we would want to check them to issue
diagnostics.
* determine an access level of a class member. E.g. a member may be
public, may be private, may be ES private, or public readonly. This
can then be used in various checks later.
PR Close#54981
Updates the function that parses initializer APIs to check any `Expression`, instead of expecting a class member. This will be useful for the upcoming changes.
PR Close#54981
This commit fixes various issues that seem to cause the 17.3.x patch
to be red for weeks:
- Eslint checking a file for aio/tools that is not part of a tsconfig—
hence an error is being reported.
- Audit-web-app importing some Lighthouse APIs that aren't available
under the given path.
PR Close#55064
Previously, a race condition could cause DevTools to enter a state where it can't detect an application on reload. This was caused by a sequencing issue between the content script connection, the devtools panel connection and an event "backendReady" that lets DevTools know when a particular frame is ready to be inspected.
This commit replaces the previously stored backendReady boolean with a promise, so that the devtools panel can eventually run a callback to connect to a content script when that content script emits it's backendReady message.
PR Close#54805
Passes the attributes of the `ng-content` element to the container that is created for the fallback content so that it can be re-projected into the same slot.
PR Close#54854
Moves the logic that declares a template out into a separate function so that it can be reused in other places like control flow and defer, without having to call directly into the `template` instruction.
PR Close#54854
Adds the ability to specify content that Angular should fall back to if nothing is projected into an `ng-content` slot. For example, if we have the following setup
```
@Component({
selector: 'my-comp',
template: `
<ng-content select="header">Default header</ng-content>
<ng-content select="footer">Default footer</ng-content>
`
})
class MyComp {}
@Component({
template: `
<my-comp>
<footer>New footer</footer>
</my-comp>
`
})
class MyApp {}
```
The instance of `my-comp` in the app will have the default header and the new footer.
**Note:** Angular's content projection happens during creation time. This means that dynamically changing the contents of the slot will not cause the default content to show up, e.g. if a `if` block goes from `true` to `false`.
Fixes#12530.
PR Close#54854
Adds logic to ingest the content of an `ng-content` element in the template type checker. We treat `ng-content` as a `ScopedNode`, because its content is inserted conditionally.
PR Close#54854
This commit adds support for ignoring specific doc entries when
extracting doc entries. This allows us to drop e.g. `InputFunction` from
the API docs, given that the `input` API entry holds all the relevant
information.
`InputFunction` only exists for type purposes in the `.d.ts`.
PR Close#54925
Similar to `input`, `model`, `output`, the query initializer APIs are
also explicitly denoted as such. This allows angular.dev to display them
more readable and compactly.
PR Close#54925
This improves the API documentatino for `output` in angular.dev,
similar to how we improved the API for `input`.
Angular.dev can now show these documentation entries more
readable if annotated explicitly as initializer API.
Note: output API is short enough that we want to include
the types in the code snippet previews.
PR Close#54925
This commit improves the API documentation for `input` after
we added support for initializer APIs in angular.dev docs generation.
Changes:
- Rename `ReadT` to `T`. This conceptually makes it easy to talk about
inputs of type `T` if there is no transform involved. The common case.
- Rename `WriteT` to `TransformT`. This makes it clear that this is the
type that the "transform" needs to handle.
- Improves the "overall" description of the input function so that it
can be shown as a general overview for the API site.
- Improves usage notes to be a little more helpful, yielding more useful
content in the API docs usage notes section.
- Add short JSDoc description for each individual overload.
PR Close#54925
This commit adds support for extracting initializer API functions.
Initialixer API functions are functions conceptually that can are
intended to be used as class member initializers.
Angular started introducing a few of these for the new signal
APIs, like `input`, `model` or signal-based queries.
These APIs are currently confusingly represented in the API docs because
the API extraction:
- does not properly account for call signatures of interfaces
- does not expose information about sub-property objects and call
signatures (e.g. `input.required`)
- the docs rendering syntax highlighting is too bloated and confusing
with all types being included.
This commit adds support for initializer API functions, namely two
variants:
- interface-based initializer APIs. e.g. `export const input:
InputFunction`- which is a pattern for `input` and `input.required`.
- function-based simpler initializer APIs with overloads. e.g.
`contentChildren` has many signatures but doesn't need to be an
interface as there are no sub-property call signatures.
PR Close#54925
When creating the Angular Language Service instance, attempts to read
configuration files are now only attempted if the project is considered
a `Configured` project. Such a project has been analyzed by TypeScript
and one or more configuration files (tsconfig/jsconfig) files have been
found for the project.
PR Close#55035
Based on some internal feedback, these changes add validations to prevent cases where the `@for` loop variable name is the same as one of the built-in context variables, or when one of the context variables is aliased to the same name as the item.
PR Close#55045
This update enhances the encoding handling of request bodies to generate the necessary cache key for transfer cache functionality.
Closes#54956
PR Close#54980
Builds on top of the previous changes to add support for deferred blocks during partial compilation. To do this, the following changes had to be made:
* The metadata passed into `ɵɵngDeclareComponent` has an additional field called `deferBlockDependencies` which has an array of the dependency loading functions for each defer block in the template. During linking, the dependency functions are loaded by matching their template index to the index in the `deferBlockDependencies` array.
* There's a new `ɵɵngDeclareClassMetadataAsync` function that is created for components that have deferred dependencies. It gets transpiled to `setClassMetadataAsync` and works in the same way by capturing a dependency loading function and setting the metadata after the dependencies are resolved. It also has some extra fields for capturing the version which are standard in linker-generated code.
* Deferred import statements are now stripped in partial compilation mode, similar to full compilation.
PR Close#54908
Adds the `ɵɵngDeclareClassMetadataAsync` function that will be produced during partial compilation for component classes that have deferred dependencies. At runtime the dependencies will be resolved before setting the metadata.
PR Close#54908
Updates the type of the resolver function to be any `Expression` since JIT may receive a function reference rather than a `ArrowFunctionExpr`.
PR Close#54908
Switches to tracking the deferred blocks in a flat array in the binder to ensure that their template order is maintained. This will be relevant in the next commits where we'll match deferred blocks by their index.
Note that the current map we have technically guarantees the insertion order in the spec, but the array is a bit more explicit.
PR Close#54908
Updates the logic that detects if a node should be checked for control flow content projection to exit as soon as it detects a second root node, instead of counting the total and then checking if it's more than one.
PR Close#54921
Previously only the first branch of an `if` block was captured for content projection. This was done because of some planned refactors in the future. Since we've decided not to apply those refactors to conditionals, these changes update the compiler to capture each branch individually for content projection purposes.
PR Close#54921
This commit changes the way we use containers to insert conditional content.
Previously if and switch conditional would always use the first content as the
insertion container. This strategy interfered with content projection that
projects entire containers - as the consequence content for _all_ cases would
end up in slot matched by the first container. This could be very surprising
as desicribed in https://github.com/angular/angular/issues/54840
After the change each conditional content is projected into its own container.
This means that content projection can match more than one container and
result in correct display.
Fixes#54840
PR Close#54921
Currently when aliasing a `for` loop variable with `let`, we replace the variable's old name with the new one. Since users have found this to be confusing, these changes switch to a model where the variable is available both under the original name and the new one.
Fixes#52528.
PR Close#54942
Since the PR is always expected to be ready to merge as renovate won't make changes in response to any sort of comment, it should already be marked as merge ready
PR Close#54947
Previously we assumed that if a `for` loop tracking function is in the form of `someMethod($index, $item)`, it will be pure so we didn't pass the parameter to bind the context to it. This appears to be risky, because we don't know if the method is trying to access `this`.
These changes play it safe by always binding method-based tracking functions.
Fixes#53628.
PR Close#54960
This commit adds `declare` to each interface in the `zone-impl` to
prevent renaming of any interface properties by compiler optimizations.
This would otherwise cause issues if multiple applications depend on ZoneJS and
compile the interface properties to different names.
PR Close#54966
This commit refactors the router module to enhance performance by substituting the startsWith method with direct access `[0]` when verifying the value of a single character. This optimization improves efficiency, as direct access retrieves the character's value stored at a specific index in the string, resulting in slightly faster execution.
PR Close#54940
This change updates the approach to the loop in `ApplicationRef.tick`
for allowing state updates in `afterRender` hooks. It is valid to update
state in render hooks and we need to ensure we refresh views that may be
marked for check in these hooks (this can happen simply as a result of
focusing an element). This change ensures that the behavior of `markForCheck`
with respect to this loop does not change while we are actively running
change detection on a view tree.
This approach also has the benefit of preventing a regression for #18917,
where updating state in animation listeners can cause `ExpressionChanged...Error`
This should be allowed - there is nothing wrong with respect to unidirectional
data flow in this case.
There may be other cases in the future where it is valid to update
state. Rather than wrapping the render hooks and the animation flushing
in something which flips a global state flag, the idea here is that
`markForCheck` is safe and valid in all cases whenever change detection
is not actively running.
PR Close#54900
In some cases the hydration mismatch is nested within a component.
As the devTool only reports issues on the component level, we need to mark the component node rather than the actual mismatched node.
PR Close#54671
This commit updates the name of an internal function argument that represents an embedded view injector. Also it introduces a new config option that allows passing an environment injector to be used in the underlying LView. There are no changes to the behavior, just some initial cleanup for upcoming changes.
PR Close#54903
BREAKING CHANGE:
Legacy handling or Node.js URL parsing has been removed from `ServerPlatformLocation`.
The main differences are;
- `pathname` is always suffixed with a `/`.
- `port` is empty when `http:` protocol and port in url is `80`
- `port` is empty when `https:` protocol and port in url is `443`
PR Close#54874
BREAKING CHANGE: deprecated `platformDynamicServer` has been removed. Add an `import @angular/compiler` and replace the usage with `platformServer`
PR Close#54874
I initially tried switching to use public entry points under `zone.js/plugins/*`, however this file is both manually compiled for Saucelabs and also built with Bazel for a number of tests. The Bazel integration doesn't work well with depending on real NPM packages, so importing `zone.js/plugins/*` in that context doesn't really work. Instead we need to depend on the internals and manually call the `patch*` functions.
PR Close#53443
This was a bit complicated, but the typings test (`packages/zone.js/test/typings/...`) was failing due to an unresolved import on `./zone-impl`.
The main cause is that `//packages/zone.js:zone_js_d_ts` was generating the output `zone.d.ts` file by _concatenating_ `zone.d.ts` with `zone.api.extensions.d.ts` and `zone.configurations.api.d.ts`. Now that `zone.d.ts` imports `zone-impl.d.ts`, concatenation is no longer a viable means of bundling this content.
To fix this, I created a new `packages/zone.js/zone.ts` entry point and imported the underlying `zone.ts` file as well as the two extensions. I added `extract_types` to pull the `*.d.ts` files out of the target (because all the JS is bundled separately) and used those files in the final NPM package. This is sufficient to pass the typings test and should be equivalent to what exists today.
PR Close#53443
The `rxjs|electron` regex was causing `import { /* ... */ } from './electron';` to be treated as external and not bundled, which is an issue for the Electron entry point which just happens to be named `electron.ts`. Now only the actual `electron` package should be treated as external, while internal files of any name should not.
I actually tried updating to `^rxjs` as well, however this appears to break some tests and isn't necessary to fix the failing Electron test, so I'm leaving it alone.
PR Close#53443
Not sure why this becomes a problem now. These errors appear to be preexisting. Most likely the file wasn't loaded previously and now it is.
PR Close#53443
As this was, `__symbol__` was being called as a static field initializer, which runs during module evaluation, meaning it happened at import time. However for tests, the Zone prefix is overridden which changes the result of `__symbol__`. This change happens too late to be picked up by `__symbol__` at top-level execution, so instead we defer it until `symbolParentUnresolved` is actually read.
PR Close#53443
This moves timer patching from a top-level side effect into the `patchFakeAsyncTest` function. Top-level statements are evaluated before the Node patches run and have a chance to patch them with the Zone versions of these timers, meaning `FakeAsyncTestZoneSpec` was repatching the native versions between tests. The fix here is to grab the patched versions of these timers during the `patchFakeAsyncTest` function where we can be confident Node patches have already run.
PR Close#53443
This moves the internals of `fake-async-test.ts` outside `patchFakeAsyncTest` and exports them. This way they can be imported without depending on the top-level side effects of loading Zone.
PR Close#53443
For some reason the `_global` name appears to conflict with another `_global` name. Not entirely sure how or why, but the easiest fix seems to be to just give the variable a unique name.
PR Close#53443
While reading this is not a top-level side effect, it does _depend_ on a top-level side effect. Specifically, `node-env-setup.ts` set this value. Now that its side effect is moved into a function, we can't read it as the top-level of `zone-impl.ts` and need to wait until `__symbol__` is actually called outside of top-level scope.
PR Close#53443
While `TaskTrackingZoneSpec` was implicitly global previously, it does not need to be exposed in a `declare global {}` block. This is because classic scripts in TypeScript are only implicitly global within the same compilation. `TaskTrackingZoneSpec` was not exposed in the existing `.d.ts` files shipped with the `zone.js` package. Within google3, this is also a separate compilation and was not accessible. As a result, `TaskTrackingZoneSpec` was always private and we do not need a global to maintain compatibility.
PR Close#53443
While `ProxyZoneSpec` was implicitly global previously, it does not need to be exposed in a `declare global {}` block. This is because classic scripts in TypeScript are only implicitly global within the same compilation. `ProxyZoneSpec` was not exposed in the existing `.d.ts` files shipped with the `zone.js` package. Within google3, this is also a separate compilation and was not accessible. As a result, `ProxyZoneSpec` was always private and we do not need a global to maintain compatibility.
PR Close#53443
Since each patch no longer contains top-level side effects, each bundled entry point needs to import and call its associated patch. For the most part this just means that each entry point imports the associated patch and invokes it at the top-level scope.
Note that many of these entry points did not actually have a dependency on `Zone` and had no guarantee that it was loaded prior to execution. To maintain consistency, the missing dependencies on `Zone` are left as-is. They will use the global instance of `Zone` and if users fail to load it prior to importing a specific patch, then the patch will fail just as it did previously.
PR Close#53443
This drop the top-level side effects in `zone.ts` and allows the initialization to be reused across the various entry points in the package.
PR Close#53443
This particular is slightly different from the others because it does not have a hard dependency on `Zone`. It doesn't actually use `Zone` directly during the patch because the patch just sets a `legacyPatch` global. To maintain consistency, this continues to use global `Zone` and does _not_ accept `Zone` as a parameter. While it's using a global in an inconvenient way, this isn't a problem right now because it doesn't cause or require a dependency on a top-level side effect.
PR Close#53443
This removes top-level side effects from each of these files and drops the dependency on global `Zone`, instead allowing it to be provided to each patch as a parameter.
Most of these are pure mechanical transformations. A couple notable files which were somewhat unique:
* `async-test.ts`, `fake-async-test.ts`, and `wtf.ts` had unique IIFE usage and patch `Zone` itself. This removes the IIFE and exports the function instead.
* `jest.ts` and `jasmine.ts` have a unique `jest` global usage which needs to be declared.
PR Close#53443
These are all the symbols originally under `declare global {}` with the same names. Unfortunatley TypeScript treats a `declare global {}` scope as the parent scope, so we need to import with a different name than the global, meaning everything gets an `_` prefix.
PR Close#53443
This removes a name collision on `Zone` with the interface. Otherwise putting the `interface Zone {}` and `class Zone {}` in the same scope when the IIFE is removed will cause a conflict.
PR Close#53443
This drops global declarations from this file (as they will be limited to `zone.ts`. It also deletes the `/** @internal */` annotation on `AmbientZone` which is no longer necessary since it isn't in the `declare global` and deletes the global Zone declaration which is also unnecessary.
PR Close#53443
This is just a straight copy, no code is altered. The new `zone-impl.ts` file will contain the actual definitions exported directly without any global declarations or top-level side effects. The existing `zone.ts` will remain as an entry point with those globals and side-effects.
PR Close#53443
We are already testing the JIT transforms via integration tests, but
this commit adds dedicated unit tests for the transform behavior for
proper test coverage (planned follow-up).
PR Close#54841
Move the initialization of class field `DelegatingPerfRecorder` into the constructor.
This fixes the error : `TypeError: Cannot read properties of undefined (reading 'eventCount')`
This is blocking the roll-out of public class.
PR Close#54834
This commit updates the logic for preserving file overview comments
to be more reliable and less dependent on previous transforms.
Previously, with the old import manager, we had a utility called
`addImport` that always separated import statements and non-import
statements. This meant that the non-emitted statement from Tsickle
for the synthetic file-overview comments no longer lived at the
beginning of the file.
`addImports` tried to overcome this by adding another new non-emitted
statement *before* all imports. This then was later used by the
transform (or was assumed!) to attach the synthetic file overview
comments if the original tsickle AST Node is no longer at the top.
This logic can be improved, because the import manager shouldn't need to
bother about this fileoverview non-emitted statement, and the logic for
re-attaching the fileoverview comment should be local. This commit fixes
this and makes it a local transform.
PR Close#54819
This commit adds some unit tests verifying the import generation in TCB
files and inline blocks. We don't seem to have any unit tests for these
in general. This commit adds some, verifying some characteristics we
would like to guarantee.
PR Close#54819
To ease review and to allow for both instances to co-exist, `ImportManagerV2`
was introduced. This commit renames it to `ImportManager` now that we
deleted the older one.
PR Close#54819
Enables the incremental type-checking test that we never enabled when we
landed signal inputs. Now that we fixed incremental re-use by re-using
the existing user imports for inline type check blocks, the test is
passing and can be enabled.
PR Close#54819
Updates the type-check block generation code (also for inline type check
blocks) to use the new import manager.
This is now a requirement because the translator utilities from the
reference emit environment expect an import manager that follows the
new contract established via `ImportGenerator<TFile, TExpression>`.
For type check files, we can simply print new imports as we don't expect
existing imports to be updated. That is because type check files do not
have any _original_ source files (or in practice— those are empty).
For type check blocks inline, or constructors, imports _may_ be re-used.
This is great as it helps fixing some incrementality bugs that we were
seeing in the type check code. That is, sometimes the type check block
code may generate imports conditionally for e.g. `TemplateRef`, or
animations. Those then **prevent** incremental re-use if TCB code
switches between those continously. We tried to account for that with
signal inputs by always pre-generating such imports. This fixed the
issue for type-check files, but for inline type check blocks this is
different as we would introduce new imports in user code that would then
be changed back in subsequential edit iterations. See:
https://github.com/angular/angular/pull/53521#pullrequestreview-1778130879.
In practice, the assumption was that we would be fine since user code is
most likely containing imports to `@angular/core` already. That is a
true assumption, but unfortunately it doesn't help with incremental
re-use because TypeScript's structural change detection does not dedupe
and expects 1:1 exact imports from their old source files.
https://github.com/microsoft/TypeScript/pull/56845
To improve incremental re-use for the type check integration, we should
re-use original source file imports when possible. This commit enables
this.
To update imports and execute inline operations, we are now uisng
`magic-string` (which is then bundled) as it simplifies the string
manipulatuons.
PR Close#54819
This commit switches ngtsc's JS and DTS transform to use the new import
manager. This is a drop-in replacement as we've updated the translator
helpers in the previous commit to align with the new API suggested by
the `ImportManagerV2` (to be renamed then).
PR Close#54819
`ImportGenerator` is the abstraction used by the translator functions to
insert imports for `ExternalExpr` in an AST-agnostic way.
This was built specifically for the linker which does not use any of the
complex import managers- but rather re-uses `ngImport` or uses
`ngImport.Bla`.
This commit also switches the linker AST-agnostic generator to follow
the new signatures. This was rather trivial.
PR Close#54819
This commit introduces a new implementation of `ImportManager` that has
numerous benefits:
- It allows efficient re-use of original source file imports.
* either fully re-using original imports if matching
* updating existing import declarations to include new symbols.
- It allows efficient re-use of previous generated imports.
- The manager can be used for schematics and migrations.
The implementation is a rework of the import manager that we originally
built for schematics in Angular Material, but this commit improved it
to be more flexible, more readable, and "correct".
In follow-ups we can use this for schematics/migrations.
PR Close#54819
This commit ensures components in the route config predictably always
get their providers from the hierarchy available to routes rather than
sometimes being dependent on where they are inserted.
fixes#53369
BREAKING CHANGE: Providers available to the routed components always
come from the injector heirarchy of the routes and never inherit from
the `RouterOutlet`. This means that providers available only to the
component that defines the `RouterOutlet` will no longer be available to
route components in any circumstances. This was already the case
whenever routes defined providers, either through lazy loading an
`NgModule` or through explicit `providers` on the route config.
PR Close#54265
This commit updates the logic around `Route.redirectTo` to enable using a
function to create the redirect. This function can return a string,
ands acts the same as previous string redirects, or a `UrlTree`, which
will act as an absolute redirect.
To be useful, the redirect function needs access to the params and data.
Today, developers can access these in their redirect strings, for
example `{path: ':id', redirectTo: '/user/:id'}`. Unfortunately,
developers only have access to params and data on the _current route_
today in the redirect strings. The params and data in the `RedirectFn`
give developers access to anything from the matched parent routes as
well. This is done as the same way as param and data aggregation later
on (https://github.com/angular/angular/blob/897f014785578d87bc655ea6ae9e113653960f50/packages/router/src/router_state.ts#L236-L278).
In order to accomplish this, we inherit params and data while
matching, after the `ActivatedRouteSnapshot` is created for the matched
route rather than waiting until the end.
The `RedirectFunction` does not return the full
`ActivatedRouteSnapshot` interface. Some things are not accurately known
at the route matching phase. For example, resolvers are not run until
later, so any resolved title would not be populated. The same goes for lazy
loaded components. The is also true for all the snapshots up to the
root, so properties that include parents (root, parent, pathFromRoot)
are also excluded. And naturally, the full route matching hasn't yet
happened so firstChild and children are not available either.
fixes#13373resolves#28661 (though not for the redirect string - you would return a
`UrlTree` from the function)
BREAKING CHANGE: This change allows `Route.redirectTo` to be a function
in addition to the previous string. Code which expects `redirectTo` to
only be a string on `Route` objects will need to be adjusted.
PR Close#52606
This commit updates the loop in ApplicationRef.tick to only throw in dev
mode. In addition, it reduces the reruns to 10 from 100 in order to
reduce the impact on production applications that encounter this error.
That is, the loop will bail out much earlier and prevent prolonged
unresponsiveness.
PR Close#54848
Zone event and run coalescing now races `requestAnimationFrame` and
`setTimeout`. There are tradeoffs to both functions and racing the two
gives us the benefits of both. This is explained in more detail in the
jsdoc comment. This change also aligns the timing of zone coalescing
with what will be used for zoneless.
BREAKING CHANGE: The exact timing of change detection execution when
using event or run coalescing with `NgZone` is now the first of either
`setTimeout` or `requestAnimationFrame`. Code which relies on this
timing (usually by accident) will need to be adjusted. If a callback
needs to execute after change detection, we recommend `afterNextRender`
instead of something like `setTimeout`.
fixes#54544fixes#44314fixes#39854 (unverified but seems likely)
PR Close#54578
This is a follow-up to #53718 that applies the same logic to the
`autoDetect` feature of the fixture's host view. This now unifies the
logic between `ApplicationRef` and `ComponentFixture` autodetect.
BREAKING CHANGE: The `ComponentFixture` `autoDetect` feature will no
longer refresh the component's host view when the component is `OnPush`
and not marked dirty. This exposes existing issues in components which
claim to be `OnPush` but do not correctly call `markForCheck` when they
need to be refreshed. If this change causes test failures, the easiest
fix is to change the component to `ChangeDetectionStrategy.Default`.
PR Close#54824
The logic in `isCssClassMatching` is only interested in two areas in the attributes:
implicit attributes and the `AttributeMarker.Classes` area, with the first area only
of interest for projection matching, not directive matching. This commit splits these
two searches to make this more apparent.
PR Close#54800
This commit resolves a regression that was introduced when the compiler switched from
`TemplateDefinitionBuilder` (TDB) to the template pipeline (TP) compiler. The TP compiler
has changed the output of
```html
if (false) { <div class="test"></div> }
```
from
```ts
defineComponent({
consts: [['class', 'test'], [AttributeMarker.Classes, 'test']],
template: function(rf) {
if (rf & 1) {
ɵɵtemplate(0, App_Conditional_0_Template, 2, 0, "div", 0)
}
}
});
```
to
```ts
defineComponent({
consts: [[AttributeMarker.Classes, 'test']],
template: function(rf) {
if (rf & 1) {
ɵɵtemplate(0, App_Conditional_0_Template, 2, 0, "div", 0)
}
}
});
```
The last argument to the `ɵɵtemplate` instruction (0 in both compilation outputs) corresponds with
the index in `consts` of the element's attribute's, and we observe how TP has allocated only a single
attribute array for the `div`, where there used to be two `consts` entries with TDB. Consequently,
the `ɵɵtemplate` instruction is now effectively referencing a different attributes array, where the
distinction between the `"class"` attribute vs. the `AttributeMarker.Classes` distinction affects
the behavior: TP's emit causes the runtime to incorrectly match a directive with `selector: '.foo'` to
be instantiated on the `ɵɵtemplate` instruction as if it corresponds with a structural directive!
Instead of changing TP to align with TDB's emit, this commit updates the runtime instead. This uncovered
an inconsistency in selector matching for class names, where there used to be two paths dealing with
class matching:
1. The first check was commented to be a special-case for class matching, implemented in `isCssClassMatching`.
2. The second path was part of the main selector matching algorithm, where `findAttrIndexInNode` was being used
to find the start position in `tNode.attrs` to match the selector's value against.
The second path only considers `AttributeMarker.Classes` values if matching for content projection, OR of the
`TNode` is not an inline template. The special-case in path 1 however does not make that distinction, so it
would consider the `AttributeMarker.Classes` binding as a selector match, incorrectly causing a directive to
match on the `ɵɵtemplate` itself.
The second path was also buggy for class bindings, as the return value of `classIndexOf` was incorrectly
negated: it considered a matching class attribute as non-matching and vice-versa. This bug was not observable
because of another issue, where the class-handling in part 2 was never relevant because of the special-case
in part 1.
This commit separates path 1 entirely from path 2 and removes the buggy class-matching logic in part 2, as
that is entirely handled by path 1 anyway. `isCssClassMatching` is updated to exclude class bindings from
being matched for inline templates.
Fixes#54798
PR Close#54800
The paths for the security guide were flipped in the original PR. As a result, it looked for a markdown file in the best-practices directory when it should have looked for it in the guide directory instead.
PR Close#54830
Add an internal API to enable and use i18n hydration for testing and development. This helps ensure that we don't accidentally break the current behavior until we are completely ready to roll out i18n support.
PR Close#54784
Currently if an `(output)` listener fails, it will be handled gracefully
by Angular and reported to the `ErrorHandler`.
For programmatic subscriptions with `OutputEmitterRef`, this is not the case.
Instead, as soon as any subscription is failing, all other subsequent
subscription callbacks are not firing anymore.
This commit intends to make this more consistent by gracefully
reporting errors from `OutputEmitterRef#emit` to `ErrorHandler`,
allowing for listener execution to continue.
PR Close#54821
Returning `UrlTree` from a guard was a convenient new feature added to
the `Router`. However, it does not have feature-parity with the old
`router.navigate(...); return false;` pattern. The most common use-case
for this feature is to redirect to a new page _without_ updating the URL
from the initially attempted navigation. For example, rendering a 404
page when the user does not have access privelages to a route.
Fixes#17004Fixes#27148
BREAKING CHANGE: Guards can now return `RedirectCommand` for redirects
in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree`
values in `Route` types will need to be adjusted.
PR Close#45023
Ensures that all of the functions intended to be run in initializers are in an injection context. This is a stop-gap until we have a compiler diagnostic for it.
PR Close#54761
This commits assert that the repeater instruction gets a reference
to a tracking function. This change will allow us to better track
occurences of https://github.com/angular/angular/issues/53628 -
in certain situations a reference to a tracking function might be
undefiened.
We are not fixing the underlying issue here, just getting better
visibility.
PR Close#54814
Speeds up the retrieval of `DestroyRef` in `EventEmitter` because
`try/catch` is expensive if there is no injection context.
We saw a script time regression in Cloud.
The goldens had to be updated because `getInjectImplementation` is now
referenced. `inject` also references the underlying field, but directly.
This is super minimal overhead of a function exposing the internal
field.
PR Close#54748
Moves the logic that creates the defer resolver function into `@angular/compiler` for consistency with the rest of the compilation APIs. Also renames some of the symbols to make it clearer what they're used for.
PR Close#54759
Fixes an issue where we were outputting the reference to non-deferrable dependencies as strings, rather than going through the reference emitter. This caused some issues internally because the reference wasn't maintained in the generated JS.
PR Close#54759
Currently we have the `deferrableDeclToImportDecl`, `deferBlocks`, `deferrableTypes` and `deferBlockDepsEmitMode` fields on the `R3ComponentMetadata` which is incorrect, because the interface is used both for JIT and AOT mode even though the information for those fields is AOT-specific. It will be problematic for partial compilation since the runtime will have a reference to the dependency loading function, but will not be able to provide any of the other information.
These changes make the following refactors:
1. It changes the defer-related information in `R3ComponentMetadata` to include only references to dependency functions which can be provided both in JIT and AOT.
2. Moves the AOT-specific defer analysis into the `ComponentResolutionData`.
3. Moves the construction the defer dependency function into the compilation phase of the `ComponentDecoratorHandler`.
4. Drops support for defer blocks from the `TemplateDefinitionBuilder`. This allows us to clean up some TDB-specific code and shouldn't have an effect on users since the TDB isn't used anymore.
PR Close#54759
This commit updates `ApplicationRef.tick` to use `detectChangesInternal` for root
views rather than go through the `ChangeDetectorRef.detectChanges` API
which refreshes the host view without first looking at whether the view
is `OnPush` and not dirty. The current behavior would hide errors in
`OnPush` components that do not correctly get marked for check and would
break when migrating to zoneless change detection because `markForCheck`
was never called so change detection was never scheduled.
The error would be surprising and blamed on switching to zoneless when in
reality the issue already exists and is a problem with the component not
calling `markForCheck`. However, this error is hidden today because
`ApplicationRef.tick` refresh host bindings unconditionally.
BREAKING CHANGE: `OnPush` views at the root of the application need to
be marked dirty for their host bindings to refresh. Previously, the host
bindings were refreshed for all root views without respecting the
`OnPush` change detection strategy.
PR Close#53718
PR Close#53718
This commit updates HTML sanitization logic to avoid infinite loops in case clobbered elements contain fields like `nextSibling` or `parentNode`. Those fields are used for DOM traversal and this update makes sure that those calls return valid results.
Also this commit fixes an issue when clobbering `nodeName` causes JS exceptions.
PR Close#54425
An i18n message effectively acts as a dynamic template: two elements with contiguous instruction indices won't necessarily be contiguous in the DOM.
For that reason, we need to maintain a mapping from instruction index to a physical DOM node in order to hydrate views with i18n, pointing to where hydration for that view should begin.
PR Close#54750
Updates the instruction generation for two-way bindings to only emit the `twoWayBindingSet` call when writing to template variables. Since template variables are constants, it's only allowed to write to them when they're signals. Non-signal values are flagged during template type checking.
Fixes#54670.
PR Close#54714
We have a diagnostic that reports writes to template variables which worked both for regular event bindings and two-way bindings, however the latter was broken by #54154 because two-way bindings no longer had a `PropertyWrite` AST.
These changes fix the diagnostic and expand it to allow two-way bindings to template variables that are signals.
PR Close#54714
Moves the check which ensures that there are no writes to template variables into the `TemplateSemanticsChecker` to prepare for the upcoming changes.
PR Close#54714
Introduces a new `TemplateSemanticsChecker` that will be used to flag semantic errors in the user's template. Currently we do some of this in the type check block, but the problem is that it doesn't have access to the template type checker which prevents us from properly checking cases like #54670. This pass is also distinct from the extended template checks, because we don't want users to be able to turn the checks off and we want them to run even if `strictTemplates` are disabled.
PR Close#54714
The `runCallbackOnce` closure is declared not to have any parameters itself, so it is
compatible as `queueMicrotask` callback without the extra closure. This reduces the call
stack by a frame and avoids the extra closure allocation.
PR Close#54801
This commit addresses a typing mismatch, where these functions were declared to return whichever
value their callback returned, but this was inaccurate: it's always a test callback function
with `done` argument.
PR Close#54801
The assertion in `packages/core/test/acceptance/after_render_hook_spec.ts:165` was prone to flakes,
where Jasmine could frequently report an error:
```
Error: 'expect' was used when there was no current spec, this could be because an asynchronous test timed out
at Env.expect (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1945:15)
at expect (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8267:18)
at file:///packages/core/test/acceptance/after_render_hook_spec.ts:165:12
```
This happens because `wrapTestFn` checks for an exact type of `Promise`, which may have been patched by zone.js
such that the `instanceof` condition is dependent on whether zone.js has patched the `Promise` constructor.
PR Close#54801
Many acceptance tests define goldens for both `TemplateDefinitionBuilder` and Template Pipeline. All such tests have had the TDB golden files removed, and the corresponding expectations adjusted.
PR Close#54757
`TemplateDefinitionBuilder` is the legacy template compiler, and was replaced by Template Pipeline as the default in v17.3.
This PR attempts to delete `TemplateDefinitionBuilder`, `ExpressionConverter`, and various helpers (i18n context, style builder, property visitors, etc).
Consider this a first pass: a lot of code has not yet been deleted (e.g. old TDB-specific test cases), and I'm sure I have missed additional helper code.
PR Close#54757
There is an edge case where synchronous navigations caused in
response to navigation events can result in a previous navigation not
being unsubscribed from. b/328219996
PR Close#54710
This commit ensures that render hooks are rerun when a node is attached
or detached. We do not necessarily need to run change detection but DOM
did change so render hooks should execute.
PR Close#54083
This commit updates the `afterRender` and `afterNextRender` hooks to
notify the scheduler (which subsequently schedules change detection)
when created. This makes the hooks similar to `requestAnimationFrame`,
which requests that the browser schedule a rendering operation. This
reqeust is not conditional. Even if there was nothing to repaint, the
`requestAnimationFrame` callback will execute.
In Angular, this is useful because callers of `afterNextRender` don't
necessarily have any way of knowing whether a change detection is even
scheduled. For example, the anchor scrolling with the Angular Router
needs to wait for rendering to complete before attempting to scroll
because rendering can affect the size of the page. However, if the user
is already on the page that the navigation is targeting, such as
navigating to an anchor on the page, there is nothing new for the Router
to render so a render might not even be scheduled.
Related to https://github.com/angular/angular/issues/53985, which
could use `afterNextRender` instead of `setTimeout` to ensure the
scrolling happens in the same frame as the page rendering, but would not
necessarily work without this change (as described above). Note that the
scrolling _cannot_ use a microtask to ensure scrolling happens in the
same frame because `NgZone` will ensure microtasks flush before
change detection, so it would cause the scroll to happen before rendering.
PR Close#54083
Currently we have the `deferrableDeclToImportDecl`, `deferBlocks`, `deferrableTypes` and `deferBlockDepsEmitMode` fields on the `R3ComponentMetadata` which is incorrect, because the interface is used both for JIT and AOT mode even though the information for those fields is AOT-specific. It will be problematic for partial compilation since the runtime will have a reference to the dependency loading function, but will not be able to provide any of the other information.
These changes make the following refactors:
1. It changes the defer-related information in `R3ComponentMetadata` to include only references to dependency functions which can be provided both in JIT and AOT.
2. Moves the AOT-specific defer analysis into the `ComponentResolutionData`.
3. Moves the construction the defer dependency function into the compilation phase of the `ComponentDecoratorHandler`.
4. Drops support for defer blocks from the `TemplateDefinitionBuilder`. This allows us to clean up some TDB-specific code and shouldn't have an effect on users since the TDB isn't used anymore.
PR Close#54700
This commit updates `ApplicationRef.tick` to use `detectChangesInternal` for root
views rather than go through the `ChangeDetectorRef.detectChanges` API
which refreshes the host view without first looking at whether the view
is `OnPush` and not dirty. The current behavior would hide errors in
`OnPush` components that do not correctly get marked for check and would
break when migrating to zoneless change detection because `markForCheck`
was never called so change detection was never scheduled.
The error would be surprising and blamed on switching to zoneless when in
reality the issue already exists and is a problem with the component not
calling `markForCheck`. However, this error is hidden today because
`ApplicationRef.tick` refresh host bindings unconditionally.
BREAKING CHANGE: `OnPush` views at the root of the application need to
be marked dirty for their host bindings to refresh. Previously, the host
bindings were refreshed for all root views without respecting the
`OnPush` change detection strategy.
PR Close#53718
In order to serialize and hydrate i18n blocks, we need to be able to walk an AST for the translated message. This AST is generated during normal parsing of the message.
PR Close#54724
The following changes help the language service code build in g3:
* `Omit<T>` produces an index signature, so we must access the resulting properties with square bracket (because `noPropertyAccessFromIndexSignature` is on in g3).
* Explicitly export `absoluteFrom` from `packages/compiler-cli/index.ts`, since the `*` re-export is patched out in g3.
* Remove const from a few const enums, since accessing const enums across modules is not compatible with `isolatedModules` (which is on in g3).
PR Close#54726
When a view has the `Dirty` flag and is reattached, we should ensure that it is
reached and refreshed during the next change detection run from above.
In addition, when a view is created and attached, we should ensure that it is reached
and refreshed during change detection. This can happen if the view is
created and attached outside a change run or when it is created and
attached after its insertion view was already checked. In both cases, we
should ensure that the view is reached and refreshed during either the
current change detection or the next one (if change detection is not
already running).
We can achieve this by creating all views with the `Dirty` flag set.
However, this does happen to be a breaking change in some scenarios.
The one identified internally was actually depending on change detection
_not_ running immediately because it relied on an input value that was
set using `ngModel`. Because `ngModel` sets its value in a `Promise`, it
is not available until the _next_ change detection cycle. Ensuring
created views run in the current change change detection will result in
different behavior in this case.
fixes#52928fixes#15634
BREAKING CHANGE: Newly created and views marked for check and reattached
during change detection are now guaranteed to be refreshed in that same
change detection cycle. Previously, if they were attached at a location
in the view tree that was already checked, they would either throw
`ExpressionChangedAfterItHasBeenCheckedError` or not be refreshed until
some future round of change detection. In rare circumstances, this
correction can cause issues. We identified one instance that relied on
the previous behavior by reading a value on initialization which was
queued to be updated in a microtask instead of being available in the
current change detection round. The component only read this value during
initialization and did not read it again after the microtask updated it.
PR Close#54735
When the `ApplicationRef` refreshes attached views, it will continue to
do so while there is still one marked for check after the refresh
completes.
BREAKING CHANGE: When Angular runs change detection, it will continue to
refresh any views attached to `ApplicationRef` that are still marked for
check after one round completes. In rare cases, this can result in infinite
loops when certain patterns continue to mark views for check using
`ChangeDetectorRef.detectChanges`. This will be surfaced as a runtime
error with the `NG0103` code.
PR Close#54734
The current behavior of `autoDetect` in `ComponentFixture` does not
match production very well. It has several flaws that make it an
insufficient change detection mechanism:
* It runs change detection for the component under test _after_ views
attached to the `ApplicationRef`. This can cause real behavior
differences that break in production, because tests can observe view
refreshes in the incorrect order (for example, a dialog refreshing
before the component which opened it).
* Because of the above ordering, render hooks registered during change
detection of the fixture views _will not execute at all_ because
`ApplicationRef.tick` already happen.
* It does not rerun change detection on the view tree if there are more
dirty views to refresh after the render hooks complete.
* It effectively hides/swallows errors from change detection inside the
`onMicrotaskEmpty` subscription by not reporting them to the error
handler. Instead, this error ends up being unhandled in the
subscription and rxjs throws these in a `setTimeout`.
All of the above are problematic but this commit _does not_ fix the
final point. Ideally, we can land this in a future change but this
requires additional internal fixes. In the meantime, we have to juggle
special-case handling of the component fixture views within
`ApplicationRef.tick` using some special events to retain current
behavior and avoid errors from the fixture propagating to the `ErrorHandler`.
BREAKING CHANGE: The `ComponentFixture.autoDetect` feature now executes
change detection for the fixture within `ApplicationRef.tick`. This more
closely matches the behavior of how a component would refresh in
production. The order of component refresh in tests may be slightly
affected as a result, especially when dealing with additional components
attached to the application, such as dialogs. Tests sensitive to this
type of change (such as screenshot tests) may need to be updated.
Concretely, this change means that the component will refresh _before_
additional views attached to `ApplicationRef` (i.e. dialog components).
Prior to this change, the fixture component would refresh _after_ other
views attached to the application.
PR Close#54733
For model signals we introduced some sniffing on the return type of a
`.subscribe` invocation- allowing for subscribe to _just_ return a
callback directly to unsubscribe.
This works in practice, but the positive `tCleanup` indices have more
meaning, especially in the context of `DebugElement`. A positive index
indicates a DOM event- so we need to revert this change. This now
surfaced as we made `EventEmitter` return a function + the subscription
via a proxy that ended up `typeof function` --> and broke some tests
where debug element incorrectly invoked non-dom outputs as dom
listeners. We don't need this change with current unsubscribe function
concept.
PR Close#54650
Currently the `makeProgram` utility from `ngtsc/testing` does not use
the test host by default- optimizing for source file caching.
Additionally, the host can be updated to attempt caching of the `.d.ts`
files from `@angular/core`— whether that's fake core, or the real core-
is irrelevant. We are never caching if these changes between tests, so
correctness is guaranteed.
This commit reduces the type check test times form 80s to just 11
seconds, faster than what it was before with `fake_core`. The ngtsc
tests also run significantly faster. From 40s to 30s
PR Close#54650
The `inject` global augmentation from upgrade tests, leak into
all source files for IDEs, making it easy to run into issues
when actually trying to deal with `inject` from Angular core for DI.
PR Close#54650
Technically `model()` and `output()` already need to be defined in an
injection context- because `OutputRef` requires this.
To improve the error messaging, this commit asserts this as part of the
top-level entry functions for `model()` and `output()`. Without this
change, the error would mention the `_createOutputRef` internal
function.
PR Close#54650
An `EventEmitter` is a construct owned by Angular that should be
used for outputs as of right now.
As we are introducing the new `OutputRef` interface for the new output
function APIs, we also think `EventEmitter` should implement
`OutputRef`— ensuring all "known" outputs follow the same contract.
This commit ensures `EventEmitter` implements an `OutputRef`
Note: An output ref captures the destroy ref from the current injection
context for clean-up purposes. This is also done for `EventEmitter` in a
backwards compatible way:
- not requiring an injection context. EventEmitter may be used
elsewhere.
- not cleaning up subscriptions/completing the emitter when the
directive/component is destroyed. This would be a change in behavior.
Note 2: The dependency on `DestroyRef` causes it to be retained in all
bundling examples because ironically `NgZone` uses `EventEmitter`- not
for outputs. The code is pretty minimal though, so that should be
acceptable.
`EventEmitter` will now always retain `NgZone. This increases the
payload size slightly around 800b for AIO. Note that the other increases
were coming from previous changes. This commit just pushed it over the
threshold.
PR Close#54650
A model signal is technically an output, at runtime and conceptually.
This commit re-uses the shared output ref logic and ensures the
interfaces match.
PR Close#54650
This commit introduces an addition to `output()` and
`outputFromObservable`()` —called `outputToObservable()`.
The helper lives in the RxJS interop package and allows agnostic
programmatic subscriptions to `OutputRef`s by converting the output
to an observable with `.pipe` etc.
The function is ideally used in all places where you subscribe to an
output programmatically. Those outputs in the future, with the new APIs,
may not be actual RxJS constructs, but abstract `OutputRef`'s that
simply expose a `.subscribe` method. The helper allows you to
agnostically convert outputs to RxJS observables that you can safely
interact with.
The observables are also completed automatically, if possible, when the
owning directive/component is destroyed— Something that is not
guaranteed right now.
PR Close#54650
Introduces a second API in addition to the new `output()` function.
The new function `outputFromObservable()` can be used to declare outputs
using the new `OutputRef` API and `output()` API, while using a custom
RxJS observable as data source.
This is something that is currently possible in Angular and we would
like to keep possible- even though we never intended to support custom
observables aside from RxJS-based `EventEmitter`.
The interop bridges the gap and allows you to continue using
`Subject`, `ReplaySubject`, `BehaivorSubjct,` - or cold custom
observables for outputs. You can still trigger logic only when
the output is subscribed- unlike with imperative `emit`s of
`EventEmitter` or the new `OutputEmitterRef`.
A notable difference is that you need two class members where you
previously could access the `Subject` directly. This is an intentional
trade-off we've made to ensure that all new outputs implement the
`OutputRef` interface and we are exposing a minimal API surface to
consumers of components that currently access the output
programmatically.
PR Close#54650
This commit allows us to detect initializer APIs like
`outputFromObservable` that are declared in different modules- not
necessarily `@angular/core`.
PR Close#54650
This commit exposes the new `output()` API with numerous benefits:
- Symmetrical API to `input()`, `model()` etc.
- Fixed types for `EventEmitter.emit`— current `emit` method of
`EventEmitter` is broken and accepts `undefined` via `emit(value?: T)`
- Removal of RxJS specific concepts from outputs. error channels,
completion channels etc. We now have a simple consistent
interface.
- Automatic clean-up of subscribers upon directive/component destory-
when subscribed programmatically.
```ts
@Directive({..})
export class MyDir {
nameChange = output<string>(); // OutputEmitterRef<string>
onClick = output(); // OutputEmitterRef<void>
}
```
Note: RxJS custom observable cases will be handled in future commits via
explicit helpers from the interop.
PR Close#54650
This commit creates the proposed `OutputRef` interface along
with `OutputEmitterRef`:
- `OutputRef` is the consistent interface for all Angular outputs.
- `OutputEmitterRef` is an extension for emitting values. Like
`EventEmitter`.
- subscriptions are cleaned up automatically upon directive/component
destroy.
- emitting is an error when destroyed
- subscribing programmatically is an error when already destroyed.
This commit will also implement the shared output ref runtime construct,
that can be used by `output()`, `outputFromObservable()` and `model()`.
We will manage subscriptions in a simple way, manually, without RxJS.
PR Close#54650
This commit replaces `fake_core` with the real `@angular/core`
output. See previous commit for reasons.
Overall, this commit:
* Replaces references of `fake_core`
* Fixes tests that were testing Angular compiler detection that _would_
already be flagged by type-checking of TS directly. We keep these
tests for now, and add `@ts-ignore` to verify the Angular checks, in
case type checking is disabled in user applications- but it's worth
considering to remove these tests. Follow-up question/non-priority.
* Adds `@ts-ignore` to the tests for `defer` 1P because the property is
marked as `@internal` and now is (correctly) causing failures in the
compiler test environment.
* Fixes a couple of tests with typos, wrong properties etc that
previously weren't detected! A good sign.
PR Close#54650
As part of improving test safety of the compiler, I've noticed that
we have a special pass for detecting external `ModuleWithProviders`
where we detect the module type from an object literal.
This literal is structured like the following: `{ngModule: T}`. The
detection currently takes `T` directly, but in practice it should be
`typeof T` to satisfy the `ModuleWithProviders` type that is accepted
as part of `Component#imports`.
This commit adds support for this, so that we can fix the unit test
in preparation for using the real Angular core types in ngtsc tests.
PR Close#54650
This adds documentation regarding the latest changes to framework merge tools. It specifically covers the requires: TGP label and separate sync for primitives.
PR Close#54664
Previously, the language service relied on deep imports such as `@angular/compiler/render3/...`. This is bad form, because that creates a dependency on the package's internal structure. Additionally, this is not compatible with google3.
In this PR, I replace all the deep imports with shallow imports, in some cases adding the missing symbol to the `compiler.ts` exports.
PR Close#54695
This commit updates TestBed logic to take into account situations when dependencies loaded within `@defer` blocks may import NgModules with providers. For such components, we invoke provider override function, which recursively inspects and applies the necessary changes.
PR Close#54667
In zone-full applications, this is already true because effects are
scheduled inside a microtask and tracked by ZoneJS. When not using
zones, this should stay consistent on principle and for testability
reasons. A general pattern with zoneless testing will be to update state
and `await` some promise (i.e. `fixture.whenStable`, which will be
linked to `ApplicationRef.isStable`).
PR Close#53835
The current behavior of `autoDetect` in `ComponentFixture` does not
match production very well. It has several flaws that make it an
insufficient change detection mechanism:
* It runs change detection for the component under test _after_ views
attached to the `ApplicationRef`. This can cause real behavior
differences that break in production, because tests can observe view
refreshes in the incorrect order (for example, a dialog refreshing
before the component which opened it).
* Because of the above ordering, render hooks registered during change
detection of the fixture views _will not execute at all_ because
`ApplicationRef.tick` already happen.
* It does not rerun change detection on the view tree if there are more
dirty views to refresh after the render hooks complete.
* It effectively hides/swallows errors from change detection inside the
`onMicrotaskEmpty` subscription by not reporting them to the error
handler. Instead, this error ends up being unhandled in the
subscription and rxjs throws these in a `setTimeout`.
All of the above are problematic but this commit _does not_ fix the
final point. Ideally, we can land this in a future change but this
requires additional internal fixes. In the meantime, we have to juggle
special-case handling of the component fixture views within
`ApplicationRef.tick` using some special events to retain current
behavior and avoid errors from the fixture propagating to the `ErrorHandler`.
breaking note for future when isG3 flag condition is removed for v18:
The `ComponentFixture.autoDetect` feature now executes
change detection for the fixture within `ApplicationRef.tick`. This more
closely matches the behavior of how a component would refresh in
production. The order of component refresh in tests may be slightly
affected as a result, especially when dealing with additional components
attached to the application, such as dialogs. Tests sensitive to this
type of change (such as screenshot tests) may need to be updated.
PR Close#54354
One downside of implicit dependency tracking in `effect()`s is that it's easy
to for downstream code to end up running inside the effect context by accident.
For example, if an effect raises an event (e.g. by `next()`ing a `Subject`), the
subscribers to that `Observable` will run inside the effect's reactive context,
and any signals read within the subscriber will end up as dependencies of the
effect. This is why the `untracked` function is useful, to run certain
operations without incidental signal reads ending up tracked.
However, knowing when this is necessary is non-trivial. For example, injecting
a dependency might cause it to be instantiated, which would run the constructor
in the effect context unless the injection operation is untracked.
Therefore, Angular will automatically drop the reactive context within a number
of framework APIs. This commit addresses these use cases:
* creating and destroying views
* creating and destroying DI injectors
* injecting dependencies
* emitting outputs
Fixes#54548
There are likely other APIs which would benefit from this approach, but this
is a start.
PR Close#54614
This refactor makes it easier to update the return types of guards.
Rather than having to track what types guards can return, which may
change with new features over time, `MaybeAsync<GuardResult>` can be
used instead.
PR Close#54580
As a part of #54154, an old parser behavior came up where two-way bindings were parsed by appending `= $event` to the event side. This was problematic, because it allowed some non-writable expressions to be passed into two-way bindings.
These changes introduce a migration that will change the two-way bindings into two separate input/output bindings that represent the old behavior so that in a future version we can throw a parser error for the invalid expressions.
```ts
// Before
@Component({
template: `<input [(ngModel)]="a && b"/>`
})
export class MyComp {}
// After
@Component({
template: `<input [ngModel]="a && b" (ngModelChange)="a && (b = $event)"/>`
})
export class MyComp {}
```
PR Close#54630
Fixes that a query like `viewChild('locator', {read: ElementRef<HTMLElement>})` would throw because we didn't account for expressions with type parameters.
I've also included support for parenthesized expressions and `as` expressions since it's pretty easy to support them.
Fixes#54645.
PR Close#54647
Updated the "Setting up Zone.js" instructions to the latest convention from
how the Angular CLI configures it.
Include adding zone-flats.ts to the tsconfig.app.json file step.
Added src/ to zone-flag.ts in the code example.
PR Close#52409
Add more details around:
- What we consider a breaking change
- What is a deprecation
- How do we guarantee Angular stays stable
- Update invalid links
PR Close#51423
Angular has the `@Attribute` decorator that allows for attributes to be injected from the host node, but we don't have an equivalent for the `inject` function. These changes introduce the new `HostAttributeToken` class that can be used to inject attributes similarly to `@Attribute`. It can be used as follows:
```typescript
import {HostAttributeToken, inject} from '@angular/core';
class MyDir {
someAttr = inject(new HostAttributeToken('some-attr'));
}
```
The new API works similarly to `@Attribute` with one key exception: it will throw a DI error when the attribute doesn't exist, instead of returning `null` like `@Attribute`. We made this change to align its behavior closer to other injection tokens.
PR Close#54604
This commit ensures that any internal render hooks that cause views to
become dirty again first refresh those dirty views before running user
render hooks. This ensures that user render hooks have the most complete
render state possible and stops them from needlessly executing multiple
times. This is important to maintain the goal of the public render
hooks, which is to provide the safest place to place code that depends
on DOM state, especially in ways that may force a browser paint.
PR Close#54224
This adds a helper function to defer application state updates to the
first possible "safe" moment. If application-wide change detection
(ApplicationRef.tick) is currently executing when this function is used,
the callback will execute as soon as all views attached to the
`ApplicationRef` have been refreshed. Refreshing the application views
will happen again before `checkNoChanges` executes.
When a change detection is _not_ running, this state update will execute
in the microtask queue.
This function is necessary as a replacement for current
`Promise.resolve().then(() => stateUpdate())` to be zoneless compatible
while ensuring those state updates are synchronized to the DOM before
the browser repaint. Without this, updates done in `Promise.resolve(...)` would
queue another round of change detection in zoneless applications, and
this change detection could happen in the next browser frame, and cause
noticeable flicker for the user.
Additionally, this function provides a way to perform state updates that
will run on the server as well as in the browser.
Last, current applications using `ngZone: 'noop'` may not be
calling `ApplicationRef.tick` at all so this function provides a
mechanism to ensure the state update still happens by racing
a microtask with `afterNextRender` (which might never execute).
PR Close#54224
Fixes that initializer functions weren't being recognized if they are aliased (e.g. `import {model as alias} from '@angular/core';`).
To do this efficiently, I had to introduce the `ImportedSymbolsTracker` which scans the top-level imports of a file and allows them to be checked quickly, without having to go through the type checker. It will be useful in the future when verifying that that initializer APIs aren't used in unexpected places.
I've also introduced tests specifically for the `tryParseInitializerApiMember` function so that we can test it in isolation instead of going through the various functions that call into it.
PR Close#54609
Currently, when a `@defer` block contains standalone components that import NgModules with providers, those providers are not available to components declared within the same NgModule. The problem is that the standalone injector is not created for the host component (that hosts this `@defer` block), since dependencies become defer-loaded, thus no information is available at host component creation time.
This commit updates the logic to collect all providers from all NgModules used as a dependency for standalone components used within a `@defer` block. When an instance of a defer block is created, a new environment injector instance with those providers is created.
Resolves#52876.
PR Close#52881
This PR enhances the Angular documentation by replacing the placeholder `<component-name>` with the actual `PageNotFoundComponent` in the wildcard route configuration. This update ensures that the documentation accurately reflects the recommended practice for handling page-not-found scenarios. Additionally, it addresses the issue where HTML entities like `<` were being displayed instead of the desired `<` symbol, resulting in clearer and more readable documentation for users.
PR Close#54570
Fixes that initializer functions weren't being recognized if they are aliased (e.g. `import {model as alias} from '@angular/core';`).
To do this efficiently, I had to introduce the `ImportedSymbolsTracker` which scans the top-level imports of a file and allows them to be checked quickly, without having to go through the type checker. It will be useful in the future when verifying that that initializer APIs aren't used in unexpected places.
I've also introduced tests specifically for the `tryParseInitializerApiMember` function so that we can test it in isolation instead of going through the various functions that call into it.
PR Close#54480
The diagnostic for signals that haven't been invoked wasn't working internally, because the path to `@angular/core` is different. These changes resolve the issue and do some general cleanup.
PR Close#54585
Fixes an edge case where a single-line elemnt with a long tag name a closing bracket on a new line was putting the control flow migration into an infinite loop.
Fixes#54587.
PR Close#54588
Template pipeline is now the default template compiler.
A pair of source map tests is failing, related to DI in JIT mode; I will fix and re-enable these during the preview period.
PR Close#54571
ApplicationRef.tick has a loop that will refresh views again that have
an updated signal. This change ensures views marked with the `Dirty`
flag are also considered in this loop, but only inside g3 for now
because this may be considered a breaking change and we need to wait for
v18 to land externally.
PR Close#54572
This commit prevents `AsyncPipe` from calling `markForCheck` when values
are synchronously emit during subscription to an observable. This
prevents subscriptions to `Replay` observables from needlessly walking
up to the root of the view tree during template execution for each
new replay observable in the template.
PR Close#54554
Use no-remote-exec to allow for building and serving to occur locally but still allow remote caching. Because of the number of
files involved in being passed to and from the RBE server, it is actually a bit faster to perform these actions locally.
PR Close#54549
In rare cases people may use an underscore in their component names, which was not accounted for in the formatting portion of the migration.
fixes: #54532
PR Close#54533
This provides some more information on how to release and notably includes commands for zipping extension code and source code, which can otherwise be tricky to get exactly right.
PR Close#54525
This is based on an internal issue report.
An earlier change introduced a diagnostic to report cases where a symbol is in the `deferredImports` array, but is used eagerly. The check worked by looking through the deferred blocks in a scope, resolving the scope for each and checking if the element is within the scope. The problem is that resolving the scope won't work across scoped node boundaries. For example, if there's a control flow statement around the block or within the block but around the deferred dependency, it won't be able to resolve the scope since it isn't a direct child, e.g.
```
@if (true) {
@defer {
<deferred-dep/>
}
}
```
To fix this the case where the deferred block is inside a scoped node, I've changed the `R3BoundTarget.deferBlocks` to be a `Map` holding both the deferred block and its corresponding scope. Then to resolve the case where the dependency is within a scoped node inside the deferred block, I've added a depth-first traversal through the scopes within the deferred block.
PR Close#54499
We have a couple of cases now (#53753 and #54414) where we're forced to redefine enums as object literals. These literals aren't rendered in the best way in the docs so these changes introduce a new `object-literal-as-enum` tag that we can use to mark them so they're treated for documentation purposes.
PR Close#54487
This change allows template binding "inert" attribute with the following syntax: [inert]="isInert"
Fixes#51879
fixup! fix(compiler): adding the inert property to the "SCHEMA" array
revert: "fixup! fix(compiler): adding the inert property to the "SCHEMA" array"
This reverts commit b637b7ce646e8bab2f585339028a84018e8ea982.
This commit is being reverted because the inert property is safe as a boolean attribute
PR Close#53148
This commit addresses a problem with PR #53695 that introduced support for default imports,
where the actual dynamic import used in the defer loading function continued to use the
symbol name, instead of `.default` for the dynamic import. This issue went unnoticed in the
testcase because a proper instance was being generated for the `ɵsetClassMetadataAsync` function,
but not the generated dependency loader function.
Fixes#54491
PR Close#54495
Prior to this fix an incorrect view instance (a dynamically created component
one instead of the root view) was passed to the content query function. Having
incorrect view instance meant that a component instance could not be found.
This is a pre-existing bug, introduction of signal-based queries just surfaced it.
Fixes#54450
PR Close#54457
The documentation on angular.dev mentions build-angular:browser as default
application builder. This is not correct. Recent applications are setup
with build-angular:application by default.
PR Close#54386
In the Angular DevTools Chrome DevTools page:
- Angular DevTools is able to ask the background script to list each frame that has been registered on a page.
- Angular Devtools is able to ask the background script to "enable" the connection on a particular frame. This enables the messaging between the content script <-> background script <-> devtools page
- Implements detection of non unique urls on the inspected page
Limitations:
- The `inspectedWindow.eval` API is only able to target frames by frameURL. This means some features that integrate with Chrome DevTools like inspect element and open source will not be available when inspecting frames that do not have a unique url on the page.
PR Close#53934
Modifies the messaging layer of devtools to allow for switching communication between frames on a page. When served as a browser extension.
Design:
- When a page renders, DevTools installs a content script onto it through it's manifest file. The all_frames option is used here to install this script onto every frame in a page.
- When Angular is detected, the content script will install a backend script into it's frame.
- Each content script / backend script pairing is kept track of in the background script. This pairing represents an angular devtools context in a particular frame.
- Angular DevTools is able to ask the background script to list each frame that has been registered on a page.
- Angular Devtools is able to ask the background script to "enable" the connection on a particular frame. This enables the messaging between the content script <-> background script <-> devtools page
Limitations:
- The `inspectedWindow.eval` API is only able to target frames by frameURL. This means some features that integrate with Chrome DevTools like inspect element and open source will not be available when inspecting frames that do not have a unique url on the page.
PR Close#53934
When the linker is running using an unpublished version of angular, locally built, the version will be `0.0.0`.
When encountering this situation, the range that for the linker map support is considered to be `*.*.*` allowing
for the linker to work at build time with packages built with versioned angular.
Most notably this allows for us to properly use the linker in building our documentation site with the locally
built version of angular.
PR Close#54439
The version detection condition for signal two-way bindings used an OR
instead of an AND, resulting in every `.0` patch version being considered
as supporting two-way bindings to signals.
This commit fixes the logic and adds additional parentheses to ensure the
meaning of the condition is more clear. Long term, we should switch to
semver version parsing instead.
PR Close#54443
In order to allow both signals and non-signals in two-way bindings, we have to pass the expression through `ɵunwrapWritableSignal`. The problem is that the language service uses a bundled compiler that is fairly new, but it may be compiling an older version of Angular that doesn't expose `ɵunwrapWritableSignal` (see https://github.com/angular/vscode-ng-language-service/issues/2001).
These changes add a `_angularCoreVersion` flag to the compiler which the language service can use to pass the parsed Angular version to the compiler which can then decide whether to emit the function.
PR Close#54423
Currently all triggers are set up to show the placeholder block on the server, except for `on immediate` which is basically a noop. These changes update `on immediate` to match the rest of the triggers.
Fixes#54385.
PR Close#54394
Getting the typing for `ɵunwrapWritableSignal` just right was tricky so these changes add some tests to ensure that we don't regress.
Also reworks the type tester a bit to make it easier to find where to add new test files.
PR Close#54387
This commit updates the implementation of the `customElements` patch and also
patches FACE callbacks (`formAssociatedCallback`, `formDisabledCallback`, `formResetCallback`
and `formStateRestoreCallback`). This now allows invoking those callbacks in the same zone
where the custom element has been defined.
PR Close#50686
Assure that the same readonly array corresponding to the children query results
is returned for cases where a query is marked as dirty but there were no actual
changes to the content of the results array (this can happen if a view is added
and removed thus marking queries as dirty but not influencing final results).
Fixes#54376
PR Close#54392
Creates a "fast mode" for building the adev site, currently only disabling prerender during fast build.
This is intended to be used for local development.
PR Close#54364
The newly introduced signal queries would error if no match exists, due to an
invalid read within the query internals.
This commit addresses the crash by allowing there to be no matches.
PR Close#54353
Currently we have two fake copies of `@angular/core` in the compiler tests which can be out of sync and cause inconsistent tests. These changes reuse a single copy instead.
PR Close#54344
This updates some tests to use the public imports from `@angular/core` now that they are available,
and cleans up useless imports and inaccurate names.
PR Close#54334
In some situations, calling `markForCheck` can result in an infinite
loop in seemingly valid scenarios. When a transplanted view is inserted
before its declaration, it gets refreshed in the retry loop of
`detectChanges`. At this point, the `Dirty` flag has been cleared from
all parents. Calling `markForCheck` marks the insertion tree up to the
root `Dirty`. If the declaration is checked again as a result (i.e.
because it has default change detection) and is reachable because its
parent was marked `Dirty`, this can cause an infinite loop. The
declaration is refreshed again, so the insertion is marked for refresh
(again). We enter an infinite loop if the insertion tree always calls
`markForCheck` for some reason (i.e. `{{createReplayObservable() | async}}`).
While the case above does fall into an infinite loop, it also truly is a
problem in the application. While it's not an infinite synchronous loop,
the declaration and insertion are infinitely dirty and will be refreshed
on every change detection round.
Usually `markForCheck` does not have this problem because the `Dirty`
flag is not cleared until the very end of change detection. However, if
the view did not already have the `Dirty` flag set, it is never cleared
because we never entered view refresh. One solution to this problem
could be to clear the `Dirty` flag even after skipping view refresh but
traversing to children.
PR Close#54329
The `subscribe` methods on `ModelSignal` and `OutputEmitter` were marked as `@internal` which will break when the TCB needs to reference them. These changes make them `@deprecated` temporarily so we can address the properly later.
PR Close#54342
The new `model()` signal introduces a `ModelSignal` type that needs to be handled by the interpolatedSignalNotInvoked diagnostic to catch issues like:
```
<div>{{ myModel }}</div>
```
PR Close#54338
Add an image loader for Netlify Image CDN. It is slightly different in implementation from existing loaders, because it allows absolute URLs
Fixes#54303
PR Close#54311
The import of `module` can conflict with the native global variable called `module` and can break some internal tests. These switch to only importing the function we need.
PR Close#54333
Adds usages of signal-based queries into the signal integration test to
verify queries can be used in production, and testing environments as
expected (i.e. the transform works as expected).
PR Close#54314
This helps with the Angular CLI currently swallowing fatal diagnostic
errors in ways that are extremely difficult to debug due to workers
executing Angular compiler logic.
The worker logic, via piscina, is currently not forwarding such Angular
errors because those don't extend `Error.`
https://github.com/piscinajs/piscina/blob/a7042ea27d129f3cad75c422f5aa92f0663854ee/src/worker.ts#L175
Even with access to these errors by manually forwarding errors, via
patching of the Angular CLI, there is no stack trace due to us not using
`Error` as base class for fatal diagnostic errors. This commit improves
this for future debugging and also better reporting of such errors to
our users- if we would accidentally leak one.
PR Close#54309
An identical addition to: 760b1f3d0b.
This commit expands the `try/catch`-es:
- to properly NOT throw and just convert the diagnostic.
- to be in place for all top-level instances. Notably, this logic cannot
reside in the template type checker directly as otherwise we would
risk multiple duplicate diagnostics.
PR Close#54309
Fixes that `ɵunwrapWritableSignal` inferring getter functions as not matching the interface of `WritableSignal` instead of preserving them.
PR Close#54252
In a previous commit the TCB was changed to cast the assignment to an input in order to widen its type to allow `WritableSignal`. This ended up breaking existing inputs whose setter has a wider type than its getter. These changes switch to unwrapping the value on the binding side.
PR Close#54252
Reworks the TCB for two-way bindings to make them simpler and to avoid regressions for two-way bindings to generic inputs. The new TCB looks as follows:
```
var _t1: Dir;
var _t2 = _t1.input;
(_t1 as typeof _t2 | WritableSignal<typeof _t2>) = expression;
```
PR Close#54252
Adds support for model inputs in the framework. `model()` returns a writable signal that implicitly defines a input/output pair that can be used either in two-way bindings to keep two values in sync or by binding individually to the input and output. When the value of the `model` changes, it will emit an event with the current value.
Furthermore, these changes expand two-way bindings to accept `WritableSignal`. This will make it easier to transition existing code to signals in a backwards-compatible way.
Example:
```ts
@Directive({
selector: 'counter',
standalone: true,
host: {
'(click)': 'increment()',
}
})
export class Counter {
value = model(0);
increment(): void {
this.value.update(current => current + 1);
}
}
@Component({
template: `<counter [(value)]="count"/> The current count is: {{count()}}`,
})
class App {
count = signal(0);
}
```
PR Close#54252
This commit improves IDE completion of the `read` option for
signal-based queries.
Currently, TS only matches the first overload when starting out with
defining a query. TS doesn't build up the combination of possible
options from the second overload- so in practice users will only see
IDE completions for the `descendants` option.
This is not a problem for view queries as the only option is `read`, so
TS will always match the overload with the `read` option.
```
class X {
query = contentChild('', {^^ <--
here we should completion for `read` an `descendants`
}
```
PR Close#54280
Currently the error is a generic error "exportAs must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the error is a generic error "selector must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the error is a generic error "selector must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the correct error message is shown only if @Component.styles is an array with some unresolved element. This change supports the new case of string type for the @Component.styles field.
PR Close#54230
A helper `validateLocalCompilationUnresolvedConst` is added to encapsulate a common pattern which leads to the error `LOCAL_COMPILATION_UNRESOLVED_CONST`.
PR Close#54230
The trailing error message comes from tracing the chain of DymaicValue which leads to a mostly useless error that highlights the same symbol as the original message and emits the error message "Unknown reference". This error message is removed in the favour of the original message which suffices.
PR Close#54230
A single error code is created to unify the common error pattern in local compilation mode where an imported const cannot be resolved, but needs to be resolved. This mainly happens for Angular decorator fields such as @Component.template.
The error messages are also upgraded to be more centered around this unifying theme.
PR Close#54230
Currently, when two components are named `TestComponent`, and both would
use e.g. control flow. Templates would be generated by the compiler and
those would conflict at runtime because the names for the template
functions are not ensured to be unique.
This seems like a more general problem that could be tackled in the
future in the template pipeline by always using the `ConstantPool`, but
for now, we should be good already, given us ensuring the `baseName`'s are
always unique.
PR Close#54273
This commit updates the implementation of the zone.js `fs` patch to
restore the implementation of `realpath.native` and patches it as a macrotask,
along with other functions of the `fs` package. This is the only nested function
that must be patched.
Closes: #45546
PR Close#54208
The `read` option for queries can rely on lexical variables inside the
class. These constructs are fine from a technical perspective in
TypeScript, but in practice, when the component/directive definition is
being created, the read value is extracted into the definition,
**outside** of the class. This breaks `this` references.
To fix this, we are restricting the `read` option to literal values.
Similar to `descendants`. Literal references are in practice constructs
like:
- `read: bla.X`
- `read: X`
where `bla` or `X` is never a `ThisKeywoord`- hence fixing the issue
and also simplifying the patterns for easier single file compilation.
PR Close#54257
This commit adds a JIT transform for signal-based queries, so that
queries are working as expected in JIT environments like `ng test` where
decorator metadata is needed as a prerequisite for the component
definition creation.
This is similar to the JIT transforms for signal inputs etc.
PR Close#54257
Extracts common JIT transform helper into the transform API, so that
those helpers can be re-used for output, model, queries and inputs.
PR Close#54257
Adding debug information for failing firebase deploy, hoping
to yield information about the missing resource. The next
multi-site seems to be failing, but is available.
PR Close#54275
The compileNgModuleFactory dont need to be in the application_ref file (in fact
the whole logic has little to do with ApplicationRef and it is not even called
from the application_ref). Performing this move to avoid circular dependencies
when the new query as signals authoring functions are exported.
PR Close#54103
This commit changes the approach to the reactive node representing query
results: instead of creating a custom node type we can use a computed -
the main change to get there is representing dirty change notification as
a signal (a counter updated every time a query changes its dirty status).
This change is dictated by simplification (we can avoid creation of a custom
signal type) as well as fixes to the multiple issues not covered by the
initial implementation:
- assuring referential stability of results (ex.: the same array instance
returned from child queries until results change);
- per-view results collection to avoid a situation where accessing query
results during view creation would return partial / inconsistent results;
- proper refresh of query results for both live and non-connected consumers.
All the above cases are covered by the additional tests in this commit.
PR Close#54103
This commit adds tests for content queries and fixes the arguments
order in the contentQuerySignal instruction, thus fixing a bug
discovered while adding tests.
PR Close#54103
This commits converts the hand-written tests into their usual,
compiled form. We can perform this change now since the compiler
bits of the queries-as-signal story landed.
PR Close#54103
This commit updates the logic of defer blocks to create an internal pending task to indicate that an application is not yet stable. This change would be helpful for zoneless applications.
PR Close#54239
Updates the acceptance authoring test compiler targets to support
multiple spec files. This will be useful for output, model, inputs
and queries.
PR Close#54253
Adds `output()` to the signal inputs integration test to verify
full integration with the Angular CLI. In the future we may
consider renaming the test to something less specific to signal inputs,
but for now this serves the purpose and `output()` is a closely related
part to signal-based inputs.
it doesn't warrant creating another new integration test, as those are
quite expensive to maintain and run.
PR Close#54217
The `listener` instruction currently always assumes RxJS subscribables,
and verifies this via `isSubscribable`. The type narrowing is not
ignored and the type remains `any` given the `ngDevMode` check.
This commit improves type safety, and actually switches to a dedicated
interface for "output subscribable" values. This is needed because
`Subscribable` from `RxJS` is typed to expect an observer in object
literal form- which is not correct and doesn't apply to `EventEmitter`
and matches the form of `.subscribe` we are using in the `listener`
instruction.
PR Close#54217
Similar to `input()`, initializer-based `output()`'s need to be
transformed in JIT to be annotated with an `@Output()` decorator.
This is necessary so that Angular can statically collect all defined
outputs without instantiating the class (which would not be possible
upon directive definition computation).
This commit introduces a transform next to the input transform that
automatically runs with the Angular CLI and `ng test`.
PR Close#54217
Adds type check diagnostic tests for the `output()` API. This
is necessary because we are maintaining a separate emitter
for `output()` as with the current design (still discussed - but this is
a starting foundation).
Note: `OutputEmitter` currently does not publicly expose `.subscribe`,
while the testing infrastructure exposes it for now. That is because we
are still discussing this before making changes in the TCB to account
for the case where `.subscribe` might be `@internal` ultimately.
PR Close#54217
Generalizes the type check table scenario testing infrastructure
so that it can also be used for testing outputs in a table-scheme
without a lot of TS code repetition.
PR Close#54217
Adds an ngtsc diagnostic and compilation output test for `output()`. The
test will verify certain recognition restrictions and ensures that
diagnostics are raised, in addition to proper full compilation output
being generated (aside from the compliance tests verifying output more
closely).
PR Close#54217
Adds compliance output tests for `output()` to verify that
we are emitting proper full compilation output, as well as proper
partial compilation output that can be linked to match the full output.
PR Close#54217
This commit introduces the `output()` function and corresponding
runtime code.
In practice, `output()` will defer to `EventEmitter` as outlined in the
RFC, but we are considering limiting the type to a minimal version that
is not coupled with RxJS, less complex, and also has better type safety
around emitting of values.
E.g. currently `EventEmitter.emit` can always be called without
any value, even though the output may be typed to always pass around
values of type `T`. This could cause subtle and confusing bugs.
PR Close#54217
As we are introducing the new `output()` function as an inituive
alternative to `@Output()` that matches with signal-based inputs,
this commit prepares the compiler to detect such initializer-based
outputs.
PR Close#54217
The deps tracker which is responsible to track orphan components does not work for classes mutated by custom decorator. Some work needed to make this happen (tracked in b/320536434). As a result, with option `forbidOrphanComponents` being true the deps tracker will falsely report any component as orphan if it or its NgModule have custom/duplicate decorators. So it is unsafe to use this option in the presence of custom/duplicate decorator and we disable it until it is made compatible. Note that applying custom/duplicate decorators to `@Injectable` classes is ok since these classes never make it into the deps tracker. So we excempt them.
PR Close#54139
Custom/duplicate decorators break the deps tracker in local mode. But deps tracker only deals with non-injectable classes. So applying custom/duplicate decorators to `@Injectable` only classes does not disturb deps tracker and local compilation in general. There are also ~ 100 such cases in g3 which cannot be cleaned up.
PR Close#54139
For cases like this:
```
@Component({...})
@Component({...})
export class SomeComp {
}
```
The `DecoratorHandler.detect` apparantly matches only one of the `@Component` decorator, leaving the other undetected which will be transformed by TS decorator helper and that breaks local compilation runtimes. But the error message only mentioned "custom" decorator, while in this case it is a "duplicate Angular" decorator. The respective error message is updated thus.
PR Close#54139
Consider the following very quirky Angular template, which has both an i18n attribute binding and a property binding to `in`:
```
<cmp [in]="foo" in="bar" i18n-in />
```
What would you expect the above template to do? `TemplateDefinitionBuilder` will emit the following Ivy instructions:
```
// Element constant attributes
consts: () => {
__i18nMsg__('bar', [], {}, {})
return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
// Create mode
i0.ɵɵelement(0, "cmp", 0);
}
}
```
This makes some sense -- we create a single element, and attach an i18n message to the `in` attribute. But is this actually correct? Notice that the property binding is completely missing!
Indeed, Template Pipeline actually produces this code:
```
// Element constant attributes
consts: () => {
__i18nMsg__('bar', [], {}, {})
return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
// Create mode
i0.ɵɵelement(0, "cmp", 0);
} else if (rf & 2) {
// Update mode
i0.ɵɵproperty("in", ctx.foo);
}
}
```
Aha! There's the property binding! Arguably, this is a bug in `TemplateDefinitionBuilder`, but after some discussion on Slack, we have decided to ban this practice in a future Angular version.
For now, we allow Template Pipeline to have slightly different output, but print an error to warn the user of the issue.
PR Close#54063
This test ensures that the `ExpressionChanged...` error does not happen
when signals are updated in a view that is attached to `ApplicationRef`
but was already checked. This was fixed in 432afd1ef4
which actually consequently fixes it for regular `markForCheck` as well.
PR Close#54206
* Renames the `input_signals` directory to `signals` so it can be reused for other tests.
* Reworks the build file to allow multiple test files.
PR Close#54213
Instead of maintaining individual transforms for `input`, `output`,
`model` etc. we are grouping them directly and the first one matching,
will execute.
This reduces needed traversal through AST and also makes it a little
more clean to write new initializer API metadata transforms.
Note: The Angular JIT transform is now also moving from `tooling.ts`
directly into `/transformers` for more local placement of transformer
logic.
PR Close#54200
Fixes that `@defer` blocks weren't recognizing default imports and generating the proper code for them. Default symbols need to be accessed through the `default` property in the `import` statement, rather than by their name.
PR Close#53695
One of the earlier commits separated one-way and two-way bindings which ended up breaking some internal targets, because it changed the assignment order. These changes bring back the old order.
PR Close#54154
In one of the earlier commits, the logic that appends `=$event` before parsing two-way bindings was removed and some validation was added to prevent unassignable expressions from being used. This ended up being problematic, because previously the parser was incorrectly allowing some invalid expressions which users came to depend on. For example, it transformed `[(value)]="a && a.b"` to `a && (a.b = $event)`.
These changes add some special cases for the common breakages that came up during the TGP.
PR Close#54154
Updates the template definition builder to emit the new format for the listener side of two-way bindings.
```js
// Before
listener("ngModelChange", function($event) {
return ctx.name = $event;
});
// After
ɵɵtwoWayListener("ngModelChange", function($event) {
ɵɵtwoWayBindingSet(ctx.name, $event) || (ctx.name = $event);
return $event;
});
```
PR Close#54154
Currently the listener side two-way listeners are parsed by appending `=$event` to the raw expression. This is problematic, because:
1. It can interfere with other expressions (see #37809).
2. It can lead to confusing error messages because users will see code that they didn't write.
3. It doesn't allow us to further manipulate the expression.
These changes remove the logic that appends `=$event` to resolve the issue. There's also some new logic that checks the expression after it has been parsed to ensure that the result is an assignable expression.
Subsequent commits will update the code that emits the expression to add back the `$event` assignment where it's needed.
PR Close#54154
Adds the following new instructions:
* `twoWayBindingSet` - used to assign values inside of the listener side of a two-way binding. Currently a noop, but will come into play later.
* `twoWayListener` - used to bind a two-way listener. Currently calls directly into `listener`, but it may be useful in the future.
PR Close#54154
Currently all the members of `_ParseAST` are public, even though they're all used only within the class. This change marks them as private so that it's explicit which ones are intended to be used outside the class.
PR Close#54154
Reworks the compiler so that it generates a `twoWayProperty` instruction, instead of `property`, for the property side of a two-way binding. Currently the new instruction passes through to `property`, but it'll have some two-way-binding-specific logic in subsequent PRs.
PR Close#54154
It was always the intent to have `afterRender` hooks allow updating
state, as long as those state updates specifically mark views for
(re)check. This commit delivers that behavior. Developers can now use
`afterRender` hooks to perform further updates within the same change
detection cycle rather than needing to defer this work to another round
(i.e. `queueMicrotask(() => <<updateState>>)`). This is an important
change to support migrating from the `queueMicrotask`-style deferred
updates, which are not entirely compatible with zoneless or event `NgZone` run
coalescing.
When using a microtask to update state after a render, it
doesn't work with coalescing because the render may not have happened
yet (coalescing and zoneless use `requestAnimationFrame` while the
default for `NgZone` is effectively a microtask-based change detection
scheduler). Second, when using a `microtask` _during_ change detection to defer
updates to the next cycle, this can cause updates to be split across
multiple frames with run coalescing and with zoneless (again, because of
`requestAnimationFrame`/`macrotask` change detection scheduling).
PR Close#54074
This change updates the `checkNoChanges` pass to only run once after
both view refresh and `afterRender` hooks execute rather than both
before and after the hooks. The original motivation was to specifically
ensure that the application was in a "clean state" before running the
`afterRender` hooks and ensure that `afterRender` hooks don't "fix"
`ExpressionChanged...` errors. This, however, adds to the complexity and
cost of running change detection in dev mode. Instead, the
`checkNoChanges` pass runs once we have done all render-related work and
want to ensure that the application state has been synced to the DOM
(without additional changes).
PR Close#54074
Errors during change detection are terminal and we do not generally
attempt to continue processing or recover after one occurs. This helps clean
up the `tick` implementation with respect to running `afterRender` hooks.
PR Close#54074
ISO 8601 defines
* Monday as the first day of the week.
* week 01 is the week with the first Thursday
Therefore:
Sunday Dec 31st 2023 is the last day of the last week of the year : W52 2023.
PR Close#53879
This commit updates the implementation of the `fetch` patch and additionally
patches `Response` methods which return promises. These are `arrayBuffer`, `blob`,
`formData`, `json` and `text`. This fixes the issue when zone becomes stable too early
before all of the `fetch` tasks complete. Given the following code:
```ts
appRef.isStable.subscribe(console.log);
fetch(...).then(response => response.json()).then(console.log);
```
The `isStable` observer would log `false, true, false, true`. This was happening because
`json()` was returning a native promise (and not a `ZoneAwarePromise`). But calling `then`
on the native promise returns a `ZoneAwarePromise` which notifies Angular about the task
being scheduled and forces to re-calculate the `isStable` state.
Issue: #50327
PR Close#50653
This commit updates the signature of the `ZoneGlobalConfigurations` interface and adds
missing `__Zone_ignore_on_properties` property, which may be setup to ignore specific `on`
properties from being patched.
PR Close#50737
`isNavigationCancelingError` & `isRedirectingNavigationCancelingError` had duplicate implementations. This commit also cleans-up those functions.
PR Close#53762
This commit adds hydration informations to the devtools.
* List of hydrated/hydrated components
* Shows hydration overlays
* Shows hydration errors for NG0500, 501 & 502
PR Close#53910
At the moment the extra import generation in local compilation mode fails if these extra imports produce a cycle. To handle this, the cycle handling strategy is updated for local compilation, and following the behaviour in the full compilation mode, the compiler does not generate extra import if it leads to cycle and instead leave things to the runtime.
PR Close#53543
With option `generateExtraImportsInLocalMode` set, in local mode the compiler generates extra imports for each component local dependencies. Here local dependencies means all component's dependencies within the same compilation unit.
To achieve this, the compiler performs a "local version" of its regular static analysis to find each component's deps, and these deps are used to generate extra side effect imports.
PR Close#53543
In this commit the resolve method for components is run fully when the option `generateExtraImportsInLocalMode` is set. This is because we need local component depedencies in order to generate extra imports causing by them. This requires cutting some resolve phase logics that are unnecessary in local mode, such as diagnostics.
PR Close#53543
When option `generateExtraImportsInLocalMode` is set, we need to compute component local depednecies in order to generate extra imports related to them. At the same time running the register phase in general is harmless in local compilation. So we run it anyway.
PR Close#53543
With option `generateExtraImportsInLocalMode` set in local compilation mode, the compiler generates extra side effect imports using this rule: any external module from which an identifier is imported into an NgModule will be added as side effect import to every file in the compilation unit. To illustrate this better assume the compilation unit has source files `a.ts` and `b.ts`, and:
```
// a.ts
import {SomeExternalStuff} from 'path/to/some_where';
import {SomeExternalStuff2} from 'path/to/some_where2';
...
@NgModule({imports: [SomeExternalStuff]})
```
then the extra import `import "path/to/some_where"` will be added to both `a.js` and `b.js`. Note that this is not the case for `import "path/to/some_where2"` though, since the symbol `SomeExternalStuff2` is not imported into any NgModule.
The math behind this mechanism is, in local compilation mode we cannot resolve component external dependencies fully. For example if a component in `a.ts` uses an external component defined in an external file `some_external_comp.ts` then we can generate the import to this file in `a.js`. Instead, we want to generate an import to a file that "gurantees" that `a.js` is placed after `some_external_comp.js` in the bundle. Now since the component in `some_external_comp.ts` is used in `a.ts`, then there must be a chain of imports starting from the NgModule that declares the component in `a.ts` to the component in `some_external_comp.ts`. This chain means some file in the same compilation unit as `a.ts` should import some external NgModule which includes `some_external_comp.ts` in its transitive closure and import it to some NgModule. So by adding this import to `a.js` we ensure that the bundling will have the right order.
PR Close#53543
As the first step, the import manager's `generateSideEffectImport` method is implemented to enable it to store info for side effect imports. Next, the helper `addImports` is modified to be able to generate correct statement for side effect imports.
These changes will be tested in the subsequent commits when these tools are used to generate an actual extra import for the generated file.
PR Close#53543
This commit includes a skeleton of how the tool `LocalCompilationExtraImportsTracker` is used in the overall compilation workflow end-to-end.
First of all, a new option `generateExtraImportsInLocalMode` is added, whose presence will make `LocalCompilationExtraImportsTracker` part of the compilation process. When this option is set an instance of `LocalCompilationExtraImportsTracker` is created within the NgCompiler. Then it is passed to the Ivy transformer and plumbed all the way down and the extra imports registered in it are added to the `ImportManager` instances before the imports are added from `ImportManager` to the generated file. This required adding a new method `generateSideEffectImport` to the `ImportManager`, which is an empty method and will be implemented in the subsequent commits.
This commit expected to make no change in the compilation behavior as the methods are not implemented yet.
PR Close#53543
The tracker is responsible for registering the extra imports during the analysis and resolve compiler phases, and later to be used by the transformer to get a list of extra imports to be generated for each source file.
This commit only contains the API, and the actual implementation for each method will be done in subsequent commits where an application of that method is available and so tests can be written for the implementation.
PR Close#53543
This commit updates the router integration tests to cover both the
classic History and the new Navigation API. There is more work to be
done here, but this commit works to prove the efficacy of the
`FakeNavigation` implementation.
PR Close#53799
When the zoneless scheduler is provided, we want to update the behavior
of `ComponentFixture` to address common issues and painpoints in testing.
Developers should never have to call `detectChanges` on a fixture
manually. Instead of calling `detectChanges` after performing an
action that updates state and requies a template refresh, developers
should wait for change detection to run because the update needs to also have
notified the scheduler. If this was not the case, the component would
not work correctly in the application. Calling `detectChanges` to force
an update could hide real bugs.
This commit also updates the zoneless tests to uses `ComponentFixture`
instead of manually attaching to the `ApplicationRef` and rewriting a
lot of the helpers (`getDebugNode`, `isStable` as a value, `whenStable` as a
Promise).
PR Close#54024
Clarify the range of TypeScript versions supported in Angular v15 and v16 upgrade guides. The previous documentation's phrasing led to potential misunderstandings, as it suggested broader compatibility than actually supported. This change prevents errors by explicitly stating the maximum TypeScript version for each Angular version, ensuring developers have clear guidance during upgrades.
PR Close#54131
Adds some logic to skip over `TestBed.configureTestingModule` calls where the `declarations` aren't initialized to an array. We can't migrate these cases, because test migrations don't have access to the Angular compiler. Previously the migration would throw a runtime error.
PR Close#54122
At the moment local compilation mode does not support custom decorators, and it leads to unhandled errors. In this change a compile time diagnostic is produced in local mode for custom decorators. This is a temporary solution since there are few custom decorators are in use in g3. Custom decorators will be eventually supported in local mode.
PR Close#53983
I've been working on framework parts and compiler since pre-Ivy, and
helped with Ivy, runtime and compiler. Adding myself as a reviewer to
ease future work and to help with review load.
PR Close#54053
This enables us to show overloads of methods in the API overview. This
is useful for e.g. showing the various signatures of the signal input
function, or for signal-based queris.
There seems to be some issues with the length of the `InputFunction`
overloads. There is some line wrapping that doesn't make it _super_
readable but this is an unrelated problem to this change, but rather
a question of UI / API representation in the angular.io site.
PR Close#54053
clang-format seems to have problems with the call signature for
`input.required`. This commit works around the formatting issues that
obfuscate the signature. Users will actually see similar output when
they are looking for the `input` function definition of `@angular/core`.
PR Close#54053
This adds initial support for extracting and rendering call and construct
signatures of classes, like within the new `InputFunction` for signal
inputs.
For now, signatures are a rare occasion and represented as class member
entries. In the future we might consider exposing this via its own entry
type, and field on the class/interface entry.
PR Close#54053
This fixes the definitions for signal-based inputs in the language
service and type checking symbol builder.
Signal inputs emit a slightly different output. The output works well
for comppletion and was designed to affect language service minimally.
Turns out there is a small adjustment needed for the definition symbols.
PR Close#54053
This commit separates `InputSignal` for input signals with transforms.
The reason being that most of the time, signal inputs are not using
transforms and the generics are rather confusing.
Especially for users with inferred types displayed in their IDEs, the
input signal types are seemingly complex, even if no transform is used.
For this reason, we are introducing a new type called
`InputSignalWithTransform`. This type will be used for inputs with
transforms, while non-transform inputs just use `InputSignal`.
A notable fact is that `InputSignal` extends `InputSignalWithTransform`,
with the "identity transform". i.e. there is no transform. This allows
us to share the code for input signals. In practice, we don't expect
users to pass around `InputSignal`'s anyway.
PR Close#54053
Fix case of not wanted internal properties displayed in the documentation by adding if blocks in the concerned templates. So if the option is marked as internal the template won't create an entry in the documentation table for the concerned property of method
Fixes#52018
PR Close#52020
docs: testing-components-basics.md and components-basics.md links to css selector documentation are dead
As MDN's documentation link to the "css selector" topic is dead, this commit makes the angular documentation use the new valid link.
PR Close#53586
The "Providing HttpClient through dependency injection" documentation now shows that in case of a standalone boostraped app, the provideHttpClient is to include in the app.config.ts file.
Also updated the http setup server communication example to align the new doc (adev) with the old one (aio).
PR Close#52806
Follow-up to #54002 that:
* Remove the `toString` implementation from the `primitives`.
* Guards the `toString` with `ngDevMode` and prints out the value.
PR Close#54079
Since signals are function, currently stringifying them reveals the implementation of the function. This can lead to confusion since it contains internal implementation details. These changes add static `toString` function to address the issue.
**Note:** it's tempting to have `toString` output the actual value of the signal, but that would encourage users not to call the function which will be problematic in the long run. That's why these changes are using a static string instead.
PR Close#54002
Currently, when using `provideAnimationsAsync`, Angular uses `AnimationRenderer`
as the renderer. When the root view is removed, the `AnimationRenderer` defers the actual
work to the `TransitionAnimationEngine` to do this, and the `TransitionAnimationEngine`
doesn't actually remove the DOM node, but just calls `markElementAsRemoved()`.
The actual DOM node is not removed until `TransitionAnimationEngine` "flushes".
Unfortunately, though, that "flush" will never happen, since the root view is being
destroyed and there will be no more flushes.
This commit adds `flush()` call when the root view is being destroyed.
PR Close#53033
During the template parsing stage two-way bindings are split up into a property and event binding. All the downstream code treats these binding the same as their one-way equivalents. For some future work we'll have to distinguish between the two so these changes update the `BoundElementProperty.type` and `ParsedEvent.type` to include a `TwoWay` type. All existing call-sites have been updated to treat `TwoWay` the same as `Property`/`Regular`, but more specialized logic will be added in the future.
PR Close#54065
Previously, defer deps fns names were only prefixed with the component name, meaning that distinct deps fns in the same component would produce a name collision. Now, we take into account the entire template function name when naming inner deps fns.
PR Close#54060
This refactoring expands the QueryList such that we can add onDirty
callback to be invoked when a given query gets marked as dirty during
view insertion / removal. This mechanism is needed for signal-based
queries.
PR Close#54017
This is a refactor commit that moves more query construction / refresh
logic from the body of instructions into dedicated functions. This is
in preparation for the signal-based query instructions.
PR Close#54017
In some bundling scenarios, there may be local references to `ngDevMode` that need to be kept in sync with the global variable. This becomes hard to impossible if the global is reassigned. This allows setting the global to an empty object instead of `true` and preserve identity during `initNgDevMode`.
PR Close#53862
The Template Pipeline is a brand new backend for the Angular compiler, replacing `TemplateDefinitionBuilder`. It generates the Ivy instructions corresponding to an input template (or host binding). The Template Pipeline has an all-new design based on an intermediate representation compiled over many phases, which will allow us to experiment with compiler changes more easily in the future.
With this commit, the template pipeline can now be enabled in any project via the `useTemplatePipeline` TSConfig option. However, it is still disabled by default.
PR Close#54057
In #53591, Andrew added local compliation support for defer blocks. However, this requires the ability to emit pre-generated static defer deps functions. We now also support that feature in Template Pipeline.
PR Close#54043
Similar to signal-based inputs, we support signal-based queries in JIT
by expecting a decorator to be added. This is a consequence of the
design, given that JIT requires query declaration information before
the class is initialized- but ironically there is no way to collect this
information without instantiating the class.
A JIT transform in the Angular CLI will automatically generate these
decorators for testing.
PR Close#54019
This commit introduces three additional diagnostics for queries:
- If a query (either using decorator or signal-based) is declared on a
static class member, a diagnostic is raised.
- If a signal-based query is mixed with a query decorator, a diagnostic
is raised. Similar to signal inputs.
- If a singal-based query is also declared in the directive/component
class decorator metadata, a diagnostic is raised.
PR Close#54019
Due to some refactorings, we were only checking the function name
and whether it originates from an import. We should also verify the
module. This seems like logic we lost in the refactorings.
PR Close#54019
Collapses multiple sibling query advance statements into single
query advance invocations. This will help reducing generated code
for directives/components with many queries.
PR Close#54019
Currently the ZoneJS typing tests executes outside of Bazel, as a legacy
artifact of the monorepo merging (as it seems - not ideal at all).
Looks like this test relies on its own node modules, that were NOT
locked using a yarn lock file. This commit adds one, and specifically
locks it to a `@types/node` version that does not include the most
recent patch release (which seemingly introduced a breaking change)
that causes issues with TypeScript's lib checking.
Whenever we perform lock file maintenance in the future, we have the
following options:
- Consider disabling lib checking via `skipLibCheck` for this test. This
may be acceptable.
- Continue locking the node version,
- Waiting for chokidar to comply with the new signature
- Waiting for the breaking change to be rolled back.
Culprit change:
https://github.com/DefinitelyTyped/DefinitelyTyped/pull/68300
PR Close#54048
While `Array.at` is technically supported in all browsers we officially
support, the change was needlessly breaking without any real benefit.
PR Close#54021
This changes include mentioning the experimental application builder migration and changes to the `outputPath` and `optimization` option.
PR Close#53949
Previously, if an ICU was inside a nested i18n root, it would use the nested root to calculate whether it should be applied. Now, we use the root i18n block.
PR Close#54026
This commit adds compliance tests to ensure that the generated output of
signal-based queries matches our expectation.
Note: collapsing query advance instructions is not implemented yet.
PR Close#53978
This commit ensures that libraries can use signal-based queries, and the
partial compilation output will capture their metadata.
The linker is updated to support parsing this.
Two notes:
1. Older linker versions are not capable of parsing this, so the minimum
version for signal-based queries is adjusted when such are used.
2. We only emit `isSignal` metadata for queries when signal queries are
used. This enables libraries to continue supporting older linker
versions, if signal-based queries are not used.
PR Close#53978
Adds a compiler integration test for recognizing signal-based queries,
and emitting the expected output. Concrete output will be verified via
the compliance tests.
PR Close#53978
Currently, Angular tries to recognize string locators/predicates for
queries at compile time, and attempts to split multi-selector predicates
into an array as generated output. This is a a performance optimization.
In practice, this works most of the time because the compiler can detect
string locactors/predicates through static analysis.
Though, there are cases where it's not possible. That is when advanced
constructs are used, identifier references etc. that ultimately evaluate
to a string. Currently this breaks with queries and also surfaces now
with signal-based queries.
PR Close#53978
This commit uses the initializer API recognition that we built for
signal-based inputs, and teaches the compiler to recognize class members
that refer to `viewChild`, `viewChildren`, `contentChild` or
`contentChildren`. Those will declare signal-based view or content queries.
PR Close#53978
This commit introduces the compiler output generation for signal-based
queries. Signal-based queries will have new creation-mode instructions
and update instructions to advance the current query indices in the
global shared context.
An output like the following is the expected output for signal-based
queries:
```
i0.ɵɵdefineComponent({
viewQuery: function App_Query(rf, ctx) {
if (rf & 1) {
i0.ɵɵviewQuery(ctx.d, _c0, 5);
i0.ɵɵviewQuerySignal(ctx.ds1, _c0, 5);
i0.ɵɵviewQuerySignal(ctx.ds2, _c0, 5);
}
if (rf & 2) {
let _t;
// only change-detected queries need explicit refresh
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.d = _t.first);
// we bump up current query index by 2 positions since there are 2 signal-based queries
i0.ɵɵqueryAdvance(2);
}
…
},
…
});
```
Note: For now, the collapsing of multiple advance instructions is not
implemented. This will be a follow-up.
Note 2: A couple of query helpers are now in their own file. This makes
it easier to focus on query-specific compiler code. The new function is
called `createQueryCreateCall`, which is a modified variant of the
existing function that previously only generated query parameters.
PR Close#53978
The new `input` API is recognized using class member initializers.
We want to support similar APIs for queries, using e.g. `viewChild`
or `viewChild.required`.
This commit extracts the input recognition API and makes it reusable,
so that the same logic can be used to detect queries on a class member.
Additional changes:
- replacing `coreModule` with the simpler `isCore` parameter. This is
more readable.
- support for detecting a list of API names on a single class member.
This allows us to detect possible query functions on the same class
member without having to check X times. We simply check for the
initializer API pattern and check if one API function name matches.
PR Close#53978
At the moment local compilation breaks for host directives because the current logic relies on global static analysis. This change creates a local version by cutting the diagnostics and copying the directive identifier as it is to the generated code without attempting to statically resolve it.
PR Close#53877
At the moment when unified host is selected (through option `_useHostForImportGeneration`) the compiler always generates alias reexports. Such reexports are mainly generated to satisfy strict dependency condition for generated files. Such condition is no longer the case for G3. At the same time, these alias reexports make it impossible to mix locally compiled targets with globally compiled targets. More precisely, a globally compiled target may not be able to consume a locally compiled target as its dependency since the former may import from the alias reexports which do not exist in the latter due to local compilation mode. So, to make global-local compilation interop possible, it is required to be able to turn off alias reexport generation.
PR Close#53937
Node removal is immediate and does not require change detection to run
when animations are not provided. This refactor makes the animation
engine notify the scheduler rather than doing it on all node removals.
PR Close#53857
The devtools now support signals.
Writable signals of primitives are editable.
Object Signal and other non-writable signals (like computed) are not editable.
Co-authored-by: Tomasz Ducin <tomasz.ducin@gmail.com>
PR Close#53269
This commit adds extra logic to produce a diagnostic in case `@Component.deferredImports` contain types from imports that also bring eager symbols. This would result in retaining a regular import and generating a dynamic import, which would not allow to defer-load dependencies.
PR Close#53899
The new type testing infrastructure was introduced for the input-as-signals
authoring functions. This commit modifies this infrastructure to make it more
generic and support queries-as-signals.
PR Close#53829
This commit update the logic to enable `register` and `resolve` phases for local compilation. Those phases will be useful for local compilation in certain cases (will be used in followup PRs).
PR Close#53901
These docs are out of date with how we currently build devtools in dev mode and as a browser extension. This commit brings these docs up to date.
PR Close#53948
This commit splits the query implementation and instructions
into a separate files. This is a pattern frequently used by
other functional areas of the framework and is a preparation for
introducing queries-as-signals where we are going to see more
instructions delegating to the same core functionality.
PR Close#53922
Currently when the extended type check fails due to an import reference
that cannot be generated, the fatal diagnostic is not caught and
not properly exposed as a `ts.Diagnostic` that can be gracefully
handled. This is inconsistent to non-extended type checking diagnostics.
This is problematic because Angular CLI applications currently fail in
obscure ways because:
- the CLI does not expect `getDiagnosticsForFile` to actually throw
runtime errors.
- the CLI does not seem to properly print these errors given the
parallel workers and build excection, and those errors are
especially hard to debug because there is no `stack` for
`FatalDiagnosticError`'s.
Example: `MyDir` is not exported and the type check block cannot reference it.
PR Close#53896
Prior to this commit, `TestBed` would require tests call `flushEffects`
or `fixture.detectChanges` in order to execute effects. In general, we
want to discourage authoring tests like this because it makes the timing
of change detection and effects differ from what happens in the
application. Instead, developers should perform actions and `await` (or
`flush`/`tick` when using `fakeAsync`) some `Promise` so that Angular
can react to the changes in the same way that it does in the
application.
Note that this still _allows_ developers to flush effects synchronously
with `flushEffects` and `detectChanges` but also enables the <action>,
`await` pattern described above.
PR Close#53843
This commit updates the logic of the `TemplateDefinitionBuilder` to support local compilation and generate a single dependency function for all explicitly deferred deps within a component.
PR Close#53591
This commit updates the `DeferredSymbolTracker` class to take info account the `onlyExplicitDeferDependencyImports` flag. The `DeferredSymbolTracker` class also exposes a new API to register import declarations as explicitly deferred, which will be used in followup commits.
PR Close#53591
This commit updates typechecker to store full Pipe metadata in internal data strctures, so that this information is available to more places in the code, which will be updated in a followup commit.
PR Close#53591
This commit updates a few places to extract the logic into a separate functions which will be reused in a few places in followup commits.
PR Close#53591
The content is written primarly in Markdown format located in `src/content`. For simple edits, you can directly edit the file on GitHub and generate a Pull Request.
## Local Development
For local development, [yarn](https://yarnpkg.com/) is the preferred package manager. You can setup a local environment with the following commands
:
```bash
# Clone Angular repo
git clone https://github.com/angular/angular.git
# Navigate to project directory
cd angular
# Install dependencies
yarn
# Build and run local dev server
# Note: Initial build will take some time
yarn docs
```
## Contributing
Want to report a bug, contribute some code, or improve the documentation? Excellent!
Read through our [contributing guidelines](CONTRIBUTING.md) to learn about our submission process, coding rules, and more.
And if you're new, check out one of our issues labeled as <kbd>[help wanted](https://github.com/angular/angular/labels/help%20wanted)</kbd> or <kbd>[good first issue](https://github.com/angular/angular/labels/good%20first%20issue)</kbd>.
### Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
* Map of the previews components, values are functions which returns the promise of the component type, which will be displayed as preview in the ExampleViewer component.
* Keys has to be equal to paths written down in the docs markdown files.
This script updates the Angular CLI help JSON files stored in `adev/src/content/cli/help`. This files are used to generate the [angular.dev CLI](https://angular.dev/cli) pages.
/** Time to wait after navigation starts before showing the progress bar. This delay allows a small amount of time to skip showing the progress bar when a navigation is effectively immediate. 30ms is approximately the amount of time we can wait before a delay is perceptible.*/
- See [scripts/tutorials/README.md](/scripts/tutorials/README.md) for more information about the tutorials script.
- See [adev/src/content/tutorials/README.md](/adev/src/content/tutorials/README.md) for more information about the tutorials content.
---
## Scenarios
### Loading a project
1. The page responsible for the embedded editor lazy loads the [`EmbeddedEditor`](./embedded-editor.component.ts) component and the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts), then triggers the initialization of all components and services. The embedded editor is available in the following pages:
- homepage: https://angular.dev
- playground: https://angular.dev/playground
- tutorial pages: https://angular.dev/tutorials
2. The project assets are fetched by the [`EmbeddedTutorialManager`](./embedded-tutorial-manager.service.ts). Meanwhile:
- The code editor is initialized
- The code editor initializes the TypeScript Web Worker, which initializes the "default file system map" using TypeScript's CDN.
- The WebContainer is initialized
- The terminal is initialized
3. The tutorial source code is mounted in the `WebContainer`'s filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts)
4. The tutorial project dependencies are installed by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
5. The development server is started by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts) and the types are loaded by the [`TypingsLoader`](./typings-loader.service.ts) service.
6. The preview is loaded with the URL provided by the WebContainer API after the development server is started.
7. The project is ready.
### Updating the code
1. The user update the code in the code editor.
2. The code editor state is updated on real time, without debouncing so that the user can see the changes in the code editor and CodeMirror can handle the changes accordingly.
3. At the same time, the changes are sent to the TypeScript web worker to provide diagnostics, autocomplete and type features as soon as possible.
4. The code changes are debounced to be written in the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
5. After the debounce time is reached, the code changes are written in the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts), then the user can see the changes in the preview.
### Creating a new file
1. The user clicks on the new file button.
2. The new file tab is opened.
3. The user types the new file name.
4. If the file name is valid, the file is created in the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
- `..` is disallowed in the file name to prevent users to create files outside the `src` directory.
5. The file is added to the TypeScript virtual file system, allowing the TypeScript web worker to provide diagnostics, autocomplete and type features for the new file. Also, exports from the new file are available in other files.
6. The new file is added as the last tab in the code editor and the new file can be edited.
Note: If the new file name matches a file that already exists but is hidden in the code editor, the content for that file will show up in the created file. An example for a file that always exists is `index.html`.
### Deleting a file
1. The user clicks on the delete file button.
2. The file is deleted from the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
3. The file is removed from the TypeScript virtual file system.
4. The file is removed from the code editor tabs.
Note: Some files can't be deleted to prevent users to break the app, being `src/main.ts`and `src/index.html`
### Switching a project
The embedded editor considers a project change when the embedded editor was already initialized and the user changes the page in the following scenarios:
- Navigating through tutorial steps
- Going from the homepage after the embedded editor is initialized to the playground
- Going from a tutorial page to the playground
- Going from a tutorial page to the homepage
- Going from the playground to the homepage
When a project change is detected, the [`EmbeddedTutorialManager`](./embedded-tutorial-manager.service.ts) emits the `tutorialChanged` observable, which is listened in multiple sub-components and services, then each component/service performs the necessary operations to switch the project.
The following steps are executed on project change:
1. The new project files are fetched by the [`EmbeddedTutorialManager`](./embedded-tutorial-manager.service.ts).
2. The new project files are mounted in the WebContainer filesystem.
3. The TypeScript virtual filesystem is updated with the new files and contents.
4. The previous project and new project files are compared.
1. Files that are not available in the new project are deleted from the WebContainer filesystem.
2. Files that have the same path and name have their content replaced on the previous step when the files are mounted.
5. The previous project dependencies are compared with the new project dependencies.
1. If there are differences, a `npm install` is triggered, hiding the preview and going to the install loading step.
2. If there are no differences, the project is ready.
6. Some states are reset, for example the "reveal answer" state if the previous project was in the "reveal answer" state.
[CodeMirror](https://codemirror.net/) is the library used to handle the code editor.
The `CodeMirrorEditor` service manages the CodeMirror instance and all the interactions with the library used to handle the code editor.
- handle the file edits and the CodeMirror view and state
- handle the current project files in the code editor
- handle the file creations and deletions
- handle the file changes
- handle all the CodeMirror specific events and extensions
###### [TypeScript Web Worker](./code-editor/workers/typescript-vfs.worker.ts)
The TypeScript features are provided by the TypeScript web worker, that is initialized by the `CodeMirrorEditor` service.
The TypeScript web worker uses `@typescript/vfs` and the TypeScript language service to provide diagnostics, autocomplete and type features.
#### [`Preview`](./preview/preview.component.ts)
The preview component manages the `iframe` responsible for displaying the tutorial project preview, with the URL provided by the WebContainer API after the development server is started.
While the project is being initialized, the preview displays the loading state.
Responsible for managing the WebContainer instance and all communication with its API. This service handles:
- the WebContainer instance
- all Node.js scripts
- the WebContainer filesystem, mounting the tutorial project files, writing new content, deleting and creating files.
- the terminal session, reading and processing user inputs.
- the tutorial project dependencies, installing the dependencies.
- the processes running inside the WebContainer, being the npm scripts to install the dependencies, run the development server and the user inputs for the `ng` CLI.
Manages the editor UI state, being responsible for handling the user interactions with the editor tabs, switching between the preview, the terminal and the console.
Responsible for handling the download button in the embedded editor, fetching the tutorial project files and generating a zip file with the project content.
#### [`AlertManager`](./alert-manager.service.ts)
Manage the alerts displayed in the embedded editor, being the out of memory alert when multiple tabs are opened, and unsupported environments alerts.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.