Compare commits

..

475 Commits

Author SHA1 Message Date
Andrew Kushnir 7529512e7b release: cut the v19.2.2 release 2025-03-12 09:42:52 -07:00
Andrew Scott 05729f4116 refactor(router): split remainder of describes in integration test file (#60313)
to more easily navigate and identify different suites of integration tests,
this commit splits them into several different files

PR Close #60313
2025-03-11 17:13:28 -07:00
Matthieu Riegler 41fd77664e docs(docs-infra): Bump tutorial/playground to 19.2 (#60337)
fixes #60335

PR Close #60337
2025-03-11 16:54:32 -07:00
Paul Gschwendtner 044dac98c9 feat(bazel): support bundling .d.ts with code splitting (#60321) (#60332)
Instead of relying on Microsoft's API extractor for `d.ts` bundling,
we are switching to Rollup-based `.d.ts` bundling.

This allows us to support code spliting, even for `.d.ts` files,
allowing for relative imports to be used between entry-points, without
ending up duplicating `.d.ts` definitions in two files. This would otherwise cause
problems with assignability of types.

It also nicely integrates into our existing rollup configuration, and
overall simplifies the `ng_package` rule even further!

Notably `tsup` also uses this rollup plugin, and it seems to work well.
Keep in mind that Microsoft's API extractor is pretty hard to integrate,
caused many problems in the past, and isn't capable of code splitting.
This aligns our d.ts bundling with the .mjs bundling (great alignment).

PR Close #60321

PR Close #60332
2025-03-11 15:33:05 -07:00
Kristiyan Kostadinov 56b551d273 fix(compiler): incorrect spans for template literals (#60323) (#60331)
Fixes that we were producing zero-length spans for template literals and template literal elements.

Fixes #60320.
Fixes #60319.

PR Close #60323

PR Close #60331
2025-03-11 15:02:17 -07:00
Matthieu Riegler 705fb0d236 docs: add mention of GH issue for devPreview feedback (#60010)
fixes #59902

PR Close #60010
2025-03-11 14:26:25 -07:00
arturovt b6f22a7526 refactor(core): inline standalone check to be dropped (#60305)
Inlines `standalone` check into the message to be dropped.

PR Close #60305
2025-03-11 13:01:44 -07:00
Matthieu Riegler 8ed63bc1bb docs: remove mention of #59443 in 19.2 changelog (#60329)
#59443 was reverted for breaking projects in G3.

PR Close #60329
2025-03-11 12:58:16 -07:00
AlirezaEbrahimkhani e98facebac docs: change xss doc url to angular new documentation (#59915)
PR Close #59915
2025-03-11 12:57:48 -07:00
Juhmer-Tena f9b6bf91be docs: fix commit message guideline link (#60296)
Fixes the link for the commit message guideline in CONTRIBUTING.md
pointing to the building and testing angular guide instead of the
commit message guidelines

Fixes #60925

PR Close #60296
2025-03-11 11:08:24 -07:00
Kristiyan Kostadinov c41b3c83ca build: update public-api approvers (#60328)
Adds myself and Paul to the public API reviewers to help with the reviews.

PR Close #60328
2025-03-11 11:07:19 -07:00
Doug Parker e59432cf07 refactor(devtools): refactors property view drag-and-drop behavior (#60286)
The main goal of this change is to remove `categoryOrder` which effectively hard-codes the supported length of `panels`. Adding another item to `panels` is not rendered unless that is added to `categoryOrder`.

My solution to this is to make the set of categories a signal, with each category able to produce the data inside it. This allow `CdkDragDrop` to rearrange categories but then still produce the correct data in the template without needing a separate array to track order.

Also removed `hidden` and inlined it in the template, since the logic was the same for every panel.

`moveItemInArray` is unfortunately an in-place move, so I needed to manually clone the array to ensure `panels` observes an immutable update which works better with signals and change detection.

PR Close #60286
2025-03-11 09:27:04 -07:00
aparzi b144dd946e fix(core): fix removal of a container reference used in the component file (#60210)
During migration a container reference was deleted even though it was used in the component file.

PR Close #60210
2025-03-11 09:26:14 -07:00
Vlad Boisa 64bdffb97a docs: fix one broke link by #57591 (#60237)
Fix 1 link in adev toolchain `{@link forRoot}`
PR Close #60237
2025-03-11 09:24:03 -07:00
Matthieu Riegler 7832be5905 docs: fix event listener key modifier example (#60280)
PR Close #60280
2025-03-11 09:23:02 -07:00
Angular Robot 4e1f28eddf build: update github/codeql-action action to v3.28.11 (#60316)
See associated pull request for more information.

PR Close #60316
2025-03-11 09:21:44 -07:00
Angular Robot 36d740d6ef build: update dependency typescript to ~5.8.0 (#60317)
See associated pull request for more information.

PR Close #60317
2025-03-11 09:21:07 -07:00
Matthieu Riegler 30f6db37a0 refactor(core): log a warning instead of throwing error on OutputRef.emit when the directive is destroyed. (#60293)
This should not be a hard error, as nothing bad happens but the users should be warned that no event will be emitted.

fixes #60110

PR Close #60293
2025-03-10 16:08:53 -07:00
Matthieu Riegler 442ef134b8 docs(docs-infra): Extract class constructors (#60302)
fixes #59180

PR Close #60302
2025-03-10 16:05:03 -07:00
Andrew Scott b1d0d20240 refactor(router): split integration test file (#60311)
to more easily navigate and identify different suites of integration tests,
this commit splits them into several different files

PR Close #60311
2025-03-10 16:03:54 -07:00
Jessica Janiuk 4e87b58fd1 ci: fix timer test flakiness (#60310)
This replaces the TimerScheduler entirely and ensures the callback is called immediately. This should prevent any further flakiness.

PR Close #60310
2025-03-10 15:08:54 -07:00
arturovt ec65169dfb refactor(core): replace PLATFORM_ID in initTransferState (#60299)
Replaces `PLATFORM_ID` check with the `ngServerMode`.

PR Close #60299
2025-03-10 13:49:24 -07:00
Paul Gschwendtner 15c42969fc fix(platform-server): add missing peer dependency for rxjs (#60308)
The server package imports from `rxjs`, but the dependency was not
specified as `peerDependency`, nor `dependency`. This surfaces as an
error in strict dependency environments, like with pnpm's symlinked node
modules structure.

This commit fixes this. It presumably doesn't fail with e.g. Yarn, or
npm because of node modules hoisting.

PR Close #60308
2025-03-10 11:41:06 -07:00
Doug Parker cfdadb562f release: bump Angular DevTools version to 1.0.26 (#60309)
PR Close #60309
2025-03-10 11:40:27 -07:00
Kristiyan Kostadinov 23ca88522b fix(compiler-cli): handle transformed classes when generating HMR code (#60298)
We had several places where we were trying to get the source file of a class for which we're generating HMR-related code. These calls will fail if the class was transformed so we have to get its source file through the original node.

Fixes #60287.

PR Close #60298
2025-03-10 09:58:53 -07:00
Doug Parker ea8008d95e fix(devtools): handle case where directive metadata has undefined dependencies (#60256)
This fixes a bug introduced by [#60206](https://github.com/angular/angular/pull/60206/files#diff-c07b9ecd59f6e0ed636ac9672b9644178d9a999f04bc8b8198b13e86589dfa5b). Previously `DirectiveMetadata.prototype.dependencies` was always set, but in that PR `dependencies` is only set if an `Injector` is found (which only happens when `ng.getInjector` is *not* defined). This causes an error when evaluating `dependencies.length` in the template.

Fix is just to check for existance before calling `length`.

PR Close #60256
2025-03-10 09:57:26 -07:00
Doug Parker cef606aa8e refactor(devtools): remove input/output/property links (#60284)
These links aren't that helpful in the context of Angular DevTools for a few reasons:
1. Users of the extension should already have a general understanding of core Angular concepts, inputs and outputs included.
2. The input and output links go to API documentation which isn't useful for someone who doesn't actually understand the core concepts anyways.
3. These links point to signals documentation even though DevTools shows non-signal inputs and outputs.
4. Properties linked to template binding docs, which doesn't *really* have anything to do with the plain JS properties being shown in DevTools anyways.

PR Close #60284
2025-03-10 09:56:20 -07:00
Joey Perrott 44155c9209 refactor(bazel): remove primary_bundle_name as attr for ng_package (#60306)
Remove primary_bundle_name as an attr for ng_package as it is unused.

PR Close #60306
2025-03-10 09:31:20 -07:00
Joey Perrott 43b89e7bb1 refactor(bazel): hardcode esm as the ouput for rollup (#60306)
Remove the option as an arg for creating a rollup config since it is static.

PR Close #60306
2025-03-10 09:31:20 -07:00
Hryhorii Avcharov 5e2f312321 fix(docs-infra): terminal light mode text color (#60246)
This commit changes the text color in terminal light mode to improve
visibility and user experience. The previous color was too light and
made it difficult to read the text.

PR Close #60246
2025-03-10 09:23:20 -07:00
François bd15db3960 docs: fix typo and link in v16 update guide (#60277)
PR Close #60277
2025-03-10 09:22:34 -07:00
Paul Gschwendtner bde1b37e0b build: properly compile tests in core with Angular compiler (#60268)
Previously we never could use relative imports to import e.g. `Component`
in e.g. the `core/tests/bundling` folder. This was necessary because otherwise the
Angular compiler wouldn't process those files as it wouldn't recognize
the Angular decorator as the one from `@angular/core`.

Notably this still isn't a large issue because relative imports still
work for most core tests, that are JIT compiled!

For bundling tests though, or some smaller targets, our new upcoming
guidelines for using relative imports inside the full package; fall
apart. This commit unblocks this effort and allows us to use relative
imports in all tests of `packages/core`. This is achieved by leveraging
the existing `isCore` functionality of the compiler, and fixing a few
instances that were missing before.

PR Close #60268
2025-03-07 11:00:48 -08:00
Vlad Boisa 5131794cde docs: fix typo in desription (#60261)
Fix typos in description of `styleUrl`

Fixes #60258
PR Close #60261
2025-03-07 10:55:38 -08:00
Paul Gschwendtner 70fb3bba4b refactor: add fast-glob to bazel dependencies (#60253)
This will be necessary for downstream (private) consumers
of the `@angular/bazel` package.

PR Close #60253
2025-03-06 12:50:29 -08:00
Jessica Janiuk 5db2df8aad ci: fix flakey timer tests (#60254)
This adjusts the tests to have a longer await time and removes the click portion of the test. These tests should only pass if the timer has triggered hydration.

PR Close #60254
2025-03-06 12:49:48 -08:00
Jessica Janiuk bb12b30d52 fix(core): ensures immediate trigger fires properly with lazy loaded routes (#60203)
In the case that a route was lazy loaded, some triggers would never properly finish hydrating due to things firing before the route finished resolving.
This will find the topmost parent defer block and ensure the registry knows about it before trying to hydrate.
In the case that the registry does not yet know, just the affected triggers await app stability before initializing.
fixes #59997

PR Close #60203
2025-03-06 12:47:47 -08:00
Angular Robot 0c105476a1 docs: update Angular CLI help [19.2.x] (#60249)
Updated Angular CLI help contents.

PR Close #60249
2025-03-06 11:27:46 -08:00
Kristiyan Kostadinov 48dc0d6dc7 refactor(language-service): rename internal symbols to accommodate type checking outside a template (#60191)
Currently the language service has some template-specific terminology around type checking, because that's the only place where we had TCB support. These changes make it more generic to accommodate future functionality.

PR Close #60191
2025-03-06 10:39:32 -08:00
Kristiyan Kostadinov 9d8e943e62 refactor(compiler-cli): rework resource handling to allow directives (#60191)
Currently only components can have resources, because they're the only symbol kinds being type checked. Since we want to add directives to it, these changes rework the resource handling to accommodate them.

PR Close #60191
2025-03-06 10:39:32 -08:00
Kristiyan Kostadinov 1a71167b5c refactor(compiler-cli): rework source manager to accommodate directives (#60191)
Currently the `TemplateSourceManager` is set up to specifically cater to component templates. These changes make it more generic so we can reuse it for directives.

PR Close #60191
2025-03-06 10:39:32 -08:00
Kristiyan Kostadinov 83218bd0d1 refactor(compiler-cli): rework type checking internals to accommodate more than components (#60191)
Currently a lot of the internal type checking data structures are set up specifically for components, because we only support type checking of templates. Since this will change in future commits, these changes prepare for it by renaming various methods and separating out component-specific data.

PR Close #60191
2025-03-06 10:39:32 -08:00
Kristiyan Kostadinov 5cc80dc72f refactor(compiler-cli): change TemplateId terminology (#60191)
Renames the `TemplateId` and terminology related to it, because we'll be using it for more than just templates.

PR Close #60191
2025-03-06 10:39:32 -08:00
Kristiyan Kostadinov 9cdf950108 refactor(compiler): allow binder to apply to more than one set of nodes (#60191)
Currently `R3TargetBinder.bind` gets a set of data back from `DirectiveBinder.apply` and `TemplateBinder.applyWithScope`. This will be annoying  if we have multiple sources of data, because we'd have to do merge them at the end.

These changes switch to constructing the various data structures ahead of time and passing them into the binders to populate them instead.

I also extracted some of the less trivial types into type aliases so we don't have to repeat them.

PR Close #60191
2025-03-06 10:39:31 -08:00
kw 279e6b846f docs: Correct comments for FormControl (#58352)
PR Close #58352
2025-03-06 10:36:47 -08:00
Doug Parker 07cc97ff9b release: bump Angular DevTools version to 1.0.25 (#60235)
PR Close #60235
2025-03-06 10:32:02 -08:00
Paul Gschwendtner 684e837758 feat(bazel): support shared chunks in ng_package (#60241)
Historically we've had to be VERY cautious about the way we import
things between entry-points. That is because the `ng_package` rule
bundling is subject to silently introducing code duplication, breaking
singletons etc. We've had this surface a couple of times already, and
dev-infra tried to help detect such cases by adding safety analysis into
`ng_package`.

Long-term we want to get to an approach where it's easy to simply share
code between chunks. Precisely, with the upcoming `rules_js` migration,
this will be necessary as we will have different import "guidelines"
that would currently, before this commit, result in code duplication, or
trigger our "safety check/lint".

This commit prepares `ng_package` to support relative imports between
entry-points, so that we only need the safety check for cross-package
imports/exports. The result is that `ng_package`/APF is now smartly able
to generate shared chunks for things that are needed between multiple
entry-points. Yay!

Note that those shared chunks still remain private, and are guarded by
our `package.json` "exports"; so no new public API surface is
exposed.

PR Close #60241
2025-03-06 10:29:05 -08:00
Matthieu Riegler dad02c6535 refactor(http): Make sur to pass context & transferCache from httpResource to the underlying request. (#60228)
Prior to this change, both were accepted as argument but never passed to the client.

PR Close #60228
2025-03-06 07:59:07 -08:00
Matthieu Riegler dfc8c432db docs(docs-infra): fix initial TOC selection (#60240)
PR Close #60240
2025-03-06 07:55:43 -08:00
Andrew Kushnir b967ca6b3b Revert "fix(router): update symbols (#60233)" (#60236)
This reverts commit 7bcdf7c143.
The original change causing CI failures was affecting the main branch only, reverting from the patch branch (since it causes CI failures).

PR Close #60236
2025-03-06 10:22:01 +01:00
Jessica Janiuk 7bcdf7c143 fix(router): update symbols (#60233)
This updates the goldens for the router.

PR Close #60233
2025-03-05 15:34:05 -08:00
arturovt 484e0cf43e refactor(platform-browser): drop unsupported event target error message in production (#60016)
Drops unsupported event target error message in production and replaces it with an existing error code.

PR Close #60016
2025-03-05 14:45:50 -08:00
arturovt 6b019ae958 refactor(core): add token to missing injection context error message (#60009)
In this commit, we add injector token information to the error message to improve debugging and context awareness, because it is hard to capture the `inject()` stack trace in asynchronous contexts.

PR Close #60009
2025-03-05 14:44:44 -08:00
arturovt 6dc41265fd fix(core): check whether application is destroyed before initializing event replay (#59789)
In this commit, we check whether the application is destroyed before initializing event replay. The application may be destroyed before it becomes stable, so when the `whenStable` resolves, the injector might already be in a destroyed state. As a result, calling `injector.get` would throw an error indicating that the injector has already been destroyed.

PR Close #59789
2025-03-05 14:43:48 -08:00
arturovt 3076254567 refactor(common): drop ngIf assert template error in production (#59705)
This commit removes the `assertTemplate` error message in production.

PR Close #59705
2025-03-05 14:42:19 -08:00
cexbrayat 90a16a1088 fix(common): support equality function in httpResource (#60026)
The `equal` option was not passed to the underlying resource.

PR Close #60026
2025-03-05 14:41:15 -08:00
iteriani 8d770eccee refactor(core): Remove the optional flag from Injector and all casts. (#60154)
Note that this does NOT use the retrieve method yet. I believe we need to move the logic for notFoundValue into the inject implementation.

PR Close #60154
2025-03-05 13:44:00 -08:00
Taygan Caldwell 699733fcc3 refactor: add untracked to primitives (#60105)
add untracked to primitives to allow Wiz to use it

PR Close #60105
2025-03-05 12:11:40 -08:00
Vlad Boisa b76af47966 docs: change broke Pipe link (#60226)
Change broke link, swap from /guides  to /guide
PR Close #60226
2025-03-05 12:11:06 -08:00
Matthieu Riegler 6accd1b0f5 docs(docs-infra): Use intersectionObserver for TOC (#60166)
Using IntersectionObservers simplfies the code and doesn't rely on APIs that will trigger a reflow.

PR Close #60166
2025-03-05 12:09:45 -08:00
Andrew Scott f08dbe0970 docs: Add more pending tasks documentation in zoneless readme (#59689)
This commit expands on the pending tasks documentation in the zoneless readme

PR Close #59689
2025-03-05 12:08:58 -08:00
Andrew Scott 6c7493e39d docs(core): Update zoneless test documentation to clarify OnPush requirement (#59689)
This updates the zoneless documentation to mention that components under
test a required to be onpush compatible. This includes any wrapper
components only used in tests.

fixes #59082

PR Close #59689
2025-03-05 12:08:58 -08:00
Andrew Scott cc97128760 docs(core): Clarify what it means to be a host for user components (#59689)
Adds a note to clarify what it means for a component to host a user
component in the context of `OnPush` restrictions.

fixes #58648

PR Close #59689
2025-03-05 12:08:58 -08:00
Doug Parker 39e8bd0f4b refactor(devtools): ignore getInjector when it is not supported (#60206)
Previously Angular DevTools would throw when run on an application which does not support `getInjector`, now it safely ignores it and assumes dependency injection is not supported.

PR Close #60206
2025-03-05 12:05:46 -08:00
AleksanderBodurri ba4b3dbed7 fix(devtools): handle case where router tree does not exist (#60221)
Previously this was throwing errors in applications with no Router token.

Now it skips emitting events for the router tree when it is unable to find the Router token.

Note: If these events don't emit, DevTools treats the RouterTree feature as disabled.

PR Close #60221
2025-03-05 12:05:02 -08:00
Miles Malerba d9e022dae2 release: cut the v19.2.1 release 2025-03-05 11:12:18 -08:00
arturovt 48d899f423 docs(zone.js): update NON-STANDARD-APIS.md (#58098)
This commit makes some grammatical changes to the existing documentation.

PR Close #58098
2025-03-05 17:30:43 +00:00
arturovt 19b6564cb2 docs(zone.js): update STANDARD-APIS.md (#58091)
This commit makes some grammatical changes to the existing documentation and adds additional
information about events.

PR Close #58091
2025-03-05 17:28:41 +00:00
arturovt f24246ef25 refactor(core): inline isFactory within getNodeInjectable (#59824)
This commit inlines the `isFactory` function body directly within `getNodeInjectable` because it is only used once. ESBuild does not inline its body within the function, which can be observed when running the build with `NG_BUILD_MANGLE=0`. The results after inlining are as follows:

```
getNodeInjectable x 70,397,377 ops/sec ±3.88% (52 runs sampled)
getNodeInjectable_inlined x 77,834,432 ops/sec ±3.13% (60 runs sampled)
```

PR Close #59824
2025-03-05 17:24:53 +00:00
Doug Parker 65d2ca9ed3 refactor(devtools): ignore ng.applyChanges if not supported (#60207)
Previously Angular DevTools would throw if `ng.applyChanges` was not defined. Now DevTools silently ignores the issue, assuming `mutateComponentOrDirective` was sufficient to update the application.

PR Close #60207
2025-03-05 16:53:57 +00:00
Matthieu Riegler a2db87ef81 docs(docs-infra): fix secondary menu (#60212)
fixes #58897

PR Close #60212
2025-03-05 11:05:07 +01:00
Matthieu Riegler 94ed3c3630 docs(docs-infra): AppComponent cleanup (#60212)
PR Close #60212
2025-03-05 11:05:07 +01:00
Pawel Kozlowski a64a5755e8 refactor(docs-infra): AppComponent cleanups (#58897)
This change contains multiple cleanups in the AppComponent:
- remove unused code;
- use router input bindings instead of manual read from
  the active route;
- remove isBrowser checks from even handlers (click events
  should not be invoked on the server, right?)

PR Close #58897
2025-03-04 22:20:49 +00:00
Jeevan Mahesha 20add2738c docs: update Angular CLI installation instructions for npm, pnpm, yarn, and bun (#59832)
PR Close #59832
2025-03-04 22:19:47 +00:00
Jeevan Mahesha e27a319261 docs: extend Angular CLI installation instructions for pnpm, yarn, and bun (#59832)
PR Close #59832
2025-03-04 22:19:47 +00:00
Mithilesh Zavar fbbe5d55b1 docs(migrations): Fix indentation in documentation for signal inputs migration (#60204)
PR Close #60204
2025-03-04 22:08:29 +00:00
Matthieu Riegler 507ed58152 refactor(core): extract dirty and markForRefresh from the private ViewRef. (#59122)
This allows better tree shaking from projects without the `element` package.

PR Close #59122
2025-03-04 22:05:41 +00:00
Matthieu Riegler 31bbbe9665 docs(docs-infra): Throw error at build time for invalid links (#59162)
PR Close #59162
2025-03-04 20:07:24 +00:00
Samuel Perez 83abe5f606 docs: fix all brokens links on the API pages (#59162)
This PR fix is for the broken links on the API
pages mentioned in issue #57591.

PR Close #59162
2025-03-04 20:07:24 +00:00
Matthieu Riegler 26b3a8f206 refactor(http): add context property to httpResource (#60188)
This was an oversight, `context` can be supported out of the box.

PR Close #60188
2025-03-04 19:57:22 +00:00
Matthieu Riegler edae26e117 docs(docs-infra): Don't truncate types in symbol extraction (#59909)
PR Close #59909
2025-03-04 19:54:58 +00:00
Alexis 8579ff8352 docs: Remove misleading default value DEFAULT_CURRENCY_CODE (#59977)
PR Close #59977
2025-03-04 19:37:57 +00:00
Matthieu Riegler 2bffacbe5e refactor(core): throw an Cyclic Dependency Error in prod mode (#60118)
Prior to this change, cyclic injection didn't trigger any error in prod mode, resulting into injecting the `CIRCULAR` object.
This could lead to strange errors where no method would be found on the token.

fixes #60074

PR Close #60118
2025-03-04 19:37:19 +00:00
naaajii f24a8c60ad docs: update license year (#59883)
updates the year in footer and placeholder for generated files

PR Close #59883
2025-03-04 19:36:48 +00:00
kirjs 036ee75684 docs: mention that log format makes it analyzable for changelog generation. (#58786)
PR Close #58786
2025-03-04 19:35:55 +00:00
kirjs 33a826b196 docs: sync the scope lists and drop ve (#58786)
PR Close #58786
2025-03-04 19:35:55 +00:00
kirjs 114658cf8c docs: address comments (#58786)
PR Close #58786
2025-03-04 19:35:55 +00:00
kirjs d30ea1b89c docs: move commit message guidelies to a separate file (#58786)
PR Close #58786
2025-03-04 19:35:54 +00:00
michael-small aff6d3d135 docs: update version table for 19.2 (#60173)
PR Close #60173
2025-03-04 17:47:10 +00:00
hawkgs 1c31c0d141 docs(docs-infra): API doc content rendering fixes (#60116)
The PR introduces a few doc content rendering fixes:
- Fix highlighted section heading styles (regression from #59965).
- Convert JSDoc links within 'Usage Notes' sections to HTML and render them.
- Add IDs to doc content headings. This, by itself, makes these headings available in the page ToC.

PR Close #60116
2025-03-04 17:46:31 +00:00
Andrew Scott 3f0116607d fix(language-service): Forward the tags for quick info from the type definition (#59524)
Prior to this commit, the tags from the type definition were dropped.
Tags may include, but are not limited to, deprecation information from
the jsdoc.

PR Close #59524
2025-03-04 17:37:23 +00:00
Lang 080fb08b76 docs: fix the wrong way to get a signal value (#59194)
PR Close #59194
2025-03-04 17:28:09 +00:00
Lang d3dde17693 docs: fix typo (#59194)
Co-authored-by: Enea Jahollari <jahollarienea14@gmail.com>
PR Close #59194
2025-03-04 17:28:09 +00:00
Lang 9ae9d9adde docs: use model API in two-way binding example (#59194)
PR Close #59194
2025-03-04 17:28:08 +00:00
Miles Malerba c615bdcde9 docs(docs-infra): Improve support for @link within the jsdoc. (#60201)
PR Close #60201
2025-03-04 17:13:43 +00:00
hawkgs 79c337448e docs: fix AnimationGroupMetadata description (#59733)
Fix the `animations/group()` link.

PR Close #59733
2025-03-04 17:12:11 +00:00
Jeevan Mahesha c67c551fb8 docs: update template syntax to new control flow (#59760)
PR Close #59760
2025-03-04 17:07:06 +00:00
Matthieu Riegler 1149686da5 docs(docs-infra): hide github link for external repos. (#60114)
fixes #60113

PR Close #60114
2025-03-04 17:02:37 +00:00
Matthieu Riegler 5c3be24712 docs(docs-infra): remove animation package (#60165)
PR Close #60165
2025-03-04 17:01:47 +00:00
Angular Robot 444671ac5b build: update dependency @types/chrome to ^0.0.307 (#60195)
See associated pull request for more information.

PR Close #60195
2025-03-04 17:00:22 +00:00
Matthieu Riegler d1233ebfa8 docs(docs-infra): wait for the DOM to be rendered (#60163)
the code inside `renderExample` is explicitly querying the DOM. We need to wait for it to be rendered for those functions to work.

PR Close #60163
2025-03-04 16:58:14 +00:00
Kristiyan Kostadinov 1c328ac261 build: update to TypeScript 5.8 final (#60176)
Updates the repo to stable version of TypeScript 5.8.

PR Close #60176
2025-03-04 16:57:36 +00:00
vladboisa cd31bfcc3e docs: change broke link (#60189)
Change the broked link to the working one

PR Close #60189
2025-03-03 22:20:53 +00:00
Andrew Scott 27174165a6 refactor(core): Update push/replace navigation to not trigger popstate (#60028)
This matches the spec, though there is a bug in chrome that does trigger these events.

PR Close #60028
2025-03-03 18:40:59 +00:00
Andrew Scott bf89792f8b refactor(core): Update fake navigation to more closely follow the spec (#60028)
This commit updates the implementation of the fake navigation to more
closely follow the spec. This includes links to spec parts as well as
some reorganization to have the flow of the code more exactly follow the
corresponding steps in the spec. This makes it easier to verify that th
behavior is correct.

PR Close #60028
2025-03-03 18:40:59 +00:00
Andrew Scott 49e3ec0dcf refactor(core): Ensure fake navigation is not aborted after it succeeds (#60028)
The navigate event was only ever being cleared when a new navigation
happened. That new navigation would abort the previous one, even if it
had already finished successfully.

PR Close #60028
2025-03-03 18:40:59 +00:00
arturovt c2de5f68b3 fix(common): clean up onUrlChange listener when root scope is destroyed (#60004)
This cleans up the `onUrlChange` listener once the root scope is destroyed.

PR Close #60004
2025-03-03 17:14:33 +00:00
Doug Parker dd70675893 release: bump Angular DevTools version to 1.0.24 (#60148)
PR Close #60148
2025-03-03 17:12:23 +00:00
Andrew Scott 1dd94476b3 fix(compiler-cli): ensure template IDs are not reused if a source file changes (#60152)
This commit fixes a bug where nodes are reused across incremental
compilations. The source file's next template ID is lost because a new
source file is created but nodes may still be retained.

PR Close #60152
2025-02-28 19:53:06 +00:00
Vlad Boisa c288a037b5 docs: fix not working links (#60160)
Remove JSDocs link, and replace the automatic linking with a regular markdown link

Fixes #59983

PR Close #60160
2025-02-28 19:52:33 +00:00
iteriani b81ea4f672 refactor(core): Move getCurrentInjector/setCurrentInjector to primitives package. (#60090)
This change casts the injector back and forth since all instances of
injector currently don't implement the `retrieve` method. Note that
the retrieve method is seen as optional, so that Angular can revert back to
inject if necessary.

PR Close #60090
2025-02-28 18:47:09 +00:00
Kristiyan Kostadinov 1b3b05bf72 fix(core): cache ComponentRef inputs and outputs (#60156)
The set of inputs and outputs of a component is static, but the getter for the `inputs` and `outputs` property was re-computing them every time which the user might not expect. These changes add a couple of lines to cache them instead.

PR Close #60156
2025-02-28 16:31:05 +00:00
Jessica Janiuk cfad089cc3 fix(core): prevents event replay from being called on comment nodes (#60130)
In some rare cases with directives, it is possible that the stash function might be called on a comment node. This actually verifies that the node is an element and exits otherwise.

fixes: #60070

PR Close #60130
2025-02-28 16:30:28 +00:00
Jessica Janiuk 95d227e5ef refactor(core): clean up event replay tests (#60130)
This updates the event replay tests to make them share the structure and utility functions used by hydration tests. This also resolves some soft errors in the event replay tests.

PR Close #60130
2025-02-28 16:30:28 +00:00
Matthieu Riegler ddfaf0cd46 refactor(migrations): Don't migrate twice the same file on the self-closing tag migration (#60065)
This commit fixes an issue when ts files are referenced multiple times (and thus analyzed multiple times) for example from a `tsconfig.json` and `tsconfig.spec.json`.

PR Close #60065
2025-02-28 16:27:40 +00:00
Hakeem b09f4a5c79 docs(docs-infra): add a tooltip to show the full text when nav item text is lengthy (#59038)
PR Close #59038
2025-02-27 18:25:19 +00:00
Hakeem 6c0c012e08 docs(docs-infra): handle long names in the sub nav (#59038)
PR Close #59038
2025-02-27 18:25:19 +00:00
Angular Robot a16dfb1b36 build: update actions/cache digest to d4323d4 (#60145)
See associated pull request for more information.

PR Close #60145
2025-02-27 18:23:42 +00:00
arturovt e549bdec8c refactor(animations): tree-shake regular expressions (#60095)
Adds a pure annotation to regular expressions because if the animations package is indirectly referenced in the code, it would include regular expressions in the bundle, even if they're unused (since `new` is side-effectful).

PR Close #60095
2025-02-27 17:53:25 +00:00
Lang 16ca676db0 docs: replace NgIf with new template syntax @if (#59159)
PR Close #59159
2025-02-27 17:41:54 +00:00
ColinJolivet 187758ccca refactor(docs-infra): remove expand button in example viewer if there is no hidden lines (#59086)
Remove the expand button of an example viewer if there is no hidden lines in it, in order not to confuse people

PR Close #59086
2025-02-27 15:48:02 +00:00
Jessica Janiuk 330c24aed9 fix(core): prevent invoking replay listeners on disconnected nodes (#60103)
This prevents replay from happening on nodes that have been removed from the DOM.

fixes: #59841

PR Close #60103
2025-02-27 15:45:14 +00:00
Matthieu Riegler ada75b605e docs(docs-infra): remove tutorial redirection (#60138)
PR Close #60138
2025-02-27 15:41:19 +00:00
Hryhorii Avcharov b06ed3cbf8 docs: fix mermaid event node text visibility in light mode (#60124)
PR Close #60124
2025-02-27 00:27:12 +00:00
Jessica Janiuk e012cf0acf build: add ignore revs file for git blame (#60117)
This allows for setting git and vscode gitlens to ignore specific commit hashes for bulk changes.

PR Close #60117
2025-02-26 16:19:26 -05:00
kirjs 8e9463bffb release: cut the v19.2.0 release 2025-02-26 16:10:05 -05:00
Matthieu Riegler 9b4727587a docs(docs-infra): remove explicit dectectChanges() (#60098)
PR Close #60098
2025-02-26 12:01:00 -05:00
Matthieu Riegler ee2f07fcff refactor(http): rename map to parse on HttpResourceOptions (#60112)
This reflects more the feature intended for this callback.

PR Close #60112
2025-02-26 11:52:44 -05:00
arturovt f76fd48b4a refactor(core): tree-shake REF_EXTRACTOR_REGEXP (#60081)
The `REF_EXTRACTOR_REGEXP` is a `new` expression that has side effects and is not dropped in production, even if it is unused.

PR Close #60081
2025-02-26 11:17:51 -05:00
arturovt 5de4b0cb70 refactor(core): inline depPath in throwCyclicDependencyError to be dropped (#60084)
Inlines the `depPath` within the `throwCyclicDependencyError`, because it's not being tree-shaken in production.

PR Close #60084
2025-02-26 11:10:38 -05:00
Jens Kuehlers fca21320e6 docs: move release date for v20 by one week (#60111)
PR Close #60111
2025-02-26 11:00:44 -05:00
arturovt c4126c7b9a refactor(forms): tree-shake _checkParentType in production (#60041)
In this commit, we move `_checkParentType` to a separate function to avoid a redundant prototype method in production.

PR Close #60041
2025-02-25 14:12:44 -05:00
Andrew Scott 176475f0fc fix(language-service): provide correct rename info for elements (#60088)
This commit ensures we do not block element rename if it is supported by
other rename providers.

fixes https://github.com/angular/vscode-ng-language-service/issues/2077

PR Close #60088
2025-02-25 14:10:55 -05:00
Kristiyan Kostadinov 7d6636087d fix(common): make types for HttpClient more readable (#59901)
`HttpClient` has a lot of overloads to achieve proper type checking, however each overload is also very long which makes it hard to read on adev. These changes replace the object literal types with `Record` to make them a bit more concise.

PR Close #59901
2025-02-25 13:01:11 -05:00
Pawel Kozlowski ce3a9a24d7 refactor(core): remove performance mark feature for signals (#59991)
Remove the performance mark feature from the Angular signal impl
so more code can be shared between primitives and other frameworks.

PR Close #59991
2025-02-25 11:10:09 -05:00
Kristiyan Kostadinov ef17371ab6 refactor(core): add infrastructure for setting inputs on specific directives (#60075)
Sets up the infrastructure that will allow to write only to a specific directive and its host directives as a base for future functionality.

I've also renamed `setInputsForProperty` to be a bit more explicit that its sets all inputs.

PR Close #60075
2025-02-25 10:58:51 -05:00
Kristiyan Kostadinov 6473214384 refactor(core): avoid memory allocations if there are no host directives (#60075)
Currently the host directive logic disassembles and re-assembles the array of directive matches, in case there are host directives which in most cases produces an identical array.

These changes add some logic so that we only need to allocate the additional memory if we actually need it.

PR Close #60075
2025-02-25 10:58:51 -05:00
Kristiyan Kostadinov f23946abe9 refactor(core): move component logic out of host directives resolution (#60075)
In order to mark a TNode as a component, we need to store the index of the component definition. Currently this happens in the logic that resolves host directives, because the component's host directives can move affect the index.

These changes move the logic out into the directive initialization logic since it doesn't have much to do with host directives.

PR Close #60075
2025-02-25 10:58:51 -05:00
Kristiyan Kostadinov fa6d9c22ac refactor(core): track match index of directives (#60075)
If we want to target an input write to a directive, we have to know the index at which its instance is stored. Technically we can already find this by looking through `TView.data`, but that'll require a linear lookup for each write which can get slow.

These changes introduce the new `TNode.directiveToIndex` map which allows us to quickly find the index of a directive based on its definition, as well as any host directives that its might've brought in.

PR Close #60075
2025-02-25 10:58:51 -05:00
Angular Robot d5f467e601 build: update all non-major dependencies (#60093)
See associated pull request for more information.

PR Close #60093
2025-02-25 10:49:25 -05:00
Angular Robot b5f28006b3 build: update io_bazel_rules_sass digest to 3b3667f (#60092)
See associated pull request for more information.

PR Close #60092
2025-02-25 10:45:36 -05:00
Angular Robot aac3e8acf6 build: update scorecard action dependencies (#60094)
See associated pull request for more information.

PR Close #60094
2025-02-25 10:43:28 -05:00
mgechev 10fb8722fe docs: add a page for custom build pipeline (#60058)
Add a documentation page for creating a custom build pipeline
with community plugins.

PR Close #60058
2025-02-25 10:40:36 -05:00
Aristeidis Bampakos 93c1918ab1 docs: update security guide (#59885)
PR Close #59885
2025-02-25 10:24:27 -05:00
Kristiyan Kostadinov ebfbaeba54 fix(core): capture stack for HMR errors (#60067)
Currently we send the `message` of an error thrown during HMR. That's usually not enough so now we also capture the stack trace.

Relates to https://github.com/angular/angular-cli/issues/29695.

PR Close #60067
2025-02-24 11:56:17 -05:00
hawkgs 9c5a6a6442 refactor(devtools): drop @ from inputs and outputs label (#60053)
Drop '@' from inputs and outputs label to fit in with the new signal-based API.

PR Close #60053
2025-02-24 10:49:13 -05:00
Evgeniy Aksyonov 67366d2f93 docs: fix typo in outputs.md for migrations section (#60055)
PR Close #60055
2025-02-24 10:46:23 -05:00
hawkgs 225e602176 docs(docs-infra): fix the top position of the search dialog (#60012)
Instead of centering the dialog, fix the top position in such way that when the results container is full, the dialog looks centered. This prevents the dialog from "jumping" when you type and the results change.

PR Close #60012
2025-02-24 10:44:19 -05:00
Charles Lyding 02a768e1d2 docs: use @angular/build directly in example/tutorial projects (#60046)
By using the `@angular/build` package directly within projects for each
example and tutorial, the total install size can be reduced. This lowers the amount
of time required to be spent setting up the dependencies in browser
before the example is displayed.

The `@angular/build@19.2.0-next.2` package currently has a total unpacked size of ~115 MB.
The `@angular-devkit/build-angular@19.2.0-next.2` package currently has a total unpacked size of ~291 MB.

This also removes the now unneeded `NG_BUILD_PARALLEL_TS=0` environment variable usage.

PR Close #60046
2025-02-24 10:14:18 -05:00
Kristiyan Kostadinov 35d20cb4b4 refactor(core): do not store input/output public names (#60036)
Reworks the `TNode.inputs` and `TNode.outputs` to not store the public names of bindings. The only reason they were stored was for host directive re-aliasing which is handled through a different data structure now.

PR Close #60036
2025-02-21 14:07:35 -05:00
Kristiyan Kostadinov 352021e1d2 refactor(core): separate host directive inputs from selector-matched ones (#60036)
Currently `TNode.inputs`/`TNode.outputs` store all of the available bindings on that node, no matter if they came from a directive that the user applied directly or from a host directive. This has a couple of drawbacks:
1. We need to store more information that necessary. For example, the only reason we have strings in the arrays is to facilitate host directive aliasing.
2. It doesn't allow us to distinguish which host directives belong to which selector-matched directives.

These changes are a step towards resolving both issues by storing the host directive binding information in separate data structures.

PR Close #60036
2025-02-21 14:07:35 -05:00
Kristiyan Kostadinov 285abbb38f refactor(core): rework how inputs/outputs are initialized (#60036)
Reworks the functions that create the `initialInputs`, `inputs` and `outputs` structures to initilize them within the function, instead of returning them to be initialized later. This will simplify future refactors where they'll produce more than one piece of information.

PR Close #60036
2025-02-21 14:07:35 -05:00
Jessica Janiuk 3fd6551cae docs: remove todo from jsdoc (#60042)
This removes TODO from a JSDoc block that made it show up on adev.

PR Close #60042
2025-02-21 11:16:48 -05:00
Pawel Kozlowski ea8662ab3e refactor(core): remove duplicated checks for ngNonBindable (#60048)
This refactoring consolidates logic around detecting ngNonBindable
mode - previously those checks were done in two separate places.
By doing the check in one place we can simplify the directive resolution
logic.

PR Close #60048
2025-02-21 11:08:50 -05:00
Jessica Janiuk 1d28a42815 refactor(core): clean up when blocks fail to fetch or hydrate (#59740)
There are cases where resources fail to fetch or the DOM has changed due to an if block. This should clean up the remaining promises and any registry references to those blocks in that case.

PR Close #59740
2025-02-21 11:08:04 -05:00
arturovt 21740846b5 refactor(core): drop platform check in ImagePerformanceWarning (#59809)
Replaces `PLATFORM_ID` checks with `ngServerMode`.

PR Close #59809
2025-02-20 12:32:23 -05:00
hawkgs 4fde15438f refactor(devtools): fix component inspector highlighting (#59995)
Use `position: absolute` instead of `position: fixed`. This fixes the odd behavior that can be reproduced when scrolling.

PR Close #59995
2025-02-20 11:56:09 -05:00
Trevor Florence 7a1bf0610e fix(benchpress): Ensure future-proof correct initialization order (#60025)
Future changes to initialization order can cause this previously OK code to start having compiler erroring like: `TS2729: Property 'foo' is used before its initialization.`

PR Close #60025
2025-02-20 11:21:55 -05:00
muhammadali1658 195d0b1ff5 docs: Fix typo ')' in banner-initial.component.spec.ts (#60032)
PR Close #60032
2025-02-20 11:03:11 -05:00
Joey Perrott 053593ef3e ci: update deploy doc site script (#60021)
Update the checked in version of the deploy script

PR Close #60021
2025-02-19 21:01:32 +00:00
Miles Malerba 347c3d5761 build: remove circular deps goldens (#60021)
Removes the circular dependencies golden file and cleans up the
associated pullapprove group. All circular dependencies have been
removed and no new ones may be added.

PR Close #60021
2025-02-19 21:01:32 +00:00
Miles Malerba 8449c071da build: update to latest @angular/ng-dev version (#60021)
Update to the latest version to gain circular deps updates.

PR Close #60021
2025-02-19 21:01:32 +00:00
Andrew Scott f88ed8e470 refactor(core): Add fake navigation to primitives for code sharing (#59857)
This moves the `FakeNavigation` implementation to the primitives folder
so its implementation can be shared with Wiz. This class was initially
copied directly from the Wiz implementation, with some small modifications.
There will still need to be some work done to align the implementations
and fix anything internally that needs adjusting.

PR Close #59857
2025-02-19 20:09:10 +00:00
Jessica Janiuk 11ea0a0f7d release: cut the v19.2.0-rc.0 release 2025-02-19 14:02:38 -05:00
Jessica Janiuk 497028cc52 docs: release notes for the v19.1.7 release 2025-02-19 13:44:52 -05:00
arturovt 40dc99da9c refactor(common): inline supports check in slice pipe (#59684)
The refactored version improves the original code by removing the `supports` method from the prototype and inlining the logic directly into the `transform` method. This reduces indirection and simplifies the class, especially since `supports` is not reused elsewhere. ESBuild can directly inline the condition into the `if` statement by removing the variable: `if (!("string" == typeof e || Array.isArray(e))) throw i(s, e);`.

PR Close #59684
2025-02-19 15:22:49 +00:00
arturovt b2947e83f7 refactor(forms): remove _checkFormPresent and move directly to ngOnChanges (#59741)
In this commit, we remove `_checkFormPresent` because it is a no-op in production. We move its body directly into `ngOnChanges` to eliminate the redundant method from the prototype. Previously, `_checkFormPresent` was being called with no body in production each time `ngOnChanges` was executed.

PR Close #59741
2025-02-19 15:22:13 +00:00
arturovt cf3a5073ec refactor(core): improve stringify (#59745)
In this commit, we improve branching in the `stringify` function, which is widely used by the framework, and add additional comments for clarification. Benchmark results of the old and new implementations (using `slice` makes it slightly faster) are as follows:
```
stringify (old version) x 117,945,419 ops/sec ±5.25% (55 runs sampled)
stringify (new version) x 136,692,820 ops/sec ±4.82% (56 runs sampled)
```

PR Close #59745
2025-02-19 15:21:36 +00:00
arturovt 967488247e refactor(common): simplify stripTrailingSlash (#59746)
The new version of the function is smaller, eliminating extra bytes. The refactor improves both code size and readability while optimizing the implementation. Benchmark results for the old and new implementations are as follows:

```
stripTrailingSlash_old x 15,446,602 ops/sec ±0.89% (66 runs sampled)
stripTrailingSlash_new x 19,694,523 ops/sec ±1.10% (61 runs sampled)
```

Thus, the new implementation is both smaller and faster.

PR Close #59746
2025-02-19 15:20:53 +00:00
Vlad Boisa 5283c2b080 docs: add serve section to Service-worker (#59972)
Add the section which mention way to enable service-worker during local development

Fixes #59949

PR Close #59972
2025-02-19 15:19:19 +00:00
Matthieu Riegler 4298bf199b docs(docs-infra): remove unused examples (#59252)
PR Close #59252
2025-02-19 15:18:47 +00:00
Miles Malerba c056fb9df9 ci: add mmalerba to pullapprove (#60005)
Add mmalerba to pullapprove config

PR Close #60005
2025-02-19 15:18:07 +00:00
Angular Robot 5a2cc6c390 build: update actions/cache digest to 0c907a7 (#60002)
See associated pull request for more information.

PR Close #60002
2025-02-18 20:23:09 +00:00
Matthieu Riegler cf36951f83 fix(forms): Fix typing on FormRecord. (#59993)
Priori to this change, `ɵRawValue` of a `FormRecord` returned a `Partial`. This commit fixes it.

fixes #59985

PR Close #59993
2025-02-18 19:28:36 +00:00
Kristiyan Kostadinov f41437e6f5 refactor(core): simplify serialization of inputs and outputs (#59980)
Simplifies the functions that serialize inputs/outputs for the `ComponentFactory` type.

PR Close #59980
2025-02-18 19:28:00 +00:00
Kristiyan Kostadinov 86610f7bad build: update bundle goldens (#59980)
Updates the bundle goldens to account for the latest changes.

PR Close #59980
2025-02-18 19:28:00 +00:00
Kristiyan Kostadinov 9c6a0e5f01 refactor(core): add assertion to avoid writes to directive factories (#59980)
Attempting to write to directive inputs before the directive is created can lead to subtle issues that won't necessarily trigger errors. These changes add an assertion to catch such issues earlier.

PR Close #59980
2025-02-18 19:28:00 +00:00
Kristiyan Kostadinov 1b0fdc7eb1 refactor(core): avoid unnecessary lookup when writing inputs (#59980)
Currently we resolve the DOM node when writing inputs up-front, because it's necessary for the `ng-reflect-` attributes. Since the attributes are dev-mode-only, we can move the resolution into the function that writes them so we can avoid the resolution when it's not used.

PR Close #59980
2025-02-18 19:28:00 +00:00
Kristiyan Kostadinov 6a7fd11386 refactor(core): simplify InitialInputs data structure (#59980)
Reworks the `InitialInputs` data structure to only store a public name and initial value, resulting in less memory usage and making it easier to work with.

PR Close #59980
2025-02-18 19:28:00 +00:00
Kristiyan Kostadinov 5acdc6bd59 refactor(core): remove flags from TNode.inputs (#59980)
The input flags are already available on the definition so we don't need to store them on `TNode.inputs`.

PR Close #59980
2025-02-18 19:27:59 +00:00
Kristiyan Kostadinov db530856a8 refactor(compiler): remove input transforms feature (#59980)
An earlier refactor made the `InputTransformsFeature` a no-op so these changes remove the code that was generating it.

PR Close #59980
2025-02-18 19:27:59 +00:00
Kristiyan Kostadinov 86086604f4 refactor(core): remove inputTransforms from definition (#59980)
Removes the `inputTransform` from the directive definition since this information is already available on the `inputs`.

PR Close #59980
2025-02-18 19:27:59 +00:00
Kristiyan Kostadinov b8ad4c2117 refactor(core): simplify how inputs are stored in the directive definition (#59980)
Currently the values in `DirectiveDef.inputs` are either strings or arrays, depending if there are flags. This makes it a bit hard to work with, because each time it's read, the consumer needs to account for both cases.

These changes rework it so the values are always an arrays.

PR Close #59980
2025-02-18 19:27:59 +00:00
Enea Jahollari 1cd3a7db83 feat(migrations): add migration to convert templates to use self-closing tags (#57342)
This schematic helps developers to convert their templates to use self-closing tags mostly as a aesthetic change.

PR Close #57342
2025-02-18 17:33:59 +00:00
Angular Robot b6fa69f2c0 build: update dependency shiki to v3 (#59986)
See associated pull request for more information.

PR Close #59986
2025-02-18 16:50:02 +00:00
Pawel Kozlowski c076b57986 refactor(core): move LContainer manipulation logic to its own file (#59856)
All the view in a container logic is in the
packages/core/src/render3/view/container.ts file
plus some other associated refactorings.

PR Close #59856
2025-02-18 15:41:42 +00:00
Angular Robot 3bfa85f5c8 build: lock file maintenance (#59836)
See associated pull request for more information.

PR Close #59836
2025-02-18 15:41:09 +00:00
arturovt 7bd4be0fa5 fix(common): clean up urlChanges subscribers when root scope is destroyed (#59703)
In this commit, the `urlChanges` subject is completed to release all active observers when the root scope is destroyed. Previously, subscribing to the `urlChanges` subject caused the subscriber to capture `this`, resulting in a memory leak after the root scope was destroyed.

PR Close #59703
2025-02-18 15:40:19 +00:00
hawkgs ea5b7371e5 docs(docs-infra): fix card highlighting in the API reference details page (#59965)
Drop `pointer-events: none` and update the member card highlighting mechanism.

PR Close #59965
2025-02-18 14:56:48 +00:00
Matthieu Riegler c3e95ef1d5 docs(docs-infra): attemp to fix flaky mermaid test (#59994)
This test has 2 async parts, loading the markdown file and the marked parsing.
First attempt to fix the flakiness is by inline the markdown file.

If this test timeouts again in the future it means the timeout is related to marked itself (and the dynamic import of mermaid).

PR Close #59994
2025-02-18 14:55:49 +00:00
Matthieu Riegler 5b20bab96d feat(compiler): Add Skip Hydration diagnostic. (#59576)
The diagnostic was created in #49512 but was never added to the list of diagnostic that run.

fixes #59569

PR Close #59576
2025-02-18 14:54:51 +00:00
Doug Parker be32d63652 docs: update zip command and link to recent DevTools commits (#59792)
`-x dist/` never worked for reasons I don't really understand. Historically I've just deleted `dist/` before zipping. I tried a few different approaches, but all of them lead to some form of "Name not matched" error in `zip` of the `dist/` directory. Instead I just opted to delete `dist/` as part of the zipping command.

The link to recent DevTools commits seems good enough to manually write a changelog. All relevant commits should be using `refactor(devtools)`, so the string "devtools" should definitely be in there.

PR Close #59792
2025-02-14 19:31:59 +00:00
Angular Robot 751dc4ad5b build: update babel dependencies to v7.26.9 (#59743)
See associated pull request for more information.

PR Close #59743
2025-02-14 19:15:15 +00:00
Alex Rickabaugh 3e39da593a feat(common): introduce experimental httpResource (#59876)
`httpResource` is a new frontend to the `HttpClient` infrastructure. It
declares a dependency on an HTTP endpoint. The request to be made can be
reactive, updating in response to signals for the URL, method, or otherwise.
The response is returned as an instance of `HttpResource`, a
`WritableResource` with some additional signals which represent parts of the
HTTP response metadata (status, headers, etc).

PR Close #59876
2025-02-14 18:40:37 +00:00
Alex Rickabaugh 538c4d4c9d ci: disable adev tests (#59876)
The changes in #58288 are responsible for breaking the tests. (see #54858).
We'll re-enable them on the next release.

PR Close #59876
2025-02-14 18:40:37 +00:00
Andrew Scott e7c6ecc955 refactor(benchpress): move initializer to constructor (#59960)
Move the initializer into the constructor for instance members that reference identifiers declared in the constructor.

When TypeScript outputs modern language features, the below case throws an TS error.

PR Close #59960
2025-02-14 18:39:58 +00:00
Angular Robot 506d38dc1c build: update all non-major dependencies (#59641)
See associated pull request for more information.

PR Close #59641
2025-02-14 18:39:10 +00:00
Angular Robot 47d5e1e275 build: update dependency jsdom to v26 (#59444)
See associated pull request for more information.

PR Close #59444
2025-02-14 17:59:57 +00:00
Alan Agius 5ca2fa53d5 ci: update nvm node.js verson to 18.20.5 (#59957)
This is needed due to some deps.

PR Close #59957
2025-02-14 17:24:55 +00:00
Angular Robot 650e1f9a86 build: update io_bazel_rules_sass digest to c01e884 (#59948)
See associated pull request for more information.

PR Close #59948
2025-02-14 16:34:23 +00:00
Kristiyan Kostadinov 5553b5cfa8 build: update to TypeScript 5.8 RC (#59952)
Updates the repo to the release candidate TypeScript 5.8.

PR Close #59952
2025-02-14 16:32:50 +00:00
Doug Parker dcb23ef706 release: bump Angular DevTools version to 1.0.23 (#59931)
PR Close #59931
2025-02-14 16:31:37 +00:00
Alan Agius c93e4fe497 build: update bazel node.js version to 18.20.5 (#59943)
This is needed as selenium-webdriver requires at least this version.

PR Close #59943
2025-02-14 16:31:04 +00:00
Angular Robot 7197e82936 build: update cross-repo angular dependencies (#59946)
See associated pull request for more information.

PR Close #59946
2025-02-14 16:30:18 +00:00
Jessica Janiuk 1ebf7bfb23 ci: fix flakey incremental hydration test (#59945)
This extends the test timeout for the two timer tests while shortening the actual hydrate on timer. This hopefully should result in more reliable CI.

PR Close #59945
2025-02-13 22:35:04 +00:00
iteriani 8b757bf35c refactor(core): Check in some interfaces for the DI package (#59921)
This will be the starting point of the DI package. We will first check in some interfaces and then make sure the existing DI package implements that interface. Afterwards, we'll slowly start moving injector implementation.

PR Close #59921
2025-02-13 20:19:29 +00:00
Jessica Janiuk d46aa79873 build: update zone.js pullapprove rule (#59942)
This fixes the broken pullapprove config due to a missing array.

PR Close #59942
2025-02-13 20:16:49 +00:00
Jessica Janiuk d1a3e6203c build: update zone.js pullapprove rule (#59941)
This excludes lock and package files from requiring zones approval.

PR Close #59941
2025-02-13 19:17:13 +00:00
Matt Turco 2588985f43 feat(core): pass signal node to throwInvalidWriteToSignalErrorFn (#59600)
Updates the signature of the `throwInvalidWriteToSignalError` to take the signal node in question and pass it along to the throwInvalidWriteToSignalErrorFn handler function. This allows the handler to e.g. include the signal name in error messaging.

PR Close #59600
2025-02-13 17:56:14 +00:00
JoostK 973033abd2 fix(compiler-cli): avoid crash in isolated transform operations (#59869)
The CLI uses the `ts.transform` API to apply the Angular compiler's transformers
on the source files when `isolatedModules` is true (and various other constraints)
instead of going through a full `ts.Program.emit` operation. This results in the
transformers to operate in an environment where no emit resolver is available, which
was not previously accounted for. This commit reflects the possibility for the emit
resolver to be missing and handles this scenario accordingly.

Fixes #59837

PR Close #59869
2025-02-13 16:39:04 +00:00
Jessica Janiuk fb39fe9650 release: cut the v19.2.0-next.3 release 2025-02-13 11:30:30 -05:00
arturovt f34aeaeaad refactor(common): remove redundant transferCacheInterceptorFn dependencies (#59819)
The `transferCacheInterceptorFn` injects dependencies in itself; the `TransferCache` and cache options are redundant in the `deps` list.

PR Close #59819
2025-02-13 15:11:19 +00:00
arturovt 20f5dc5103 refactor(core): simplify concatStringsWithSpace (#59820)
The new version of the function is smaller, eliminating extra bytes. The refactor improves both code size and readability while optimizing the implementation. Benchmark results for the old and new implementations are as follows:

```
concatStringsWithSpace_old x 149,225,311 ops/sec ±8.54% (50 runs sampled)
concatStringsWithSpace_new x 160,206,834 ops/sec ±5.72% (54 runs sampled)
```

Thus, the new implementation is both smaller and faster.

PR Close #59820
2025-02-13 15:10:42 +00:00
hawkgs 9f092142d9 docs(docs-infra): replace the WebGL home page animation with a CSS+JS version of it (#59865)
1. The WebGL animation on the home page is completely removed.
2. A new animation processor/player is implemented and added to `adev` web app.
3. A new CSS+JS-based animation substitutes the existing WebGL one.

PR Close #59865
2025-02-13 15:03:36 +00:00
Doug Parker ae6dc71495 docs: link to Tailwind docs about Angular CLI integration (#59765)
We should probably have our own authoritative documentation here, but Tailwind's doc is pretty decent, so this is a good starting point.

PR Close #59765
2025-02-13 15:00:55 +00:00
rysavy-dudrtools bb946d71ed docs(localize): added link to add-package.md (#59937)
PR Close #59937
2025-02-13 14:59:37 +00:00
hawkgs b6733eeea4 docs(docs-infra): drop tabs layout from the API reference details page (#59068)
Drop the tabs in favor of a single page separated by sections.

PR Close #59068
2025-02-13 14:58:33 +00:00
Angular Robot e0c33814fd build: update github/codeql-action action to v3.28.9 (#59914)
See associated pull request for more information.

PR Close #59914
2025-02-13 14:56:39 +00:00
Doug Parker adf2a0a2d6 release: bump Angular DevTools version to 1.0.22 (#59791)
PR Close #59791
2025-02-13 14:50:39 +00:00
Miles Malerba 6789c7ef94 fix(core): Defer afterRender until after first CD (#59455) (#59551)
This reverts commit ac2dbe3eb1.

PR Close #59551
2025-02-12 12:20:04 -08:00
Miles Malerba c87e581dd9 fix(core): Don't run effects in check no changes pass (#59455) (#59551)
This reverts commit 21f1ba22a6.

PR Close #59551
2025-02-12 12:20:04 -08:00
Andrew Scott 730fe65d55 docs: release notes for the v19.1.6 release (#59930)
PR Close #59930
2025-02-12 12:19:13 -08:00
hawkgs 4f3ad98466 refactor(devtools): styles management (#59589)
- Move all styles to ng-devtools/src/styles.
- Create a BrowserService that detects the browsers and adds it as a class to the body. Move global browser styles.
- Create theme mixins that incorporate the browser type into them.
- Refactor some of the affected code along with the introduced changes.

PR Close #59589
2025-02-12 10:47:02 -08:00
Kristiyan Kostadinov 9e847fc60d fix(compiler): handle tracking expressions requiring temporary variables (#58520)
Currently when we generate the tracking expression for a `@for` block, we process its expression in the context of the creation block. This is incorrect, because the expression may require ops of its own for cases like nullish coalescing or safe reads. The result is that while we do generate the correct variable, they're added to the creation block rather than the tracking function which causes an error at runtime.

These changes address the issue by keeping track of a separate set of ops for the `track` expression that are prepended to the generated function, similarly to how we handle event listeners.

Fixes #56256.

PR Close #58520
2025-02-12 09:56:08 -08:00
Angular Robot 6f315fe501 build: update io_bazel_rules_sass digest to d829b6a (#59862)
See associated pull request for more information.

PR Close #59862
2025-02-12 09:47:52 -08:00
Bobokhuja b2f1d4eb9e docs: fix tabs in example code in creating injectable services (#59911)
PR Close #59911
2025-02-12 09:46:51 -08:00
Kristiyan Kostadinov aa285c548c fix(migrations): account for let declarations in control flow migration (#59861)
Fixes that the control flow migration wasn't accounting for `@let` when determining which symbols are used.

PR Close #59861
2025-02-12 09:45:14 -08:00
Kristiyan Kostadinov 1119f85ca9 fix(migrations): count used dependencies inside existing control flow (#59861)
Fixes that the control flow migration wasn't checking the content of pre-existing control flow nodes for dependencies.

Fixes #59846.

PR Close #59861
2025-02-12 09:45:14 -08:00
Angular Robot c69125009c build: update dependency saucelabs to v9 (#59801)
See associated pull request for more information.

PR Close #59801
2025-02-12 09:39:28 -08:00
AleksanderBodurri 28dd04a866 fix(devtools): regressions in component tree (#59873)
This commit solves two cases

Bug: When a directive of the same name is selected, the property view tab would not update properly. This was caused by a signals refactor that changed the behaviour of a string input property to not re-render because the underlying signal did not change (string equality). This is fixed by converting this input into an object.

Bug: When a selected element is removed from the component tree, DevTools would not rerender the component tree properly and deselect that component. Now if DevTools detects that a component is removed, it re-renders the tree and deselects the component.

PR Close #59873
2025-02-12 09:22:28 -08:00
Matthieu Riegler 0d88463a66 docs(docs-infra): inline example in description (#59908)
fixes #59905

PR Close #59908
2025-02-12 09:21:49 -08:00
Hendra Arfiansyah 4a5c3df824 docs: remove trailing parentheses in example code in linked signal (#59917)
PR Close #59917
2025-02-12 09:20:31 -08:00
Angular Robot 8cdb7b8e85 docs: update Angular CLI help [main] (#59925)
Updated Angular CLI help contents.

PR Close #59925
2025-02-12 09:19:37 -08:00
Kristiyan Kostadinov 5cd26a9420 fix(compiler-cli): handle deferred blocks with shared dependencies correctly (#59926)
When the compiler analyzes the defer blocks in a component, it generates two sets of dependencies: ones specific for each block and others from all the deferred blocks within the component. The logic that combines all the defer block dependencies wasn't de-duplicating them which resulted in us producing `setClassMetadataAsync` calls where the callback can have multiple parameters with the same name. This was a problem both in full and partial compilation, but the latter was more visible, because Babel throws an error in such cases.

These changes add some logic to de-duplicate the dependencies so that we produce valid code.

Fixes #59922.

PR Close #59926
2025-02-12 09:15:53 -08:00
Kristiyan Kostadinov b0266bda4a fix(core): invalidate HMR component if replacement throws an error (#59854)
Integrates https://github.com/angular/angular-cli/pull/29510 which allows us to invalidate the data in the dev server for a component if a replacement threw an error.

PR Close #59854
2025-02-12 09:05:30 -08:00
Kristiyan Kostadinov e47c1e5abe refactor(compiler): pass more information to HMR replacement function (#59854)
Adjusts the code we generate for HMR so that it passes in the HMR ID and `import.meta` to the `replaceMetadata` call. This is necessary so we can do better logging of errors.

PR Close #59854
2025-02-12 09:05:30 -08:00
Alex Rickabaugh a7f20eb863 release: cut the v19.2.0-next.2 release 2025-02-06 12:50:20 -08:00
Alex Rickabaugh 7196725622 docs: release notes for the v19.1.5 release 2025-02-06 12:34:52 -08:00
Wadie 951155eb4c fix(docs-infra): reset sandbox runtime on template change (#59844)
Ensure the sandbox runtime is properly reset when the template changes to prevent any unexpected behavior during development.

PR Close #59844
2025-02-05 15:01:33 -08:00
Alex Rickabaugh b592b1b051 fix(core): fix race condition in resource() (#59851)
The refactoring of `resource()` to use `linkedSignal()` introduced the
potential for a race condition where resources would get stuck and not update
in response to a request change. This occurred under a specific condition:

1. The request changes while the resource is still in loading state
2. The resource resolves the previous load before its `effect()` reacts to the
   request change.

In practice, the window for this race is small, because the request change in
(1) will schedule the effect in (2) immediately. However, it's easier to
trigger this sequencing in tests, especially when one resource depends on the
output of another.

To fix the race condition, the resource impl is refactored to track the request
in its state, and ignore resolved values or streams for stale requests. This
refactoring actually makes the resource code simpler and easier to follow as
well.

Fixes #59842

PR Close #59851
2025-02-05 15:01:02 -08:00
Andrew Scott 8ee91bceed build: remove self from unavailable list (#59858)
remove self from unavailable list

PR Close #59858
2025-02-05 12:18:57 -08:00
Jeevan Mahesha 4d2684d9a3 docs: Add v18 Angular version link to versions configuration (#58933)
PR Close #58933
2025-02-05 09:02:02 -08:00
muhammadali1658 a592fbc8cd docs: fix broken link of FID (#59848)
PR Close #59848
2025-02-05 09:01:31 -08:00
Miles Malerba a299e02e91 fix(core): preserve tracing snapshot until tick finishes (#59796)
This change waits until the end of `tick` to clear the tracing snapshot.
This ensures that if we notify the scheduler during `tick` the correct
tracing snapshot is used.

PR Close #59796
2025-02-05 09:00:49 -08:00
hyperlife1119 5191a41a18 docs(service-worker): corrected default values ​​for navigation URLs (#58156)
The default value described in the documentation is inconsistent with the actual default value.

PR Close #58156
2025-02-05 09:00:23 -08:00
Jeremias Peier fa0c3e3210 feat(forms): support type set in form validators (#45793)
Previously, using `Validators.required`, `Validators.minLength` and `Validators.maxLength` validators don't work with sets because a set has the `size` property instead of the `length` property. This change enables the validators to be working with sets.

PR Close #45793
2025-02-05 08:59:55 -08:00
Pawel Kozlowski 41b1a7c582 refactor(core): minor code cleanups (#59843)
Some minor code cleanups after code changes in
previous commits.

PR Close #59843
2025-02-05 08:56:28 -08:00
Pawel Kozlowski d8fca6d3df refactor(core): reuse element end first creation pass (#59843)
Reuse element end first creation pass in ComponentRef impl.

PR Close #59843
2025-02-05 08:56:28 -08:00
Pawel Kozlowski 5e0dcf1f53 refactor(core): reuse element first create pass in ComponentRef (#59843)
Reuse element first create pass in ComponentRef.

PR Close #59843
2025-02-05 08:56:28 -08:00
Pawel Kozlowski e3dcf523ea refactor(core): move directive matching logic to a separate file (#59843)
Move directive matching logic to a separate file.

PR Close #59843
2025-02-05 08:56:27 -08:00
Kristiyan Kostadinov 146ab9a76e feat(core): support TypeScript 5.8 (#59830)
Updates the repo to support TypeScript 5.8 which is currently in beta.

PR Close #59830
2025-02-03 14:00:41 -08:00
Angular Robot 5e9e9bde0d build: update dependency angular-split to v19 (#59827)
See associated pull request for more information.

PR Close #59827
2025-02-03 14:00:11 -08:00
Ole Martin Sørli 3769935df7 docs(migrations): fix misspelled link text in overview.md (#59816)
I assume that the link text should read "Try it now" instead of "Try it not". The latter is funnier, but also implies that this migration is not a recommended one.
PR Close #59816
2025-02-03 13:59:16 -08:00
Kristiyan Kostadinov a97136052f fix(compiler-cli): gracefully fall back if const enum cannot be passed through (#59815)
Adds some logic so that if we can't produce a runtime representation of an enum, the dev server can fall back to refreshing the page.

PR Close #59815
2025-02-03 13:58:31 -08:00
Kristiyan Kostadinov bae94b82fd fix(compiler-cli): handle const enums used inside HMR data (#59815)
When we generate an HMR replacement function, we determine which locals from the file are used and we pass them by reference. This works fine in most cases, but breaks down for const enums which don't have a runtime representation.

These changes work around the issue by passing in all the values as an object literal.

Fixes #59800.

PR Close #59815
2025-02-03 13:58:31 -08:00
Kristiyan Kostadinov 03bcd30e34 fix(compiler-cli): handle enum members without initializers in partial evaluator (#59815)
Fixes that the partial evaluator was interpreting initializer-less enum members as undefined. In this case the value is the same as the index.

PR Close #59815
2025-02-03 13:58:31 -08:00
arturovt a88b00c9e3 refactor(platform-browser): remove redundant DomEventsPlugin dependencies (#59811)
The `DomEventsPlugin` only injects the `DOCUMENT`; the platform ID and `NgZone` are redundant.

PR Close #59811
2025-02-03 13:57:45 -08:00
Pawel Kozlowski 2d53bacec3 refactor(core): reuse existing logic in ComponentRef impl (#59806)
This change removes some code and logic duplication by
re-using the existing functionality. It also pulls some
code into separate methods for clarity.

PR Close #59806
2025-02-03 13:57:10 -08:00
Luan Gong 4684e67fd0 docs: Fix wording for Angular CLI end-to-end testing (#59808)
PR Close #59808
2025-02-03 13:56:39 -08:00
Andrew Scott ad88304233 refactor(core): move callAndReportToErrorHandler to bootstrap file (#59793)
This function is only used in the bootstrap file and does not need to be in application_ref

PR Close #59793
2025-02-03 13:54:40 -08:00
Angular Robot f9ff989b59 build: update github/codeql-action action to v3.28.8 (#59786)
See associated pull request for more information.

PR Close #59786
2025-02-03 13:54:01 -08:00
Gerard Esteve e725c4774c docs: add clarification for sourceLocale location in angular.json (#59783)
PR Close #59783
2025-02-03 13:53:35 -08:00
Alan Agius 5762cdd7fd docs: replace provideServerRoutesConfig with provideServerRouting (#59777)
The `provideServerRoutesConfig` is replaced with `provideServerRouting`

PR Close #59777
2025-02-03 13:53:04 -08:00
arturovt f8eae13dde refactor(docs-infra): allow home animation to be cleaned up properly (#59732)
In this commit, we wrap `initCanvas` in an observable to prevent executing any code, such as `getViews()`, if the view is destroyed before the canvas becomes ready.

PR Close #59732
2025-02-03 13:52:17 -08:00
arturovt 30ff7e3f1a refactor(docs-infra): extract NodeRuntimeSandbox lazy-loading into separate function (#59344)
In this commit, we extract `NodeRuntimeSandbox` lazy-loading into a separate function (because it's duplicated).

PR Close #59344
2025-02-03 13:51:51 -08:00
BreadInvasion 5a6daa6cd3 docs: use inject() in dependency injection guide (#59079)
PR Close #59079
2025-02-03 13:51:23 -08:00
Sam Knutson 042ee75d1b docs: fix spelling of "set up" (#58362)
Fix spelling of the word "set up" in docs. "Setup" (one word) is a noun
whereas "set up" (two words) is a verb.

Fixes #58361

PR Close #58362
2025-02-03 13:50:49 -08:00
Alex Rickabaugh 9723f034c3 release: cut the v19.2.0-next.1 release 2025-01-29 15:17:55 -08:00
Alex Rickabaugh eb9dca3120 docs: release notes for the v19.1.4 release 2025-01-29 15:11:55 -08:00
Dmitry Ivanitskiy b5f9018148 docs: fix programmatic-rendering example (#59768)
Fixes example of programmatically rendering of components using dynamic import, as calling dynamic import returns module namespace object rather than component instance

PR Close #59768
2025-01-29 10:54:10 -08:00
Doug Parker c03f45ce8e docs: updates versioning docs to recommend that fixes in an RC period be released as a -next release prior to hitting stable (#59766)
PR Close #59766
2025-01-29 10:52:44 -08:00
Kristiyan Kostadinov ea2ea5e65b test(core): update tests that were relying on implicit animations module (#59762)
We had some tests that were relying on the fact that the server module was importing animations implicitly.

PR Close #59762
2025-01-29 10:52:18 -08:00
Kristiyan Kostadinov fc5d187da5 fix(platform-server): decouple server from animations module (#59762)
Removes the hard dependency between `platform-server` and `platform-browser/animations` since now the animations module will disable itself automatically.

PR Close #59762
2025-01-29 10:52:18 -08:00
Kristiyan Kostadinov e6cb411e43 fix(platform-browser): automatically disable animations on the server (#59762)
Uses `ngServerMode` to automatically disable browser animations on the server. This allows us to decouple `platform-server` from the animations package.

PR Close #59762
2025-01-29 10:52:18 -08:00
Kristiyan Kostadinov 0c1ecb453c fix(elements): not setting initial value on signal-based input (#59773)
Fixes that `createCustomElement` was incorrectly excluding signal-based inputs when setting the initial values.

Fixes #59757.

PR Close #59773
2025-01-29 08:50:25 -08:00
Angular Robot e635f42284 build: lock file maintenance (#59763)
See associated pull request for more information.

Closes #59621 as a pr takeover

PR Close #59763
2025-01-29 08:49:47 -08:00
muhammadali1658 e1504219e9 docs: fix spelling of 'static-site' (#59780)
PR Close #59780
2025-01-29 08:45:20 -08:00
Alan Agius 6b09716754 fix(platform-browser): prepend baseHref to sourceMappingURL in CSS content (#59730)
Implemented functionality to prepend the baseHref to `sourceMappingURL` in CSS content. Added handling to ensure external sourcemaps are loaded relative to the baseHref. Corrected sourcemap URL behavior when accessing pages with multi-segment URLs (e.g., `/foo/bar`). Ensured that when the baseHref is set to `/`, maps are requested from the correct path (e.g., `http://localhost/comp.css.map` instead of `http://localhost/foo/bar/comp.css.map`).

Closes #59729

PR Close #59730
2025-01-29 08:44:19 -08:00
arturovt cf9054248d fix(core): check whether application is destroyed before printing hydration stats (#59716)
In this commit, we check whether the application is destroyed before printing hydration stats. The application may be destroyed before it becomes stable, so when the `whenStableWithTimeout` resolves, the injector might already be in a destroyed state. As a result, calling `injector.get` would throw an error indicating that the injector has already been destroyed.

PR Close #59716
2025-01-29 08:43:34 -08:00
Kristiyan Kostadinov 96e602ebe9 fix(core): cancel in-progress request when same value is assigned (#59280)
Fixes that `resource` wasn't cancelling its in-progress request if the same value as the current one is assigned.

Fixes #59272.

PR Close #59280
2025-01-29 08:40:11 -08:00
Matthieu Riegler 9ed9c40479 docs(docs-infra): remove non-necessary files from playground zip. (#59728)
fixes #56739

PR Close #59728
2025-01-28 20:34:23 +01:00
Matthieu Riegler e98b0f1d39 docs(docs-infra): Check for files without using / as root. (#59726)
In certain circonstances, a leading slash in the file paths created a incorrect unarchived project.

fixes #57075

PR Close #59726
2025-01-28 20:33:23 +01:00
Matthieu Riegler 97897eebd8 docs(docs-infra): Remove leading path from zipped files. (#59726)
In certain circonstances, a leading slash in the file paths created a incorrect unarchived project.

fixes #57075

PR Close #59726
2025-01-28 20:33:23 +01:00
Joey Perrott ccebbbae6e ci: prevent renovate from updating @bazel/ibazel (#59761)
Add @bazel/ibazel to the ignored deps list for renovate to prevent us from updating to a version that
is incompatible with our repository.

PR Close #59761
2025-01-28 19:17:34 +01:00
Luan Gong b16d8a1c55 docs(core): Fix typo in documentation of linkedSignal (#59752)
PR Close #59752
2025-01-28 19:14:21 +01:00
Angular Robot 3c3620e84a build: update cross-repo angular dependencies (#59669)
See associated pull request for more information.

PR Close #59669
2025-01-28 18:51:00 +01:00
Tyler Luckewicz 3da7e908bb docs(docs-infra): fix gammatical error in two way binding with plain properties section (#59755)
PR Close #59755
2025-01-28 18:48:09 +01:00
Alan Agius e2987a1d4a fix(service-worker): add missing rxjs peer dependency (#59747)
The `@angular/service-worker` package now explicitly declares `rxjs` as a peer dependency.

PR Close #59747
2025-01-28 13:09:50 +01:00
Alan Agius c9045aa7fd build: remove @angular/common from Service Worker dependencies (#59747)
The `@angular/service-worker` package no longer directly depends on `@angular/common`.

PR Close #59747
2025-01-28 13:09:49 +01:00
Paul Gschwendtner a8139f77ea ci: configure merge tool to enforce mandatory PR statuses (#59749)
The merge tool is currently hard-coded to only check `lint` as a
required status. This was added because at some point the old GitHub
robot was replaced with a so-called `unified-statuses` check GitHub
action; but that one never worked/impacted productivity of the team.

I've added support to the merge tool to require specific jobs/checks to
run, before allowing merge (can be forcibly ignored). We are using this
ability now to enforce a few "common" required jobs, as a safety measure
when GitHub didn't trigger CI runs (e.g. for new contributors).

This recently became a more prominent issue as the GitHub org enforces
that CI doesn't run for e.g. first time contributors.

PR Close #59749
2025-01-28 12:53:33 +01:00
hawkgs 3554dbccd1 build: revert back to @bazel/ibazel v0.16 (#59748)
v0.25 is causing issues with adev and devtools – file changes do not trigger a rebuild.

PR Close #59748
2025-01-28 12:42:38 +01:00
Pawel Kozlowski c202682957 refactor(core): reuse host directive resolution logic (#59685)
Reuse host directive resolution logic in ComponentRef

PR Close #59685
2025-01-28 11:31:29 +01:00
Alex Rickabaugh 6c92d65349 fix(core): add hasValue narrowing to ResourceRef (#59708)
`hasValue` attempts to narrow the type of a resource to exclude `undefined`.
Because of the way signal types merge in TS, this only works if the type
of the resource is the same general type as `hasValue` asserts.

For example, if `res` is `WritableResource<string|undefined>` then
`.hasValue()` correctly asserts that `res` is `WritableResource<string>` and
`.value()` will be narrowed. If `res` is `ResourceRef<string|undefined>`
then that narrowing does _not_ work correctly, since `.hasValue()` will
assert `res` is `WritableResource<string>` and TS will combine that for a
final type of `ResourceRef<string|undefined> & WritableResource<string>`.
The final type of `.value()` then will not narrow.

This commit fixes the above problem by adding a `.hasValue()` override to
`ResourceRef` which asserts the resource is of type `ResourceRef`.

Fixes #59707

PR Close #59708
2025-01-28 09:40:29 +01:00
Alex Rickabaugh 127fc0dc84 fix(core): fix resource()'s previous.state (#59708)
When a resource first starts up, even if it transitions immediately to
`Loading` it should report a `previous.state` of `Idle`. It was reporting
`Loading` as the previous state in such a case because of an oversight in
the migration to `linkedSignal` which this commit addresses.

PR Close #59708
2025-01-28 09:40:29 +01:00
arturovt b7dd0483d0 refactor(common): drop error messages in production (#59545)
Switches to using `RuntimeError` and drops error messages in production by replacing it with an error code.

PR Close #59545
2025-01-28 09:39:42 +01:00
arturovt acdde4aa35 refactor(router): remove unused code (#59704)
This code is never used.

PR Close #59704
2025-01-28 09:38:34 +01:00
Angular Robot 3373b4f82a build: update github/codeql-action action to v3.28.6 (#59744)
See associated pull request for more information.

PR Close #59744
2025-01-28 09:08:46 +01:00
arturovt 762e56e210 refactor(common): drop platform check in PreconnectLinkChecker (#59714)
Replaces platform check within the `PreconnectLinkChecker` with the `ngServerMode` global.

PR Close #59714
2025-01-27 17:22:43 +01:00
hawkgs 69fe9163f5 docs(docs-infra): fix header layout for tablets (#59734)
The version picker and the theme and socials buttons were not properly styled.

PR Close #59734
2025-01-27 17:07:53 +01:00
arturovt b409330223 refactor(service-worker): drop platform checks (#59475)
In this commit, we drop `isPlatformBrowser` checks in favor of `ngServerMode` compile-time variable.

PR Close #59475
2025-01-27 16:41:09 +01:00
Pawel Kozlowski df143b486b refactor(core): remove unused LifecycleHooksFeature (#59678)
LifecycleHooksFeature seems to be unused and can be deleted.

PR Close #59678
2025-01-27 13:15:21 +01:00
Pawel Kozlowski cfa9fc2098 refactor(core): simplify ComponentRef creation (#59678)
Move more logic to a constructor of a ComponentRef.

PR Close #59678
2025-01-27 13:15:21 +01:00
Pawel Kozlowski 9af14b25d1 refactor(core): simplify attributes extraction logic for ComponentRef (#59678)
Make extractAttrsAndClassesFromSelector to return TAttributes directly to
simplify the overall logic and remove unecessary code.

PR Close #59678
2025-01-27 13:15:21 +01:00
Sebastian Ochoa fd7ee47bf7 fix(platform-browser): Update pseudoevent created by createMouseSpecialEvent to populate _originalEvent property (#59690)
This fixes an internal bug

PR Close #59690
2025-01-27 10:28:58 +01:00
Sebastian Ochoa 65cf061feb fix(platform-browser): Update pseudoevent created by createMouseSpecialEvent to populate _originalEvent property (#59690)
This fixes an internal bug

PR Close #59690
2025-01-27 10:28:58 +01:00
Sebastian Ochoa af9d74710c fix(platform-browser): Update pseudoevent created by createMouseSpecialEvent to populate _originalEvent property (#59690)
This fixes an internal bug.

PR Close #59690
2025-01-27 10:28:58 +01:00
arturovt 5c1690f07d refactor(docs-infra): allow home to be cleaned up (#59683)
In this commit, we're using the `from()` in the `adev-home` component, which allows us to invert a dependency and avoid memory leaks. Because an `async` function would be executed even if the component is already destroyed.

PR Close #59683
2025-01-27 10:27:20 +01:00
arturovt 14ceec60fe refactor(docs-infra): prevent leak in tutorial component (#59675)
In this commit, we're using the `from()` in the `adev-tutorial` component, which allows us to invert a dependency and avoid memory leaks. Because `then()` would be executed even if the component is already destroyed.

PR Close #59675
2025-01-27 10:26:36 +01:00
Aaditree Jaisswal c65c609491 docs: Add link to Language Service page from the Installation page (#59654)
PR Close #59654
2025-01-27 10:25:21 +01:00
Andrew Seguin b8948f219c docs: fix broken material.angular.io test harness links (#59709)
PR Close #59709
2025-01-27 10:22:49 +01:00
waify 6d6708c5b9 docs: fix typo in signals-interop.md (#59724)
PR Close #59724
2025-01-27 09:55:42 +01:00
Kristiyan Kostadinov 0c3b75558a docs: add template string to supported literals (#59710)
Updates the docs since we'll have support for template strings in 19.2. Also mentions that tagged template string aren't supported.

Fixes #59160.

PR Close #59710
2025-01-27 09:26:14 +01:00
Matthieu Riegler 7daf268cff docs(docs-infra): bump tutorials to 19.1 (#59642)
PR Close #59642
2025-01-24 20:43:15 +01:00
arturovt 10cdf0afae refactor(common): tree-shake PreloadLinkCreator for client bundles (#59431)
In this commit, we tree-shake the `PreloadLinkCreator` for client bundles because it's targeting only server code. We use the pending tasks service to contribute to app stability by waiting for the module to load.

PR Close #59431
2025-01-24 17:17:58 +01:00
Kristiyan Kostadinov 82876242e5 fix(core): ensure type is preserved during HMR (#59700)
Fixes an internal HMR issue where the type might be replaced when swapping out the definition. Externally this is a no-op.

PR Close #59700
2025-01-24 17:16:58 +01:00
arturovt d634ca7633 refactor(common): simplify joinWithSlash (#59484)
The new version is 2x smaller in the reduced code size; as thus this eliminates extra bytes. Refactors `joinWithSlash` function to reduce code size and improve readability. Added checks to handle leading and trailing slashes more concisely and provided comments for clarity.

PR Close #59484
2025-01-24 17:16:11 +01:00
arturovt e271639022 refactor(core): re-use isDetachedByI18n (#59668)
We already have a function called `isDetachedByI18n` which checks whether a `tNode` is in `isDetached` state; as thus, there's no reason to apply those checks manually.

PR Close #59668
2025-01-24 17:15:08 +01:00
Alex Rickabaugh 168516462a feat(core): support default value in resource() (#59655)
Before `resource()` resolves, its value is in an unknown state. By default
it returns `undefined` in these scenarios, so the type of `.value()`
includes `undefined`.

This commit adds a `defaultValue` option to `resource()` and `rxResource()`
which overrides this default. When provided, an unresolved resource will
return this value instead of `undefined`, which simplifies the typing of
`.value()`.

PR Close #59655
2025-01-24 13:39:02 +01:00
arturovt edb8407d4f refactor(common): simplify null/undefined check in keyvalue pipe (#59696)
In this commit, we remove the separate `a === undefined` and `a === null` checks and replace them with `a == null`. Using `a == null` is better and more concise because it checks for both `null` and `undefined` in a single operation. The loose equality `==` is specifically designed to treat `null` and `undefined` as equivalent. This change only reduces some bytes in the code and simplifies it, with no performance impact, as modern JavaScript engines handle `a == null` efficiently. Additionally, comments have been added for clarification.

PR Close #59696
2025-01-24 12:45:04 +01:00
Angular Robot 434568ba28 docs: update Angular CLI help [main] (#59699)
Updated Angular CLI help contents.

PR Close #59699
2025-01-24 12:31:36 +01:00
arturovt e4838310c9 refactor(forms): wrap _checkParentType with ngDevMode (#59489)
The `_checkParentType` bodies are wrapped with `ngDevMode`, meaning they act as no-ops in production. We can wrap the actual calls to `_checkParentType` with `ngDevMode` to prevent calling no-op functions in production

PR Close #59489
2025-01-24 11:51:36 +01:00
Ezequiel Cicala 819795bf51 docs: replace word in using-component-harnesses.md (#59687)
PR Close #59687
2025-01-24 11:29:19 +01:00
Doug Parker 3f53dd1129 docs: sort application and browser-esbuild builders first (#59686)
This emphasizes these as the default/preferred options over `browser` builder.

PR Close #59686
2025-01-23 14:27:52 -08:00
Ezequiel Cicala 6d9bc7654d docs: add missing word on components-scenarios.md (#59681)
PR Close #59681
2025-01-23 14:26:23 -08:00
Ezequiel Cicala f68e81ea2c docs: add another missing word on components-scenarios.md (#59680)
PR Close #59680
2025-01-23 14:25:50 -08:00
arturovt 8897e96fa6 refactor(core): prevent duplicating componentOffset checks (#59611)
The `type_checks` module already exposes a utility function that checks whether `TNode.componentOffset` is greater than -1. There is no need to check that property manually in other places, as we can reuse the helper function.

PR Close #59611
2025-01-23 14:23:29 -08:00
arturovt 6fc180b3ff refactor(common): prevent duplicating Accept header name (#59546)
Drops some bytes by moving `Accept` into a variable, which is then minified to something like `var a="Accept"` and reused in all the places.

PR Close #59546
2025-01-23 14:21:51 -08:00
arturovt c7b6e1107c fix(router): prevent error handling when injector is destroyed (#59457)
In this commit, we prevent error handling when the root injector is already destroyed. This may happen when the observable completes before emitting a value, which would trigger a `catchError` block that attempts to call `runInInjectionContext` on a destroyed injector.

PR Close #59457
2025-01-23 14:21:07 -08:00
hawkgs 6ce8ed7404 refactor(devtools): select the root element by default (#59626)
Select the application root element when you start Angular DevTools.

PR Close #59626
2025-01-22 13:34:40 -08:00
Pawel Kozlowski 3f6d9ff113 refactor(core): reuse directive instantiate logic (#59633)
This refactor reuses the existing directive instantiation
logic for a given component.

PR Close #59633
2025-01-22 13:27:48 -08:00
Jessica Janiuk f862ace181 fix(core): fixes test timer-based test flakiness in CI (#59674)
This converts two tests that rely on timers to use fakeAsync. This resolves the flakiness.

PR Close #59674
2025-01-22 13:27:05 -08:00
arturovt ae1dfdf82a refactor(core): prevent duplicating isRootView checks (#59614)
The `type_checks` module already exposes a utility function that checks whether `LView` is marked as a root view. There is no need to check flags in other places, as we can reuse the helper function.

PR Close #59614
2025-01-22 12:30:27 -08:00
Pawel Kozlowski afd8df3522 refactor(core): use linkedSignal primitives (#59599)
This change refactors the linkedSignal to use implementation
from the shared primitives package.

PR Close #59599
2025-01-22 12:29:37 -08:00
Pawel Kozlowski a0b5fdfe02 test(core): additional linkedSignal tests (#59599)
Adds a test veryfing that downstream dependencies are
not recomputed when the source of the linkedSignal is
equal to its current value.

PR Close #59599
2025-01-22 12:29:37 -08:00
Andrew Kushnir 2ed633a259 release: cut the v19.2.0-next.0 release 2025-01-22 11:49:18 -08:00
Andrew Kushnir ec8c288968 docs: release notes for the v19.1.3 release 2025-01-22 11:43:44 -08:00
Jens Kuehlers 61302cb4b6 docs: add Bluesky links (#59661)
PR Close #59661
2025-01-22 07:58:15 -08:00
Kristiyan Kostadinov d66881d172 fix(migrations): avoid applying the same replacements twice when cleaning up unused imports (#59656)
If a file ends up in multiple programs, the unused imports migration was counting it twice. This was fine since the string replacements were handling it correctly, but it was printing out incorrect data.

These changes rework the migration to de-duplicate the replacements and produce the data from the de-duplicated results.

PR Close #59656
2025-01-22 07:57:38 -08:00
Pawel Kozlowski 6c96d795bc Revert "refactor(core): reuse directive instantiate logic (#59633)" (#59659)
This reverts commit c089d21eb0.

PR Close #59659
2025-01-22 12:19:17 +01:00
Pawel Kozlowski c089d21eb0 refactor(core): reuse directive instantiate logic (#59633)
This refactor reuses the existing directive instantiation
logic for a given component.

PR Close #59633
2025-01-21 13:33:09 -08:00
Andrew Kushnir 4f46b02f29 test(zone.js): reduce flakiness of a timer-related test (#59653)
This commit updates a flaky test to increase the amount of work (more `for` loop iterations) to minimize the chance of getting the same timestamp after that work.

PR Close #59653
2025-01-21 13:20:24 -08:00
Kristiyan Kostadinov fe8a68329b feat(compiler): support untagged template literals in expressions (#59230)
Updates the compiler to support untagged template literals inside of the expression syntax (e.g. ``hello ${world}``).

PR Close #59230
2025-01-21 12:04:53 -08:00
Kristiyan Kostadinov 6960ec0c03 refactor(compiler-cli): handle template literals in ngtsc (#59230)
Updates the translators that convert expression ASTs to account for template literals.

PR Close #59230
2025-01-21 12:04:53 -08:00
Kristiyan Kostadinov 4016aa3229 refactor(compiler): clean up tagged templates in output AST (#59230)
Makes the following cleanups in the output AST:
* The `TemplateLiteral` and `TemplateLiteralElement` nodes have been renamed to `TemplateLiteralExpr` and `TemplateLiteralElementExpr` respectively for consistency and to avoid overlaps with the expression AST nodes.
* The `TemplateLiteralExpr` and `TemplateLiteralElementExpr` have been refactored to be `Expression`s for correctness. This involves updating some existing code.
* The `TaggedTemplateExpr` has been renamed to `TaggedTemplateLiteralExpr` for consistency.

PR Close #59230
2025-01-21 12:04:52 -08:00
Kristiyan Kostadinov eb7e765e2f refactor(compiler): produce AST for template literals (#59230)
Updates the compiler to parse the template literal tokens into the new `TemplateLiteral` and `TemplateLiteralElement` AST nodes.

PR Close #59230
2025-01-21 12:04:52 -08:00
Kristiyan Kostadinov 353005b97f refactor(compiler): tokenize template literals (#59230)
Reworks the lexer to produce tokens for template literal expressions.

PR Close #59230
2025-01-21 12:04:52 -08:00
Kristiyan Kostadinov 98998bbd42 refactor(compiler): allow lexer to produce multiple tokens (#59230)
Reworks the lexer's scanner to produce more than one token at a time. This can be useful for the cases where one token means the end of another one.

Also cleans up the scanner by making all non-essential methods private and using strict equality everywhere.

PR Close #59230
2025-01-21 12:04:52 -08:00
Pawel Kozlowski 76c4a77af7 refactor(core): move TNode manipulation logic to its own file (#59601)
Move TNode manipulation logic to its own file and update existing refereces.

PR Close #59601
2025-01-21 10:48:44 -08:00
Charles Lyding 5a13dff22c fix(compiler-cli): handle new expressions when extracting dependencies (#59637)
Updates the HMR dependencies extraction logic to handle new expressions.
For example, `deps: [[new Optional(), dep]]`.

PR Close #59637
2025-01-21 10:47:43 -08:00
Charles Lyding 8de0f3f79b fix(compiler-cli): handle conditional expressions when extracting dependencies (#59637)
Updates the HMR dependencies extraction logic to handle conditional expressions.
For example, `providers: [condition ? providersA : providersB]`.

PR Close #59637
2025-01-21 10:47:43 -08:00
Kristiyan Kostadinov 431166d93f fix(core): skip component ID collision warning during SSR (#59625)
The component ID collision check tries to account for components being replaced by checking for the `type`, however that might not work during SSR.

These changes disable the warning since it's primarily useful on the browser anyways.

PR Close #59625
2025-01-21 09:56:52 -08:00
Alex Rickabaugh bc2ad7bfd3 feat(core): support streaming resources (#59573)
This commit adds support for creating `resource()`s with streaming response
data. A streaming resource is defined by a `stream` option instead of a
`loader`, with `stream` being a function returning
`Promise<Signal<{value: T}|{error: unknown}>>`. Once the streaming loader
resolves to a `Signal`, it can continue to update that signal over time, and
the values (or errors) will be delivered to via the resource's state.

`rxResource()` is updated to leverage this new functionality to handle
multiple responses from the underlying Observable.

PR Close #59573
2025-01-21 09:55:32 -08:00
Kristiyan Kostadinov 67be7d2e06 fix(compiler-cli): extract parenthesized dependencies during HMR (#59644)
Fixes that the HMR dependency extraction logic wasn't accounting for parenthesized identifiers correctly.

PR Close #59644
2025-01-21 09:50:27 -08:00
Kristiyan Kostadinov 65f51e16aa fix(platform-browser): clear renderer cache during HMR when using async animations (#59644)
Fixes that the async animations renderer didn't have the logic to clean up its style cache during HMR. This is identical to #59393.

Fixes #59640.

PR Close #59644
2025-01-21 09:50:27 -08:00
Kristiyan Kostadinov ea2346955c fix(core): capture self-referencing component during HMR (#59644)
Fixes that we were filtering out the component itself from the set of dependencies when HMR is enabled, breaking self-referencing components.

Fixes #59632.

PR Close #59644
2025-01-21 09:50:27 -08:00
Kristiyan Kostadinov 9714b65d99 fix(core): replace metadata in place during HMR (#59644)
Currently during HMR we swap out the entire module definition (e.g. `MyComp.ɵcmp = newDef`). In standalone components and most module-based ones this works fine, however in some cases (e.g. circular dependencies) the compiler can produce a `setComponentScope` call for a module-based component. This call doesn't make it into the HMR replacement function, because it is defined in the module's file, not the component's. As a result, the dependencies of these components are cleared out upon replacement.

A secondary problem is that the `directiveDefs` and `pipeDefs` fields can save references to definitions that later become stale as a result of HMR.

These changes resolve both issues by:
1. Performing the replacement by copying the properties from the new definition onto the old one, while keeping it in place.
2. Preserving the initial `directiveDefs`, `pipeDefs` and `setInput`.

Fixes #59639.

PR Close #59644
2025-01-21 09:50:27 -08:00
Angular Robot 8e5c0f8e29 build: update dependency shiki to v2 (#59623)
See associated pull request for more information.

PR Close #59623
2025-01-21 09:12:02 -08:00
Kristiyan Kostadinov 98f820737b fix(compiler): handle :host-context with comma-separated child selector (#59276)
Both `:host` and `:host-context` work by looking for a specific character sequence that is terminated by `,` or `{` and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for `:host`, because each `:host` produces one scoped selector which doesn't affect any child selectors, however it breaks down with `:host-context` which replaces each instance with two selectors. For example, if we have a selector in the form of `:host-context(.foo) a:not(.a, .b)`, the compiler ends up determining that `.a,` is the end selector and produces `.foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}`.

These changes resolve the issue by splitting the CSS alogn top-level commas, processing the `:host-context` in them individually, and stiching the CSS back together.

PR Close #59276
2025-01-21 09:11:16 -08:00
Pawel Kozlowski 04c24472d2 refactor(core): move linkedSignal implementation to primitives (#59501)
This change refactors the Angular-specific linkedSignal implementation
such that its core logic can be shared with other frameworks.

PR Close #59501
2025-01-21 07:58:09 -08:00
Pawel Kozlowski 2d8fa73c1d docs: release notes for the v19.1.2 release 2025-01-20 15:14:49 +01:00
Kristiyan Kostadinov 394a683e2a fix(core): handle shadow DOM encapsulated component with HMR (#59597)
When a component is created with shadow DOM encapsulation, we attach a shadow root to it. When the component is re-created during HMR, it was throwing an error because only one shadow root can be attached to a node at a time.

Since there's no way to detach a shadow root from a node, these changes resolve the issue by making a shallow clone of the element, replacing it and using the clone for any future updates.

Fixes #59588.

PR Close #59597
2025-01-20 09:54:00 +01:00
Alan Agius 30c4404752 fix(compiler): update @ng/component URL to be relative (#59620)
This change is required to resolve https://github.com/angular/angular-cli/pull/29248 and works in conjunction with https://github.com/angular/angular-cli/pull/29386. It ensures that HMR (Hot Module Replacement) functions correctly with `base href`, proxies, and other advanced development setups.

PR Close #59620
2025-01-20 09:10:13 +01:00
Kristiyan Kostadinov f9b13e4e58 fix(compiler-cli): disable tree shaking during HMR (#59595)
When HMR is enabled, we need to capture the dependencies used in a template and forward them to the HMR replacement function. One half of this process is static, meaning that we can't change it after the initial compilation. Tree shaking becomes a problem in such a case, because the user can change the template in a way that changes the set of dependencies which will start matching with the static part of the HMR code.

These changes disable the tree shaking when HMR is enabled to ensure that the dependencies stay stable.

Fixes #59581.

PR Close #59595
2025-01-20 08:59:30 +01:00
Kristiyan Kostadinov 2caa45a6e1 fix(core): HMR not matching component that injects ViewContainerRef (#59596)
If a component injects `ViewContainerRef`, its `LView` gets wrapped in an empty `LContainer` and the container's host becomes the `LView`. The HMR logic wasn't accounting for this which meant that such components wouldn't be replaced.

Fixes #59592.

PR Close #59596
2025-01-20 08:57:17 +01:00
Matt Janssen 16b08853bc docs(router): Fix small grammatical errors (#59568)
Improves readability.
PR Close #59568
2025-01-17 13:21:26 -08:00
arturovt 14791f3e12 fix(core): cleanup stash listener when app is destroyed (#59598)
In this commit, we clean up the reference to the function set by the environment initializer, as the function closure may capture injected elements and prevent them from being properly garbage collected.

PR Close #59598
2025-01-17 10:00:56 -08:00
Pawel Kozlowski 35e5bbb0dc refactor(core): reuse setupStaticAttributes in ComponentRef (#59572)
This change refactor how the dynamically created component
deals with attributes in order to reuse the existing
setupStaticAttributes logic (instead of having specific
and similar code).

PR Close #59572
2025-01-17 09:59:59 -08:00
Andrew Kushnir 4e6017a9f5 test(platform-server): fix flaky incremental hydration test (#59584)
This commit updates a test setup to define a global `ngServerMode` correctly for a test that was emulating client-only behavior. The flag could've been set by prior tests and depending on its state, the test was acting differently.

PR Close #59584
2025-01-17 10:45:37 +01:00
Andrew Kushnir 8ea691a9d8 test(platform-server): fix flaky hydration test (#59579)
This commit updates testing setup logic to apply correct `document` reference, which should be used by the runtime. Previously, the timing of that operation was less predictable and in some cases led to reusing document state from previous tests.

PR Close #59579
2025-01-17 10:30:51 +01:00
arturovt f6e97763cf fix(core): cleanup _ejsa when app is destroyed (#59492)
In this commit, we delete `_ejsa` when the app is destroyed, ensuring that no elements are still captured in the global list and are not prevented from being garbage collected.

PR Close #59492
2025-01-16 13:56:28 -08:00
arturovt c51c66ef1e refactor(router): drop forRoot guard in production (#59458)
In this commit, we switch from decorators (which also produce redundant metadata, such as in the `declareFactory`
instruction) to the `inject` function to drop the `ROUTER_FORROOT_GUARD` token in production. This token factory function is only in development mode but is still referenced in the constructor due to the `@Inject(ROUTER_FORROOT_GUARD)` decorator.

PR Close #59458
2025-01-16 13:55:49 -08:00
Kristiyan Kostadinov b76be83b4d fix(core): animation sometimes renderer not being destroyed during HMR (#59574)
These changes aim to resolve the issue that prompted #59514. The animations module is a bit tricky for HMR, because it schedules the destruction of its renderer after the currently-running animations are done. If there are no running animations, the renderer gets destroyed next time around. This is a problem, because it means that the styles can stay around for a long time.

These changes resolve the issue by:
1. Moving the cleanup of the renderer to after the destruction of the old view. This ensures that the usual clean up flow has been kicked off.
2. Flushing the animations when a component is replaced to ensure that the renderer is cleaned up in a timely manner.

PR Close #59574
2025-01-16 11:36:43 -08:00
Angular Robot 884e0b437a build: update cross-repo angular dependencies to v19.2.0-next.0 (#59571)
See associated pull request for more information.

PR Close #59571
2025-01-16 10:40:01 -08:00
Pawel Kozlowski 10f280a4d3 refactor(core): move DOM manipulation logic to its own file (#59462)
This refactoring takes a step toward breaking down the
node_manipulation file into smaller, more focused files.

PR Close #59462
2025-01-16 10:38:44 -08:00
Alex Rickabaugh 01fffdb547 refactor(core): port resource() to linkedSignal() (#59024)
When the reactive `request` of a resource() notifies, it transitions to the
Loading state, fires the loader, and eventually transitions to Resolved.
With the prior implementation, a change of the `request` will queue the
effect, but the state remains unchanged until the effect actually runs. For
a brief period, the resource is in a state where the request has changed,
but the state has yet to update.

This is problematic if we want to use resources in certain contexts where we
care about the state of the resource in a synchronous way. For example, an
async validator backed by a resource might be checked after an update:

```
value.set(123);

if (validator.value()) {
  // value is still valid, even though the resource is dirty and will soon
  // flip to loading state (returning value(): undefined) while revalidating
}
```

To address this timing concern, `linkedSignal()` is used within the
`resource()` to synchronously transition the state in response to the
request changing. This ensures any followup reads see a consistent view of
the resource regardless of whether the effect has run.

This also addresses a race condition where `.set()` behaves differently on a
`resource()` depending on whether or not the effect has run.

PR Close #59024
2025-01-16 09:22:46 -08:00
Alex Rickabaugh 329cf9fbde fix(core): change Resource to use explicit undefined in its typings (#59024)
Originally the `T` in `Resource<T>` represented the resolved type of the
resource, and `undefined` was explicitly added to this type in the `.value`
signal. This turned out to be problematic, as it wasn't possible to write a
type for a resource which didn't return `undefined` values. Such a type is
useful for 2 reasons:

1. to support narrowing of the resource type when `Resource.hasValue()`
   returns `true`.

2. for resources which use a different value instead of `undefined` to
   represent not having a value (for example, array resources which want to
   use `[]` as their default).

Instead, this commit changes `resource()` and `rxResource()` to return an
explicit `ResourceRef<T|undefined>`, and removes the union with `undefined`
from all types related to the resource's value. This way, it's trivially
possible to write `Resource<T>` to represent resources where `.value` only
returns `T`.

`hasValue()` then actually works to perform narrowing, by narrowing the
resource type to `Exclude<T, undefined>`.

PR Close #59024
2025-01-16 09:22:46 -08:00
Leon Senft f8b8e80d79 fix(core): treat exceptions in equal as part of computation (#55818)
Prevent leaking signal reads and exceptions from a custom `equal`
function of a producer `computed()` to a consumer.

Upstream https://github.com/tc39/proposal-signals/pull/90 with a notable
change: Angular does **not** track reactive reads in custom `equal`
implementations.

PR Close #55818
2025-01-16 08:10:10 -08:00
Pawel Kozlowski 055624d0da docs: update linkedSignal documentation (#59532)
This commit updates the linkedSignal documentation around
the quality function option.

Fixes #59094

PR Close #59532
2025-01-16 08:09:23 -08:00
Matthieu Riegler e4dd1773db docs: update examples to the application builder (#59539)
fixes #59538

PR Close #59539
2025-01-16 08:08:36 -08:00
Pawel Kozlowski aa45d44c5b docs: release notes for the v19.1.1 release 2025-01-16 13:19:36 +01:00
Kristiyan Kostadinov c9cd5585c2 fix(core): run HMR replacement in the zone (#59562)
Fixes that in some cases the HMR replacement function was being run outside the zone which meant that change detection would break down after a replacement.

Fixes #59559.

PR Close #59562
2025-01-16 12:36:58 +01:00
Kristiyan Kostadinov 2fe54a11f4 fix(platform-browser): roll back HMR fix (#59557)
Rolls back the changes from #59514 because they ended up being breaking in 1P. We can revisit the internal fix in a different way.

Fixes #59558.

PR Close #59557
2025-01-16 12:27:51 +01:00
Pawel Kozlowski db745cd75f test(devtools): disable flaky highlighter test (#59561)
The test in question was very flaky on CI, example run:
https://github.com/angular/angular/actions/runs/12805645683/job/35702462974?pr=59557

Disabling as it is causing productivity loose for the team.

PR Close #59561
2025-01-16 12:19:39 +01:00
Doug Parker c9eaf53b4f release: bump Angular DevTools version to 1.0.21 (#59548)
PR Close #59548
2025-01-15 16:48:00 -08:00
Andrew Kushnir d0ad030ec7 Revert "feat(compiler-cli): detect missing structural directive imports (#59443)" (#59544)
This reverts commit ed705a856a.

PR Close #59544
2025-01-15 13:38:37 -08:00
arturovt 2e138e644c refactor(common): prevent duplicating Content-Type header (#59518)
Drops some bytes by moving `Content-Type` into a variable, which is then minified to something like `var b="Content-Type"` and reused in all the places.

PR Close #59518
2025-01-15 12:22:29 -08:00
Pawel Kozlowski af99c6c109 refactor(core): move logic out of shared instructions code (#59453)
This is first of a series of refactorings that moves code
around such that logic from the shared instruction file
is dispatched to the relevant functional parts.

PR Close #59453
2025-01-15 12:20:27 -08:00
kirjs e2925cccf8 docs: release notes for the v19.1.0 release 2025-01-15 14:59:28 -05:00
kirjs b223f7e9c6 docs: release notes for the v19.0.7 release 2025-01-15 14:47:20 -05:00
Kevin Brey ed705a856a feat(compiler-cli): detect missing structural directive imports (#59443)
Adds a new diagnostic that ensures that a standalone component using custom structural directives in a template has the necessary imports for those directives.

Fixes #37322

PR Close #59443
2025-01-15 13:59:37 -05:00
arturovt 3b3040d32a refactor(common): drop error message in production (#59471)
Switches to using `RuntimeError` and drops the error message in production by replacing it with an error code.

PR Close #59471
2025-01-15 12:28:29 -05:00
Matthieu Riegler d797c5cb94 docs: update class & style binding recommendation (#59240)
This commit introduces an update to the official recommendations when it comes to class & styles bindings.

`[class]` & `[style]` bindings are now recommended for basic uses cases.

`[ngClass]` and `[ngStyle]` allow more advanced bindings (like space separated keys) or keys with units (for `ngStyle`) which are not supported by the native bindings. They still require the dedicated directives.

PR Close #59240
2025-01-15 12:27:12 -05:00
Angular Robot 2a92dcf4b7 docs: update Angular CLI help [main] (#59535)
Updated Angular CLI help contents.

PR Close #59535
2025-01-15 12:25:32 -05:00
Jeremy Elbourn c38ea0767e docs: clarify that @for doesn't support break/continue (#59533)
We recently saw some confusion around this, so it's worth adding a
sentence to clarify

PR Close #59533
2025-01-15 12:00:21 -05:00
carimatics 3e31438d59 docs(forms): escape inequality signs of input tags in flowchart (#59517)
The input tags written within the flowcharts in the document were not being escaped, so we did that.
This change will ensure that the flowcharts in the document are properly displayed.

PR Close #59517
2025-01-15 10:17:21 -05:00
Sandeep Salwan e702934080 docs: fix typos in let.md (#59526)
PR Close #59526
2025-01-15 09:44:25 -05:00
Andrew Kushnir eadf6a35bb Revert "refactor: initialize headers map directly in HttpHeaders class (#59268)" (#59523)
This reverts commit e15226a444.

PR Close #59523
2025-01-14 17:48:34 -05:00
Abdul Wahab 9db23f9d12 docs: fix property wrong usage inside afterNextRender in lifecycle.md (#59521)
PR Close #59521
2025-01-14 16:27:39 -05:00
Angular Robot 88305373d1 build: update cross-repo angular dependencies (#59520)
See associated pull request for more information.

PR Close #59520
2025-01-14 16:05:15 -05:00
hawkgs b9155b5121 docs: set syntax highlighting to the remaining Markdown code examples blocks (#59088)
There are some code blocks that slipped through the initial Regex-es.

Related to #59026

PR Close #59088
2025-01-14 15:14:02 -05:00
hawkgs 265265a3f8 docs(docs-infra): fix scrolling issues in the API reference (#59207)
Fix issues related to scrolling in the API reference:
- Scroll to the top of the page when navigating to the API details page
- Preserve scroll position when navigating back from the API details page

PR Close #59207
2025-01-14 14:56:42 -05:00
arturovt bc77f44802 refactor(common): tree-shake lcpObserver in NgOptimizedImage (#59481)
Prior to this commit, the `this.lcpObserver?.updateImage` expression was still preserved in the production code because it wasn't wrapped with `ngDevMode`. The observer is injected only in development mode. Additionally, we moved the logic from `ngOnDestroy` to avoid having an empty method in production.

PR Close #59481
2025-01-14 14:54:16 -05:00
Angular Robot 19d224117e build: lock file maintenance (#59519)
See associated pull request for more information.

Closes #59494 as a takeover pull request

PR Close #59519
2025-01-14 14:44:30 -05:00
arturovt 1ff5cd6906 refactor(common): tree-shake transfer cache interceptor stuff (#59439)
In this commit, we replace `isPlatformServer` runtime call with the `ngServerMode` in the `transferCacheInterceptorFn` in order to make the functionality tree-shakable between client and server bundles.

PR Close #59439
2025-01-14 14:40:05 -05:00
Pawel Kozlowski 815f1b1457 refactor(core): add profiler calls for tne newly introduced events (#59233)
The set of profiler events was recently extended. This commit plugs
newly created events dispatch into the approriate places
of the Angular core.

PR Close #59233
2025-01-14 12:35:21 -05:00
Pawel Kozlowski 9c835e89fe refactor(core): profiler takes null as a default instance (#59233)
Several profiler calls don't have any meaningful instance when
producing a profiling event. This commit changes the default
instance value to null to sreamline profiler invocations.

PR Close #59233
2025-01-14 12:35:21 -05:00
Kristiyan Kostadinov 2ca258705f fix(core): destroy renderer when replacing styles during HMR (#59514)
Currently when we swap out the component during HMR, we remove the renderer from the cache, but we never destroy it which means that its styles are still in the DOM. This can cause the old styles to leak into the component after they're replaced. These changes add a `destroy` call to ensure that they're removed.

PR Close #59514
2025-01-14 11:22:06 -05:00
hawkgs 803358f0a3 docs(docs-infra): change API reference list items order to top-down (#58655)
Change the order from left-right to top-down (columns) and additionally make columns equal width.

PR Close #58655
2025-01-14 11:10:52 -05:00
hawkgs 6cd6780d38 docs(docs-infra): fix SCSS build-time warnings (#59115)
Fix SCSS "declarations after nested rules" and `@import` warnings.

PR Close #59115
2025-01-14 11:09:23 -05:00
Matthieu Riegler 52334e02e7 refactor(compiler): remove unused AstVisitors (#59297)
Those 2 clases weren't imported anywhere.

PR Close #59297
2025-01-14 11:08:25 -05:00
Andrew Kushnir ed05cb5695 refactor(core): do not serialize parent block id for top level blocks (#59190)
This commit updates incremental hydration-related annotation logic to avoid serializing parent block id when it's `null` (for top-level blocks).

PR Close #59190
2025-01-14 11:06:58 -05:00
Angular Robot 9ae0d3e189 build: update dependency typescript to v5.7.3 (#59512)
See associated pull request for more information.

PR Close #59512
2025-01-14 11:03:56 -05:00
Angular Robot d19b7bbe4e build: update io_bazel_rules_sass digest to adeaf81 (#59508)
See associated pull request for more information.

PR Close #59508
2025-01-14 11:03:21 -05:00
hawkgs 220608e4cc docs(docs-infra): generate errors and extended-diagnostics route NavigationItem-s (#59355)
Generate the `NavigationItem`-s as part of adev/shared-docs pipeline and use the output JSON files instead of the hardcoded objects in the `sub-navigation-data.ts`.

PR Close #59355
2025-01-14 11:00:06 -05:00
Angular Robot 1f4c9ec2cf build: update all non-major dependencies (#59510)
See associated pull request for more information.

PR Close #59510
2025-01-14 10:57:23 -05:00
Angular Robot 2c8f199cf7 build: update dependency @babel/generator to v7.26.5 (#59511)
See associated pull request for more information.

PR Close #59511
2025-01-14 10:55:24 -05:00
Angular Robot 5462c64047 build: update scorecard action dependencies (#59513)
See associated pull request for more information.

PR Close #59513
2025-01-14 10:53:21 -05:00
Pawel Kozlowski 3d1496274c ci: update Ethan Cline GitHub user name (#59516)
Use case-sensitive user name.

PR Close #59516
2025-01-14 10:52:04 -05:00
RafaelJCamara e15226a444 refactor: initialize headers map directly in HttpHeaders class (#59268)
Improved the initialization of the headers map to enhance performance
and code readability.

No breaking changes.

PR Close #59268
2025-01-14 10:50:15 -05:00
arturovt d038b3cdd1 refactor(docs-infra): lazy-load EmbeddedTutorialManager in editor UI state (#59509)
In this commit, we lazy-load the `EmbeddedTutorialManager` in the editor UI state as done in other parts of the code.

PR Close #59509
2025-01-14 10:15:12 -05:00
Charles Lyding 9963a73699 docs: update component HMR to fully stable (#59503)
As of 19.1, component HMR for both styles and templates is considered
stable and enabled by default. This includes support for both inline
and file-based component styles/templates.

PR Close #59503
2025-01-14 09:49:15 -05:00
Andrew Kushnir 412ac303bc Revert "refactor(core): profiler takes null as a default instance (#59233)" (#59506)
This reverts commit c4ad8fb2e7.

PR Close #59506
2025-01-13 17:03:36 -05:00
Andrew Kushnir e77df14620 Revert "refactor(core): add profiler calls for tne newly introduced events (#59233)" (#59506)
This reverts commit 435d31ed5f.

PR Close #59506
2025-01-13 17:03:36 -05:00
hawkgs 0bb81c5ab4 feat(devtools): tone down obtrusive elements in the Injector Tree tab (#59499)
Some of the elements are a bit too large so they have been shrunken to fit in with the rest of the UI.

PR Close #59499
2025-01-13 15:06:24 -05:00
arturovt 47e48b44dc refactor(docs-infra): lazy-load EmbeddedTutorialManager in code editor (#59505)
In this commit, we lazy-load the `EmbeddedTutorialManager` in the code editor component as done in other parts of the code.

PR Close #59505
2025-01-13 15:00:26 -05:00
AleksanderBodurri 065e1187fc fix(devtools): remove property tab css that is hiding directive metadata (#59493)
It looks like this height property was redundant prior to upgrading to angular/material 19.1.0-rc.0. An interaction between this property and that update caused elements inside of material expansion panels to be hidden.

This PR removes this unnecessary height assignment entirely.

PR Close #59493
2025-01-13 14:48:01 -05:00
Angular Robot 368d69e115 build: update cross-repo angular dependencies (#59474)
See associated pull request for more information.

PR Close #59474
2025-01-13 12:52:11 -05:00
arturovt 5d6358168a refactor(common): prevent duplicating Accept header (#59467)
In this commit, we extract content types into a variable to eliminate extra bytes, as these values are duplicated in multiple places.

PR Close #59467
2025-01-13 12:38:46 -05:00
arturovt 4491704fba refactor(common): drop enums by changing to const enum (#59468)
Note: this enums are not a part of the public API.

Prior to this commit, the compiler produced:

```js
var DateType;
(function (DateType) {
    DateType[DateType["FullYear"] = 0] = "FullYear";
    DateType[DateType["Month"] = 1] = "Month";
    DateType[DateType["Date"] = 2] = "Date";
    DateType[DateType["Hours"] = 3] = "Hours";
    DateType[DateType["Minutes"] = 4] = "Minutes";
    DateType[DateType["Seconds"] = 5] = "Seconds";
    DateType[DateType["FractionalSeconds"] = 6] = "FractionalSeconds";
    DateType[DateType["Day"] = 7] = "Day";
})(DateType || (DateType = {}));
```

With these changes, we allow objects to be dropped entirely and inlined.

PR Close #59468
2025-01-13 11:14:27 -05:00
arturovt 783c5bb586 refactor(core): change node navigation step to plain const (#59469)
We change the `enum` to a plain `const` to eliminate extra bytes, as `enum` is not really required. We might not be able to switch to `const enum` due to single-file compilation restrictions.

PR Close #59469
2025-01-13 11:12:47 -05:00
Kristiyan Kostadinov 9931030b0e test(migrations): add test for earlier fix (#59497)
Adds a test for the fix from #59452 now that we know what caused the issue.

PR Close #59497
2025-01-13 11:10:18 -05:00
Kristiyan Kostadinov 915593ad25 refactor(compiler): fix typo in method name (#59479)
Fixes a typo in the `AstVisitor.visitTypeofExpresion` method's name.

PR Close #59479
2025-01-13 10:57:51 -05:00
Pawel Kozlowski 435d31ed5f refactor(core): add profiler calls for tne newly introduced events (#59233)
The set of profiler events was recently extended. This commit plugs
newly created events dispatch into the approriate places
of the Angular core.

PR Close #59233
2025-01-13 10:52:19 -05:00
Pawel Kozlowski c4ad8fb2e7 refactor(core): profiler takes null as a default instance (#59233)
Several profiler calls don't have any meaningful instance when
producing a profiling event. This commit changes the default
instance value to null to sreamline profiler invocations.

PR Close #59233
2025-01-13 10:52:19 -05:00
Amy Sorto 790221b1d2 docs: add component harnesses guides (#59078)
PR Close #59078
2025-01-13 10:46:43 -05:00
arturovt fdbb57f798 refactor(docs-infra): lazy-load EmbeddedTutorialManager in home editor (#59491)
In this commit, we lazy-load `EmbeddedTutorialManager` in the home editor component via `injectAsync` as done in other parts of the code.

PR Close #59491
2025-01-13 10:45:43 -05:00
Bobokhuja cb30fecdd4 docs: fix typo example code in pipes documentation (#59312)
PR Close #59312
2025-01-13 10:38:06 -05:00
RafaelJCamara dd8b651794 docs: add $default to path (#59383)
Closes: #59378

PR Close #59383
2025-01-13 10:36:17 -05:00
Matthieu Riegler 69aa4e91f5 docs(docs-infra): remove sorting from API manager (#59427)
fixes #59423

PR Close #59427
2025-01-13 10:33:37 -05:00
PhilippMDoerner 4c12f07970 docs: Adjust lines of server.ts example in server-side-rendering docs (#59490)
docs: Adjust lines of server.ts example in ssr docs

The server.ts excerpt used in the server-side-rendering docs
(https://angular.dev/guide/ssr#configure-server-side-rendering)
does not fully encapsulate the commonEngine code-block.

It begins too early in line 31, leading to the inclusions of lines
from another codeblock that is not intended to be shown here:
```
 );  

// All regular routes use the Angular engine
```
It should be beginning with the line
`// All regular routes use the Angular engine`.

It also ends too soon, cutting off these parts of the code-block:
```
      .catch((err) => next(err));
  });
```
PR Close #59490
2025-01-13 10:32:15 -05:00
Matthieu Riegler 40e7904bd8 docs(docs-infra): prevent the host class from being replaced (#59460)
When removing the binding, the class defined on the host element is being replaced

fixes #59442

PR Close #59460
2025-01-10 14:03:38 -05:00
Angular Robot f978cdef63 build: update cross-repo angular dependencies (#59473)
See associated pull request for more information.

PR Close #59473
2025-01-10 13:36:51 -05:00
Jessica Janiuk 7d5d693eda fix(dev-infra): remove no longer necessary scope (#59472)
We no longer have need for the view engine scope.

PR Close #59472
2025-01-10 13:28:28 -05:00
Angular Robot 49dbf093eb build: update cross-repo angular dependencies (#59470)
See associated pull request for more information.

PR Close #59470
2025-01-10 12:27:22 -05:00
Paul Gschwendtner 8496fb16bc fix(migrations): incorrect stats when migrating queries with best effort mode (#59463)
We previously did count forcibly ignored queries as incompatible. This
resulted in incorrect migration stats that are printed upon migration
completion.

See: #58657

PR Close #59463
2025-01-10 11:52:13 -05:00
Paul Gschwendtner 86cbaaa2a2 test: add test to verify extending tsconfig works in signal input migration (#59463)
Related to https://github.com/angular/angular/issues/59348

PR Close #59463
2025-01-10 11:52:13 -05:00
Paul Gschwendtner 24f383ab4f test: improve typescript version coverage for signal input migration (#59463)
This ensures the migration works for these TypeScript versions. The
migration is very sensitive to the TS version and its internals; so it
makes sense to test all of these.

PR Close #59463
2025-01-10 11:52:12 -05:00
arturovt 17510becb0 refactor(platform-browser): drop BROWSER_MODULE_PROVIDERS_MARKER in production (#59412)
In this commit, we switch from decorators (which also produce redundant metadata, such as in the
`declareFactory` instruction) to the `inject` function to drop the `BROWSER_MODULE_PROVIDERS_MARKER`
token in production. This token is actually provided only in development mode but is still
referenced in the constructor due to the `@Inject(BROWSER_MODULE_PROVIDERS_MARKER)` decorator.

PR Close #59412
2025-01-10 11:47:32 -05:00
Aristeidis Bampakos e8df770141 docs: update component scenarios guide (#59461)
PR Close #59461
2025-01-10 10:55:40 -05:00
Kristiyan Kostadinov 966a370390 fix(migrations): resolve text replacement issue (#59452)
Based on https://github.com/angular/angular/pull/59353#issuecomment-2580320424, fixes a text replacement issue that seems to cause code to be duplicated in some setups.

PR Close #59452
2025-01-10 10:47:54 -05:00
Matthieu Riegler 676357dbe0 docs: update linkedSignal. (#59221)
The commit adds the mention that it is intentionnal that the computation is reactive even if there is an explicit `source`.

fixes #59094

PR Close #59221
2025-01-10 10:41:18 -05:00
Angular Robot e178cbb8b7 build: update cross-repo angular dependencies (#59464)
See associated pull request for more information.

PR Close #59464
2025-01-10 10:38:10 -05:00
Charles Lyding a4164141a3 fix(compiler): use chunk origin in template HMR request URL (#59459)
The URL that is dynamically imported to fetch a potential component update
for HMR is now based on the value of `import.meta.url`. This ensures that
the request is sent to the same location that was used to retrieve the
application code. For some development server setups the HTML base HREF
may not be the location of the Angular development server. By using the
application code location which was generated by the development server,
HMR requests can continue to work as expected in these scenarios. In
most common cases, this change will not have any effect as the HTML base
HREF aligns with the location of the application code files.

PR Close #59459
2025-01-09 18:21:48 -05:00
arturovt d51d67b725 refactor(common): prevent duplicating X-Request-URL (#59420)
The `X-Request-URL` string is duplicated in multiple places. It is worth moving it to a shared constant that would be minified to something like `const a = "X-Request-URL"` and referenced in all the used places.

PR Close #59420
2025-01-09 18:18:24 -05:00
Doug Parker c1bc06c337 release: bump Angular DevTools version to 1.0.20 (#59454)
PR Close #59454
2025-01-09 15:41:54 -05:00
Andrew Kushnir ac2dbe3eb1 Revert "fix(core): Defer afterRender until after first CD (#58250)" (#59455)
This reverts commit 9870b643bf.

PR Close #59455
2025-01-09 14:30:01 -05:00
Andrew Kushnir 21f1ba22a6 Revert "fix(core): Don't run effects in check no changes pass (#58250)" (#59455)
This reverts commit a5fc962094.

PR Close #59455
2025-01-09 14:30:01 -05:00
arturovt 5884153e12 refactor(animations): drop warning functions in production (#59408)
Prior to this commit, functions that issued warnings were not wrapped with `ngDevMode` at the point
of invocation but had the `ngDevMode` check inside. This meant they acted as no-ops in production.
In this commit, we wrap them externally with `ngDevMode`, so they are entirely removed.

PR Close #59408
2025-01-09 13:15:06 -05:00
arturovt 17234213f6 refactor(platform-browser): remove Console from Hammer gestures (#59409)
Injecting the `Console` is redundant because it directly calls the global `console` object.
There is no reason to reference this class in Hammer gestures, as it is only used in development
mode. We can safely call the `console` object directly.

PR Close #59409
2025-01-09 13:09:51 -05:00
arturovt e194573d0d refactor(common): tree-shake fetch backend (#59418)
This commit updates the code of the HTTP code to make the `FetchBackend` class tree-shakable. The class is only needed with `withFetch()` is called and it should not be included into bundles that do not use that feature.

PR Close #59418
2025-01-09 13:05:56 -05:00
arturovt f2e293db4e refactor(platform-browser): drop Hammer token names in production (#59438)
In this commit, we drop `HAMMER_GESTURE_CONFIG` and `HAMMER_LOADER` injection token names in production.

PR Close #59438
2025-01-09 12:38:06 -05:00
arturovt 83bd63fa7c refactor(common): drop NullViewportScroller for client bundles (#59440)
In this commit, we replace the `isPlatformBrowser` runtime call with the `ngServerMode` in order to drop the `NullViewportScroller` for client bundles.

PR Close #59440
2025-01-09 12:33:04 -05:00
arturovt 205330d46a refactor(core): drop platform injection token names in production (#59400)
In this commit, we tree-shake the injection token names in production.

PR Close #59400
2025-01-09 12:28:17 -05:00
Kristiyan Kostadinov 3638f93acc fix(compiler-cli): handle more node types when extracting dependencies (#59445)
Fixes that the HMR dependency extraction logic wasn't handling some node types. Most of these are a bit edge-case-ey in component definitions, but variable initializers and arrow functions can realistically happen in factories.

PR Close #59445
2025-01-09 12:22:46 -05:00
Angular Robot 9abc79bb23 build: update cross-repo angular dependencies (#59249)
See associated pull request for more information.

PR Close #59249
2025-01-09 12:18:45 -05:00
arturovt 06214821ca refactor(core): change LContainerFlags to const enum (#59416)
Prior to this commit, the compiler produced:

```js
No = (function (e) {
  return (
    (e[(e.None = 0)] = "None"),
    (e[(e.HasTransplantedViews = 2)] = "HasTransplantedViews"),
    e
  );
})(No || {});
```

Changing to `const enum` allows it to be entirely dropped and inline values.

PR Close #59416
2025-01-09 10:38:28 -05:00
Sumit Arora a55575d4d6 fix(devtools): fixing dark mode colors for devtools and router tree (#59329)
added dark mode colors for devtools and router tree  and fixed the router tree legend rerendering issue

PR Close #59329
2025-01-09 10:32:41 -05:00
Ethan Cline a648fa14dd ci: Add self (Ethan Cline) as primitives-shared reviewer. (#59437)
Add self (Ethan Cline) as primitives-shared reviewer.

PR Close #59437
2025-01-09 10:31:29 -05:00
Angular Robot 092557ef98 build: update dependency @bazel/buildifier to v8 (#59446)
See associated pull request for more information.

PR Close #59446
2025-01-09 10:30:41 -05:00
zhangenming a201d455e6 docs(router): update link to development guide in README.md (#59388)
PR Close #59388
2025-01-09 10:29:38 -05:00
Kristiyan Kostadinov d564506164 docs: add doc page about unused imports schematic (#59449)
Adds a docs for the new `ng generate @angular/core:cleanup-unused-imports` schematic.

PR Close #59449
2025-01-09 10:28:39 -05:00
RafaelJCamara 5c9e84acd6 docs: update license URL from angular.io to angular.dev and year of license to 2025 (#59407)
PR Close #59407
2025-01-09 10:27:54 -05:00
Kristiyan Kostadinov adc6c094f4 build: clean up pipeline-specific tests (#59450)
Now that we only have the template pipeline, we can remove the `.pipeline` extension from the files.

PR Close #59450
2025-01-09 09:56:06 -05:00
arturovt 854a5616bf refactor(forms): drop CALL_SET_DISABLED_STATE name in production (#59430)
In this commit, we drop the `CALL_SET_DISABLED_STATE` injection token name in production.

PR Close #59430
2025-01-09 09:21:00 -05:00
Jessica Janiuk e689aaed30 docs: release notes for the v19.1.0-rc.0 release 2025-01-08 10:26:08 -08:00
Jessica Janiuk f39425a489 release: bump the next branch to v19.2.0-next.0 2025-01-08 10:26:08 -08:00
981 changed files with 58255 additions and 43341 deletions
+21
View File
@@ -0,0 +1,21 @@
# all commits that change formatting to prettier
fd544159e300340a25a48e3f40c58795991a4c17
31fdf0fbea6b89c8d3d141b2ef8e79c2737287cb
0d78a92431178be73342aeddda4b62d9e49138ba
f307e95459898b9027d5e13357a809d8952e9017
b1dffa4abe8321a47d79b2ea29ee32a81acfe031
ca517d7f2c38775969a65fde1d88f41ad5f27931
8f69c83b848ad0dc3c7ffce2541fc726693dedcf
a5b5b7d5ef84b9852d2115dd7a764f4ab3299379
894c1c5f100a62866cc7ed3e23d025c8e505c60d
ca39926de2ccaceb11de47a35e5bf9899147a877
b857aafcb9bdb5f1400a4cfedd56657e71ebe8cd
c4b880a025823efadb9d76195c6261f2992c7654
4c2b0d94e22f022969b86b95af516b76322840e0
0460a9dfafe3a7ebbff1b87e52048fb7416bba43
ec03e462f3d4ec90d1267474cc344563c949c2cf
bbbe477f479f20722f0fea7ccc46095aad5d4253
cc34e5fb072e7903e01463953a19d18503a39347
f9781f9804f1e7c84df356d9aeb267730a7fc499
dc62446ef7f2898a20d3be1196ecaf2a92a1077d
711cb416260ca11ff158fc39b372efa2cf022d36
+1 -1
View File
@@ -1,7 +1,7 @@
## PR Checklist
Please check if your PR fulfills the following requirements:
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -5,9 +5,9 @@ runs:
using: 'composite'
steps:
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/saucelabs@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Starting Saucelabs tunnel service
shell: bash
run: ./tools/saucelabs/sauce-service.sh run &
+1 -1
View File
@@ -4,7 +4,7 @@ description: 'Installs the dependencies using Yarn'
runs:
using: 'composite'
steps:
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4
- uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4
with:
path: |
./node_modules/
+4 -4
View File
@@ -21,16 +21,16 @@ jobs:
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'adev: preview'))
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel build //adev:build --full_build_adev --config=release
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@e8d26efbaea89c31f1580c61c968c8119f5247a6
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
workflow-artifact-name: 'adev-preview'
pull-number: '${{github.event.pull_request.number}}'
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs ${{env.PREVIEW_SITE}}
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@e8d26efbaea89c31f1580c61c968c8119f5247a6
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
github-token: '${{secrets.GITHUB_TOKEN}}'
workflow-artifact-name: 'adev-preview'
@@ -16,6 +16,6 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: angular/dev-infra/github-actions/branch-manager@e8d26efbaea89c31f1580c61c968c8119f5247a6
- uses: angular/dev-infra/github-actions/branch-manager@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+1 -1
View File
@@ -38,7 +38,7 @@ jobs:
- uses: ./.github/actions/yarn-install
- uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
- uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
bazelrc: ./.bazelrc.user
+24 -22
View File
@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Install node modules
@@ -41,13 +41,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
@@ -59,13 +59,13 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
@@ -76,30 +76,32 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev in fast mode to ensure it continues to work
run: yarn bazel build //adev:build --config=release
- name: Run tests
run: yarn bazel test //adev/...
# TODO: re-enable tests once the next release is shipped
# Tests are broken because of https://github.com/angular/angular/issues/54858
# - name: Run tests
# run: yarn bazel test //adev/...
publish-snapshots:
runs-on:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
@@ -111,7 +113,7 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
node-module-directories: |
@@ -119,9 +121,9 @@ jobs:
./packages/zone.js/node_modules
./packages/zone.js/test/typings/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
@@ -158,7 +160,7 @@ jobs:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Install node modules
@@ -171,11 +173,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
+2 -2
View File
@@ -13,13 +13,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: angular/dev-infra/github-actions/commit-message-based-labels@e8d26efbaea89c31f1580c61c968c8119f5247a6
- uses: angular/dev-infra/github-actions/commit-message-based-labels@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
post_approval_changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: angular/dev-infra/github-actions/post-approval-changes@e8d26efbaea89c31f1580c61c968c8119f5247a6
- uses: angular/dev-infra/github-actions/post-approval-changes@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: angular/dev-infra/github-actions/google-internal-tests@e8d26efbaea89c31f1580c61c968c8119f5247a6
- uses: angular/dev-infra/github-actions/google-internal-tests@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
run-tests-guide-url: http://go/angular-g3sync-start
github-token: ${{ secrets.GITHUB_TOKEN }}
+4 -4
View File
@@ -13,17 +13,17 @@ jobs:
JOBS: 2
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/saucelabs@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Set up Sauce Tunnel Daemon
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
env:
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
status:
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/unified-status-check@e8d26efbaea89c31f1580c61c968c8119f5247a6
- uses: angular/dev-infra/github-actions/unified-status-check@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+3 -3
View File
@@ -21,7 +21,7 @@ jobs:
workflows: ${{ steps.workflows.outputs.workflows }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn -s install --frozen-lockfile
- id: workflows
@@ -36,9 +36,9 @@ jobs:
workflow: ${{ fromJSON(needs.list.outputs.workflows) }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn -s install --frozen-lockfile
# We utilize the google-github-actions/auth action to allow us to get an active credential using workflow
+23 -21
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Install node modules
@@ -39,7 +39,7 @@ jobs:
- name: Check code format
run: yarn ng-dev format changed --check ${{ github.event.pull_request.base.sha }}
- name: Check Package Licenses
uses: angular/dev-infra/github-actions/linting/licenses@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/linting/licenses@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
allow-dependencies-licenses: 'pkg:npm/google-protobuf@'
@@ -47,13 +47,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
@@ -65,13 +65,13 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
@@ -83,19 +83,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
run: yarn tsx ./scripts/build/build-packages-dist.mts
- name: Archive build artifacts
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: pr-artifacts-${{ github.event.number }}
path: dist/packages-dist/
@@ -105,24 +105,26 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev in fast mode to ensure it continues to work
run: yarn bazel build //adev:build --config=release
- name: Run tests
run: yarn bazel test //adev/...
# TODO: re-enable tests once the next release is shipped
# Tests are broken because of https://github.com/angular/angular/issues/54858
# - name: Run tests
# run: yarn bazel test //adev/...
zone-js:
runs-on:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
node-module-directories: |
@@ -130,9 +132,9 @@ jobs:
./packages/zone.js/node_modules
./packages/zone.js/test/typings/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/setup@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/bazel/configure-remote@002a34e9875f55bf1850fb57d34261b33b2fd492
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
@@ -169,7 +171,7 @@ jobs:
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
cache-node-modules: true
- name: Install node modules
+3 -3
View File
@@ -30,7 +30,7 @@ jobs:
persist-credentials: false
- name: 'Run analysis'
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
@@ -39,7 +39,7 @@ jobs:
# Upload the results as artifacts.
- name: 'Upload artifact'
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: SARIF file
path: results.sarif
@@ -47,6 +47,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: 'Upload to code-scanning'
uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
uses: github/codeql-action/upload-sarif@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11
with:
sarif_file: results.sarif
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
env:
ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN }}
- name: Create a PR (if necessary)
uses: angular/dev-infra/github-actions/create-pr-for-changes@e8d26efbaea89c31f1580c61c968c8119f5247a6
uses: angular/dev-infra/github-actions/create-pr-for-changes@002a34e9875f55bf1850fb57d34261b33b2fd492
with:
branch-prefix: update-cli-help
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
+1 -1
View File
@@ -74,7 +74,7 @@ Fixes #<issue number>
# =============================
#
# The full specification of the Angular Commit Message Format can be found at
# https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit
# https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md
#
# The following is an excerpt of the specification with the most commonly needed info.
#
+2
View File
@@ -7,6 +7,8 @@ export const commitMessage: CommitMessageConfig = {
maxLineLength: Infinity,
minBodyLength: 20,
minBodyLengthTypeExcludes: ['docs'],
// If you update this, also update the docs.
// https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md#scope
scopes: [
'animations',
'bazel',
+8
View File
@@ -22,4 +22,12 @@ export const pullRequest: PullRequestConfig = {
assertEnforceTested: true,
assertIsolatedSeparateFiles: true,
},
requiredStatuses: [
{type: 'check', name: 'test'},
{type: 'check', name: 'lint'},
{type: 'check', name: 'adev'},
{type: 'check', name: 'zone-js'},
{type: 'status', name: 'google-internal-tests'},
],
};
+1 -1
View File
@@ -1 +1 @@
18.20.0
18.20.5
+11 -27
View File
@@ -56,8 +56,8 @@
version: 3
availability:
users_unavailable: ['atscott']
# availability:
# users_unavailable: ['atscott']
# Meta field that goes unused by PullApprove to allow for defining aliases to be
# used throughout the config.
@@ -133,6 +133,7 @@ groups:
- devversion
- kirjs
- JoostK
- mmalerba
# =========================================================
# Framework: General (most code in our packages)
@@ -143,7 +144,6 @@ groups:
- >
contains_any_globs(files.exclude('packages/core/primitives/*'), [
'contributing-docs/public-api-surface.md',
'goldens/circular-deps/packages.json',
'integration/**/{*,.*}',
'modules/**/{*,.*}',
'packages/animations/**/{*,.*}',
@@ -175,6 +175,7 @@ groups:
- ~jelbourn
- thePunderWoman
- pkozlowski-opensource
- mmalerba
# =========================================================
# Framework: Security-sensitive files which require extra review
@@ -227,9 +228,9 @@ groups:
<<: *defaults
conditions:
- >
contains_any_globs(files, [
contains_any_globs(files.exclude('yarn.lock'), [
'packages/zone.js/**/{*,.*}',
])
])
reviewers:
users:
- JiaLiPassion
@@ -285,6 +286,7 @@ groups:
- mgechev
- MarkTechson
- kirjs
- mmalerba
# =========================================================
# Angular DevTools
@@ -391,6 +393,9 @@ groups:
- thePunderWoman
- pkozlowski-opensource
- kirjs
- mmalerba
- crisbeto
- devversion
- ~iteriani
- ~tbondwilkinson
- ~rahatarmanahmed
@@ -420,33 +425,12 @@ groups:
- ~jelbourn
- thePunderWoman
- pkozlowski-opensource
- mmalerba
reviews:
request: 2 # Request reviews from 2 people
required: 1 # Require that 1 person approve
reviewed_for: required
# ================================================
# Circular dependencies
# ================================================
circular-dependencies:
<<: *defaults
conditions:
- *no-groups-above-this-pending
- *no-groups-above-this-rejected
- >
contains_any_globs(files, [
'goldens/circular-deps/packages.json'
])
reviewers:
users:
- alxhub
- AndrewKushnir
- atscott
- ~jelbourn
- thePunderWoman
- pkozlowski-opensource
- kirjs
####################################################################################
# Special Cases
####################################################################################
+8 -5
View File
@@ -1,9 +1,9 @@
{
"[javascript]": {
"editor.formatOnSave": true,
"editor.formatOnSave": true
},
"[typescript]": {
"editor.formatOnSave": true,
"editor.formatOnSave": true
},
// Exclude third party modules and build artifacts from the editor watchers/searches.
"files.watcherExclude": {
@@ -11,14 +11,17 @@
"**/.git/subtree-cache/**": true,
"**/node_modules/**": true,
"**/bazel-out/**": true,
"**/dist/**": true,
"**/dist/**": true
},
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/bazel-out": true,
"**/dist": true,
".history": true,
".history": true
},
"git.ignoreLimitWarning": true,
}
"gitlens.advanced.blame.customArguments": [
"--ignore-revs-file .git-blame-ignore-revs"
]
}
+224
View File
@@ -1,3 +1,210 @@
<a name="19.2.2"></a>
# 19.2.2 (2025-03-12)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [90a16a1088](https://github.com/angular/angular/commit/90a16a10888eee37d8a61cdbfad070e002a3cfdf) | fix | support equality function in httpResource ([#60026](https://github.com/angular/angular/pull/60026)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [56b551d273](https://github.com/angular/angular/commit/56b551d273a0978e1f2e2ef914c1d7ae942a28a8) | fix | incorrect spans for template literals ([#60323](https://github.com/angular/angular/pull/60323)) ([#60331](https://github.com/angular/angular/pull/60331)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [23ca88522b](https://github.com/angular/angular/commit/23ca88522bbc23e24a2b20e48e62edcce3a42eb6) | fix | handle transformed classes when generating HMR code ([#60298](https://github.com/angular/angular/pull/60298)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [6dc41265fd](https://github.com/angular/angular/commit/6dc41265fd47df3fd0462bcd8f451eb6aea972ef) | fix | check whether application is destroyed before initializing event replay ([#59789](https://github.com/angular/angular/pull/59789)) |
| [bb12b30d52](https://github.com/angular/angular/commit/bb12b30d5213912f50f53aff60a11e6d47349c82) | fix | ensures immediate trigger fires properly with lazy loaded routes ([#60203](https://github.com/angular/angular/pull/60203)) |
| [b144dd946e](https://github.com/angular/angular/commit/b144dd946e38e52ce716aca7c6ba7c1a1a02f13d) | fix | fix removal of a container reference used in the component file ([#60210](https://github.com/angular/angular/pull/60210)) |
### platform-server
| Commit | Type | Description |
| -- | -- | -- |
| [15c42969fc](https://github.com/angular/angular/commit/15c42969fc42c76e3bd593201164183fb82d70f6) | fix | add missing peer dependency for `rxjs` ([#60308](https://github.com/angular/angular/pull/60308)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [7bcdf7c143](https://github.com/angular/angular/commit/7bcdf7c1435f766b2b0bbd383358ef2ddabf217a) | fix | update symbols ([#60233](https://github.com/angular/angular/pull/60233)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.2.1"></a>
# 19.2.1 (2025-03-05)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [c2de5f68b3](https://github.com/angular/angular/commit/c2de5f68b3d3cd8a0c43b3c4325a1a1db874e132) | fix | clean up `onUrlChange` listener when root scope is destroyed ([#60004](https://github.com/angular/angular/pull/60004)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [1dd94476b3](https://github.com/angular/angular/commit/1dd94476b35d08e753766b1d0c5d8af5faa017a9) | fix | ensure template IDs are not reused if a source file changes ([#60152](https://github.com/angular/angular/pull/60152)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [1b3b05bf72](https://github.com/angular/angular/commit/1b3b05bf7294963aa50f83b726db620b250b1a5c) | fix | cache ComponentRef inputs and outputs ([#60156](https://github.com/angular/angular/pull/60156)) |
| [330c24aed9](https://github.com/angular/angular/commit/330c24aed92e4b916fb7ac6a91fb17c3ae728869) | fix | prevent invoking replay listeners on disconnected nodes ([#60103](https://github.com/angular/angular/pull/60103)) |
| [cfad089cc3](https://github.com/angular/angular/commit/cfad089cc359cddf08d462662d2a6bf3acab9b22) | fix | prevents event replay from being called on comment nodes ([#60130](https://github.com/angular/angular/pull/60130)) |
### language-service
| Commit | Type | Description |
| -- | -- | -- |
| [3f0116607d](https://github.com/angular/angular/commit/3f0116607dc3ad7e31cb4d895a56094f77c82f5d) | fix | Forward the tags for quick info from the type definition ([#59524](https://github.com/angular/angular/pull/59524)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.2.0"></a>
# 19.2.0 (2025-02-26)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [3e39da593a](https://github.com/angular/angular/commit/3e39da593a0a0c047a2a03b8d5fcabf9dbace40f) | feat | introduce experimental `httpResource` ([#59876](https://github.com/angular/angular/pull/59876)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [5b20bab96d](https://github.com/angular/angular/commit/5b20bab96d20fe89b5cc4b4af28edbaae2604da1) | feat | Add Skip Hydration diagnostic. ([#59576](https://github.com/angular/angular/pull/59576)) |
| [fe8a68329b](https://github.com/angular/angular/commit/fe8a68329b50363f914a728579392f3fc68670a6) | feat | support untagged template literals in expressions ([#59230](https://github.com/angular/angular/pull/59230)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [2588985f43](https://github.com/angular/angular/commit/2588985f433b20a6a5a8d239347291f5d6fb2451) | feat | pass signal node to throwInvalidWriteToSignalErrorFn ([#59600](https://github.com/angular/angular/pull/59600)) |
| [168516462a](https://github.com/angular/angular/commit/168516462a9673b158fcaa38b8ce17bf684a8ac9) | feat | support default value in `resource()` ([#59655](https://github.com/angular/angular/pull/59655)) |
| [bc2ad7bfd3](https://github.com/angular/angular/commit/bc2ad7bfd37a61992b550943de5da0eab2eec98b) | feat | support streaming resources ([#59573](https://github.com/angular/angular/pull/59573)) |
| [146ab9a76e](https://github.com/angular/angular/commit/146ab9a76e6b4d8db7d08d34e2571ba5207f8756) | feat | support TypeScript 5.8 ([#59830](https://github.com/angular/angular/pull/59830)) |
| [6c92d65349](https://github.com/angular/angular/commit/6c92d653493404a5f13aa59cde390bcbed973fb6) | fix | add `hasValue` narrowing to `ResourceRef` ([#59708](https://github.com/angular/angular/pull/59708)) |
| [96e602ebe9](https://github.com/angular/angular/commit/96e602ebe9cdf7355befad22c11f9f91e0436e01) | fix | cancel in-progress request when same value is assigned ([#59280](https://github.com/angular/angular/pull/59280)) |
| [6789c7ef94](https://github.com/angular/angular/commit/6789c7ef947952551d7598fe37a3d86093b75720) | fix | Defer afterRender until after first CD ([#59455](https://github.com/angular/angular/pull/59455)) ([#59551](https://github.com/angular/angular/pull/59551)) |
| [c87e581dd9](https://github.com/angular/angular/commit/c87e581dd9e240c88cea50f222942873bdccd01d) | fix | Don't run effects in check no changes pass ([#59455](https://github.com/angular/angular/pull/59455)) ([#59551](https://github.com/angular/angular/pull/59551)) |
| [127fc0dc84](https://github.com/angular/angular/commit/127fc0dc847a4e8b62be36cdd980a067c4da974f) | fix | fix `resource()`'s `previous.state` ([#59708](https://github.com/angular/angular/pull/59708)) |
| [b592b1b051](https://github.com/angular/angular/commit/b592b1b0516786c52c7d0638c4e7545b0de8a545) | fix | fix race condition in resource() ([#59851](https://github.com/angular/angular/pull/59851)) |
| [a299e02e91](https://github.com/angular/angular/commit/a299e02e9141cdc4d74185deb58308fa010bb36e) | fix | preserve tracing snapshot until tick finishes ([#59796](https://github.com/angular/angular/pull/59796)) |
### forms
| Commit | Type | Description |
| -- | -- | -- |
| [fa0c3e3210](https://github.com/angular/angular/commit/fa0c3e3210885a36e5c9e9eb76e821032f5cd215) | feat | support type set in form validators ([#45793](https://github.com/angular/angular/pull/45793)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [1cd3a7db83](https://github.com/angular/angular/commit/1cd3a7db83e1d05a31d23324676420b614cdabe2) | feat | add migration to convert templates to use self-closing tags ([#57342](https://github.com/angular/angular/pull/57342)) |
### platform-browser
| Commit | Type | Description |
| -- | -- | -- |
| [e6cb411e43](https://github.com/angular/angular/commit/e6cb411e4393a4b1f5852d3d7c5b9622504399b1) | fix | automatically disable animations on the server ([#59762](https://github.com/angular/angular/pull/59762)) |
### platform-server
| Commit | Type | Description |
| -- | -- | -- |
| [fc5d187da5](https://github.com/angular/angular/commit/fc5d187da5e8895d60caa35b7b59e234998eddf0) | fix | decouple server from animations module ([#59762](https://github.com/angular/angular/pull/59762)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.1.7"></a>
# 19.1.7 (2025-02-19)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [e9f10eb4c9](https://github.com/angular/angular/commit/e9f10eb4c950692992098619b9628ecefd1b36ce) | fix | clean up `urlChanges` subscribers when root scope is destroyed ([#59703](https://github.com/angular/angular/pull/59703)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [16fc074689](https://github.com/angular/angular/commit/16fc074689d31ef6886c49525b020bc6c1529d0e) | fix | avoid crash in isolated transform operations ([#59869](https://github.com/angular/angular/pull/59869)) |
### forms
| Commit | Type | Description |
| -- | -- | -- |
| [ec1e4c3d94](https://github.com/angular/angular/commit/ec1e4c3d9430f5ea4380252098d2b4b71d8a950f) | fix | Fix typing on `FormRecord`. ([#59993](https://github.com/angular/angular/pull/59993)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.1.6"></a>
# 19.1.6 (2025-02-12)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [01f669a274](https://github.com/angular/angular/commit/01f669a27425c5034a04274763cc60801f961aa2) | fix | handle tracking expressions requiring temporary variables ([#58520](https://github.com/angular/angular/pull/58520)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [dcfb9f1959](https://github.com/angular/angular/commit/dcfb9f1959164baf45f5f954b4bf681d650d8a2d) | fix | handle deferred blocks with shared dependencies correctly ([#59926](https://github.com/angular/angular/pull/59926)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [cab7a9b69c](https://github.com/angular/angular/commit/cab7a9b69c3a5d789432a87a554e8489c78a0f15) | fix | invalidate HMR component if replacement throws an error ([#59854](https://github.com/angular/angular/pull/59854)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [710759ddcc](https://github.com/angular/angular/commit/710759ddcc0ecbad68deb20821b535fd5deb69c6) | fix | account for let declarations in control flow migration ([#59861](https://github.com/angular/angular/pull/59861)) |
| [46f36a58bf](https://github.com/angular/angular/commit/46f36a58bf3a7b9131b6330e84d4adb3e73f3601) | fix | count used dependencies inside existing control flow ([#59861](https://github.com/angular/angular/pull/59861)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.1.5"></a>
# 19.1.5 (2025-02-06)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [d7b5c597ffc](https://github.com/angular/angular/commit/d7b5c597ffcb6469ae3f08a97e7790599d569cc4) | fix | gracefully fall back if const enum cannot be passed through ([#59815](https://github.com/angular/angular/pull/59815)) |
| [53a4668b58b](https://github.com/angular/angular/commit/53a4668b58b645e41baddc5b67d52ede21c8e945) | fix | handle const enums used inside HMR data ([#59815](https://github.com/angular/angular/pull/59815)) |
| [976125e0b4c](https://github.com/angular/angular/commit/976125e0b4cf4e7fb4621a7203e3f43b009885f0) | fix | handle enum members without initializers in partial evaluator ([#59815](https://github.com/angular/angular/pull/59815)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.1.4"></a>
# 19.1.4 (2025-01-29)
### core
| Commit | Type | Description |
| -- | -- | -- |
| [544b9ee7ca0](https://github.com/angular/angular/commit/544b9ee7ca00925e62b7c74cf7930777a10aaf76) | fix | check whether application is destroyed before printing hydration stats ([#59716](https://github.com/angular/angular/pull/59716)) |
| [d6e78c072dc](https://github.com/angular/angular/commit/d6e78c072dcb5b0b6efc2b098fdb911ccddf6e81) | fix | ensure type is preserved during HMR ([#59700](https://github.com/angular/angular/pull/59700)) |
| [c2436702df9](https://github.com/angular/angular/commit/c2436702df980bbf2db0fe3bee4c72860edb4e63) | fix | fixes test timer-based test flakiness in CI ([#59674](https://github.com/angular/angular/pull/59674)) |
### elements
| Commit | Type | Description |
| -- | -- | -- |
| [44180645992](https://github.com/angular/angular/commit/44180645992f7d9018ccb2d7663530b3cffde36b) | fix | not setting initial value on signal-based input ([#59773](https://github.com/angular/angular/pull/59773)) |
### platform-browser
| Commit | Type | Description |
| -- | -- | -- |
| [1828a840620](https://github.com/angular/angular/commit/1828a8406201827e52549c8afa487bf6364a70c3) | fix | prepend `baseHref` to `sourceMappingURL` in CSS content ([#59730](https://github.com/angular/angular/pull/59730)) |
| [1c84cbca30e](https://github.com/angular/angular/commit/1c84cbca30e6606e6df3f40346989d9434d89bc6) | fix | Update pseudoevent created by createMouseSpecialEvent to populate `_originalEvent` property ([#59690](https://github.com/angular/angular/pull/59690)) |
| [12256574626](https://github.com/angular/angular/commit/12256574626f04f5fe2b41e805f7bdc93d62df0a) | fix | Update pseudoevent created by createMouseSpecialEvent to populate `_originalEvent` property ([#59690](https://github.com/angular/angular/pull/59690)) |
| [3f4d5f636aa](https://github.com/angular/angular/commit/3f4d5f636aac90cabe32ff6c4d75180ced99eb97) | fix | Update pseudoevent created by createMouseSpecialEvent to populate `_originalEvent` property ([#59690](https://github.com/angular/angular/pull/59690)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [e3da35ec749](https://github.com/angular/angular/commit/e3da35ec749395239731158f89e29d47e7a9ef36) | fix | prevent error handling when injector is destroyed ([#59457](https://github.com/angular/angular/pull/59457)) |
### service-worker
| Commit | Type | Description |
| -- | -- | -- |
| [522acbf3d7e](https://github.com/angular/angular/commit/522acbf3d7ed502e7802117776acda3529a9a2b4) | fix | add missing `rxjs` peer dependency ([#59747](https://github.com/angular/angular/pull/59747)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.1.3"></a>
# 19.1.3 (2025-01-22)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [ecfb74d287](https://github.com/angular/angular/commit/ecfb74d287bec7bec37d0b476b321b047bef2c43) | fix | handle :host-context with comma-separated child selector ([#59276](https://github.com/angular/angular/pull/59276)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [53160e504d](https://github.com/angular/angular/commit/53160e504df44b05f59cacd9afeb40a0e627b744) | fix | extract parenthesized dependencies during HMR ([#59644](https://github.com/angular/angular/pull/59644)) |
| [39690969af](https://github.com/angular/angular/commit/39690969af14914df0c9b5a009b2df920f5c03e7) | fix | handle conditional expressions when extracting dependencies ([#59637](https://github.com/angular/angular/pull/59637)) |
| [78af7a5059](https://github.com/angular/angular/commit/78af7a5059cc3e03704ba63f8512351a40470557) | fix | handle new expressions when extracting dependencies ([#59637](https://github.com/angular/angular/pull/59637)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [408af24ff3](https://github.com/angular/angular/commit/408af24ff3490926e9992cb4f1f71914d71ad6ad) | fix | capture self-referencing component during HMR ([#59644](https://github.com/angular/angular/pull/59644)) |
| [d7575c201c](https://github.com/angular/angular/commit/d7575c201cfd61010952b3a633eec03e32f58220) | fix | replace metadata in place during HMR ([#59644](https://github.com/angular/angular/pull/59644)) |
| [26f6d4c485](https://github.com/angular/angular/commit/26f6d4c485b566d7bc127c78cc163c376d0fe6b5) | fix | skip component ID collision warning during SSR ([#59625](https://github.com/angular/angular/pull/59625)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [a62c84bc18](https://github.com/angular/angular/commit/a62c84bc188d41ea24cf0eca14ac18c4b917ccd0) | fix | avoid applying the same replacements twice when cleaning up unused imports ([#59656](https://github.com/angular/angular/pull/59656)) |
### platform-browser
| Commit | Type | Description |
| -- | -- | -- |
| [b2b3816cb1](https://github.com/angular/angular/commit/b2b3816cb1c5c573dc9368f05fd2971671d7159f) | fix | clear renderer cache during HMR when using async animations ([#59644](https://github.com/angular/angular/pull/59644)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.1.2"></a>
# 19.1.2 (2025-01-20)
### compiler
@@ -75,6 +282,23 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.7"></a>
# 19.0.7 (2025-01-15)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [2b4b7c3ebf](https://github.com/angular/angular/commit/2b4b7c3ebfb2d4f4fd96fd2f1890b67c832505fd) | fix | handle more node types when extracting dependencies ([#59445](https://github.com/angular/angular/pull/59445)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [f893d07232](https://github.com/angular/angular/commit/f893d0723262d699979d55e43e4ddbcf64a3fc13) | fix | destroy renderer when replacing styles during HMR ([#59514](https://github.com/angular/angular/pull/59514)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [eb2fcd1896](https://github.com/angular/angular/commit/eb2fcd1896e0b834b86fe79e8d806bdab24aabcc) | fix | incorrect stats when migrating queries with best effort mode ([#59463](https://github.com/angular/angular/pull/59463)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="19.0.6"></a>
# 19.0.6 (2025-01-08)
### compiler-cli
+6 -155
View File
@@ -103,7 +103,7 @@ Before you submit your Pull Request (PR) consider the following guidelines:
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
9. Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit).
9. Commit your changes using a descriptive commit message that follows our [commit message conventions][commit-message-guidelines].
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
```shell
@@ -145,7 +145,7 @@ That's it! Thank you for your contribution!
##### Updating the commit message
A reviewer might often suggest changes to a commit message (for example, to add more context for a change or adhere to our [commit message guidelines](#commit)).
A reviewer might often suggest changes to a commit message (for example, to add more context for a change or adhere to our [commit message guidelines][commit-message-guidelines]).
In order to update the commit message of the last commit on your branch:
1. Check out your branch:
@@ -210,163 +210,14 @@ To ensure consistency throughout the source code, keep these rules in mind as yo
An automated formatter is available, see [DEVELOPER.md](contributing-docs/building-and-testing-angular.md#formatting-your-source-code).
## <a name="commit"></a> Commit Message Format
*This specification is inspired by and supersedes the [AngularJS commit message format][commit-message-format].*
We have very precise rules over how our Git commit messages must be formatted.
This format leads to **easier to read commit history**.
Each commit message consists of a **header**, a **body**, and a **footer**.
```
<header>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format.
The `body` is mandatory for all commits except for those of type "docs".
When the body is present it must be at least 20 characters long and must conform to the [Commit Message Body](#commit-body) format.
The `footer` is optional. The [Commit Message Footer](#commit-footer) format describes what the footer is used for and the structure it must have.
#### <a name="commit-header"></a>Commit Message Header
## <a name="commit"></a> Commit Message Guidelines
We have very precise rules over how our Git commit messages must be formatted:
```
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
│ elements|forms|http|language-service|localize|platform-browser|
│ platform-browser-dynamic|platform-server|router|service-worker|
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|
│ devtools
│
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
```
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.
##### Type
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (examples: Github Actions, SauceLabs)
* **docs**: Documentation only changes
* **feat**: A new feature
* **fix**: A bug fix
* **perf**: A code change that improves performance
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **test**: Adding missing tests or correcting existing tests
##### Scope
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
The following is the list of supported scopes:
* `animations`
* `bazel`
* `benchpress`
* `common`
* `compiler`
* `compiler-cli`
* `core`
* `elements`
* `forms`
* `http`
* `language-service`
* `localize`
* `platform-browser`
* `platform-browser-dynamic`
* `platform-server`
* `router`
* `service-worker`
* `upgrade`
* `zone.js`
There are currently a few exceptions to the "use package name" rule:
* `packaging`: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
* `changelog`: used for updating the release notes in CHANGELOG.md
* `dev-infra`: used for dev-infra related changes within the directories /scripts and /tools
* `docs-infra`: used for docs-app (angular.dev) related changes within the /adev directory of the repo
* `migrations`: used for changes to the `ng update` migrations.
* `devtools`: used for changes in the [browser extension](./devtools/README.md).
* none/empty string: useful for `test` and `refactor` changes that are done across all packages (e.g. `test: add missing unit tests`) and for docs changes that are not related to a specific package (e.g. `docs: fix typo in tutorial`).
##### Summary
Use the summary field to provide a succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize the first letter
* no dot (.) at the end
#### <a name="commit-body"></a>Commit Message Body
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change.
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
#### <a name="commit-footer"></a>Commit Message Footer
The footer can contain information about breaking changes and deprecations and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
For example:
```
BREAKING CHANGE: <breaking change summary>
<BLANK LINE>
<breaking change description + migration instructions>
<BLANK LINE>
<BLANK LINE>
Fixes #<issue number>
```
or
```
DEPRECATED: <what is deprecated>
<BLANK LINE>
<deprecation description + recommended update path>
<BLANK LINE>
<BLANK LINE>
Closes #<pr number>
```
Breaking Change section should start with the phrase `BREAKING CHANGE: ` followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
Similarly, a Deprecation section should start with `DEPRECATED: ` followed by a short description of what is deprecated, a blank line, and a detailed description of the deprecation that also mentions the recommended update path.
### Revert commits
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
The content of the commit message body should contain:
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`,
- a clear description of the reason for reverting the commit message.
See [Commit Message Guidelines][commit-message-guidelines] for details.
## <a name="cla"></a> Signing the CLA
@@ -390,9 +241,9 @@ The following documents can help you sort out issues with GitHub accounts and mu
[coc]: https://github.com/angular/code-of-conduct/blob/main/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[corporate-cla]: https://cla.developers.google.com/about/google-corporate
[dev-doc]: ./contributing-docs/building-and-testing-angular.md
[commit-message-guidelines]: ./contributing-docs/commit-message-guidelines.md
[github]: https://github.com/angular/angular
[discord]: https://discord.gg/angular
[individual-cla]: https://cla.developers.google.com/about/google-individual
+2
View File
@@ -125,6 +125,7 @@ Help us keep Angular open and inclusive. Please read and follow our [Code of Con
Join the conversation and help the community.
- [X (formerly Twitter)][X (formerly Twitter)]
- [Bluesky][bluesky]
- [Discord][discord]
- [Gitter][gitter]
- [YouTube][youtube]
@@ -154,6 +155,7 @@ Join the conversation and help the community.
[npm]: https://www.npmjs.com/get-npm
[codeofconduct]: CODE_OF_CONDUCT.md
[X (formerly Twitter)]: https://www.twitter.com/angular
[bluesky]: https://bsky.app/profile/angular.dev
[discord]: https://discord.gg/angular
[gitter]: https://gitter.im/angular/angular
[stackoverflow]: https://stackoverflow.com/questions/tagged/angular
+12 -12
View File
@@ -50,16 +50,16 @@ load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
nodejs_register_toolchains(
name = "nodejs",
node_repositories = {
"18.20.0-darwin_arm64": ("node-v18.20.0-darwin-arm64.tar.gz", "node-v18.20.0-darwin-arm64", "10066ad4dd9e03ea5c4c45ef8775420ff37b860de09bbdf87b97e0c07b1ea036"),
"18.20.0-darwin_amd64": ("node-v18.20.0-darwin-x64.tar.gz", "node-v18.20.0-darwin-x64", "062ba71618e88e06321de5caa038843c350aababa2d315f3ca7b8551f8e66c1c"),
"18.20.0-linux_arm64": ("node-v18.20.0-linux-arm64.tar.xz", "node-v18.20.0-linux-arm64", "afe51da9ffb38ac1e3a20d9a06efd403ced4bf8831ab554a02a088dd8392fd79"),
"18.20.0-linux_ppc64le": ("node-v18.20.0-linux-ppc64le.tar.xz", "node-v18.20.0-linux-ppc64le", "9e652bbf53a3e37285b11dfb9d6a9bb8b02010c3b50e5c8229d4cc10e72681da"),
"18.20.0-linux_s390x": ("node-v18.20.0-linux-s390x.tar.xz", "node-v18.20.0-linux-s390x", "a6c2a5796b9d9e9bf21da62ec89ff30b41a8108880b9eaa3c912f1ce795a7743"),
"18.20.0-linux_amd64": ("node-v18.20.0-linux-x64.tar.xz", "node-v18.20.0-linux-x64", "03eea148e56785babb27930b05ed6bf311aaa3bc573c0399dd63cad2fe5713c7"),
"18.20.0-windows_amd64": ("node-v18.20.0-win-x64.zip", "node-v18.20.0-win-x64", "1c0aab05cc6836a8f5148cca345b92ebc948a4a2013f18d117b7ade6ff05aca6"),
"18.20.5-darwin_arm64": ("node-v18.20.5-darwin-arm64.tar.gz", "node-v18.20.5-darwin-arm64", "bdfeaf59dbf29aec08c0c66130edf0a8a17014b4f2997727641dfd0b58b51f48"),
"18.20.5-darwin_amd64": ("node-v18.20.5-darwin-x64.tar.gz", "node-v18.20.5-darwin-x64", "dff01068da7d3fe7b515f72a3903dca96a34dc377f6f426b6a813901274b6441"),
"18.20.5-linux_arm64": ("node-v18.20.5-linux-arm64.tar.xz", "node-v18.20.5-linux-arm64", "a77db6ab34267f3bc80e02ed68abf51b7065eb5c82fcd69adc4b40e390d9b116"),
"18.20.5-linux_ppc64le": ("node-v18.20.5-linux-ppc64le.tar.xz", "node-v18.20.5-linux-ppc64le", "63b4c6801c96fb452e3bd8125e8b5b195ecacc4fa2505e47a128e94587999aeb"),
"18.20.5-linux_s390x": ("node-v18.20.5-linux-s390x.tar.xz", "node-v18.20.5-linux-s390x", "617d7456e16534a4b4e03f5285cc8d13581f39cdad9196efff2516d6588de319"),
"18.20.5-linux_amd64": ("node-v18.20.5-linux-x64.tar.xz", "node-v18.20.5-linux-x64", "e4a3a21e5ac7e074ed50d2533dd0087d8460647ab567464867141a2b643f3fb3"),
"18.20.5-windows_amd64": ("node-v18.20.5-win-x64.zip", "node-v18.20.5-win-x64", "910237449895b4de61026568dc076fa6c3ffcd667563ed03112a4a77e1f1556b"),
},
# We need at least Node 18.17 due to some transitive dependencies.
node_version = "18.20.0",
# We need at least Node 18.20.5 due to some transitive dependencies.
node_version = "18.20.5",
)
# Download npm dependencies.
@@ -143,10 +143,10 @@ cldr_xml_data_repository(
# sass rules
http_archive(
name = "io_bazel_rules_sass",
sha256 = "1d840af29fe9b6dd1d3cebb31ca143450ab8d4036bff76f958c7873a770a46ba",
strip_prefix = "rules_sass-adeaf81181b25f15a2d1d1081630506cd6bd0045",
sha256 = "e8b863f6be5609c6ed15664d12512ee36d93e8bcb2c1a331f85d9e8758a82ee7",
strip_prefix = "rules_sass-3b3667fd5861b06a03bea1f1946b55ac7100d4ea",
urls = [
"https://github.com/bazelbuild/rules_sass/archive/adeaf81181b25f15a2d1d1081630506cd6bd0045.zip",
"https://github.com/bazelbuild/rules_sass/archive/3b3667fd5861b06a03bea1f1946b55ac7100d4ea.zip",
],
)
+3 -6
View File
@@ -1,9 +1,9 @@
load("@npm//@angular/build-tooling/bazel/remote-execution:index.bzl", "ENABLE_NETWORK")
load("@npm//@angular/build-tooling/bazel/http-server:index.bzl", "http_server")
load("@bazel_skylib//lib:collections.bzl", "collections")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
load("@npm//@angular/build-tooling/bazel/http-server:index.bzl", "http_server")
load("@npm//@angular/build-tooling/bazel/remote-execution:index.bzl", "ENABLE_NETWORK")
load("@npm//@angular-devkit/architect-cli:index.bzl", "architect", "architect_test")
load("@bazel_skylib//lib:collections.bzl", "collections")
load("//adev/tools/local_deps:index.bzl", "ensure_local_package_deps", "link_local_packages")
package(default_visibility = ["//visibility:public"])
@@ -35,7 +35,6 @@ TEST_FILES = APPLICATION_FILES + [
APPLICATION_ASSETS = [
"//adev/src/assets/images",
"//adev/src/assets/textures",
"//adev/src/assets/previews",
"//adev/src/assets:tutorials",
"//adev/src/assets/icons",
@@ -59,10 +58,8 @@ APPLICATION_DEPS = [
"@npm//@angular/platform-server",
"@npm//@angular/router",
"@npm//@angular/ssr",
"@npm//gsap",
"@npm//marked",
"@npm//ngx-progressbar",
"@npm//ogl",
"@npm//rxjs",
"@npm//typescript",
"@npm//@typescript/vfs",
+1 -1
View File
@@ -6,7 +6,7 @@ The content is written primarily in Markdown format located in `src/content`. Fo
## Local Development
For local development, [yarn](https://yarnpkg.com/) is the preferred package manager. You can setup a local environment with the following commands
For local development, [yarn](https://yarnpkg.com/) is the preferred package manager. You can set up a local environment with the following commands
:
```bash
-1
View File
@@ -10,7 +10,6 @@ ng_module(
module_name = "@angular/docs",
deps = [
"//adev/shared-docs/components",
"//adev/shared-docs/constants",
"//adev/shared-docs/directives",
"//adev/shared-docs/interfaces",
"//adev/shared-docs/pipes",
@@ -1,5 +1,5 @@
load("//tools:defaults.bzl", "karma_web_test_suite", "ng_module", "ts_library")
load("@io_bazel_rules_sass//:defs.bzl", "sass_binary")
load("//tools:defaults.bzl", "karma_web_test_suite", "ng_module", "ts_library")
package(default_visibility = ["//visibility:private"])
@@ -23,6 +23,7 @@ ng_module(
"//packages/common",
"//packages/core",
"//packages/router",
"@npm//@angular/material",
],
)
@@ -7,8 +7,15 @@
<li class="docs-faceted-list-item">
@if (item.path) {
@if (item.isExternal) {
<a [href]="item.path" target="_blank">
<span [class.docs-external-link]="item.isExternal">{{ item.label }}</span>
<a
[href]="item.path" target="_blank"
[matTooltip]="item.label"
[matTooltipDisabled]="item.label.length < 27"
matTooltipPosition="after"
[attr.aria-label]="item.label"
[matTooltipClass]="'API-tooltip'"
>
<span [class.docs-external-link]="item.isExternal" class="docs-faceted-list-item-text">{{ item.label }}</span>
@if (item.children && item.level! > 1 && !item.isExpanded) {
<docs-icon>chevron_right</docs-icon>
}
@@ -25,8 +32,13 @@
}"
routerLinkActive="docs-faceted-list-item-active"
(click)="emitClickOnLink()"
[matTooltip]="item.label"
[matTooltipDisabled]="item.label.length < 27"
matTooltipPosition="after"
[attr.aria-label]="item.label"
[matTooltipClass]="'API-tooltip'"
>
<span>{{item.label}}</span>
<span class="docs-faceted-list-item-text">{{item.label}}</span>
@if (item.children && !item.isExpanded) {
<docs-icon>chevron_right</docs-icon>
}
@@ -35,8 +47,14 @@
} @else {
<!-- Nav Section Header -->
@if (item.level !== collapsableLevel() && item.level !== expandableLevel()) {
<div class="docs-secondary-nav-header">
<span>{{item.label}}</span>
<div class="docs-secondary-nav-header"
[matTooltip]="item.label"
[matTooltipDisabled]="item.label.length < 27"
matTooltipPosition="after"
[attr.aria-label]="item.label"
[matTooltipClass]="'API-tooltip'"
>
<span class="docs-faceted-list-item-text">{{item.label}}</span>
</div>
}
@@ -54,13 +72,17 @@
[class.docs-expanded-button]="item.children && item.level == collapsableLevel()"
[class.docs-not-expanded-button]="item.children && item.level === expandableLevel()"
[class.docs-nav-item-has-icon]="
item.children && item.level === expandableLevel() && !item.isExpanded
"
item.children && item.level === expandableLevel() && !item.isExpanded"
[matTooltip]="item.label"
[matTooltipDisabled]="item.label.length < 27"
matTooltipPosition="after"
[attr.aria-label]="item.label"
[matTooltipClass]="'API-tooltip'"
>
@if (item.children && item.level === collapsableLevel()) {
<docs-icon>arrow_back</docs-icon>
}
<span>{{ item.label }}</span>
<span class="docs-faceted-list-item-text">{{ item.label }}</span>
</button>
}
}
@@ -45,6 +45,12 @@
border: 0;
}
.docs-faceted-list-item-text {
max-width: calc(100% - 1rem);
overflow: hidden;
text-overflow: ellipsis;
}
.docs-nav-item-has-icon {
&::after {
// FIXME: for some reason this disappears when transformed
@@ -115,7 +121,7 @@ a,
// Add padding-bottom to last item in the list
.docs-navigation-list {
width: 100%;
width: 15rem;
li:last-of-type {
ul:last-of-type {
@@ -144,3 +150,12 @@ a,
margin-inline-end: 0.4rem;
}
}
::ng-deep .API-tooltip{
.mat-mdc-tooltip-surface{
max-width: unset;
width:auto;
word-break: keep-all;
white-space: pre;
}
}
@@ -13,10 +13,18 @@ import {RouterLink, RouterLinkActive} from '@angular/router';
import {IconComponent} from '../icon/icon.component';
import {IsActiveNavigationItem} from '../../pipes/is-active-navigation-item.pipe';
import {NgTemplateOutlet} from '@angular/common';
import {MatTooltipModule} from '@angular/material/tooltip';
@Component({
selector: 'docs-navigation-list',
imports: [RouterLink, RouterLinkActive, IconComponent, IsActiveNavigationItem, NgTemplateOutlet],
imports: [
RouterLink,
RouterLinkActive,
IconComponent,
IsActiveNavigationItem,
NgTemplateOutlet,
MatTooltipModule,
],
templateUrl: './navigation-list.component.html',
styleUrls: ['./navigation-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -2,6 +2,8 @@ dialog {
background-color: transparent;
border: none;
padding-block-end: 3rem;
margin: 0 auto;
top: 15vh;
&::backdrop {
backdrop-filter: blur(5px);
@@ -6,26 +6,18 @@
<ul class="docs-faceted-list">
<!-- TODO: Hide li elements with class docs-toc-item-h3 for laptop, table and phone screen resolutions -->
@for (item of tableOfContentItems(); track item.id) {
<li
class="docs-faceted-list-item"
[class.docs-toc-item-h2]="item.level === TableOfContentsLevel.H2"
[class.docs-toc-item-h3]="item.level === TableOfContentsLevel.H3"
>
<a
routerLink="."
[fragment]="item.id"
[class.docs-faceted-list-item-active]="item.id === activeItemId()"
>
<li class="docs-faceted-list-item" [class.docs-toc-item-h2]="item.level === TableOfContentsLevel.H2"
[class.docs-toc-item-h3]="item.level === TableOfContentsLevel.H3">
<!-- Not using routerLink + fragment because of: https://github.com/angular/angular/issues/30139 -->
<a [href]="location.path() + '#' + item.id" [class.docs-faceted-list-item-active]="item.id === activeItemId()">
{{ item.title }}
</a>
</li>
}
</ul>
</nav>
@if (shouldDisplayScrollToTop()) {
<button type="button" (click)="scrollToTop()">
<docs-icon role="presentation">arrow_upward_alt</docs-icon>
Back to the top
</button>
}
</aside>
</aside>
@@ -11,10 +11,10 @@ import {
Component,
DestroyRef,
input,
computed,
inject,
afterNextRender,
} from '@angular/core';
import {RouterLink} from '@angular/router';
import {Location} from '@angular/common';
import {TableOfContentsLevel} from '../../interfaces/index';
import {TableOfContentsLoader} from '../../services/table-of-contents-loader.service';
import {TableOfContentsScrollSpy} from '../../services/table-of-contents-scroll-spy.service';
@@ -25,11 +25,12 @@ import {IconComponent} from '../icon/icon.component';
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './table-of-contents.component.html',
styleUrls: ['./table-of-contents.component.scss'],
imports: [RouterLink, IconComponent],
imports: [IconComponent],
})
export class TableOfContents {
// Element that contains the content from which the Table of Contents is built
readonly contentSourceElement = input.required<HTMLElement>();
readonly location = inject(Location);
private readonly scrollSpy = inject(TableOfContentsScrollSpy);
private readonly tableOfContentsLoader = inject(TableOfContentsLoader);
@@ -38,12 +39,15 @@ export class TableOfContents {
tableOfContentItems = this.tableOfContentsLoader.tableOfContentItems;
activeItemId = this.scrollSpy.activeItemId;
shouldDisplayScrollToTop = computed(() => !this.scrollSpy.scrollbarThumbOnTop());
TableOfContentsLevel = TableOfContentsLevel;
ngAfterViewInit() {
this.tableOfContentsLoader.buildTableOfContent(this.contentSourceElement());
this.scrollSpy.startListeningToScroll(this.contentSourceElement(), this.destroyRef);
constructor() {
afterNextRender({
read: () => {
this.tableOfContentsLoader.buildTableOfContent(this.contentSourceElement());
this.scrollSpy.setupActiveItemListener(this.contentSourceElement(), this.destroyRef);
},
});
}
scrollToTop(): void {
@@ -121,7 +121,7 @@ describe('DocViewer', () => {
expect(checkIcon.nativeElement.innerHTML).toBe('check');
});
it('should display example viewer in multi file mode when user clicks expand', async () => {
it('should display example viewer in multi file mode when provided example is multi file snippet', async () => {
const fixture = TestBed.createComponent(DocViewer);
fixture.componentRef.setInput(
'docContent',
@@ -131,10 +131,6 @@ describe('DocViewer', () => {
await fixture.whenStable();
const exampleViewer = fixture.debugElement.query(By.directive(ExampleViewer));
const expandButton = fixture.debugElement.query(
By.css('button[aria-label="Expand code example"]'),
);
expandButton.nativeElement.click();
expect(exampleViewer).not.toBeNull();
expect(exampleViewer.componentInstance.view()).toBe(CodeExampleViewMode.MULTI_FILE);
@@ -196,13 +196,13 @@ export class DocViewer implements OnChanges {
const exampleRef = this.viewContainer.createComponent(ExampleViewer);
this.countOfExamples++;
exampleRef.instance.metadata = {
exampleRef.setInput('metadata', {
title: title ?? firstCodeSnippetTitle,
path,
files: snippets,
preview,
id: this.countOfExamples,
};
});
exampleRef.instance.githubUrl = `${GITHUB_CONTENT_URL}/${snippets[0].name}`;
exampleRef.instance.stackblitzUrl = `${ASSETS_EXAMPLES_PATH}/${snippets[0].name}.html`;
@@ -293,9 +293,6 @@ export class DocViewer implements OnChanges {
}
}
// Trigger change detection after setting inputs.
componentRef.changeDetectorRef.detectChanges();
// Attach a view to the ApplicationRef for change detection
// purposes and for hydration serialization to pick it up
// during SSG.
@@ -343,7 +340,12 @@ export class DocViewer implements OnChanges {
relativeUrl = hrefAttr;
}
handleHrefClickEventWithRouter(e, this.router, relativeUrl);
// Unless this is a link to an element within the same page, use the Angular router.
// https://github.com/angular/angular/issues/30139
const scrollToElementExists = relativeUrl.startsWith(this.location.path() + '#');
if (!scrollToElementExists) {
handleHrefClickEventWithRouter(e, this.router, relativeUrl);
}
});
});
}
@@ -100,26 +100,59 @@ describe('ExampleViewer', () => {
expect(component.tabs()![2].name).toBe('another-example.ts');
});
it('should expandable be false when none of the example files have defined visibleLinesRange ', waitForAsync(async () => {
it('should expand button not appear when there is no hidden line', waitForAsync(async () => {
component.metadata = getMetadata();
await component.renderExample();
expect(component.expandable()).toBeFalse();
const button = fixture.debugElement.query(By.css('button[aria-label="Expand code example"]'));
expect(button).toBeNull();
}));
it('should expandable be true when at least one example file has defined visibleLinesRange ', waitForAsync(async () => {
it('should have line with hidden line class when expand button is present', waitForAsync(async () => {
const expectedCodeSnippetContent =
'typescript code<br/>' + '<div class="line">hidden line</div>';
component.metadata = getMetadata({
files: [
{name: 'example.ts', content: 'typescript file'},
{
name: 'example.html',
content: 'html file',
visibleLinesRange: '[1, 2]',
name: 'example.ts',
content: `<pre><code>${expectedCodeSnippetContent}</code></pre>`,
visibleLinesRange: '[1]',
},
{name: 'another-example.ts', content: 'css file'},
],
});
await component.renderExample();
expect(component.expandable()).toBeTrue();
fixture.detectChanges();
const hiddenLine = fixture.debugElement.query(By.css('div[class="line hidden"]'));
expect(hiddenLine).toBeTruthy();
}));
it('should have no more line with hidden line class when expand button is clicked', waitForAsync(async () => {
const expectedCodeSnippetContent =
'typescript code<br/>' + '<div class="line">hidden line</div>';
component.metadata = getMetadata({
files: [
{
name: 'example.ts',
content: `<pre><code>${expectedCodeSnippetContent}</code></pre>`,
visibleLinesRange: '[1]',
},
],
});
await component.renderExample();
fixture.detectChanges();
const expandButton = fixture.debugElement.query(
By.css('button[aria-label="Expand code example"]'),
);
expandButton.nativeElement.click();
fixture.detectChanges();
const hiddenLine = fixture.debugElement.query(By.css('div[class="line hidden"]'));
expect(hiddenLine).toBeNull();
}));
it('should set exampleComponent when metadata contains path and preview is true', waitForAsync(async () => {
@@ -7,18 +7,21 @@
*/
import {
afterNextRender,
ChangeDetectionStrategy,
Component,
DestroyRef,
Input,
Type,
computed,
inject,
ChangeDetectorRef,
ViewChild,
signal,
Component,
computed,
DestroyRef,
ElementRef,
forwardRef,
inject,
Injector,
input,
Input,
signal,
Type,
ViewChild,
} from '@angular/core';
import {CommonModule, DOCUMENT} from '@angular/common';
import {MatTabGroup, MatTabsModule} from '@angular/material/tabs';
@@ -47,10 +50,7 @@ export const HIDDEN_CLASS_NAME = 'hidden';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ExampleViewer {
// TODO: replace by signal-based input when it'll be available
@Input({required: true}) set metadata(value: ExampleMetadata) {
this.exampleMetadata.set(value);
}
exampleMetadata = input.required<ExampleMetadata>({alias: 'metadata'});
@Input() githubUrl: string | null = null;
@Input() stackblitzUrl: string | null = null;
@@ -60,6 +60,7 @@ export class ExampleViewer {
private readonly clipboard = inject(Clipboard);
private readonly destroyRef = inject(DestroyRef);
private readonly document = inject(DOCUMENT);
private readonly injector = inject(Injector);
private readonly elementRef = inject(ElementRef<HTMLElement>);
private readonly exampleViewerContentLoader = inject(EXAMPLE_VIEWER_CONTENT_LOADER);
@@ -74,8 +75,8 @@ export class ExampleViewer {
CodeExampleViewMode = CodeExampleViewMode;
exampleComponent?: Type<unknown>;
expandable = signal<boolean>(false);
expanded = signal<boolean>(false);
exampleMetadata = signal<ExampleMetadata | null>(null);
snippetCode = signal<Snippet | undefined>(undefined);
tabs = computed(() =>
this.exampleMetadata()?.files.map((file) => ({
@@ -89,9 +90,6 @@ export class ExampleViewer {
? CodeExampleViewMode.SNIPPET
: CodeExampleViewMode.MULTI_FILE,
);
expandable = computed(() =>
this.exampleMetadata()?.files.some((file) => !!file.visibleLinesRange),
);
async renderExample(): Promise<void> {
// Lazy load live example component
@@ -103,18 +101,27 @@ export class ExampleViewer {
this.snippetCode.set(this.exampleMetadata()?.files[0]);
this.changeDetector.detectChanges();
afterNextRender(
() => {
// Several function below query the DOM directly, we need to wait until the DOM is rendered.
this.setCodeLinesVisibility();
this.setCodeLinesVisibility();
this.elementRef.nativeElement.setAttribute(
'id',
`example-${this.exampleMetadata()?.id.toString()!}`,
);
this.elementRef.nativeElement.setAttribute(
'id',
`example-${this.exampleMetadata()?.id.toString()!}`,
this.matTabGroup?.realignInkBar();
this.listenToMatTabIndexChange();
const lines = this.getHiddenCodeLines();
const lineNumbers = this.getHiddenCodeLineNumbers();
this.expandable.set(lines.length > 0 || lineNumbers.length > 0);
},
{injector: this.injector},
);
this.matTabGroup?.realignInkBar();
this.listenToMatTabIndexChange();
}
toggleExampleVisibility(): void {
@@ -157,21 +164,9 @@ export class ExampleViewer {
}
private handleExpandedStateForCodeBlock(): void {
const lines = <HTMLDivElement[]>(
Array.from(
this.elementRef.nativeElement.querySelectorAll(
`.${CODE_LINE_CLASS_NAME}.${HIDDEN_CLASS_NAME}`,
),
)
);
const lines = this.getHiddenCodeLines();
const lineNumbers = <HTMLSpanElement[]>(
Array.from(
this.elementRef.nativeElement.querySelectorAll(
`.${CODE_LINE_NUMBER_CLASS_NAME}.${HIDDEN_CLASS_NAME}`,
),
)
);
const lineNumbers = this.getHiddenCodeLineNumbers();
const gapLines = <HTMLDivElement[]>(
Array.from(
@@ -239,4 +234,24 @@ export class ExampleViewer {
element.parentNode?.insertBefore(separator, element);
}
}
private getHiddenCodeLines(): HTMLDivElement[] {
return <HTMLDivElement[]>(
Array.from(
this.elementRef.nativeElement.querySelectorAll(
`.${CODE_LINE_CLASS_NAME}.${HIDDEN_CLASS_NAME}`,
),
)
);
}
private getHiddenCodeLineNumbers(): HTMLSpanElement[] {
return <HTMLSpanElement[]>(
Array.from(
this.elementRef.nativeElement.querySelectorAll(
`.${CODE_LINE_NUMBER_CLASS_NAME}.${HIDDEN_CLASS_NAME}`,
),
)
);
}
}
-28
View File
@@ -1,28 +0,0 @@
load("//tools:defaults.bzl", "ts_library")
package(default_visibility = ["//visibility:private"])
ts_library(
name = "constants",
srcs = [
"index.ts",
],
visibility = [
"//adev/shared-docs:__subpackages__",
],
deps = [
":lib",
],
)
ts_library(
name = "lib",
srcs = glob(
[
"*.ts",
],
exclude = [
"index.ts",
],
),
)
-1
View File
@@ -12,7 +12,6 @@
export * from './directives/index';
export * from './components/index';
export * from './constants/index';
export * from './interfaces/index';
export * from './providers/index';
export * from './services/index';
@@ -19,6 +19,4 @@ export interface TableOfContentsItem {
level: TableOfContentsLevel;
/** The unique title for this document page. */
title: string;
/** The top offset px of the heading */
top: number;
}
+8 -8
View File
@@ -3,13 +3,13 @@
"version": "0.0.0-PLACEHOLDER",
"peerDependencies": {
"@angular/cdk": "^19.2.0-next",
"@angular/common": "^19.1.0-next",
"@angular/core": "^19.1.0-next",
"@angular/forms": "^19.1.0-next",
"@angular/common": "^19.2.0-next",
"@angular/core": "^19.2.0-next",
"@angular/forms": "^19.2.0-next",
"@angular/material": "^19.2.0-next",
"@angular/platform-browser": "^19.1.0-next",
"@angular/router": "^19.1.0-next",
"@angular/ssr": "^19.1.0-next",
"@angular/platform-browser": "^19.2.0-next",
"@angular/router": "^19.2.0-next",
"@angular/ssr": "^19.2.0-next",
"algoliasearch": "^5.0.0",
"rxjs": "^7.8.1"
},
@@ -20,10 +20,10 @@
"fast-glob": "~3.3.2",
"fflate": "^0.8.2",
"html-entities": "~2.5.2",
"jsdom": "~25.0.0",
"jsdom": "~26.0.0",
"marked": "~15.0.0",
"mermaid": "^11.0.0",
"shiki": "^1.10.3"
"shiki": "^3.0.0"
},
"exports": {
"./styles/*": {
@@ -43,6 +43,7 @@ const MD_CTYPE_MAP: {[key in FileType]: string} = {
export function interpolateCodeExamples(entries: DocEntry[]): void {
for (const entry of entries) {
entry.rawComment = replaceExample(entry.rawComment);
entry.description = replaceExample(entry.description);
for (const jsdocTag of entry.jsdocTags) {
jsdocTag.comment = replaceExample(jsdocTag.comment);
@@ -15,7 +15,7 @@ const tsMdBlock = (code: string) => '```angular-ts\n' + code + '\n```';
const htmlMdBlock = (code: string) => '```angular-html\n' + code + '\n```';
const entriesBuilder = (comment: string): DocEntry[] => [
{jsdocTags: [], rawComment: comment} as unknown as DocEntry,
{jsdocTags: [], rawComment: comment, description: ''} as unknown as DocEntry,
];
const getComment = (entries: DocEntry[]) => entries[0].rawComment;
@@ -35,6 +35,7 @@ describe('interpolate_code_examples', () => {
},
],
rawComment: `{@example dummy/jsdocs_raw.ts region='function'}`,
description: `{@example dummy/jsdocs_raw.ts region='function'}`,
},
];
@@ -8,6 +8,7 @@
import {Renderer, Tokens} from 'marked';
import {codeToHtml} from '../shiki/shiki';
import {SECTION_HEADING, SECTION_SUB_HEADING} from '../styling/css-classes';
/**
* Custom renderer for marked that will be used to transform markdown files to HTML
@@ -55,21 +56,39 @@ export const renderer: Partial<Renderer> = {
<div class="docs-table docs-scroll-track-transparent">
<table>
<thead>
${this.tablerow({
text: header.map((cell) => this.tablecell(cell)).join(''),
})}
${this.tablerow({text: header.map((cell) => this.tablecell(cell)).join('')})}
</thead>
<tbody>
${rows
.map((row) =>
this.tablerow({
text: row.map((cell) => this.tablecell(cell)).join(''),
}),
)
.map((row) => this.tablerow({text: row.map((cell) => this.tablecell(cell)).join('')}))
.join('')}
</tbody>
</table>
</div>
`;
},
heading(this: Renderer, {text, depth, tokens}: Tokens.Heading) {
const id = text
.toLowerCase()
.replaceAll(' ', '-')
.replace(/[^a-z0-9-]/g, '');
// Since we have a code transformer `addApiLinksToHtml` which adds anchors
// to code blocks of known symbols, we add an additional `data-skip-anchor`
// attribute that prevents the transformation. This is needed since nested
// anchor tags are illegal and break the HTML.
const textRenderer = new Renderer();
textRenderer.codespan = ({text}) => `<code data-skip-anchor>${text}</code>`;
const parsedText = this.parser.parseInline(tokens, textRenderer);
// The template matches templates/section-heading.tsx
return `
<h${depth} id="${id}" class="${SECTION_HEADING} ${SECTION_SUB_HEADING}">
<a href="#${id}" aria-label="Link to ${text} section" tabIndex="-1">
${parsedText}
</a>
</h${depth}>
`;
},
};
@@ -8,13 +8,13 @@
// TODO(jelbourn): all of these CSS classes should use the `docs-` prefix.
export const API_REFERENCE_CONTAINER = 'docs-api';
export const PARAM_KEYWORD_CLASS_NAME = 'docs-param-keyword';
export const PARAM_GROUP_CLASS_NAME = 'docs-param-group';
export const REFERENCE_HEADER = 'docs-reference-header';
export const REFERENCE_MEMBERS = 'docs-reference-members';
export const REFERENCE_DEPRECATED = 'docs-reference-deprecated';
export const REFERENCE_MEMBERS_CONTAINER = 'docs-reference-members-container';
export const REFERENCE_MEMBER_CARD = 'docs-reference-member-card';
export const REFERENCE_MEMBER_CARD_HEADER = 'docs-reference-card-header';
export const REFERENCE_MEMBER_CARD_BODY = 'docs-reference-card-body';
@@ -24,3 +24,7 @@ export const HEADER_CLASS_NAME = 'docs-reference-header';
export const HEADER_ENTRY_CATEGORY = 'docs-reference-category';
export const HEADER_ENTRY_TITLE = 'docs-reference-title';
export const HEADER_ENTRY_LABEL = 'docs-api-item-label';
export const SECTION_CONTAINER = 'docs-reference-section';
export const SECTION_HEADING = 'docs-reference-section-heading';
export const SECTION_SUB_HEADING = 'docs-reference-section-heading--sub';
@@ -38,8 +38,6 @@ export function getCurrentSymbol(): string | undefined {
return currentSymbol;
}
export function logUnknownSymbol(link: string, symbol: string): void {
console.warn(
`WARNING: {@link ${link}} is invalid, ${symbol} or ${currentSymbol}.${symbol} is unknown in this context`,
);
export function unknownSymbolMessage(link: string, symbol: string): string {
return `WARNING: {@link ${link}} is invalid, ${symbol} or ${currentSymbol}.${symbol} is unknown in this context`;
}
@@ -13,7 +13,7 @@ import {
isPropertyEntry,
isSetterEntry,
} from '../entities/categorization';
import {MemberEntryRenderable} from '../entities/renderables';
import {MemberEntryRenderable, MethodEntryRenderable} from '../entities/renderables';
import {
REFERENCE_MEMBER_CARD,
REFERENCE_MEMBER_CARD_BODY,
@@ -27,20 +27,24 @@ import {getFunctionMetadataRenderable} from '../transforms/function-transforms';
import {CodeSymbol} from './code-symbols';
export function ClassMember(props: {member: MemberEntryRenderable}) {
const member = props.member;
const renderMethod = (method: MethodEntryRenderable) => {
const signature = method.signatures.length ? method.signatures : [method.implementation];
return signature.map((sig) => {
const renderableMember = getFunctionMetadataRenderable(sig);
return <ClassMethodInfo entry={renderableMember} options={{showUsageNotes: true}} />;
});
};
const body = (
<div className={REFERENCE_MEMBER_CARD_BODY}>
{isClassMethodEntry(props.member) ? (
(props.member.signatures.length
? props.member.signatures
: [props.member.implementation]
).map((sig) => {
const renderableMember = getFunctionMetadataRenderable(sig);
return <ClassMethodInfo entry={renderableMember} options={{showUsageNotes: true}} />;
})
) : props.member.htmlDescription || props.member.deprecationMessage ? (
{isClassMethodEntry(member) ? (
renderMethod(member)
) : member.htmlDescription || member.deprecationMessage ? (
<div className={REFERENCE_MEMBER_CARD_ITEM}>
<DeprecatedLabel entry={props.member} />
<RawHtml value={props.member.htmlDescription} />
<DeprecatedLabel entry={member} />
<RawHtml value={member.htmlDescription} />
</div>
) : (
<></>
@@ -48,23 +52,19 @@ export function ClassMember(props: {member: MemberEntryRenderable}) {
</div>
);
const memberName = props.member.name;
const returnType = getMemberType(props.member);
const memberName = member.name;
const returnType = getMemberType(member);
return (
<div id={memberName} className={REFERENCE_MEMBER_CARD} tabIndex={-1}>
<header>
<div className={REFERENCE_MEMBER_CARD_HEADER}>
<h3>{memberName}</h3>
<div>
{isClassMethodEntry(props.member) && props.member.signatures.length > 1 ? (
<span>{props.member.signatures.length} overloads</span>
) : returnType ? (
<CodeSymbol code={returnType} />
) : (
<></>
)}
</div>
</div>
<div id={memberName} className={REFERENCE_MEMBER_CARD}>
<header className={REFERENCE_MEMBER_CARD_HEADER}>
<h3>{memberName}</h3>
{isClassMethodEntry(member) && member.signatures.length > 1 ? (
<span>{member.signatures.length} overloads</span>
) : returnType ? (
<CodeSymbol code={returnType} />
) : (
<></>
)}
</header>
{body}
</div>
@@ -10,26 +10,26 @@ import {Fragment, h} from 'preact';
import {ClassEntryRenderable, DecoratorEntryRenderable} from '../entities/renderables';
import {ClassMemberList} from './class-member-list';
import {HeaderApi} from './header-api';
import {REFERENCE_MEMBERS_CONTAINER} from '../styling/css-classes';
import {TabDescription} from './tab-description';
import {TabUsageNotes} from './tab-usage-notes';
import {TabApi} from './tab-api';
import {API_REFERENCE_CONTAINER, REFERENCE_MEMBERS} from '../styling/css-classes';
import {SectionDescription} from './section-description';
import {SectionUsageNotes} from './section-usage-notes';
import {SectionApi} from './section-api';
/** Component to render a class API reference document. */
export function ClassReference(entry: ClassEntryRenderable | DecoratorEntryRenderable) {
return (
<div class="api">
<div className={API_REFERENCE_CONTAINER}>
<HeaderApi entry={entry} />
<TabApi entry={entry} />
<TabDescription entry={entry} />
<TabUsageNotes entry={entry} />
<SectionApi entry={entry} />
{entry.members.length > 0 ? (
<div class={REFERENCE_MEMBERS_CONTAINER}>
<div class={REFERENCE_MEMBERS}>
<ClassMemberList members={entry.members} />
</div>
) : (
<></>
)}
<SectionDescription entry={entry} />
<SectionUsageNotes entry={entry} />
</div>
);
}
@@ -9,17 +9,12 @@
import {Fragment, h} from 'preact';
import {CliCardRenderable} from '../entities/renderables';
import {DeprecatedLabel} from './deprecated-label';
import { REFERENCE_MEMBER_CARD, REFERENCE_MEMBER_CARD_HEADER } from '../styling/css-classes';
import {REFERENCE_MEMBER_CARD, REFERENCE_MEMBER_CARD_BODY} from '../styling/css-classes';
export function CliCard(props: {card: CliCardRenderable}) {
return (
<div id={props.card.type} class={REFERENCE_MEMBER_CARD} tabIndex={-1}>
<header>
<div class={REFERENCE_MEMBER_CARD_HEADER}>
<h3>{props.card.type}</h3>
</div>
</header>
<div class="docs-reference-card-body">
<div class={REFERENCE_MEMBER_CARD}>
<div className={REFERENCE_MEMBER_CARD_BODY}>
{props.card.items.map((item) => (
<div class="docs-ref-content">
{item.deprecated ? <DeprecatedLabel entry={item} /> : <></>}
@@ -6,55 +6,74 @@
* found in the LICENSE file at https://angular.dev/license
*/
import { Fragment, h } from 'preact';
import { CliCommandRenderable } from '../entities/renderables';
import { REFERENCE_MEMBERS, REFERENCE_MEMBERS_CONTAINER } from '../styling/css-classes';
import { CliCard } from './cli-card';
import { HeaderCli } from './header-cli';
import { RawHtml } from './raw-html';
import {Fragment, h} from 'preact';
import {CliCommandRenderable} from '../entities/renderables';
import {REFERENCE_MEMBERS} from '../styling/css-classes';
import {CliCard} from './cli-card';
import {HeaderCli} from './header-cli';
import {RawHtml} from './raw-html';
import {SectionHeading} from './section-heading';
/** Component to render a CLI command reference document. */
export function CliCommandReference(entry: CliCommandRenderable) {
return (
<div className="cli">
<div className="docs-cli">
<div className="docs-reference-cli-content">
<HeaderCli command={entry} />
{[entry.name, ...entry.aliases].map((command) =>
{[entry.name, ...entry.aliases].map((command) => (
<div class="docs-code docs-reference-cli-toc">
<pre class="docs-mini-scroll-track">
<code>
<div className={'shiki line cli'}>
ng {commandName(entry, command)}
{entry.argumentsLabel ? <button member-id={'Arguments'} className="shiki-ln-line-argument">{entry.argumentsLabel}</button> : <></>}
{entry.hasOptions ? <button member-id={'Options'} className="shiki-ln-line-option">[options]</button> : <></>}
{entry.argumentsLabel ? (
<button member-id={'Arguments'} className="shiki-ln-line-argument">
{entry.argumentsLabel}
</button>
) : (
<></>
)}
{entry.hasOptions ? (
<button member-id={'Options'} className="shiki-ln-line-option">
[options]
</button>
) : (
<></>
)}
</div>
</code>
</pre>
</div>
))}
<RawHtml value={entry.htmlDescription} />
{entry.subcommands && entry.subcommands?.length > 0 ? (
<>
<h3>Sub-commands</h3>
<p>This command has the following sub-commands</p>
<ul>
{entry.subcommands.map((subcommand) => (
<li>
<a href={`cli/${entry.name}/${subcommand.name}`}>{subcommand.name}</a>
</li>
))}
</ul>
</>
) : (
<></>
)}
<RawHtml value={entry.htmlDescription}/>
{entry.subcommands && entry.subcommands?.length > 0 ? <>
<h3>Sub-commands</h3>
<p>This command has the following sub-commands</p>
<ul>
{entry.subcommands.map((subcommand) =>
<li>
<a href={`cli/${entry.name}/${subcommand.name}`}>{subcommand.name}</a>
</li>
)}
</ul>
</> : <></>}
</div>
<div className={REFERENCE_MEMBERS_CONTAINER}>
<div className={REFERENCE_MEMBERS}>
{entry.cards.map((card) => <CliCard card={card} />)}
</div>
<div className={REFERENCE_MEMBERS}>
{entry.cards.map((card) => (
<>
<SectionHeading name={card.type} />
<CliCard card={card} />
</>
))}
</div>
</div>
);
}
function commandName(entry: CliCommandRenderable, command: string) {
if (entry.parentCommand?.name) {
return `${entry.parentCommand?.name} ${command}`;
@@ -9,18 +9,19 @@
import {h} from 'preact';
import {ConstantEntryRenderable} from '../entities/renderables';
import {HeaderApi} from './header-api';
import {TabDescription} from './tab-description';
import {TabUsageNotes} from './tab-usage-notes';
import {TabApi} from './tab-api';
import {SectionDescription} from './section-description';
import {SectionUsageNotes} from './section-usage-notes';
import {SectionApi} from './section-api';
import {API_REFERENCE_CONTAINER} from '../styling/css-classes';
/** Component to render a constant API reference document. */
export function ConstantReference(entry: ConstantEntryRenderable) {
return (
<div class="api">
<div className={API_REFERENCE_CONTAINER}>
<HeaderApi entry={entry} />
<TabApi entry={entry} />
<TabDescription entry={entry} />
<TabUsageNotes entry={entry} />
<SectionApi entry={entry} />
<SectionDescription entry={entry} />
<SectionUsageNotes entry={entry} />
</div>
);
}
@@ -9,14 +9,15 @@
import {h} from 'preact';
import {DocEntryRenderable} from '../entities/renderables';
import {HeaderApi} from './header-api';
import {TabDescription} from './tab-description';
import {SectionDescription} from './section-description';
import {API_REFERENCE_CONTAINER} from '../styling/css-classes';
/** Component to render a block or element API reference document. */
export function DocsReference(entry: DocEntryRenderable) {
return (
<div class="api">
<div className={API_REFERENCE_CONTAINER}>
<HeaderApi entry={entry} />
<TabDescription entry={entry} />
<SectionDescription entry={entry} />
</div>
);
}
@@ -9,29 +9,27 @@
import {h, Fragment} from 'preact';
import {EnumEntryRenderable, MemberEntryRenderable} from '../entities/renderables';
import {HeaderApi} from './header-api';
import {TabDescription} from './tab-description';
import {TabApi} from './tab-api';
import {REFERENCE_MEMBERS, REFERENCE_MEMBERS_CONTAINER} from '../styling/css-classes';
import {SectionDescription} from './section-description';
import {SectionApi} from './section-api';
import {API_REFERENCE_CONTAINER, REFERENCE_MEMBERS} from '../styling/css-classes';
import {ClassMember} from './class-member';
/** Component to render a enum API reference document. */
export function EnumReference(entry: EnumEntryRenderable) {
return (
<div class="api">
<div className={API_REFERENCE_CONTAINER}>
<HeaderApi entry={entry} />
<TabApi entry={entry} />
<TabDescription entry={entry} />
{
entry.members.length > 0
? (
<div class={REFERENCE_MEMBERS_CONTAINER}>
<div class={REFERENCE_MEMBERS}>
{entry.members.map((member: MemberEntryRenderable) => (<ClassMember member={member}/>))}
</div>
</div>
)
: (<></>)
}
<SectionApi entry={entry} />
{entry.members.length > 0 ? (
<div class={REFERENCE_MEMBERS}>
{entry.members.map((member: MemberEntryRenderable) => (
<ClassMember member={member} />
))}
</div>
) : (
<></>
)}
<SectionDescription entry={entry} />
</div>
);
}
@@ -6,20 +6,23 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {h} from 'preact';
import {FunctionEntryRenderable, FunctionSignatureMetadataRenderable} from '../entities/renderables';
import {h, Fragment} from 'preact';
import {
FunctionEntryRenderable,
FunctionSignatureMetadataRenderable,
} from '../entities/renderables';
import {
API_REFERENCE_CONTAINER,
REFERENCE_MEMBERS,
REFERENCE_MEMBERS_CONTAINER,
REFERENCE_MEMBER_CARD,
REFERENCE_MEMBER_CARD_BODY,
REFERENCE_MEMBER_CARD_HEADER,
} from '../styling/css-classes';
import {ClassMethodInfo} from './class-method-info';
import {HeaderApi} from './header-api';
import {TabApi} from './tab-api';
import {TabDescription} from './tab-description';
import {TabUsageNotes} from './tab-usage-notes';
import {SectionApi} from './section-api';
import {SectionDescription} from './section-description';
import {SectionUsageNotes} from './section-usage-notes';
import {HighlightTypeScript} from './highlight-ts';
import {printInitializerFunctionSignatureLine} from '../transforms/code-transforms';
import {getFunctionMetadataRenderable} from '../transforms/function-transforms';
@@ -32,8 +35,8 @@ export const signatureCard = (
printSignaturesAsHeader: boolean,
) => {
return (
<div class={REFERENCE_MEMBER_CARD} id={opts.id} tabIndex={-1}>
<header>
<div id={opts.id} class={REFERENCE_MEMBER_CARD}>
<header class={REFERENCE_MEMBER_CARD_HEADER}>
{printSignaturesAsHeader ? (
<code>
<HighlightTypeScript
@@ -46,12 +49,12 @@ export const signatureCard = (
/>
</code>
) : (
<div className={REFERENCE_MEMBER_CARD_HEADER}>
<>
<h3>{name}</h3>
<div>
<CodeSymbol code={signature.returnType} />
</div>
</div>
</>
)}
</header>
<div class={REFERENCE_MEMBER_CARD_BODY}>
@@ -67,25 +70,24 @@ export function FunctionReference(entry: FunctionEntryRenderable) {
const printSignaturesAsHeader = entry.signatures.length > 1;
return (
<div class="api">
<div className={API_REFERENCE_CONTAINER}>
<HeaderApi entry={entry} />
<TabApi entry={entry} />
<TabDescription entry={entry} />
<TabUsageNotes entry={entry} />
<div className={REFERENCE_MEMBERS_CONTAINER}>
<div className={REFERENCE_MEMBERS}>
{entry.signatures.map((s, i) =>
signatureCard(
s.name,
getFunctionMetadataRenderable(s, entry.moduleName),
{
id: `${s.name}_${i}`,
},
printSignaturesAsHeader,
),
)}
</div>
<SectionApi entry={entry} />
<div className={REFERENCE_MEMBERS}>
{entry.signatures.map((s, i) =>
signatureCard(
s.name,
getFunctionMetadataRenderable(s, entry.moduleName),
{
id: `${s.name}_${i}`,
},
printSignaturesAsHeader,
),
)}
</div>
<SectionDescription entry={entry} />
<SectionUsageNotes entry={entry} />
</div>
);
}
@@ -25,9 +25,7 @@ export function HeaderApi(props: {entry: DocEntryRenderable; showFullDescription
// When ADEV is not deployed on the main branch branch anymore,
// We should update it to point to the tag of the released version which ADEV runs on.
const sourceUrl = isDocEntryWithSourceInfo(entry)
? `https://github.com/angular/angular/blob/main${entry.source.filePath}#L${entry.source.startLine}-L${entry.source.endLine}`
: null;
const sourceUrl = sourceUrlForEntry(entry);
return (
<header className={HEADER_CLASS_NAME}>
@@ -40,9 +38,7 @@ export function HeaderApi(props: {entry: DocEntryRenderable; showFullDescription
{getEntryTypeDisplayName(entry.entryType)}
</div>
{entry.isDeprecated && (
<div className={`${HEADER_ENTRY_LABEL} type-deprecated full`}>
Deprecated
</div>
<div className={`${HEADER_ENTRY_LABEL} type-deprecated full`}>Deprecated</div>
)}
{entry.isDeveloperPreview && (
<div className={`${HEADER_ENTRY_LABEL} type-developer_preview full`}>
@@ -95,3 +91,16 @@ function getEntryTypeDisplayName(entryType: EntryType | string): string {
}
return entryType;
}
function sourceUrlForEntry(entry: DocEntryRenderable): string | null {
if (!isDocEntryWithSourceInfo(entry)) {
return null;
}
if (entry.source.filePath.includes('node_modules')) {
// We don't know the source path in external repos link the CLI
return null;
} else {
return `https://github.com/angular/angular/blob/main${entry.source.filePath}#L${entry.source.startLine}-L${entry.source.endLine}`;
}
}
@@ -9,9 +9,9 @@
import {h, JSX} from 'preact';
import {InitializerApiFunctionRenderable} from '../entities/renderables';
import {HeaderApi} from './header-api';
import {TabApi} from './tab-api';
import {TabUsageNotes} from './tab-usage-notes';
import {REFERENCE_MEMBERS, REFERENCE_MEMBERS_CONTAINER} from '../styling/css-classes';
import {SectionApi} from './section-api';
import {SectionUsageNotes} from './section-usage-notes';
import {API_REFERENCE_CONTAINER, REFERENCE_MEMBERS} from '../styling/css-classes';
import {getFunctionMetadataRenderable} from '../transforms/function-transforms';
import {signatureCard} from './function-reference';
@@ -34,42 +34,41 @@ export function InitializerApiFunction(entry: InitializerApiFunctionRenderable)
}
return (
<div class="api">
<div className={API_REFERENCE_CONTAINER}>
<HeaderApi entry={entry} showFullDescription={true} />
<TabApi entry={entry} />
<TabUsageNotes entry={entry} />
<SectionApi entry={entry} />
<div class={REFERENCE_MEMBERS_CONTAINER}>
<div class={REFERENCE_MEMBERS}>
{entry.callFunction.signatures.map((s, i) =>
signatureCard(
s.name,
getFunctionMetadataRenderable(s, entry.moduleName),
{
id: `${s.name}_${i}`,
},
printSignaturesAsHeader,
),
)}
<div class={REFERENCE_MEMBERS}>
{entry.callFunction.signatures.map((s, i) =>
signatureCard(
s.name,
getFunctionMetadataRenderable(s, entry.moduleName),
{
id: `${s.name}_${i}`,
},
printSignaturesAsHeader,
),
)}
{entry.subFunctions.reduce(
(elements, subFunction) => [
...elements,
...subFunction.signatures.map((s, i) =>
signatureCard(
`${entry.name}.${s.name}`,
getFunctionMetadataRenderable(s, entry.moduleName),
{
id: `${entry.name}_${s.name}_${i}`,
},
printSignaturesAsHeader,
),
{entry.subFunctions.reduce(
(elements, subFunction) => [
...elements,
...subFunction.signatures.map((s, i) =>
signatureCard(
`${entry.name}.${s.name}`,
getFunctionMetadataRenderable(s, entry.moduleName),
{
id: `${entry.name}_${s.name}_${i}`,
},
printSignaturesAsHeader,
),
],
[] as JSX.Element[],
)}
</div>
),
],
[] as JSX.Element[],
)}
</div>
<SectionUsageNotes entry={entry} />
</div>
);
}
@@ -0,0 +1,26 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {h} from 'preact';
import {DocEntryRenderable} from '../entities/renderables';
import {HasRenderableToc} from '../entities/traits';
import {CodeTableOfContents} from './code-table-of-contents';
import {SECTION_CONTAINER} from '../styling/css-classes';
import {SectionHeading} from './section-heading';
const API_SECTION_NAME = 'API';
/** Component to render the API section. */
export function SectionApi(props: {entry: DocEntryRenderable & HasRenderableToc}) {
return (
<div className={SECTION_CONTAINER + ' docs-reference-api-section'}>
<SectionHeading name={API_SECTION_NAME} />
<CodeTableOfContents entry={props.entry} />
</div>
);
}
@@ -8,14 +8,15 @@
import {Fragment, h} from 'preact';
import {DocEntryRenderable} from '../entities/renderables';
import {normalizeTabUrl} from '../transforms/url-transforms';
import {RawHtml} from './raw-html';
import {CodeSymbol} from './code-symbols';
import {SECTION_CONTAINER} from '../styling/css-classes';
import {SectionHeading} from './section-heading';
const DESCRIPTION_TAB_NAME = 'Description';
const DESCRIPTION_SECTION_NAME = 'Description';
/** Component to render the description tab. */
export function TabDescription(props: {entry: DocEntryRenderable}) {
/** Component to render the description section. */
export function SectionDescription(props: {entry: DocEntryRenderable}) {
const exportedBy = props.entry.jsdocTags.filter((t) => t.name === 'ngModule');
if (
(!props.entry.htmlDescription ||
@@ -26,7 +27,8 @@ export function TabDescription(props: {entry: DocEntryRenderable}) {
}
return (
<div data-tab={DESCRIPTION_TAB_NAME} data-tab-url={normalizeTabUrl(DESCRIPTION_TAB_NAME)}>
<div className={SECTION_CONTAINER}>
<SectionHeading name={DESCRIPTION_SECTION_NAME} />
<RawHtml value={props.entry.htmlDescription} />
{exportedBy.length ? (
@@ -0,0 +1,25 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {h} from 'preact';
import {convertSectionNameToId} from '../transforms/reference-section-id';
import {SECTION_HEADING} from '../styling/css-classes';
/** Component to render the API section. */
export function SectionHeading(props: {name: string}) {
const id = convertSectionNameToId(props.name);
const label = 'Link to ' + props.name + ' section';
return (
<h2 id={id} class={SECTION_HEADING}>
<a href={'#' + id} aria-label={label} tabIndex={-1}>
{props.name}
</a>
</h2>
);
}
@@ -8,19 +8,21 @@
import {Fragment, h} from 'preact';
import {DocEntryRenderable} from '../entities/renderables';
import {normalizeTabUrl} from '../transforms/url-transforms';
import {RawHtml} from './raw-html';
import {SECTION_CONTAINER} from '../styling/css-classes';
import {SectionHeading} from './section-heading';
const USAGE_NOTES_TAB_NAME = 'Usage Notes';
const USAGE_NOTES_SECTION_NAME = 'Usage Notes';
/** Component to render the usage notes tab. */
export function TabUsageNotes(props: {entry: DocEntryRenderable}) {
/** Component to render the usage notes section. */
export function SectionUsageNotes(props: {entry: DocEntryRenderable}) {
if (!props.entry.htmlUsageNotes) {
return (<></>);
return <></>;
}
return (
<div data-tab={USAGE_NOTES_TAB_NAME} data-tab-url={normalizeTabUrl(USAGE_NOTES_TAB_NAME)}>
<div className={SECTION_CONTAINER}>
<SectionHeading name={USAGE_NOTES_SECTION_NAME} />
<RawHtml value={props.entry.htmlUsageNotes} />
</div>
);
@@ -1,26 +0,0 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {h} from 'preact';
import {DocEntryRenderable} from '../entities/renderables';
import {HasRenderableToc} from '../entities/traits';
import {normalizeTabUrl} from '../transforms/url-transforms';
import {CodeTableOfContents} from './code-table-of-contents';
const API_TAB_NAME = 'API';
/** Component to render the API tab. */
export function TabApi(props: {entry: DocEntryRenderable & HasRenderableToc}) {
return (
<div data-tab={API_TAB_NAME} data-tab-url={normalizeTabUrl(API_TAB_NAME)}>
<div class={'docs-reference-api-tab'}>
<CodeTableOfContents entry={props.entry} />
</div>
</div>
);
}
@@ -9,18 +9,19 @@
import {h} from 'preact';
import {TypeAliasEntryRenderable} from '../entities/renderables';
import {HeaderApi} from './header-api';
import {TabDescription} from './tab-description';
import {TabUsageNotes} from './tab-usage-notes';
import {TabApi} from './tab-api';
import {SectionDescription} from './section-description';
import {SectionUsageNotes} from './section-usage-notes';
import {SectionApi} from './section-api';
import {API_REFERENCE_CONTAINER} from '../styling/css-classes';
/** Component to render a type alias API reference document. */
export function TypeAliasReference(entry: TypeAliasEntryRenderable) {
return (
<div class="api">
<div className={API_REFERENCE_CONTAINER}>
<HeaderApi entry={entry} />
<TabApi entry={entry} />
<TabDescription entry={entry} />
<TabUsageNotes entry={entry} />
<SectionApi entry={entry} />
<SectionDescription entry={entry} />
<SectionUsageNotes entry={entry} />
</div>
);
}
@@ -754,6 +754,525 @@
"startLine": 112,
"endLine": 115
}
},
{
"name": "HttpRequest",
"isAbstract": false,
"entryType": "undecorated_class",
"members": [
{
"name": "constructor",
"signatures": [
{
"name": "constructor",
"params": [
{
"name": "method",
"description": "",
"type": "\"GET\" | \"HEAD\"",
"isOptional": false,
"isRestParam": false
},
{
"name": "url",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "init",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
"isOptional": true,
"isRestParam": false
}
],
"returnType": "foobar",
"description": "",
"entryType": "function",
"jsdocTags": [],
"rawComment": "",
"generics": [],
"isNewType": false
},
{
"name": "constructor",
"params": [
{
"name": "method",
"description": "",
"type": "\"DELETE\" | \"JSONP\" | \"OPTIONS\"",
"isOptional": false,
"isRestParam": false
},
{
"name": "url",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "init",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; } | undefined",
"isOptional": true,
"isRestParam": false
}
],
"returnType": "foobar",
"description": "",
"entryType": "function",
"jsdocTags": [],
"rawComment": "",
"generics": [],
"isNewType": false
},
{
"name": "constructor",
"params": [
{
"name": "method",
"description": "",
"type": "\"POST\"",
"isOptional": false,
"isRestParam": false
},
{
"name": "url",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "body",
"description": "",
"type": "T | null",
"isOptional": false,
"isRestParam": false
},
{
"name": "init",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
"isOptional": true,
"isRestParam": false
}
],
"returnType": "foobar",
"description": "",
"entryType": "function",
"jsdocTags": [],
"rawComment": "",
"generics": [],
"isNewType": false
},
{
"name": "constructor",
"params": [
{
"name": "method",
"description": "",
"type": "\"PUT\" | \"PATCH\"",
"isOptional": false,
"isRestParam": false
},
{
"name": "url",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "body",
"description": "",
"type": "T | null",
"isOptional": false,
"isRestParam": false
},
{
"name": "init",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; } | undefined",
"isOptional": true,
"isRestParam": false
}
],
"returnType": "foobar",
"description": "",
"entryType": "function",
"jsdocTags": [],
"rawComment": "",
"generics": [],
"isNewType": false
},
{
"name": "constructor",
"params": [
{
"name": "method",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "url",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "body",
"description": "",
"type": "T | null",
"isOptional": false,
"isRestParam": false
},
{
"name": "init",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
"isOptional": true,
"isRestParam": false
}
],
"returnType": "foobar",
"description": "",
"entryType": "function",
"jsdocTags": [],
"rawComment": "",
"generics": [],
"isNewType": false
},
{
"name": "constructor",
"params": [
{
"name": "method",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "url",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "third",
"description": "",
"type": "T | { headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | null | undefined",
"isOptional": true,
"isRestParam": false
},
{
"name": "fourth",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
"isOptional": true,
"isRestParam": false
}
],
"returnType": "foobar",
"description": "",
"entryType": "function",
"jsdocTags": [],
"rawComment": "",
"generics": [],
"isNewType": false
}
],
"implementation": {
"params": [
{
"name": "method",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "url",
"description": "",
"type": "string",
"isOptional": false,
"isRestParam": false
},
{
"name": "third",
"description": "",
"type": "T | { headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | null | undefined",
"isOptional": true,
"isRestParam": false
},
{
"name": "fourth",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
"isOptional": true,
"isRestParam": false
}
],
"isNewType": false,
"returnType": "HttpRequest<T>",
"generics": [],
"name": "constructor",
"description": "",
"entryType": "function",
"jsdocTags": [],
"rawComment": ""
},
"entryType": "function",
"description": "",
"jsdocTags": [],
"rawComment": "",
"memberType": "method",
"memberTags": []
},
{
"name": "body",
"type": "T | null",
"memberType": "property",
"memberTags": ["readonly"],
"description": "The request body, or `null` if one isn't set.\n\nBodies are not enforced to be immutable, as they can include a reference to any\nuser-defined data type. However, interceptors should take care to preserve\nidempotence by treating them as such.",
"jsdocTags": []
},
{
"name": "headers",
"type": "HttpHeaders",
"memberType": "property",
"memberTags": ["readonly"],
"description": "Outgoing headers for this request.",
"jsdocTags": []
},
{
"name": "context",
"type": "HttpContext",
"memberType": "property",
"memberTags": ["readonly"],
"description": "Shared and mutable context that can be used by interceptors",
"jsdocTags": []
},
{
"name": "reportProgress",
"type": "boolean",
"memberType": "property",
"memberTags": ["readonly"],
"description": "Whether this request should be made in a way that exposes progress events.\n\nProgress events are expensive (change detection runs on each event) and so\nthey should only be requested if the consumer intends to monitor them.\n\nNote: The `FetchBackend` doesn't support progress report on uploads.",
"jsdocTags": []
},
{
"name": "withCredentials",
"type": "boolean",
"memberType": "property",
"memberTags": ["readonly"],
"description": "Whether this request should be sent with outgoing credentials (cookies).",
"jsdocTags": []
},
{
"name": "responseType",
"type": "\"arraybuffer\" | \"blob\" | \"text\" | \"json\"",
"memberType": "property",
"memberTags": ["readonly"],
"description": "The expected response type of the server.\n\nThis is used to parse the response appropriately before returning it to\nthe requestee.",
"jsdocTags": []
},
{
"name": "method",
"type": "string",
"memberType": "property",
"memberTags": ["readonly"],
"description": "The outgoing HTTP request method.",
"jsdocTags": []
},
{
"name": "params",
"type": "HttpParams",
"memberType": "property",
"memberTags": ["readonly"],
"description": "Outgoing URL parameters.\n\nTo pass a string representation of HTTP parameters in the URL-query-string format,\nthe `HttpParamsOptions`' `fromString` may be used. For example:\n\n```ts\nnew HttpParams({fromString: 'angular=awesome'})\n```",
"jsdocTags": []
},
{
"name": "urlWithParams",
"type": "string",
"memberType": "property",
"memberTags": ["readonly"],
"description": "The outgoing URL with all URL parameters set.",
"jsdocTags": []
},
{
"name": "transferCache",
"type": "boolean | { includeHeaders?: string[] | undefined; } | undefined",
"memberType": "property",
"memberTags": ["readonly", "optional"],
"description": "The HttpTransferCache option for the request",
"jsdocTags": []
},
{
"name": "serializeBody",
"signatures": [
{
"name": "serializeBody",
"entryType": "function",
"description": "Transform the free-form body into a serialized format suitable for\ntransmission to the server.",
"generics": [],
"isNewType": false,
"jsdocTags": [],
"params": [],
"rawComment": "/**\n * Transform the free-form body into a serialized format suitable for\n * transmission to the server.\n */",
"returnType": "string | ArrayBuffer | Blob | FormData | URLSearchParams | null"
}
],
"implementation": {
"params": [],
"isNewType": false,
"returnType": "string | ArrayBuffer | Blob | FormData | URLSearchParams | null",
"generics": [],
"name": "serializeBody",
"description": "Transform the free-form body into a serialized format suitable for\ntransmission to the server.",
"entryType": "function",
"jsdocTags": [],
"rawComment": "/**\n * Transform the free-form body into a serialized format suitable for\n * transmission to the server.\n */"
},
"entryType": "function",
"description": "Transform the free-form body into a serialized format suitable for\ntransmission to the server.",
"jsdocTags": [],
"rawComment": "/**\n * Transform the free-form body into a serialized format suitable for\n * transmission to the server.\n */",
"memberType": "method",
"memberTags": []
},
{
"name": "detectContentTypeHeader",
"signatures": [
{
"name": "detectContentTypeHeader",
"entryType": "function",
"description": "Examine the body and attempt to infer an appropriate MIME type\nfor it.\n\nIf no such type can be inferred, this method will return `null`.",
"generics": [],
"isNewType": false,
"jsdocTags": [],
"params": [],
"rawComment": "/**\n * Examine the body and attempt to infer an appropriate MIME type\n * for it.\n *\n * If no such type can be inferred, this method will return `null`.\n */",
"returnType": "string | null"
}
],
"implementation": {
"params": [],
"isNewType": false,
"returnType": "string | null",
"generics": [],
"name": "detectContentTypeHeader",
"description": "Examine the body and attempt to infer an appropriate MIME type\nfor it.\n\nIf no such type can be inferred, this method will return `null`.",
"entryType": "function",
"jsdocTags": [],
"rawComment": "/**\n * Examine the body and attempt to infer an appropriate MIME type\n * for it.\n *\n * If no such type can be inferred, this method will return `null`.\n */"
},
"entryType": "function",
"description": "Examine the body and attempt to infer an appropriate MIME type\nfor it.\n\nIf no such type can be inferred, this method will return `null`.",
"jsdocTags": [],
"rawComment": "/**\n * Examine the body and attempt to infer an appropriate MIME type\n * for it.\n *\n * If no such type can be inferred, this method will return `null`.\n */",
"memberType": "method",
"memberTags": []
},
{
"name": "clone",
"signatures": [
{
"name": "clone",
"entryType": "function",
"description": "",
"generics": [],
"isNewType": false,
"jsdocTags": [],
"params": [],
"rawComment": "",
"returnType": "HttpRequest<T>"
},
{
"name": "clone",
"entryType": "function",
"description": "",
"generics": [],
"isNewType": false,
"jsdocTags": [],
"params": [
{
"name": "update",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; body?: T | null | undefined; method?: string | undefined; url?: string | undefined; setHeaders?: { [name: string]: string | string[]; } | undefined; setParams?: { [param: string]: string; } | undefined; }",
"isOptional": false,
"isRestParam": false
}
],
"rawComment": "",
"returnType": "HttpRequest<T>"
},
{
"name": "clone",
"entryType": "function",
"description": "",
"generics": [{"name": "V"}],
"isNewType": false,
"jsdocTags": [],
"params": [
{
"name": "update",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; body?: V | null | undefined; method?: string | undefined; url?: string | undefined; setHeaders?: { [name: string]: string | string[]; } | undefined; setParams?: { [param: string]: string; } | undefined; }",
"isOptional": false,
"isRestParam": false
}
],
"rawComment": "",
"returnType": "HttpRequest<V>"
}
],
"implementation": {
"params": [
{
"name": "update",
"description": "",
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; body?: any; method?: string | undefined; url?: string | undefined; setHeaders?: { [name: string]: string | string[]; } | undefined; setParams?: { [param: string]: string; } | undefined; }",
"isOptional": true,
"isRestParam": false
}
],
"isNewType": false,
"returnType": "HttpRequest<any>",
"generics": [],
"name": "clone",
"description": "",
"entryType": "function",
"jsdocTags": [],
"rawComment": ""
},
"entryType": "function",
"description": "",
"jsdocTags": [],
"rawComment": "",
"memberType": "method",
"memberTags": []
}
],
"generics": [{"name": "T"}],
"description": "An outgoing HTTP request with an optional typed body.\n\n`HttpRequest` represents an outgoing request, including URL, method,\nheaders, body, and other request configuration options. Instances should be\nassumed to be immutable. To modify a `HttpRequest`, the `clone`\nmethod should be used.",
"jsdocTags": [{"name": "publicApi", "comment": ""}],
"rawComment": "/**\n * An outgoing HTTP request with an optional typed body.\n *\n * `HttpRequest` represents an outgoing request, including URL, method,\n * headers, body, and other request configuration options. Instances should be\n * assumed to be immutable. To modify a `HttpRequest`, the `clone`\n * method should be used.\n *\n * @publicApi\n */",
"implements": [],
"source": {
"filePath": "/packages/common/http/src/request.ts",
"startLine": 131,
"endLine": 578
}
}
]
}
@@ -34,6 +34,13 @@ describe('markdown to html', () => {
const symbols = new Map<string, string>([
['AfterRenderPhase', 'core'],
['afterRender', 'core'],
['EmbeddedViewRef', 'core'],
['ChangeDetectionStrategy', 'core'],
['ChangeDetectorRef', 'core'],
['withNoHttpTransferCache', 'platform-browser'],
['withHttpTransferCacheOptions', 'platform-browser'],
['withI18nSupport', 'platform-browser'],
['withEventReplay', 'platform-browser'],
]);
setSymbols(symbols);
for (const entry of entryJson.entries) {
@@ -12,6 +12,7 @@ import {getRenderable} from '../processing';
import {DocEntryRenderable} from '../entities/renderables';
import {initHighlighter} from '../shiki/shiki';
import {configureMarkedGlobally} from '../marked/configuration';
import {setSymbols} from '../symbol-context';
// Note: The tests will probably break if the schema of the api extraction changes.
// All entries in the fake-entries are extracted from Angular's api.
@@ -28,6 +29,19 @@ describe('renderable', () => {
encoding: 'utf-8',
});
const entryJson = JSON.parse(entryContent) as any;
const symbols = new Map<string, string>([
['AfterRenderPhase', 'core'],
['afterRender', 'core'],
['EmbeddedViewRef', 'core'],
['ChangeDetectionStrategy', 'core'],
['ChangeDetectorRef', 'core'],
['withNoHttpTransferCache', 'platform-browser'],
['withHttpTransferCacheOptions', 'platform-browser'],
['withI18nSupport', 'platform-browser'],
['withEventReplay', 'platform-browser'],
]);
setSymbols(symbols);
for (const entry of entryJson.entries) {
const renderableJson = getRenderable(entry, '@angular/fakeentry') as DocEntryRenderable;
entries.set(entry['name'], renderableJson);
@@ -66,6 +66,14 @@ describe('jsdoc transforms', () => {
name: 'see',
comment: '{@link https://angular.dev}',
},
{
name: 'see',
comment: '{@link /cli/build ng build}',
},
{
name: 'see',
comment: '{@link /ecosystem/rxjs-interop/output-interop Output Interop}',
},
],
moduleName: 'test',
});
@@ -117,5 +125,30 @@ describe('jsdoc transforms', () => {
label: 'angular.dev',
url: 'https://angular.dev',
});
expect(entry.additionalLinks[10]).toEqual({
label: 'ng build',
url: '/cli/build',
});
expect(entry.additionalLinks[11]).toEqual({
label: 'Output Interop',
url: '/ecosystem/rxjs-interop/output-interop',
});
});
it('should throw on invalid relatie @link', () => {
const entryFn = () =>
addHtmlAdditionalLinks({
jsdocTags: [
{
name: 'see',
comment: '{@link cli/build ng build}',
},
],
moduleName: 'test',
});
expect(entryFn).toThrowError(/Forbidden relative link: cli\/build ng build/);
});
});
@@ -476,10 +476,11 @@ function appendPrefixAndSuffix(entry: DocEntry, codeTocData: CodeTableOfContents
*/
export function addApiLinksToHtml(htmlString: string): string {
const result = htmlString.replace(
// This regex looks for span/code blocks not wrapped by an anchor block.
// This regex looks for span/code blocks not wrapped by an anchor block
// or the tag doesn't contain `data-skip-anchor` attribute.
// Their content are then replaced with a link if the symbol is known
// The captured content ==> vvvvvvvv
/(?<!<a[^>]*>)(<(?:(?:span)|(?:code))[^>]*>\s*)([^<]*?)(\s*<\/(?:span|code)>)/g,
// The captured content ==> vvvvvvvv
/(?<!<a[^>]*>)(<(?:(?:span)|(?:code))(?!\sdata-skip-anchor)[^>]*>\s*)([^<]*?)(\s*<\/(?:span|code)>)/g,
(type: string, span1: string, potentialSymbolName: string, span2: string) => {
let [symbol, subSymbol] = potentialSymbolName.split(/(?:#|\.)/) as [string, string?];
@@ -31,7 +31,7 @@ import {
import {getLinkToModule} from './url-transforms';
import {addApiLinksToHtml} from './code-transforms';
import {getCurrentSymbol, getModuleName, logUnknownSymbol} from '../symbol-context';
import {getCurrentSymbol, getModuleName, unknownSymbolMessage} from '../symbol-context';
export const JS_DOC_REMARKS_TAG = 'remarks';
export const JS_DOC_USAGE_NOTES_TAG = 'usageNotes';
@@ -58,16 +58,10 @@ export function addHtmlDescription<T extends HasDescription & HasModuleName>(
const description = !!entry.description ? entry.description : jsDocDescription;
const shortTextMatch = description.match(firstParagraphRule);
const htmlDescription = getHtmlForJsDocText(description, entry).trim();
const shortHtmlDescription = getHtmlForJsDocText(
shortTextMatch ? shortTextMatch[0] : '',
entry,
).trim();
return {
...entry,
htmlDescription,
shortHtmlDescription,
};
const htmlDescription = getHtmlForJsDocText(description).trim();
const shortHtmlDescription = getHtmlForJsDocText(shortTextMatch ? shortTextMatch[0] : '').trim();
return {...entry, htmlDescription, shortHtmlDescription};
}
/**
@@ -81,7 +75,7 @@ export function addHtmlJsDocTagComments<T extends HasJsDocTags & HasModuleName>(
...entry,
jsdocTags: entry.jsdocTags.map((tag) => ({
...tag,
htmlComment: getHtmlForJsDocText(tag.comment, entry),
htmlComment: getHtmlForJsDocText(tag.comment),
})),
};
}
@@ -100,20 +94,16 @@ export function addHtmlUsageNotes<T extends HasJsDocTags>(entry: T): T & HasHtml
const usageNotesTag = entry.jsdocTags.find(
({name}) => name === JS_DOC_USAGE_NOTES_TAG || name === JS_DOC_REMARKS_TAG,
);
const htmlUsageNotes = usageNotesTag
? (marked.parse(wrapExampleHtmlElementsWithCode(usageNotesTag.comment)) as string)
: '';
const transformedHtml = addApiLinksToHtml(htmlUsageNotes);
const htmlUsageNotes = usageNotesTag ? getHtmlForJsDocText(usageNotesTag.comment) : '';
return {
...entry,
htmlUsageNotes: transformedHtml,
htmlUsageNotes,
};
}
/** Given a markdown JsDoc text, gets the rendered HTML. */
function getHtmlForJsDocText<T extends HasModuleName>(text: string, entry: T): string {
function getHtmlForJsDocText(text: string): string {
const parsed = marked.parse(convertLinks(wrapExampleHtmlElementsWithCode(text))) as string;
return addApiLinksToHtml(parsed);
}
@@ -126,7 +116,7 @@ export function setEntryFlags<T extends HasJsDocTags & HasModuleName>(
...entry,
isDeprecated: isDeprecatedEntry(entry),
deprecationMessage: deprecationMessage
? getHtmlForJsDocText(deprecationMessage, entry)
? getHtmlForJsDocText(deprecationMessage)
: deprecationMessage,
isDeveloperPreview: isDeveloperPreview(entry),
isExperimental: isExperimental(entry),
@@ -195,10 +185,16 @@ function parseAtLink(link: string): {label: string; url: string} {
let [rawSymbol, description] = link.split(/\s(.+)/);
if (rawSymbol.startsWith('#')) {
rawSymbol = rawSymbol.substring(1);
} else if (rawSymbol.startsWith('http://') || rawSymbol.startsWith('https://')) {
} else if (rawSymbol.includes('/')) {
if (!rawSymbol.startsWith('/') && !rawSymbol.startsWith('http')) {
throw Error(
`Forbidden relative link: ${link}. Links should be absolute and start with a slash`,
);
}
return {
url: rawSymbol,
label: rawSymbol.split('/').pop()!,
label: description ?? rawSymbol.split('/').pop()!,
};
}
@@ -214,11 +210,9 @@ function parseAtLink(link: string): {label: string; url: string} {
moduleName = getModuleName(`${currentSymbol}.${symbol}`);
if (!moduleName || !currentSymbol) {
// TODO: remove the links that generate this error
// TODO: throw an error when there are no more warning generated
logUnknownSymbol(link, symbol);
return {label, url: '#'};
throw unknownSymbolMessage(link, symbol);
}
subSymbol = symbol;
symbol = currentSymbol;
}
@@ -0,0 +1,14 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export const convertSectionNameToId = (sectionName: string): string => {
return sectionName
.toLowerCase()
.replace(/\s|\//g, '-') // remove spaces and slashes
.replace(/[^0-9a-z\-]/g, ''); // only keep letters, digits & dashes
};
@@ -19,15 +19,3 @@ export const normalizePath = (path: string): string => {
}
return path;
};
export const normalizeTabUrl = (tabName: string): string => {
return tabName
.toLowerCase()
.replace(/<code>(.*?)<\/code>/g, '$1') // remove <code>
.replace(/<strong>(.*?)<\/strong>/g, '$1') // remove <strong>
.replace(/<em>(.*?)<\/em>/g, '$1') // remove <em>
.replace(/\s|\//g, '-') // remove spaces and slashes
.replace(/gt;|lt;/g, '') // remove escaped < and >
.replace(/&#\d+;/g, '') // remove HTML entities
.replace(/[^0-9a-zA-Z\-]/g, ''); // only keep letters, digits & dashes
};
@@ -21,7 +21,7 @@
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"builder": "@angular/build:application",
"options": {
"outputPath": "dist/example-app",
"index": "src/index.html",
@@ -66,7 +66,7 @@
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"browserTarget": "example-app:build:production"
@@ -78,13 +78,13 @@
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"builder": "@angular/build:extract-i18n",
"options": {
"browserTarget": "example-app:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular/build:karma",
"options": {
"main": "src/test.ts",
"polyfills": ["zone.js", "zone.js/testing"],
@@ -23,7 +23,7 @@
"zone.js": "~0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.0.0",
"@angular/build": "^19.0.0",
"@angular/cli": "^19.0.0",
"@angular/compiler-cli": "^19.0.0",
"@types/jasmine": "~3.10.0",
@@ -7,7 +7,7 @@
*/
import {Token, Tokens, RendererThis, TokenizerThis} from 'marked';
import {formatHeading, headingRender} from '../../tranformations/heading';
import {formatHeading} from '../../tranformations/heading';
interface DocsStepToken extends Tokens.Generic {
type: 'docs-step';
@@ -1,14 +0,0 @@
```mermaid
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
```
```mermaid
pie title Pets adopted by volunteers
"Dogs" : 386
"Cats" : 85
"Rats" : 15
```
@@ -20,9 +20,24 @@ describe('markdown to html', () => {
// Extend the timeout interval tyo 15 seconds because we were seeing issues with not being able to run marked
// within the default timeframe.
jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000;
const markdownContent = await readFile(runfiles.resolvePackageRelative('./mermaid.md'), {
encoding: 'utf-8',
});
// This test was flaky, 1st attemp to fix it is by inlining the markdown content
const markdownContent = `
\`\`\`mermaid
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
\`\`\`
\`\`\`mermaid
pie title Pets adopted by volunteers
"Dogs" : 386
"Cats" : 85
"Rats" : 15
\`\`\`
`;
marked.use({
async: true,
@@ -39,7 +39,7 @@
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"builder": "@angular/build:application",
"options": {
"outputPath": "dist/first-app",
"index": "src/index.html",
@@ -76,7 +76,7 @@
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "first-app:build:production"
@@ -88,7 +88,7 @@
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"builder": "@angular/build:extract-i18n",
"options": {
"buildTarget": "first-app:build"
}
File diff suppressed because it is too large Load Diff
@@ -3,7 +3,7 @@
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "NG_BUILD_PARALLEL_TS=0 ng serve",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development"
},
@@ -15,12 +15,12 @@
"@angular/platform-browser": "^19.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.0"
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.0.0",
"@angular/build": "^19.0.0",
"@angular/cli": "^19.0.0",
"@angular/compiler-cli": "^19.0.0",
"typescript": "~5.6.3"
"typescript": "~5.7.3"
}
}
-1
View File
@@ -25,7 +25,6 @@ ng_module(
],
),
deps = [
"//adev/shared-docs/constants",
"//adev/shared-docs/interfaces",
"//adev/shared-docs/providers",
"//adev/shared-docs/utils",
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {Injectable, inject, signal} from '@angular/core';
import {Injectable, inject, linkedSignal, signal} from '@angular/core';
import {NavigationItem} from '../interfaces/index';
import {Router} from '@angular/router';
@@ -19,11 +19,13 @@ export class NavigationState {
private readonly _activeNavigationItem = signal<NavigationItem | null>(null);
private readonly _expandedItems = signal<NavigationItem[]>([]);
private readonly _isMobileNavVisible = signal<boolean>(false);
private readonly _level = linkedSignal(() => this._expandedItems().length);
primaryActiveRouteItem = signal<string | null>(null);
activeNavigationItem = this._activeNavigationItem.asReadonly();
expandedItems = this._expandedItems.asReadonly();
isMobileNavVisible = this._isMobileNavVisible.asReadonly();
level = this._level.asReadonly();
async toggleItem(item: NavigationItem): Promise<void> {
if (!item.children) {
@@ -59,7 +61,7 @@ export class NavigationState {
return;
}
// Returns item when parent node was already expanded
const parentItem = this._expandedItems().find(
const parentItem = this.actualExpandedItems().find(
(expandedItem) =>
item.parent?.label === expandedItem.label && item.parent?.path === expandedItem.path,
);
@@ -100,13 +102,25 @@ export class NavigationState {
private expand(item: NavigationItem): void {
// Add item to the expanded items list
this._expandedItems.update((expandedItems) => {
return [...(expandedItems ?? []), {...item, isExpanded: true}];
return [...(this.actualExpandedItems() ?? []), {...item, isExpanded: true}];
});
// No need to update the level here, this is handled by linkedSignal already
}
private collapse(item: NavigationItem): void {
item.isExpanded = false;
this._expandedItems.update((expandedItems) => expandedItems.slice(0, -1));
// We won't remove the item, just update the level,
// this allows animation on the items to hide them without destroying them
this._level.set(this.actualExpandedItems().length - 1);
}
/**
* return the actual navigation items, that is to say the one that match the current level
*/
private actualExpandedItems() {
return this.expandedItems().slice(0, this.level());
}
private async navigateToFirstPageOfTheCategory(path: string): Promise<boolean> {
@@ -6,10 +6,11 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {DOCUMENT, isPlatformBrowser} from '@angular/common';
import {inject, signal, Injectable, PLATFORM_ID} from '@angular/core';
import {DOCUMENT} from '@angular/common';
import {inject, signal, Injectable, PLATFORM_ID, DestroyRef} from '@angular/core';
import {TableOfContentsItem, TableOfContentsLevel} from '../interfaces/index';
import {on} from 'events';
/**
* Name of an attribute that is set on an element that should be
@@ -29,40 +30,19 @@ export class TableOfContentsLoader {
readonly tableOfContentItems = signal([] as TableOfContentsItem[]);
private readonly document = inject(DOCUMENT);
private readonly platformId = inject(PLATFORM_ID);
buildTableOfContent(docElement: Element): void {
const headings = this.getHeadings(docElement);
const tocList: TableOfContentsItem[] = headings.map((heading) => ({
id: heading.id,
level: heading.tagName.toLowerCase() as TableOfContentsLevel,
title: this.getHeadingTitle(heading),
top: this.calculateTop(heading),
}));
this.tableOfContentItems.set(tocList);
}
// Update top value of heading, it should be executed after window resize
updateHeadingsTopValue(element: HTMLElement): void {
const headings = this.getHeadings(element);
const updatedTopValues = new Map<string, number>();
for (const heading of headings) {
const parentTop = heading.parentElement?.offsetTop ?? 0;
const top = Math.floor(parentTop + heading.offsetTop - this.toleranceThreshold);
updatedTopValues.set(heading.id, top);
}
this.tableOfContentItems.update((oldItems) => {
let newItems = [...oldItems];
for (const item of newItems) {
item.top = updatedTopValues.get(item.id) ?? 0;
}
return newItems;
});
}
private getHeadingTitle(heading: HTMLHeadingElement): string {
const div: HTMLDivElement = this.document.createElement('div');
div.innerHTML = heading.innerHTML;
@@ -81,11 +61,37 @@ export class TableOfContentsLoader {
);
}
private calculateTop(heading: HTMLHeadingElement): number {
if (!isPlatformBrowser(this.platformId)) return 0;
return (
Math.floor(heading.offsetTop > 0 ? heading.offsetTop : heading.getClientRects()[0]?.top) -
this.toleranceThreshold
);
/**
* The methods setups several IntersectionObservers to determine when a heading is at the top of
* the viewport. Using an IntersectionObserver is more efficient than reading DOM position
* as it won't trigger any reflow.
*/
setupIntersectionObserver(
element: Element,
destroyRef: DestroyRef,
onActiveId: (id: string) => void,
): void {
// If we're at the top the we need the default active id to be the first heading.
const headings = this.getHeadings(element);
onActiveId(headings[0].id);
headings.forEach((heading) => {
const ioConfiguration = {
/**
* This rootMargin creates a horizontal line at 5% from the top of the viewport
* that will help trigger an intersection at that the very point.
*/
rootMargin: '0% 0% -95% 0%',
/** 0 is the default */
threshold: 0,
};
const observer = new IntersectionObserver((entries, o) => {
if (entries[0].isIntersecting) {
onActiveId(entries[0].target.id);
}
}, ioConfiguration);
observer.observe(heading);
destroyRef.onDestroy(() => observer.disconnect());
});
}
}
@@ -6,153 +6,32 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {DOCUMENT, ViewportScroller} from '@angular/common';
import {
DestroyRef,
EnvironmentInjector,
Injectable,
afterNextRender,
inject,
signal,
} from '@angular/core';
import {RESIZE_EVENT_DELAY} from '../constants/index';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {auditTime, debounceTime, fromEvent, startWith} from 'rxjs';
import {WINDOW} from '../providers/index';
import {ViewportScroller} from '@angular/common';
import {DestroyRef, Injectable, inject, signal} from '@angular/core';
import {TableOfContentsLoader} from './table-of-contents-loader.service';
export const SCROLL_EVENT_DELAY = 20;
@Injectable({providedIn: 'root'})
// The service is responsible for listening for scrolling and resizing,
// thanks to which it sets the active item in the Table of contents
export class TableOfContentsScrollSpy {
private readonly tableOfContentsLoader = inject(TableOfContentsLoader);
private readonly document = inject(DOCUMENT);
private readonly window = inject(WINDOW);
private readonly viewportScroller = inject(ViewportScroller);
private readonly injector = inject(EnvironmentInjector);
private contentSourceElement: HTMLElement | null = null;
private lastContentWidth = 0;
activeItemId = signal<string | null>(null);
scrollbarThumbOnTop = signal<boolean>(true);
startListeningToScroll(
contentSourceElement: HTMLElement | null,
// `destroyRef` is required because the caller may invoke `startListeningToScroll`
// multiple times. Without it, previous event listeners would not be disposed of,
// leading to the accumulation of new event listeners.
destroyRef: DestroyRef,
) {
this.contentSourceElement = contentSourceElement;
this.lastContentWidth = this.getContentWidth();
this.setScrollEventHandlers(destroyRef);
this.setResizeEventHandlers(destroyRef);
destroyRef.onDestroy(() => {
// We also need to clean up the source element once the view that calls
// `startListeningToScroll` is destroyed, as this will keep a reference
// to an element that has been removed from the DOM.
this.contentSourceElement = null;
});
}
scrollToTop(): void {
this.viewportScroller.scrollToPosition([0, 0]);
}
// After window resize, we should update top value of each table content item
private setResizeEventHandlers(destroyRef: DestroyRef) {
fromEvent(this.window, 'resize')
.pipe(debounceTime(RESIZE_EVENT_DELAY), takeUntilDestroyed(destroyRef), startWith())
.subscribe(() => {
this.updateHeadingsTopAfterResize();
});
// We need to observe the height of the docs-viewer because it may change after the
// assets (fonts, images) are loaded. They can (and will) change the y-position of the headings.
const docsViewer = this.document.querySelector('docs-viewer');
if (docsViewer) {
const ref = afterNextRender(
() => {
const resizeObserver = new ResizeObserver(() => this.updateHeadingsTopAfterResize());
resizeObserver.observe(docsViewer);
destroyRef.onDestroy(() => resizeObserver.disconnect());
setupActiveItemListener(contentSourceElement: HTMLElement, destroyRef: DestroyRef): void {
if (contentSourceElement) {
this.tableOfContentsLoader.setupIntersectionObserver(
contentSourceElement,
destroyRef,
(id) => {
this.activeItemId.set(id);
},
{injector: this.injector, manualCleanup: true},
);
destroyRef.onDestroy(() => ref.destroy());
}
}
private updateHeadingsTopAfterResize(): void {
this.lastContentWidth = this.getContentWidth();
const contentElement = this.contentSourceElement;
if (contentElement) {
this.tableOfContentsLoader.updateHeadingsTopValue(contentElement);
this.setActiveItemId();
}
}
private setScrollEventHandlers(destroyRef: DestroyRef): void {
const scroll$ = fromEvent(this.document, 'scroll').pipe(
auditTime(SCROLL_EVENT_DELAY),
takeUntilDestroyed(destroyRef),
);
scroll$.subscribe(() => this.setActiveItemId());
}
private setActiveItemId(): void {
const tableOfContentItems = this.tableOfContentsLoader.tableOfContentItems();
if (tableOfContentItems.length === 0) return;
// Resize could emit scroll event, in that case we could stop setting active item until resize will be finished
if (this.lastContentWidth !== this.getContentWidth()) {
return;
}
const scrollOffset = this.getScrollOffset();
if (scrollOffset === null) return;
for (const [i, currentLink] of tableOfContentItems.entries()) {
const nextLink = tableOfContentItems[i + 1];
// A link is considered active if the page is scrolled past the
// anchor without also being scrolled passed the next link.
const isActive =
scrollOffset >= currentLink.top && (!nextLink || nextLink.top >= scrollOffset);
// When active item was changed then trigger change detection
if (isActive && this.activeItemId() !== currentLink.id) {
this.activeItemId.set(currentLink.id);
return;
}
}
if (scrollOffset < tableOfContentItems[0].top && this.activeItemId() !== null) {
this.activeItemId.set(null);
}
const scrollOffsetZero = scrollOffset === 0;
if (scrollOffsetZero !== this.scrollbarThumbOnTop()) {
// we want to trigger change detection only when the value changes
this.scrollbarThumbOnTop.set(scrollOffsetZero);
}
}
// Gets the scroll offset of the scroll container
private getScrollOffset(): number {
return this.window.scrollY;
}
private getContentWidth(): number {
return this.document.body.clientWidth || Number.MAX_SAFE_INTEGER;
}
}
+408
View File
@@ -0,0 +1,408 @@
@use './anchor' as anchor;
/* Common styles for the API & CLI references */
@mixin reference-common() {
.docs-code {
pre {
margin-block: 0;
}
}
.docs-reference-header {
// deprecated markers beside header
& ~ .docs-deprecated {
margin-block-start: 0.5rem;
}
& > p {
color: var(--secondary-contrast);
margin-block-start: 0;
margin-block-end: 1.5rem;
}
.docs-reference-title {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
padding-block-end: 0;
gap: 0.5rem;
> div {
margin-block: 0.67em;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
h1 {
margin-block: 0;
}
}
a {
fill: var(--quinary-contrast);
transition: fill 0.3s ease;
&:hover {
fill: var(--primary-contrast);
}
}
}
.docs-reference-category {
color: var(--gray-400);
font-size: 0.875rem;
font-weight: 500;
line-height: 1.4rem;
letter-spacing: -0.00875rem;
}
.docs-code {
margin-block-end: 1.5rem;
}
}
.docs-reference-section-heading {
padding-block-start: 3rem;
&--sub {
padding-block-start: 1rem;
}
& > a {
@include anchor.docs-anchor();
color: inherit;
}
}
.docs-reference-members {
box-sizing: border-box;
width: 100%;
display: flex;
flex-direction: column;
gap: 20px;
&:not(:first-child) {
margin-top: 1rem;
}
.docs-reference-member-card {
border: 1px solid var(--senary-contrast);
border-radius: 0.25rem;
position: relative;
transition: border 0.3s ease;
&::before {
content: '';
inset: -1px;
position: absolute;
background: transparent;
border-radius: 0.35rem;
z-index: 0;
}
&.docs-highlighted-card {
box-shadow: 10px 4px 40px 0 rgba(0, 0, 0, 0.01);
&::before {
background: var(--red-to-pink-to-purple-horizontal-gradient);
}
}
> p {
padding-inline: 1.25rem;
margin-block-end: 0;
}
.docs-reference-card-header {
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 0.25rem 0.25rem 0 0;
background-color: var(--octonary-contrast);
position: relative;
z-index: 10;
padding: 0.7rem 1rem;
gap: 0.5rem;
flex-wrap: wrap;
transition:
background-color 0.3s ease,
border 0.3s ease;
&:focus {
outline: none;
}
&:has(+ .docs-reference-card-body:empty) {
border-radius: 0.25rem;
}
code {
font-size: 0.875rem;
&:has(pre) {
padding: 0;
}
&:not(pre *) {
padding: 0 0.3rem;
}
}
pre {
margin: 0;
/* Do we have a better alternative ? */
overflow: auto;
}
h3 {
display: inline-block;
font-family: var(--code-font);
font-size: 1rem;
letter-spacing: -0.025rem;
margin: 0;
}
span {
font-size: 0.875rem;
}
}
.docs-reference-card-body {
padding: 0.25rem 1.25rem;
background: var(--septenary-contrast);
transition: background-color 0.3s ease;
color: var(--quaternary-contrast);
border-radius: 0 0 0.25rem 0.25rem;
position: relative;
z-index: 10;
&:empty {
display: none;
}
&:first-child {
border-radius: 0.25rem;
}
hr {
margin-block: 2rem;
}
.docs-code {
margin-block-end: 1rem;
}
.docs-deprecation-message {
border-block-end: 1px solid var(--senary-contrast);
.docs-deprecated {
color: var(--page-background);
background-color: var(--quaternary-contrast);
width: max-content;
border-radius: 0.25rem;
padding: 0.1rem 0.25rem;
margin-block-start: 1rem;
}
}
}
}
}
}
/* API reference styles */
@mixin api-reference {
// API section styles
.docs-reference-api-section {
.docs-code {
box-sizing: border-box;
width: 100%;
overflow: hidden;
padding: 0;
button {
transition: background-color 0.3s ease;
&.shiki-ln-line-highlighted {
background-color: var(--senary-contrast);
}
&:hover {
background-color: var(--septenary-contrast);
}
&:focus {
background-color: var(--senary-contrast);
span {
background-color: inherit;
}
}
}
// Hide copy source code button
button[docs-copy-source-code] {
display: none;
}
}
code {
margin-block: 0;
}
pre {
white-space: pre;
overflow-x: auto;
margin: 0;
}
}
// "API member card"-specific styles
.docs-reference-member-card {
.docs-reference-card-item {
// When it's not the only card ...
&:has(~ .docs-reference-card-item) {
border: 1px solid var(--senary-contrast);
margin-block: 1rem;
border-radius: 0.25rem;
padding-inline: 1rem;
}
// & the last card
&:last-child:not(:first-of-type) {
border: 1px solid var(--senary-contrast);
margin-block: 1rem;
border-radius: 0.25rem;
padding-inline: 1rem;
}
span {
display: inline-block;
font-size: 0.875rem;
}
code {
font-size: 0.875rem;
}
.docs-function-definition:has(*) {
border-block-end: 1px solid var(--senary-contrast);
}
.docs-param-group {
margin-block-start: 1rem;
// If it's the only param group...
&:not(:has(~ .docs-param-group)) {
margin-block: 1rem;
}
.docs-param-name {
color: var(--vivid-pink);
font-family: var(--code-font);
margin-inline-end: 0.25rem;
&::after {
content: ':';
}
}
.docs-parameter-description {
p:first-child {
margin-block-start: 0;
}
}
}
.docs-param-keyword {
color: var(--primary-contrast);
font-family: var(--code-font);
margin-inline-end: 0.5rem;
}
.docs-return-type {
padding-block: 1rem;
// & does not follow a function definition
&:not(.docs-function-definition + .docs-return-type) {
border-block-start: 1px solid var(--senary-contrast);
}
}
}
}
}
/* CLI reference styles */
@mixin cli-reference {
// CLI TOC
.docs-reference-cli-toc {
margin-bottom: 1rem;
.shiki-ln-line-argument,
.shiki-ln-line-option {
padding: 0.1rem 0.2rem 0.2rem;
margin-inline: 0.1rem;
color: var(--quaternary-contrast);
background: transparent;
border-radius: 0.25rem;
position: relative;
transition:
color 0.3s ease,
background 0.3s ease,
border 0.3s ease;
&:hover {
color: var(--primary-contrast);
background: var(--septenary-contrast);
}
&.shiki-ln-line-highlighted {
color: var(--primary-contrast);
background: var(--senary-contrast);
}
}
.shiki-ln-line-argument {
margin-inline-start: 0.2rem;
}
}
.docs-reference-members {
.docs-reference-section-heading {
margin: 0;
}
// "CLI member card"-specific styles
.docs-reference-member-card {
.docs-ref-content {
padding: 1rem 0;
&:not(:first-child) {
border-block-start: 1px solid var(--senary-contrast);
}
.docs-reference-type-and-default {
width: 4.375rem;
flex-shrink: 0;
span {
display: block;
font-size: 0.875rem;
margin-block-end: 0.2rem;
white-space: nowrap;
&:not(:first-child) {
margin-block-start: 1rem;
}
}
code {
font-size: 0.775rem;
}
}
}
}
}
}
+2
View File
@@ -79,6 +79,7 @@
}
p > a,
p > em > a,
td > a,
div > a:not(.docs-card),
code > a,
@@ -93,6 +94,7 @@
}
p > a,
p > em > a,
.docs-list a,
.docs-card a {
margin-block: 0;
+1 -2
View File
@@ -58,7 +58,7 @@
fill: var(--page-background) !important;
}
.nodeLabel:not(.node:has(polygon) .nodeLabel) {
.nodeLabel:not(.node:has(polygon) .nodeLabel):not(.eventNode .nodeLabel) {
fill: var(--primary-contrast) !important;
color: var(--primary-contrast) !important;
}
@@ -71,7 +71,6 @@
}
.nodeLabel p {
color: var(--page-background) !important;
font-weight: 800 !important;
}
}
+5 -1
View File
@@ -144,12 +144,16 @@ class FakeFileSystemAPI implements FileSystemAPI {
): Promise<DirEnt<string>[]>;
readdir(
path: unknown,
options?: unknown,
options?: {encoding?: string | null | undefined; withFileTypes?: boolean} | string | null,
):
| Promise<Uint8Array[]>
| Promise<string[]>
| Promise<DirEnt<Uint8Array>[]>
| Promise<DirEnt<string>[]> {
if (typeof options === 'object' && options?.withFileTypes === true) {
return Promise.resolve([{name: 'fake-file', isFile: () => true, isDirectory: () => false}]);
}
return Promise.resolve(['/fake-dirname']);
}
+1 -1
View File
@@ -8,7 +8,7 @@
declare global {
interface Window {
gtag: (...args: any[]) => void;
gtag?(...args: any[]): void;
}
}
+7 -3
View File
@@ -41,7 +41,7 @@ interface FileSystemAPI {
export const checkFilesInDirectory = async (
dir: string,
fs: FileSystemAPI,
filterFoldersPredicate: (path?: string) => boolean = () => true,
filterFromRootPredicate: ((path: string) => boolean) | null,
files: FileAndContent[] = [],
) => {
const entries = (await fs.readdir(dir, {withFileTypes: true})) ?? [];
@@ -49,11 +49,15 @@ export const checkFilesInDirectory = async (
for (const entry of entries) {
const fullPath = normalizePath(`${dir}/${entry.name}`);
if (filterFromRootPredicate && !filterFromRootPredicate?.(entry.name)) {
continue;
}
if (entry.isFile()) {
const content = await fs.readFile(fullPath, 'utf-8');
files.push({content, path: fullPath});
} else if (entry.isDirectory() && filterFoldersPredicate(entry.name)) {
await checkFilesInDirectory(fullPath, fs, filterFoldersPredicate, files);
} else if (entry.isDirectory()) {
await checkFilesInDirectory(fullPath, fs, null, files);
}
}
+2 -2
View File
@@ -8,7 +8,7 @@
import {TestBed} from '@angular/core/testing';
import {AppComponent} from './app.component';
import {provideRouter} from '@angular/router';
import {provideRouter, withComponentInputBinding} from '@angular/router';
import {routes} from './routes';
import {Search, WINDOW} from '@angular/docs';
import {CURRENT_MAJOR_VERSION} from './core/providers/current-version';
@@ -21,7 +21,7 @@ describe('AppComponent', () => {
it('should create the app', () => {
TestBed.configureTestingModule({
providers: [
provideRouter(routes),
provideRouter(routes, withComponentInputBinding()),
{
provide: WINDOW,
useValue: fakeWindow,
+18 -26
View File
@@ -13,11 +13,11 @@ import {
inject,
OnInit,
PLATFORM_ID,
input,
signal,
WritableSignal,
} from '@angular/core';
import {NavigationEnd, NavigationSkipped, Router, RouterOutlet} from '@angular/router';
import {filter, map, skip} from 'rxjs/operators';
import {filter, map} from 'rxjs/operators';
import {
CookiePopup,
getActivatedRouteSnapshotFromRouter,
@@ -56,13 +56,12 @@ export class AppComponent implements OnInit {
private readonly router = inject(Router);
private readonly headerService = inject(HeaderService);
currentUrl = signal('');
displayFooter = signal(false);
displaySecondaryNav = signal(false);
displaySearchDialog: WritableSignal<boolean> = inject(IS_SEARCH_DIALOG_OPEN);
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
displaySecondaryNav = signal(false);
displayFooter = signal(false);
displaySearchDialog = inject(IS_SEARCH_DIALOG_OPEN);
ngOnInit(): void {
this.closeSearchDialogOnNavigationSkipped();
this.router.events
@@ -71,35 +70,24 @@ export class AppComponent implements OnInit {
map((event) => event.urlAfterRedirects),
)
.subscribe((url) => {
this.currentUrl.set(url);
this.setComponentsVisibility();
this.displaySearchDialog.set(false);
// We can't use an input binded to the route here
// because AppComponent itself is not a routed component
// so we access it via the snapshot
const activatedRoute = getActivatedRouteSnapshotFromRouter(this.router);
this.displayFooter.set(!activatedRoute.data['hideFooter']);
this.displaySecondaryNav.set(activatedRoute.data['displaySecondaryNav']);
this.displaySearchDialog.set(false);
this.updateCanonicalLink(url);
});
}
focusFirstHeading(): void {
if (!this.isBrowser) {
return;
}
const h1 = this.document.querySelector<HTMLHeadingElement>('h1:not(docs-top-level-banner h1)');
h1?.focus();
}
private updateCanonicalLink(absoluteUrl: string) {
this.headerService.setCanonical(absoluteUrl);
}
private setComponentsVisibility(): void {
const activatedRoute = getActivatedRouteSnapshotFromRouter(this.router as any);
this.displaySecondaryNav.set(activatedRoute.data['displaySecondaryNav']);
this.displayFooter.set(!activatedRoute.data['hideFooter']);
}
private setSearchDialogVisibilityOnKeyPress(event: KeyboardEvent): void {
protected setSearchDialogVisibilityOnKeyPress(event: KeyboardEvent): void {
if (event.key === SEARCH_TRIGGER_KEY && (event.metaKey || event.ctrlKey)) {
event.preventDefault();
this.displaySearchDialog.update((display) => !display);
@@ -111,6 +99,10 @@ export class AppComponent implements OnInit {
}
}
private updateCanonicalLink(absoluteUrl: string) {
this.headerService.setCanonical(absoluteUrl);
}
private closeSearchDialogOnNavigationSkipped(): void {
this.router.events.pipe(filter((event) => event instanceof NavigationSkipped)).subscribe(() => {
this.displaySearchDialog.set(false);
+2 -2
View File
@@ -8,13 +8,13 @@
import {mergeApplicationConfig, ApplicationConfig} from '@angular/core';
import {provideServerRendering} from '@angular/platform-server';
import {provideServerRoutesConfig, RenderMode} from '@angular/ssr';
import {provideServerRouting, RenderMode} from '@angular/ssr';
import {appConfig} from './app.config';
const serverConfig: ApplicationConfig = {
providers: [
provideServerRendering(),
provideServerRoutesConfig([{path: '**', renderMode: RenderMode.Prerender}]),
provideServerRouting([{path: '**', renderMode: RenderMode.Prerender}]),
],
};
-2
View File
@@ -25,7 +25,6 @@ import {
windowProvider,
} from '@angular/docs';
import {provideClientHydration} from '@angular/platform-browser';
import {provideAnimationsAsync} from '@angular/platform-browser/animations/async';
import {
RouteReuseStrategy,
Router,
@@ -75,7 +74,6 @@ export const appConfig: ApplicationConfig = {
provideExperimentalZonelessChangeDetection(),
provideClientHydration(),
provideHttpClient(withFetch()),
provideAnimationsAsync(),
provideEnvironmentInitializer(() => inject(AppScroller)),
provideEnvironmentInitializer(() => inject(AnalyticsService)),
{
+1
View File
@@ -11,3 +11,4 @@ export const X = 'https://x.com/angular';
export const MEDIUM = 'https://blog.angular.dev';
export const YOUTUBE = 'https://www.youtube.com/angular';
export const DISCORD = 'https://discord.gg/angular';
export const BLUESKY = 'https://bsky.app/profile/angular.dev';
+4
View File
@@ -9,6 +9,10 @@
export const VERSIONS_CONFIG = {
aDevVersionsLinkPattern: 'https://{{prefix}}{{version}}angular.dev',
aioVersions: [
{
version: 'v18',
url: 'https://v18.angular.dev/overview',
},
{
version: 'v17',
url: 'https://v17.angular.io/docs',
@@ -9,6 +9,9 @@
<li>
<a [href]="X" title="X (formerly Twitter)">X (formerly Twitter)</a>
</li>
<li>
<a [href]="BLUESKY" title="Bluesky">Bluesky</a>
</li>
<li>
<a [href]="YOUTUBE" title="YouTube">YouTube</a>
</li>
@@ -116,7 +119,7 @@
</div>
</div>
<p class="docs-license">
Super-powered by Google ©2010-2024. Code licensed under an
Super-powered by Google ©2010-2025. Code licensed under an
<a routerLink="/license" title="License text">MIT-style License</a>
. Documentation licensed under
<a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>

Some files were not shown because too many files have changed in this diff Show More