Compare commits

...

389 Commits

Author SHA1 Message Date
Ben Hong 77329b70a0 docs: fix missing security guide in navigation (#54830)
The paths for the security guide were flipped in the original PR. As a result, it looked for a markdown file in the best-practices directory when it should have looked for it in the guide directory instead.

PR Close #54830
2024-03-12 13:13:01 -07:00
Gerald Monaco 43ad12b793 refactor(core): add internal API to enable i18n hydration (#54784)
Add an internal API to enable and use i18n hydration for testing and development. This helps ensure that we don't accidentally break the current behavior until we are completely ready to roll out i18n support.

PR Close #54784
2024-03-12 11:39:01 -07:00
Ben Hong a752c31453 docs: improve in-depth guides information architecture (#54365)
PR Close #54365
2024-03-12 10:25:36 -07:00
Joey Perrott 9cb228a955 fix(docs-infra): remove the prerender directory from adev (#54820)
Remove the prerender directory as it is entirely unused and unneeded

PR Close #54820
2024-03-12 10:24:06 -07:00
Joey Perrott e43b03f4bf docs: bump to 2024 for copyright text (#54822)
Bump copyright text to 2024

PR Close #54822
2024-03-11 13:39:45 -07:00
Andrew Kushnir e27b505149 fix(core): prevent infinite loops in clobbered elements check (#54425)
This commit updates HTML sanitization logic to avoid infinite loops in case clobbered elements contain fields like `nextSibling` or `parentNode`. Those fields are used for DOM traversal and this update makes sure that those calls return valid results.

Also this commit fixes an issue when clobbering `nodeName` causes JS exceptions.

PR Close #54425
2024-03-11 12:46:23 -07:00
Gerald Monaco eff06ea8be refactor(core): add i18nNodes in preparation for i18n hydration (#54750)
An i18n message effectively acts as a dynamic template: two elements with contiguous instruction indices won't necessarily be contiguous in the DOM.

For that reason, we need to maintain a mapping from instruction index to a physical DOM node in order to hydrate views with i18n, pointing to where hydration for that view should begin.

PR Close #54750
2024-03-11 11:12:44 -07:00
Matthieu Riegler 4db321cf3f docs: adding signal inputs and model to ADEV. (#54753)
Those docs are a copy from AIO.

PR Close #54753
2024-03-11 11:00:56 -07:00
theRealc0d3c 1aefc27f4b docs: fix typo in tutorial (#54817)
PR Close #54817
2024-03-11 10:59:51 -07:00
Kristiyan Kostadinov 4799a3bd5d fix(compiler): not catching for loop empty tracking expressions (#54772)
Fixes that the template parser wasn't catching empty expressions in the `track` parameter of for loops.

Fixes #54763.

PR Close #54772
2024-03-11 09:17:41 -07:00
Andrew Scott 67bc88fa54 fix(router): Navigations triggered by cancellation events should cancel previous navigation (#54710)
There is an edge case where synchronous navigations caused in
response to navigation events can result in a previous navigation not
being unsubscribed from. b/328219996

PR Close #54710
2024-03-07 13:07:09 -08:00
Gerald Monaco b9a0d022e5 refactor(core): refactor i18n node creation to prepare for hydration (#54722)
Adds a `locateOrCreateNode` helper and uses it for all DOM operations in preparation for supporting hydration.

PR Close #54722
2024-03-07 12:41:45 -08:00
Leonardo Ortiz ea9c10eabb docs: update content readme link (#53763)
PR Close #53763
2024-03-07 11:07:03 -08:00
Leonardo Ortiz 3549b5e111 docs: readme from blossom (#53763)
PR Close #53763
2024-03-07 11:07:00 -08:00
Angular Robot 729b32ee01 docs: update events (#54721)
Generated `events.json` with the latest events retrieved from the Firebase DB.

PR Close #54721
2024-03-07 11:05:37 -08:00
Gerald Monaco b0928f852a refactor(core): don't hydrate detached nodes (#54723)
In preparation for hydration support, make sure that we don't attempt to hydrate detached nodes and instead, always newly create them.

PR Close #54723
2024-03-07 11:01:30 -08:00
Gerald Monaco fec9be1942 refactor(core): add i18n AST to prepare for hydration (#54724)
In order to serialize and hydrate i18n blocks, we need to be able to walk an AST for the translated message. This AST is generated during normal parsing of the message.

PR Close #54724
2024-03-07 11:00:37 -08:00
Alan Agius 359408e0b1 fix(http): exclude caching for authenticated HTTP requests (#54746)
This update modifies the transfer cache logic to prevent caching of HTTP requests that require authorization.

Closes: #54745

PR Close #54746
2024-03-07 11:00:01 -08:00
Andrew Scott 4d708b213d refactor(core): Fix internal test util types (#54736)
This fixes and error that has been seen recently where compilation fails
due to domino.impl type not being recognized

PR Close #54736
2024-03-06 13:34:54 -08:00
Pawel Kozlowski 50623ea1e1 release: cut the v17.2.4 release 2024-03-06 20:28:55 +01:00
Matthieu Riegler 443e5f1591 fix(core): return a readonly signal on asReadonly. (#54719)
Previous `asReadonly()` returned the signal value and not the signal itself.

Fixes #54704

PR Close #54719
2024-03-06 15:18:51 +01:00
Alan Agius c75c168ed5 fix(docs-infra): do not delete BUILD.bazel in help directory during updates (#54697)
In https://github.com/angular/angular/pull/54591, a `BUILD.bazel` file was created in `aio/content/cli/help/BUILD.bazel`, this however breaks the automatic CLI help pages updates as prior to this change, the `help` directory was being deleted. See: https://github.com/angular/angular/pull/54691/commits/17346e89da2fbddf8274eeadf12bab9c5b8983d8

This commit, updates the process to delete only the JSON files and copying the new files.

PR Close #54697
2024-03-06 10:18:04 +01:00
Jessica Janiuk 3b50885691 docs: add process documentation to CARETAKER.md (#54664)
This adds documentation regarding the latest changes to framework merge tools. It specifically covers the requires: TGP label and separate sync for primitives.

PR Close #54664
2024-03-05 19:11:43 +01:00
Matthieu Riegler 6148d76e21 docs: fix clipped docs-code block in docs-reference-api-tab (#54621)
PR Close #54621
2024-03-05 18:35:20 +01:00
Matthieu Riegler aa0fce6531 docs: fix tutorial preview size (#54621)
PR Close #54621
2024-03-05 18:35:19 +01:00
Matthieu Riegler 43b027f36e docs: fix label on API link. (#54621)
Remove the unecessary double quotes on a @see link.

PR Close #54621
2024-03-05 18:35:14 +01:00
Matthieu Riegler e7eadd9aff docs(docs-infra): remove unwanted styling on API page. (#54621)
`box-sizing: border-box` prevents overflow caused by borders.

PR Close #54621
2024-03-05 18:35:13 +01:00
Jessica Janiuk badae7254e ci: fix ng-dev build for pr merging (#54708)
This updates ng-dev to the latest hash fixing the merge files query.

PR Close #54708
2024-03-05 18:28:25 +01:00
Andrew Kushnir 586cc24a10 fix(core): apply TestBed provider overrides to @defer dependencies (#54667)
This commit updates TestBed logic to take into account situations when dependencies loaded within `@defer` blocks may import NgModules with providers. For such components, we invoke provider override function, which recursively inspects and applies the necessary changes.

PR Close #54667
2024-03-05 09:21:23 +01:00
Paul Gschwendtner b558a01c84 fix(core): generic inference for signal inputs may break with --strictFunctionTypes (#54652)
This commit fixes that the generic inference for signal inputs may break
with `--strictFunctionTypes`.

We are not using --strictFunctionTypes` in all tests, so function parameters are always
checked bivariantly- while in 1P function parameters are checked contravariantly. This
breaks sub-typing and e.g. `InputSignal<number>` is not a subtype of `InputSignalWithTransform<unknown, number>`.

Root cause is that the input signal captures the equality function that
is exclusively concerned with the `ReadT`. And `ReadT` is never equal, or a
supertype of unknown.

https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBASwHY2FAZgQwMbDgSSTAFcYBlBAcyUwBsB1BGACwBUpMkBndaAWwA8AJWCYAJqwA0celCbBWAPjgBvAFBw4Aei1xWACXxlEXOCzxQIEeNkzEuwAIRmAnmDxhMHPsFRRTXnjYzMDYANbAYnDYECgcAG5eCJwwtC7SAHIA8qxwAEYIALSJcilpAHQacMAAjsR0AFxwABSYTSLiUvntohIAlHAAvMp5VrSiSADcalUA+rNQvaw9ndOa8wDucqjLMtsK0wC+aqCQsIgoaFi4BESkFNR0wkuKVaCoSGKmhCTkVDQMJhsDjcXhQQQdCTSSFKVTHNQxbjwEBNH73f50RgsdicHj8ATEJBhJAQDZIaRIYh8PJoZSDKqU2i0ZyYb53P6PWgCSnU2nTKpaABUM00rDceAA5GiOQDuVSaVBFBKTHASfBWVwMXlxmYIK53HApeyHgCscDcWDBITiaTyar5bSJZVReLTBB0HAwJZ3LAXIbavVaMrAhcYnxPDAENrgM7NHpxYbWk0eQrpHlkw6oANhvkxhNlQhTGq4BqtTqYHqYAmJUm4NaSWS00167bsyM85wnVU4-H3G6PZ5vL40KYJZhg59DeOS4tQxBw5hI9HYz2XQaJS2yQWi9YS1xNY9o7r9ZKU2gnc0AEwzDTZVgAUSaABF7wAFe8ZF8ZXJZDJwAAGhSFFwMByNgMAAGKEuBCCxGKfb-nA6C0JglArqugpaEAA

PR Close #54652
2024-03-04 19:07:47 +01:00
Jessica Janiuk 2fc1971ac6 ci: Add primitives configurations for ng-dev tools (#54663)
This adds the configs to enable validators and google sync patterns for primitives sharing.

PR Close #54663
2024-03-04 18:20:46 +01:00
cexbrayat 9637b5d03d refactor(compiler): cleanup unused code in template builder pipeline (#54654)
This removes some unused code and fixes a few typos across the pipeline code.

PR Close #54654
2024-03-04 18:15:58 +01:00
danieljancar 7ead0fccb0 docs: revise documentation for @for control flow, 'track $index' performance issues explanation, and confusing 'trackBy' mention (#53806)
PR Close #53806
2024-03-04 11:37:41 +01:00
Pawel Kozlowski 6ca8ecad54 docs: queries as signals adev guide (#54505)
Add a angular.dev version of queries as signals guide.

PR Close #54505
2024-03-04 11:11:17 +01:00
Andrew Scott e3bdab12fa refactor(core): Pending effects should make the application unstable (#53835)
In zone-full applications, this is already true because effects are
scheduled inside a microtask and tracked by ZoneJS. When not using
zones, this should stay consistent on principle and for testability
reasons. A general pattern with zoneless testing will be to update state
and `await` some promise (i.e. `fixture.whenStable`, which will be
linked to `ApplicationRef.isStable`).

PR Close #53835
2024-03-04 10:35:42 +01:00
Matthieu Riegler 342737e01f docs(docs-infra): Update tutorial deps (#54677)
PR Close #54677
2024-03-04 10:03:17 +01:00
Hozefa Mangalorewala 0767adc603 docs: fix broken link on the tutorial page (#54669)
PR Close #54669
2024-03-03 13:59:03 +01:00
Swami 37dcf8d658 refactor(core): remove unused EffectRef import statement (#53863)
Remove unused, leftover imports.

PR Close #53863
2024-02-29 14:54:51 +01:00
Alex Rickabaugh ffbafc7d4a fix(core): untrack various core operations (#54614)
One downside of implicit dependency tracking in `effect()`s is that it's easy
to for downstream code to end up running inside the effect context by accident.
For example, if an effect raises an event (e.g. by `next()`ing a `Subject`), the
subscribers to that `Observable` will run inside the effect's reactive context,
and any signals read within the subscriber will end up as dependencies of the
effect. This is why the `untracked` function is useful, to run certain
operations without incidental signal reads ending up tracked.

However, knowing when this is necessary is non-trivial. For example, injecting
a dependency might cause it to be instantiated, which would run the constructor
in the effect context unless the injection operation is untracked.

Therefore, Angular will automatically drop the reactive context within a number
of framework APIs. This commit addresses these use cases:

* creating and destroying views
* creating and destroying DI injectors
* injecting dependencies
* emitting outputs

Fixes #54548

There are likely other APIs which would benefit from this approach, but this
is a start.

PR Close #54614
2024-02-29 11:38:58 +01:00
Kristiyan Kostadinov 917b9bdd2e fix(compiler-cli): unwrap expressions with type parameters in query read property (#54647)
Fixes that a query like `viewChild('locator', {read: ElementRef<HTMLElement>})` would throw because we didn't account for expressions with type parameters.

I've also included support for parenthesized expressions and `as` expressions since it's pretty easy to support them.

Fixes #54645.

PR Close #54647
2024-02-28 18:05:15 +01:00
Tommy Gaessler 7ca08aaa5b docs: updated setting up Zone.js instructions (#52409)
Updated the "Setting up Zone.js" instructions to the latest convention from
how the Angular CLI configures it.
Include adding zone-flats.ts to the tsconfig.app.json file step.
Added src/ to zone-flag.ts in the code example.

PR Close #52409
2024-02-28 17:35:18 +01:00
Kristiyan Kostadinov c19c44d694 docs: fix broken link in AIO (#54649)
Fixes a broken link that is currently breaking the CI.

PR Close #54649
2024-02-28 17:15:11 +01:00
Nikita Barsukov b0f434a893 docs: fix broken markdown syntax (#53567)
PR Close #53567
2024-02-28 15:16:17 +01:00
mgechev c05bef0ee8 docs: update versioning and deprecation policies (#51423)
Add more details around:
- What we consider a breaking change
- What is a deprecation
- How do we guarantee Angular stays stable
- Update invalid links

PR Close #51423
2024-02-28 14:38:41 +01:00
mgechev 3f0e892638 docs: add updating to v17 guide (#52410)
PR Close #52410
2024-02-28 14:19:46 +01:00
Dylan Hunn edc45d5b6f release: cut the v17.2.3 release 2024-02-27 16:23:40 -08:00
Sumit Parakh 79a32816dc fix(core): fix typo in injectors.svg file (#54596)
this commit fixes the unnecessary single quote in injectors.svg file

Closes #54592

PR Close #54596
2024-02-27 15:21:17 -08:00
Angular Robot 11a0a5d017 build: update io_bazel_rules_sass digest to 888dd9c (#54615)
See associated pull request for more information.

PR Close #54615
2024-02-27 14:06:34 -08:00
Doug Parker 89db58691f release: bump Angular DevTools version to 1.0.11 (#54631)
PR Close #54631
2024-02-27 14:02:20 -08:00
Doug Parker 624767c076 Revert "refactor(devtools): implement iframe support for Angular DevTools' browser code (#53934)" (#54629)
This reverts commit dd3dac9cc9.

PR Close #54629
2024-02-27 14:00:17 -08:00
Doug Parker 7b30a869e1 Revert "refactor(devtools): implement multiframe support in devtools page (#53934)" (#54629)
This reverts commit ebcdc8dc96.

PR Close #54629
2024-02-27 14:00:17 -08:00
Doug Parker 986b9c3bea refactor: add --spawn_strategy local to --config debug (#54167)
This seems to be necessary to debug Node tests.

PR Close #54167
2024-02-26 18:36:42 -08:00
Andrew Scott 69598c0c6c refactor(core): Internal render hooks trigger view refresh before executing user hooks (#54224)
This commit ensures that any internal render hooks that cause views to
become dirty again first refresh those dirty views before running user
render hooks. This ensures that user render hooks have the most complete
render state possible and stops them from needlessly executing multiple
times. This is important to maintain the goal of the public render
hooks, which is to provide the safest place to place code that depends
on DOM state, especially in ways that may force a browser paint.

PR Close #54224
2024-02-26 18:31:16 -08:00
Andrew Scott ffe3aa1169 refactor(core): Add helper function for queuing state updates (#54224)
This adds a helper function to defer application state updates to the
first possible "safe" moment. If application-wide change detection
(ApplicationRef.tick) is currently executing when this function is used,
the callback will execute as soon as all views attached to the
`ApplicationRef` have been refreshed. Refreshing the application views
will happen again before `checkNoChanges` executes.

When a change detection is _not_ running, this state update will execute
in the microtask queue.

This function is necessary as a replacement for current
`Promise.resolve().then(() => stateUpdate())` to be zoneless compatible
while ensuring those state updates are synchronized to the DOM before
the browser repaint. Without this, updates done in `Promise.resolve(...)` would
queue another round of change detection in zoneless applications, and
this change detection could happen in the next browser frame, and cause
noticeable flicker for the user.

Additionally, this function provides a way to perform state updates that
will run on the server as well as in the browser.

Last, current applications using `ngZone: 'noop'` may not be
calling `ApplicationRef.tick` at all so this function provides a
mechanism to ensure the state update still happens by racing
a microtask with `afterNextRender` (which might never execute).

PR Close #54224
2024-02-26 18:31:15 -08:00
cexbrayat 2aefed8763 fix(compiler-cli): catch function instance properties in interpolated signal diagnostic (#54325)
Currently, the following template compiles without error, even if the signal is not properly called:

```
<div>{{ mySignal.name }}</div>
```

This is because `name` is one of the instance properties of Function (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function#instance_properties).

The interpolated signal diagnostic is now extended to catch such issues.

PR Close #54325
2024-02-26 18:30:06 -08:00
Angular Robot 377442d90f build: update scorecard action dependencies (#54407)
See associated pull request for more information.

PR Close #54407
2024-02-26 18:29:39 -08:00
cexbrayat 20a549f1de docs: use components in model inputs guide (#54606)
The code example showcases a `@Directive` with a template instead of a `@Component`.

PR Close #54606
2024-02-26 18:28:15 -08:00
Kristiyan Kostadinov daf7c611b2 fix(compiler-cli): identify aliased initializer functions (#54609)
Fixes that initializer functions weren't being recognized if they are aliased (e.g. `import {model as alias} from '@angular/core';`).

To do this efficiently, I had to introduce the `ImportedSymbolsTracker` which scans the top-level imports of a file and allows them to be checked quickly, without having to go through the type checker. It will be useful in the future when verifying that that initializer APIs aren't used in unexpected places.

I've also introduced tests specifically for the `tryParseInitializerApiMember` function so that we can test it in isolation instead of going through the various functions that call into it.

PR Close #54609
2024-02-26 18:27:19 -08:00
Dylan Hunn c1163535d1 Revert "fix(compiler-cli): identify aliased initializer functions (#54480)" (#54595)
This reverts commit f04ecc0cda.

PR Close #54595
2024-02-26 08:36:50 -08:00
Andrew Kushnir 57123524a2 fix(core): collect providers from NgModules while rendering @defer block (#52881)
Currently, when a `@defer` block contains standalone components that import NgModules with providers, those providers are not available to components declared within the same NgModule. The problem is that the standalone injector is not created for the host component (that hosts this `@defer` block), since dependencies become defer-loaded, thus no information is available at host component creation time.

This commit updates the logic to collect all providers from all NgModules used as a dependency for standalone components used within a `@defer` block. When an instance of a defer block is created, a new environment injector instance with those providers is created.

Resolves #52876.

PR Close #52881
2024-02-23 12:30:06 -08:00
Pawel Kozlowski dcd6c8c79b refactor(core): use performance API for signals (#54521)
This commit adds a standard performance marker that can be viewed in Chrome dev tools and other tooling.
See more info at https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark

PR Close #54521
2024-02-23 12:18:31 -08:00
Kristiyan Kostadinov fbb0398795 docs: add a guide for model inputs (#54514)
Adds a guide for `model()` inputs for angular.io. Will port this over to angular.dev once it's finalized.

PR Close #54514
2024-02-23 11:47:04 -08:00
Felix Geißler 56ad65afa7 docs: syntax error in signal input transform example (#54567)
PR Close #54567
2024-02-23 11:46:14 -08:00
loka shafeek b1b7bbffb8 docs: Update wildcard route component to PageNotFoundComponent (#54570)
This PR enhances the Angular documentation by replacing the placeholder `<component-name>` with the actual `PageNotFoundComponent` in the wildcard route configuration. This update ensures that the documentation accurately reflects the recommended practice for handling page-not-found scenarios. Additionally, it addresses the issue where HTML entities like `&lt;` were being displayed instead of the desired `<` symbol, resulting in clearer and more readable documentation for users.
PR Close #54570
2024-02-23 11:45:39 -08:00
Kristiyan Kostadinov 48aec63ee4 fix(compiler-cli): identify aliased initializer functions (#54480)
Fixes that initializer functions weren't being recognized if they are aliased (e.g. `import {model as alias} from '@angular/core';`).

To do this efficiently, I had to introduce the `ImportedSymbolsTracker` which scans the top-level imports of a file and allows them to be checked quickly, without having to go through the type checker. It will be useful in the future when verifying that that initializer APIs aren't used in unexpected places.

I've also introduced tests specifically for the `tryParseInitializerApiMember` function so that we can test it in isolation instead of going through the various functions that call into it.

PR Close #54480
2024-02-23 11:44:40 -08:00
Lukas Matta d68cf175a4 docs: remove mutate function mention (#54569)
PR Close #54569
2024-02-23 11:43:25 -08:00
Matthieu Riegler 89f8331b7e ci: adding Matthieu as approver for ADEV (#54575)
This is to help the team approve changes on the new doc site.

PR Close #54575
2024-02-23 11:42:46 -08:00
Kristiyan Kostadinov 84ade02df6 refactor(compiler-cli): changes to get signal diagnostic working internally (#54585)
The diagnostic for signals that haven't been invoked wasn't working internally, because the path to `@angular/core` is different. These changes resolve the issue and do some general cleanup.

PR Close #54585
2024-02-23 11:42:07 -08:00
Kristiyan Kostadinov dbe673b027 fix(migrations): resolve infinite loop for a single line element with a long tag name and angle bracket on a new line (#54588)
Fixes an edge case where a single-line elemnt with a long tag name a closing bracket on a new line was putting the control flow migration into an infinite loop.

Fixes #54587.

PR Close #54588
2024-02-23 11:40:31 -08:00
Andrew Scott 1a526f2881 perf(common): AsyncPipe should not call markForCheck on subscription (#54554)
This commit prevents `AsyncPipe` from calling `markForCheck` when values
are synchronously emit during subscription to an observable. This
prevents subscriptions to `Replay` observables from needlessly walking
up to the root of the view tree during template execution for each
new replay observable in the template.

PR Close #54554
2024-02-23 09:20:05 -08:00
Alex Rickabaugh 600a8cd59a release: cut the v17.2.2 release 2024-02-21 17:54:30 -08:00
Jessica Janiuk bb57d34110 fix(migrations): Fix cf migration regular expression to include underscores (#54533)
In rare cases people may use an underscore in their component names, which was not accounted for in the formatting portion of the migration.

fixes: #54532

PR Close #54533
2024-02-21 15:25:07 -08:00
Doug Parker ef94bb6bf6 docs(devtools): expand release docs (#54525)
This provides some more information on how to release and notably includes commands for zipping extension code and source code, which can otherwise be tricky to get exactly right.

PR Close #54525
2024-02-21 15:24:27 -08:00
Doug Parker e627c6eaef release: bump Angular DevTools version to 1.0.10 (#54523)
PR Close #54523
2024-02-21 15:23:37 -08:00
Kristiyan Kostadinov 65c9148c71 refactor(compiler-cli): move defer block tests into separate file (#54499)
Splits the tests for `@defer` blocks out into a separate file since the `ngtsc_spec.ts` is getting quite large.

PR Close #54499
2024-02-21 15:22:37 -08:00
Kristiyan Kostadinov 0a3edfb543 fix(compiler-cli): correctly detect deferred dependencies across scoped nodes (#54499)
This is based on an internal issue report.

An earlier change introduced a diagnostic to report cases where a symbol is in the `deferredImports` array, but is used eagerly. The check worked by looking through the deferred blocks in a scope, resolving the scope for each and checking if the element is within the scope. The problem is that resolving the scope won't work across scoped node boundaries. For example, if there's a control flow statement around the block or within the block but around the deferred dependency, it won't be able to resolve the scope since it isn't a direct child, e.g.

```
@if (true) {
  @defer {
   <deferred-dep/>
  }
}
```

To fix this the case where the deferred block is inside a scoped node, I've changed the `R3BoundTarget.deferBlocks` to be a `Map` holding both the deferred block and its corresponding scope. Then to resolve the case where the dependency is within a scoped node inside the deferred block, I've added a depth-first traversal through the scopes within the deferred block.

PR Close #54499
2024-02-21 15:22:37 -08:00
Kristiyan Kostadinov f00336c31f refactor(compiler-cli): add the ability to treat object literals as enums in docs (#54487)
We have a couple of cases now (#53753 and #54414) where we're forced to redefine enums as object literals. These literals aren't rendered in the best way in the docs so these changes introduce a new `object-literal-as-enum` tag that we can use to mark them so they're treated for documentation purposes.

PR Close #54487
2024-02-21 15:21:59 -08:00
Dean Davidson 8997260e29 docs: add closing tags to code examples (#54485)
There were two minor issues in the code examples that this addresses.
PR Close #54485
2024-02-21 15:20:17 -08:00
Lukas Matta 033608e17b docs: fix typos (#54475)
PR Close #54475
2024-02-21 15:19:40 -08:00
vladboisa 926063eb0a docs(docs-infra): fix tab shrinking (#54380)
Fix a behavior when block shrinks on Usage notes tab

Fixes #52818

PR Close #54380
2024-02-21 15:19:14 -08:00
cexbrayat 187b46a3a0 docs: view child static query differences formatting (#54370)
The docs were broken as the first line is the only one to be displayed in the table.

PR Close #54370
2024-02-21 15:18:48 -08:00
Dmitry Ivanitskiy 6447c0eecc fix(compiler): adding the inert property to the "SCHEMA" array (#53148)
This change allows template binding "inert" attribute with the following syntax: [inert]="isInert"

Fixes #51879

fixup! fix(compiler): adding the inert property to the "SCHEMA" array

revert: "fixup! fix(compiler): adding the inert property to the "SCHEMA" array"

This reverts commit b637b7ce646e8bab2f585339028a84018e8ea982.

This commit is being reverted because the inert property is safe as a boolean attribute

PR Close #53148
2024-02-21 15:13:56 -08:00
Matthieu Riegler ed8857e46f refactor(platform-browser): use performance API for async animations (#53963)
This commit adds a standard performance marker

PR Close #53963
2024-02-21 15:12:05 -08:00
Andrew Scott 3e31f1a34e fix(router): Clear internal transition when navigation finalizes (#54261)
This commit fixes a small memory issue in the router where a destroyed
component instance would be retained.

fixes #54241

PR Close #54261
2024-02-21 14:09:58 -08:00
cexbrayat d411ee735a docs: typos in signal queries guide (#54540)
PR Close #54540
2024-02-21 15:59:01 +00:00
Kristiyan Kostadinov d34e3298db fix(common): image placeholder not removed in OnPush component (#54515)
Fixes that the placeholder wasn't being removed when an optimized image is placed in an `OnPush` component.

Fixes #54478.

PR Close #54515
2024-02-20 09:50:00 -08:00
Pawel Kozlowski db35266021 test(core): more tests for queries as signals (#54508)
A couple of tests that illustrate combination of signal
and decorator queries in once component.

PR Close #54508
2024-02-20 09:49:20 -08:00
JoostK 790f4f7c26 fix(compiler-cli): use correct symbol name for default imported symbols in defer blocks (#54495)
This commit addresses a problem with PR #53695 that introduced support for default imports,
where the actual dynamic import used in the defer loading function continued to use the
symbol name, instead of `.default` for the dynamic import. This issue went unnoticed in the
testcase because a proper instance was being generated for the `ɵsetClassMetadataAsync` function,
but not the generated dependency loader function.

Fixes #54491

PR Close #54495
2024-02-20 09:45:33 -08:00
Jamie Couperwhite 5e80e6db1c docs: fix developer preview link in signal queries (#54492)
PR Close #54492
2024-02-20 09:44:43 -08:00
Alex Castle 5597e5d172 docs(common): add new faq entry to NgOptimizedImage docs (#54469)
add new FAQ entry explaining that we're not adding new loaders to the angular repo

PR Close #54469
2024-02-20 09:43:47 -08:00
Ahmed Hakeem f8a5b40489 docs: enhance Dependency injection description (#54464)
PR Close #54464
2024-02-20 09:29:54 -08:00
Pawel Kozlowski 3bd5860c74 fix(core): properly execute content queries for root components (#54457)
Prior to this fix an incorrect view instance (a dynamically created component
one instead of the root view) was passed to the content query function. Having
incorrect view instance meant that a component instance could not be found.

This is a pre-existing bug, introduction of signal-based queries just surfaced it.

Fixes #54450

PR Close #54457
2024-02-15 12:21:29 -08:00
Pawel Kozlowski b975ff1bc2 docs: add guide for signal queries (#54395)
Adding new guide for the signal-based queries.

PR Close #54395
2024-02-15 12:17:01 -08:00
Fabio Heer ba686cc43f docs: correct default application builder for new apps (#54386)
The documentation on angular.dev mentions build-angular:browser as default
application builder. This is not correct. Recent applications are setup
with build-angular:application by default.

PR Close #54386
2024-02-15 10:54:18 -08:00
AleksanderBodurri a7e4b99515 refactor(devtools): implement multiframe support in devtools page (#53934)
In the Angular DevTools Chrome DevTools page:

- Angular DevTools is able to ask the background script to list each frame that has been registered on a page.
- Angular Devtools is able to ask the background script to "enable" the connection on a particular frame. This enables the messaging between the content script <-> background script <-> devtools page
- Implements detection of non unique urls on the inspected page

Limitations:
- The `inspectedWindow.eval` API is only able to target frames by frameURL. This means some features that integrate with Chrome DevTools like inspect element and open source will not be available when inspecting frames that do not have a unique url on the page.

PR Close #53934
2024-02-14 17:15:26 -08:00
AleksanderBodurri 02fcd928b2 refactor(devtools): implement iframe support for Angular DevTools' browser code (#53934)
Modifies the messaging layer of devtools to allow for switching communication between frames on a page. When served as a browser extension.

Design:
- When a page renders, DevTools installs a content script onto it through it's manifest file. The all_frames option is used here to install this script onto every frame in a page.
- When Angular is detected, the content script will install a backend script into it's frame.
- Each content script / backend script pairing is kept track of in the background script. This pairing represents an angular devtools context in a particular frame.
- Angular DevTools is able to ask the background script to list each frame that has been registered on a page.
- Angular Devtools is able to ask the background script to "enable" the connection on a particular frame. This enables the messaging between the content script <-> background script <-> devtools page

Limitations:
- The `inspectedWindow.eval` API is only able to target frames by frameURL. This means some features that integrate with Chrome DevTools like inspect element and open source will not be available when inspecting frames that do not have a unique url on the page.

PR Close #53934
2024-02-14 17:15:26 -08:00
Angular Robot fba7fe175c build: update all non-major dependencies (#54406)
See associated pull request for more information.

PR Close #54406
2024-02-14 15:39:37 -08:00
Joey Perrott e5e8be4d72 ci: remove feature-request bot (#54442)
Remove feature request bot from usage.

PR Close #54442
2024-02-14 15:33:54 -08:00
Kisters-BS 8521188cd1 docs: fix typo (#54427)
PR Close #54427
2024-02-14 15:29:21 -08:00
Paul Gschwendtner 44a0ea4e2d docs: add guide for signal inputs (#54316)
Adds a guide for signal inputs.

We will port that to `angular.dev` once we finalized this version.

PR Close #54316
2024-02-14 15:22:49 -08:00
Andrew Kushnir 3eda005680 release: cut the v17.2.1 release 2024-02-14 14:55:28 -08:00
Alex Rickabaugh 7234824228 fix(compiler-cli): fix broken version detection condition (#54443)
The version detection condition for signal two-way bindings used an OR
instead of an AND, resulting in every `.0` patch version being considered
as supporting two-way bindings to signals.

This commit fixes the logic and adds additional parentheses to ensure the
meaning of the condition is more clear. Long term, we should switch to
semver version parsing instead.

PR Close #54443
2024-02-14 12:47:03 -08:00
Andrew Kushnir 0b95d141ab release: cut the v17.2.0 release 2024-02-14 10:55:44 -08:00
Kristiyan Kostadinov 78b48cc272 refactor(compiler-cli): do not emit signal unwrap calls in versions older than 17.2 (#54423)
In order to allow both signals and non-signals in two-way bindings, we have to pass the expression through `ɵunwrapWritableSignal`. The problem is that the language service uses a bundled compiler that is fairly new, but it may be compiling an older version of Angular that doesn't expose `ɵunwrapWritableSignal` (see https://github.com/angular/vscode-ng-language-service/issues/2001).

These changes add a `_angularCoreVersion` flag to the compiler which the language service can use to pass the parsed Angular version to the compiler which can then decide whether to emit the function.

PR Close #54423
2024-02-13 15:53:42 -08:00
Matthieu Riegler 1c536250b6 fix(http): Use string body to generate transfer cache key. (#54379)
This is particularly usefull for GraphQL queries where the string body might be the only discriminator.

Fixes #54377

PR Close #54379
2024-02-13 11:53:22 -08:00
Joey Perrott 674b6c36b0 fix(docs-infra): don't include prerender flag based on fast/full build in adev (#54400)
The serve command for architect does not support the `--prerender` flag

PR Close #54400
2024-02-13 11:52:40 -08:00
Lukas Matta 35925263bd docs: fix typo (#54403)
PR Close #54403
2024-02-13 11:51:56 -08:00
Kristiyan Kostadinov 501c159e05 build: update node (#54399)
Updates the repo to a newer version of Node to fix errors in the integration tests.

PR Close #54399
2024-02-12 15:36:19 -08:00
Kristiyan Kostadinov 277540c4fc build: reuse fake core in type checking tests (#54344) (#54398)
Currently we have two fake copies of `@angular/core` in the compiler tests which can be out of sync and cause inconsistent tests. These changes reuse a single copy instead.

PR Close #54344

PR Close #54398
2024-02-12 14:31:26 -08:00
Kristiyan Kostadinov 6d00115bf4 fix(core): show placeholder block on the server with immediate trigger (#54394)
Currently all triggers are set up to show the placeholder block on the server, except for `on immediate` which is basically a noop. These changes update `on immediate` to match the rest of the triggers.

Fixes #54385.

PR Close #54394
2024-02-12 11:02:41 -08:00
Kristiyan Kostadinov ef965ac87c test(language-service): add tests for model inputs (#54387)
Updates the language service tests to cover `model()` inputs.

PR Close #54387
2024-02-12 11:01:54 -08:00
Kristiyan Kostadinov 369e96c837 refactor(compiler-cli): split input and model tests (#54387)
Splits up the tests for `input()` and `model()` into separate files.

PR Close #54387
2024-02-12 11:01:54 -08:00
Kristiyan Kostadinov 2363e77002 refactor(compiler-cli): add diagnostic tests for models (#54387)
Sets up type checking diagnostic tests for model() inputs.

PR Close #54387
2024-02-12 11:01:54 -08:00
Kristiyan Kostadinov 1581988d2e test(core): add type tests for ɵunwrapWritableSignal (#54387)
Getting the typing for `ɵunwrapWritableSignal` just right was tricky so these changes add some tests to ensure that we don't regress.

Also reworks the type tester a bit to make it easier to find where to add new test files.

PR Close #54387
2024-02-12 11:01:54 -08:00
Kristiyan Kostadinov 0ecc2d12f1 refactor(core): reuse input signal node for models (#54387)
Reworks the model so that it reuses `INPUT_SIGNAL_NODE` instead of implementing its own.

PR Close #54387
2024-02-12 11:01:53 -08:00
Kristiyan Kostadinov 453e00c9b0 refactor(core): avoid wrapper around subscribe return value (#54387)
Reworks `ModelSignal.subscribe` so it doesn't have to wrap its value to look like a subscription.

PR Close #54387
2024-02-12 11:01:53 -08:00
arturovt 4d722a276f fix(zone.js): patch form-associated custom element callbacks (#50686)
This commit updates the implementation of the `customElements` patch and also
patches FACE callbacks (`formAssociatedCallback`, `formDisabledCallback`, `formResetCallback`
and `formStateRestoreCallback`). This now allows invoking those callbacks in the same zone
where the custom element has been defined.

PR Close #50686
2024-02-12 08:50:57 -08:00
Pawel Kozlowski 744cb1e561 fix(core): return the same children query results if there are no changes (#54392)
Assure that the same readonly array corresponding to the children query results
is returned for cases where a query is marked as dirty but there were no actual
changes to the content of the results array (this can happen if a view is added
and removed thus marking queries as dirty but not influencing final results).

Fixes #54376

PR Close #54392
2024-02-12 08:48:29 -08:00
Joey Perrott deb9ea07c5 refactor(docs-infra): create fast mode (#54364)
Creates a "fast mode" for building the adev site, currently only disabling prerender during fast build.
This is intended to be used for local development.

PR Close #54364
2024-02-09 10:59:08 -08:00
JoostK 62b87b4551 fix(core): do not crash for signal query that does not have any matches (#54353)
The newly introduced signal queries would error if no match exists, due to an
invalid read within the query internals.

This commit addresses the crash by allowing there to be no matches.

PR Close #54353
2024-02-09 14:59:51 +00:00
Hakeem 6c278a9069 docs(docs-infra): change deprecated modules' headers' style in the hover state (#54337)
PR Close #54337
2024-02-09 14:58:56 +00:00
Joey Perrott 5de985a565 fix(docs-infra): include manually defined api reference docs in adev (#54356)
Include the manual defined api reference docs in adev

PR Close #54356
2024-02-09 14:58:29 +00:00
Angular Robot 85c05514be build: update cross-repo angular dependencies (#54186)
See associated pull request for more information.

PR Close #54186
2024-02-09 14:57:46 +00:00
Paul Gschwendtner 7aa92fa8fe release: cut the v17.2.0-rc.1 release 2024-02-09 11:54:07 +01:00
Kristiyan Kostadinov 4b96f370ee fix(core): expose model signal subcribe for type checking purposes (#54357)
The `@internal` in the comment above `ModelSignal.subscribe` ended up marking the method as internal even though it wasn't meant to be.

PR Close #54357
2024-02-09 09:58:56 +00:00
Matthieu Riegler 9e2c1405d1 refactor(devtools): show tooltip for hydration icon on directive forest (#54326)
The MatTooltip was missing after migrating to standalone

PR Close #54326
2024-02-08 19:18:37 +00:00
Joey Perrott 9f05732656 refactor: migrate router to prettier formatting (#54318)
Migrate formatting to prettier for router from clang-format

PR Close #54318
2024-02-08 19:17:14 +00:00
Jessica Janiuk ed41bfcad7 release: cut the v17.2.0-rc.0 release 2024-02-08 10:38:52 -08:00
Jessica Janiuk c47bf63ccd docs: release notes for the v17.1.3 release 2024-02-08 10:20:12 -08:00
cexbrayat 8dea3b5888 test: tidy up signal signal input/query/model signature tests (#54334)
This updates some tests to use the public imports from `@angular/core` now that they are available,
and cleans up useless imports and inaccurate names.

PR Close #54334
2024-02-08 16:49:15 +00:00
Andrew Scott 898a532aef fix(core): Fix possible infinite loop with markForCheck by partially reverting #54074 (#54329)
In some situations, calling `markForCheck` can result in an infinite
loop in seemingly valid scenarios. When a transplanted view is inserted
before its declaration, it gets refreshed in the retry loop of
`detectChanges`. At this point, the `Dirty` flag has been cleared from
all parents. Calling `markForCheck` marks the insertion tree up to the
root `Dirty`. If the declaration is checked again as a result (i.e.
because it has default change detection) and is reachable because its
parent was marked `Dirty`, this can cause an infinite loop. The
declaration is refreshed again, so the insertion is marked for refresh
(again). We enter an infinite loop if the insertion tree always calls
`markForCheck` for some reason (i.e. `{{createReplayObservable() | async}}`).

While the case above does fall into an infinite loop, it also truly is a
problem in the application. While it's not an infinite synchronous loop,
the declaration and insertion are infinitely dirty and will be refreshed
on every change detection round.

Usually `markForCheck` does not have this problem because the `Dirty`
flag is not cleared until the very end of change detection. However, if
the view did not already have the `Dirty` flag set, it is never cleared
because we never entered view refresh. One solution to this problem
could be to clear the `Dirty` flag even after skipping view refresh but
traversing to children.

PR Close #54329
2024-02-08 16:45:20 +00:00
Kristiyan Kostadinov adfc3f0f95 refactor(core): temporarily mark subscribe methods as deprecated (#54342)
The `subscribe` methods on `ModelSignal` and `OutputEmitter` were marked as `@internal` which will break when the TCB needs to reference them. These changes make them `@deprecated` temporarily so we can address the properly later.

PR Close #54342
2024-02-08 16:33:41 +00:00
cexbrayat 38b01a3554 fix(compiler-cli): interpolatedSignalNotInvoked diagnostic for model signals (#54338)
The new `model()` signal introduces a `ModelSignal` type that needs to be handled by the interpolatedSignalNotInvoked diagnostic to catch issues like:

```
<div>{{ myModel }}</div>
```

PR Close #54338
2024-02-08 16:28:20 +00:00
ascorbic 03c3b3eb79 feat(common): add Netlify image loader (#54311)
Add an image loader for Netlify Image CDN. It is slightly different in implementation from existing loaders, because it allows absolute URLs

Fixes #54303

PR Close #54311
2024-02-08 16:17:57 +00:00
Kristiyan Kostadinov 9c2bad9e5e refactor(compiler-cli): avoid naming conflict with built-in global variable (#54333)
The import of `module` can conflict with the native global variable called `module` and can break some internal tests. These switch to only importing the function we need.

PR Close #54333
2024-02-08 14:59:54 +00:00
Kristiyan Kostadinov 44f65f2853 refactor(compiler-cli): work around internal test failure (#54327)
Fixes an internal test failure due to `FatalDiagnosticError` extending the native `Error`.

PR Close #54327
2024-02-08 14:59:24 +00:00
Pawel Kozlowski ca239e8b62 refactor(core): share refresh logic for cd and signal queries (#54322)
Introducing a tiny utility method to remove some code duplication
between the change change detection and signal based queries.

PR Close #54322
2024-02-07 22:22:06 +00:00
Ben Hong a3e51d99a8 docs: enable version picker (#54161)
PR Close #54161
2024-02-07 22:21:05 +00:00
Paul Gschwendtner 38c0084ed2 test: verify signal-based queries in CLI integration test (#54314)
Adds usages of signal-based queries into the signal integration test to
verify queries can be used in production, and testing environments as
expected (i.e. the transform works as expected).

PR Close #54314
2024-02-07 18:56:04 +00:00
Paul Gschwendtner a08863e7e0 refactor(compiler-cli): ensure FatalDiagnosticError extends Error (#54309)
This helps with the Angular CLI currently swallowing fatal diagnostic
errors in ways that are extremely difficult to debug due to workers
executing Angular compiler logic.

The worker logic, via piscina, is currently not forwarding such Angular
errors because those don't extend `Error.`

https://github.com/piscinajs/piscina/blob/a7042ea27d129f3cad75c422f5aa92f0663854ee/src/worker.ts#L175

Even with access to these errors by manually forwarding errors, via
patching of the Angular CLI, there is no stack trace due to us not using
`Error` as base class for fatal diagnostic errors. This commit improves
this for future debugging and also better reporting of such errors to
our users- if we would accidentally leak one.

PR Close #54309
2024-02-07 16:39:21 +00:00
Paul Gschwendtner 8e237a0161 fix(compiler-cli): properly catch fatal diagnostics in type checking (#54309)
An identical addition to: 760b1f3d0b.

This commit expands the `try/catch`-es:

- to properly NOT throw and just convert the diagnostic.
- to be in place for all top-level instances. Notably, this logic cannot
  reside in the template type checker directly as otherwise we would
  risk multiple duplicate diagnostics.

PR Close #54309
2024-02-07 16:39:20 +00:00
Kristiyan Kostadinov e921e108e1 refactor(core): correctly distinguish getter functions from writable signals (#54252)
Fixes that `ɵunwrapWritableSignal` inferring getter functions as not matching the interface of `WritableSignal` instead of preserving them.

PR Close #54252
2024-02-07 16:36:15 +00:00
Kristiyan Kostadinov a4a76c3a38 refactor(core): throw if required model is changed via update too early (#54252)
Adds an assertion that will throw if `ModelSignal.update` is accessed before an initial value is set.

PR Close #54252
2024-02-07 16:36:14 +00:00
Kristiyan Kostadinov ac9c54487e refactor(core): assert writable signal in two-way property instruction (#54252)
Asserts that the value is a `WritableSignal`, rather than a `Signal`, in the `twoWayProperty` instruction.

PR Close #54252
2024-02-07 16:36:14 +00:00
Kristiyan Kostadinov 243b94c6e1 refactor(compiler-cli): fix regression in two-way bindings to inputs with different getter/setter types (#54252)
In a previous commit the TCB was changed to cast the assignment to an input in order to widen its type to allow `WritableSignal`. This ended up breaking existing inputs whose setter has a wider type than its getter. These changes switch to unwrapping the value on the binding side.

PR Close #54252
2024-02-07 16:36:13 +00:00
Kristiyan Kostadinov 551c5791f8 refactor(core): address PR feedback (#54252)
Addresses the feedback from #54252.

PR Close #54252
2024-02-07 16:36:12 +00:00
Kristiyan Kostadinov a17f6cb2d0 refactor(compiler-cli): rework TCB for two-way bindings (#54252)
Reworks the TCB for two-way bindings to make them simpler and to avoid regressions for two-way bindings to generic inputs. The new TCB looks as follows:

```
var _t1: Dir;
var _t2 = _t1.input;
(_t1 as typeof _t2 | WritableSignal<typeof _t2>) = expression;
```

PR Close #54252
2024-02-07 16:36:11 +00:00
Kristiyan Kostadinov 372e1ffd25 refactor(compiler-cli): account for model inputs in language service (#54252)
Updates the code that resolves a node from the TCB to an input in order to fix the language service.

PR Close #54252
2024-02-07 16:36:10 +00:00
Kristiyan Kostadinov 702ab28b4c feat(core): add support for model inputs (#54252)
Adds support for model inputs in the framework. `model()` returns a writable signal that implicitly defines a input/output pair that can be used either in two-way bindings to keep two values in sync or by binding individually to the input and output. When the value of the `model` changes, it will emit an event with the current value.

Furthermore, these changes expand two-way bindings to accept `WritableSignal`. This will make it easier to transition existing code to signals in a backwards-compatible way.

Example:

```ts
@Directive({
  selector: 'counter',
  standalone: true,
  host: {
    '(click)': 'increment()',
  }
})
export class Counter {
  value = model(0);

  increment(): void {
    this.value.update(current => current + 1);
  }
}

@Component({
  template: `<counter [(value)]="count"/> The current count is: {{count()}}`,
})
class App {
  count = signal(0);
}
```

PR Close #54252
2024-02-07 16:36:09 +00:00
Kristiyan Kostadinov d006aa33bf refactor(compiler-cli): add tests for model inputs (#54252)
Adds tests in the compiler to verify the compiled output and template type checking behavior of model inputs.

PR Close #54252
2024-02-07 16:36:08 +00:00
Kristiyan Kostadinov 67b977ea97 refactor(compiler-cli): allow writable signals in two-way bindings (#54252)
Updates the TCB generation logic to allow for `WritableSignal` to be assigned in two-way bindings.

PR Close #54252
2024-02-07 16:36:07 +00:00
Kristiyan Kostadinov 8aac3c45b9 test(core): add runtime acceptance tests for model inputs (#54252)
Sets up the runtime tests for model inputs.

PR Close #54252
2024-02-07 16:36:06 +00:00
Kristiyan Kostadinov 0ea4d7086d refactor(compiler-cli): recognize model fields (#54252)
Adds the logic that recognizes fields initialized to model as an input/output pair.

PR Close #54252
2024-02-07 16:36:05 +00:00
Kristiyan Kostadinov 3faf3e23d5 refactor(core): implement two-way instructions (#54252)
Adds the implementations of the `twoWayProperty` and `twoWayListener` instructions.

PR Close #54252
2024-02-07 16:36:04 +00:00
Kristiyan Kostadinov 06fa029132 refactor(compiler-cli): add jit transform for model inputs (#54252)
Adds a JIT transform that marks `model` fields as `@Input` and `@Output`.

PR Close #54252
2024-02-07 16:36:03 +00:00
Kristiyan Kostadinov ab0c0cb832 refactor(compiler-cli): add function to identify model fields (#54252)
Adds a function to the compiler to help us identify fields initialized to a `model`.

PR Close #54252
2024-02-07 16:36:02 +00:00
Kristiyan Kostadinov 3e0a20d8fe refactor(core): add model implementation (#54252)
Adds the implementation of the `model` primitive that represents a two-way binding signal-based binding.

PR Close #54252
2024-02-07 16:36:01 +00:00
Paul Gschwendtner c023e8d58f refactor(core): improve IDE completion of read option for signal queries (#54280)
This commit improves IDE completion of the `read` option for
signal-based queries.

Currently, TS only matches the first overload when starting out with
defining a query. TS doesn't build up the combination of possible
options from the second overload- so in practice users will only see
IDE completions for the `descendants` option.

This is not a problem for view queries as the only option is `read`, so
TS will always match the overload with the `read` option.

```
class X {
  query = contentChild('', {^^ <--
    here we should completion for `read` an `descendants`
}
```

PR Close #54280
2024-02-07 16:35:14 +00:00
cexbrayat 1fb0da2668 build: simplify husky setup (#54315)
husky v9 simplified its setup, see `How to migrate` in https://github.com/typicode/husky/releases/tag/v9.0.1

PR Close #54315
2024-02-07 16:34:13 +00:00
Jessica Janiuk 0dfbde917c Revert "fix(router): Clear internal transition when navigation finalizes (#54261)" (#54317)
This reverts commit 6681292823.

PR Close #54317
2024-02-07 15:46:38 +00:00
Payam Valadkhan f39cb06418 fix(compiler-cli): show specific error for unresolved @Directive.exportAs in local compilation mode (#54230)
Currently the error is a generic error "exportAs must be a string ...". This commit makes the error more specific to local compilation and adds some action items.

PR Close #54230
2024-02-06 21:33:29 +00:00
Payam Valadkhan f3851b5945 fix(compiler-cli): show specific error for unresolved @HostBinding's argument in local compilation mode (#54230)
Currently the error is a generic error "selector must be a string ...". This commit makes the error more specific to local compilation and adds some action items.

PR Close #54230
2024-02-06 21:33:29 +00:00
Payam Valadkhan 39ddd884e8 fix(compiler-cli): show specific error for unresolved @HostListener's event name in local compilation mode (#54230)
Currently the error is a generic error "selector must be a string ...". This commit makes the error more specific to local compilation and adds some action items.

PR Close #54230
2024-02-06 21:33:29 +00:00
Payam Valadkhan 5d633240fd fix(compiler-cli): show the correct message for the error LOCAL_COMPILATION_UNRESOLVED_CONST when an unresolved symbol used for @Component.styles (#54230)
Currently the correct error message is shown only if @Component.styles is an array with some unresolved element. This change supports the new case of string type for the @Component.styles field.

PR Close #54230
2024-02-06 21:33:29 +00:00
Payam Valadkhan 6c8b09468a fix(compiler-cli): highlight the unresolved element in the @Component.styles array for the error LOCAL_COMPILATION_UNRESOLVED_CONST (#54230)
Currently the whole array is highlighted.

PR Close #54230
2024-02-06 21:33:29 +00:00
Payam Valadkhan acc98a17d9 refactor(compiler-cli): add a helper to generate error LOCAL_COMPILATION_UNRESOLVED_CONST in common scenarios (#54230)
A helper `validateLocalCompilationUnresolvedConst` is added to encapsulate a common pattern which leads to the error `LOCAL_COMPILATION_UNRESOLVED_CONST`.

PR Close #54230
2024-02-06 21:33:29 +00:00
Payam Valadkhan a3de5ba865 refactor(compiler-cli): remove the trailing error message for LOCAL_COMPILATION_UNRESOLVED_CONST (#54230)
The trailing error message comes from tracing the chain of DymaicValue which leads to a mostly useless error that highlights the same symbol as the original message and emits the error message "Unknown reference". This error message is removed in the favour of the original message which suffices.

PR Close #54230
2024-02-06 21:33:29 +00:00
Payam Valadkhan df74ed94e2 refactor(compiler-cli): upgrade error codes and messages for unresolved symbol errors in local compilation mode (#54230)
A single error code is created to unify the common error pattern in local compilation mode where an imported const cannot be resolved, but needs to be resolved. This mainly happens for Angular decorator fields such as @Component.template.

The error messages are also upgraded to be more centered around this unifying theme.

PR Close #54230
2024-02-06 21:33:29 +00:00
Angular Robot b5368eb9a6 build: update dependency marked to v12 (#54296)
See associated pull request for more information.

PR Close #54296
2024-02-06 21:13:49 +00:00
Angular Robot b96c2fec68 build: update dependency jsdom to v24 (#54291)
See associated pull request for more information.

PR Close #54291
2024-02-06 21:10:29 +00:00
Joey Perrott 8efa7cddf7 docs: remove v17 banner from adev (#54287)
PR Close #54287
2024-02-06 21:06:24 +00:00
Alejandro Cuba Ruiz faf3b45d48 docs: add alejandrocuba.jpg file to images/bios/ (#53842)
PR Close #53842
2024-02-06 20:34:01 +00:00
Alejandro Cuba Ruiz f189dbe47a docs: add alejandrocuba to GDE resources (#53842)
PR Close #53842
2024-02-06 20:34:01 +00:00
Andrew Scott 6681292823 fix(router): Clear internal transition when navigation finalizes (#54261)
This commit fixes a small memory issue in the router where a destroyed
component instance would be retained.

fixes #54241

PR Close #54261
2024-02-06 20:32:34 +00:00
Angular Robot c8a973e3b7 build: update dependency husky to v9 (#54289)
See associated pull request for more information.

PR Close #54289
2024-02-06 19:34:46 +00:00
Pawel Kozlowski 43de097704 test(core): enable signal queries tests with authoring (#54283)
Use signal queries tests with the authoring functions and without
decorators.

PR Close #54283
2024-02-06 19:31:58 +00:00
Pawel Kozlowski e95ef2cbc6 feat(core): expose queries as signals (#54283)
This commit exposes authoring functions for queries as signals
thus making those generally available.

PR Close #54283
2024-02-06 19:31:58 +00:00
Angular Robot 0d4e983c24 build: update dependency @types/jasmine to v5 (#54288)
See associated pull request for more information.

PR Close #54288
2024-02-06 19:30:33 +00:00
Angular Robot 297e73c83b build: update dependency jasmine-core to v5 (#54290)
See associated pull request for more information.

PR Close #54290
2024-02-06 19:30:07 +00:00
Joey Perrott 4d29174585 refactor: address prototype polution concern with better typing (#54286)
Update typing to show that a number is being used as index rather than any random string

PR Close #54286
2024-02-06 18:38:47 +00:00
Angular Robot 4287ca8b50 build: update dependency @octokit/graphql to v7 (#53554)
See associated pull request for more information.

PR Close #53554
2024-02-06 18:24:04 +00:00
Angular Robot eeafdb6cf3 build: update dependency firebase-tools to v13 (#54234)
See associated pull request for more information.

PR Close #54234
2024-02-06 18:11:41 +00:00
Angular Robot e9eba6b257 build: update dependency eslint-plugin-jsdoc to v48 (#54202)
See associated pull request for more information.

PR Close #54202
2024-02-06 18:11:12 +00:00
Angular Robot c512987774 build: update babel dependencies (#53222)
See associated pull request for more information.

PR Close #53222
2024-02-06 18:10:40 +00:00
Angular Robot e94942255a build: update all non-major dependencies (#53220)
See associated pull request for more information.

PR Close #53220
2024-02-06 18:10:11 +00:00
Angular Robot 2d3fc31c83 docs: update Angular CLI help [main] (#54276)
Updated Angular CLI help contents.

PR Close #54276
2024-02-06 18:09:46 +00:00
Joey Perrott 0763fba97f build: update to latest @angular/docs (#54282)
Update to the latest version of angular docs from dev-infra

PR Close #54282
2024-02-06 17:54:43 +00:00
ilir.beqiri 6ef60c0a1a docs: replace event word with property for binding properties link (#54281)
Replace the "event" word with the correct one "property" at the helpful text on event binding section

PR Close #54281
2024-02-06 17:45:11 +00:00
Paul Gschwendtner bfbb30618b fix(compiler-cli): do not error due to multiple components named equally (#54273)
Currently, when two components are named `TestComponent`, and both would
use e.g. control flow. Templates would be generated by the compiler and
those would conflict at runtime because the names for the template
functions are not ensured to be unique.

This seems like a more general problem that could be tackled in the
future in the template pipeline by always using the `ConstantPool`, but
for now, we should be good already, given us ensuring the `baseName`'s are
always unique.

PR Close #54273
2024-02-06 17:33:23 +00:00
arturovt 19fae76bad fix(zone.js): patch fs.realpath.native as macrotask (#54208)
This commit updates the implementation of the zone.js `fs` patch to
restore the implementation of `realpath.native` and patches it as a macrotask,
along with other functions of the `fs` package. This is the only nested function
that must be patched.

Closes: #45546

PR Close #54208
2024-02-06 16:04:40 +00:00
Paul Gschwendtner f8c02b69b9 refactor(compiler-cli): restrict read option values for signal-based queries (#54257)
The `read` option for queries can rely on lexical variables inside the
class. These constructs are fine from a technical perspective in
TypeScript, but in practice, when the component/directive definition is
being created, the read value is extracted into the definition,
**outside** of the class. This breaks `this` references.

To fix this, we are restricting the `read` option to literal values.
Similar to `descendants`. Literal references are in practice constructs
like:

 - `read: bla.X`
 - `read: X`

 where `bla` or `X` is never a `ThisKeywoord`- hence fixing the issue
 and also simplifying the patterns for easier single file compilation.

PR Close #54257
2024-02-06 16:04:10 +00:00
Paul Gschwendtner 902481b6ec refactor(compiler-cli): add JIT transform for signal-based queries (#54257)
This commit adds a JIT transform for signal-based queries, so that
queries are working as expected in JIT environments like `ng test` where
decorator metadata is needed as a prerequisite for the component
definition creation.

This is similar to the JIT transforms for signal inputs etc.

PR Close #54257
2024-02-06 16:04:10 +00:00
Paul Gschwendtner 351426853d refactor(compiler-cli): extract common JIT transform helper into transform API (#54257)
Extracts common JIT transform helper into the transform API, so that
those helpers can be re-used for output, model, queries and inputs.

PR Close #54257
2024-02-06 16:04:10 +00:00
Paul Gschwendtner 1d077fca10 refactor(compiler-cli): expose query function detection logic for JIT transform (#54257)
This commit exposes the query function detection logic so that it can
be used in the JIT transform later on.

PR Close #54257
2024-02-06 16:04:10 +00:00
Paul Gschwendtner 4851453735 ci: add debug information for failing firebase deploy (#54275)
Adding debug information for failing firebase deploy, hoping
to yield information about the missing resource. The next
multi-site seems to be failing, but is available.

PR Close #54275
2024-02-06 15:23:13 +00:00
Pawel Kozlowski 99bfbabe50 refactor(core): break circular dependencies in preparation for queries as signals (#54103)
Break circular dependencies by using type imports and code moves.

PR Close #54103
2024-02-06 15:04:36 +00:00
Pawel Kozlowski 84d1fa7c56 refactor(core): pull compileNgModuleFactory out of application_ref (#54103)
The compileNgModuleFactory dont need to be in the application_ref file (in fact
the whole logic has little to do with ApplicationRef and it is not even called
from the application_ref). Performing this move to avoid circular dependencies
when the new query as signals authoring functions are exported.

PR Close #54103
2024-02-06 15:04:36 +00:00
Pawel Kozlowski 3a2ce9e0a2 refactor(core): add error code for required query results (#54103)
This commit introduces a dedicated error code for queries that require
results but none are available.

PR Close #54103
2024-02-06 15:04:36 +00:00
Pawel Kozlowski 20008a6b56 refactor(core): rework runtime implementation to simplify and fix issues (#54103)
This commit changes the approach to the reactive node representing query
results: instead of creating a custom node type we can use a computed -
the main change to get there is representing dirty change notification as
a signal (a counter updated every time a query changes its dirty status).

This change is dictated by simplification (we can avoid creation of a custom
signal type) as well as fixes to the multiple issues not covered by the
initial implementation:
- assuring referential stability of results (ex.: the same array instance
  returned from child queries until results change);
- per-view results collection to avoid a situation where accessing query
  results during view creation would return partial / inconsistent results;
- proper refresh of query results for both live and non-connected consumers.

All the above cases are covered by the additional tests in this commit.

PR Close #54103
2024-02-06 15:04:36 +00:00
Pawel Kozlowski 1aa63c158b refactor(core): enable content query as signal tests (#54103)
This commit adds tests for content queries and fixes the arguments
order in the contentQuerySignal instruction, thus fixing a bug
discovered while adding tests.

PR Close #54103
2024-02-06 15:04:36 +00:00
Pawel Kozlowski 26b11b5b0e test(core): convert query-as-signals test to the compiled ones (#54103)
This commits converts the hand-written tests into their usual,
compiled form. We can perform this change now since the compiler
bits of the queries-as-signal story landed.

PR Close #54103
2024-02-06 15:04:36 +00:00
Jessica Janiuk e46c08170f Revert "fix(compiler-cli): consider the case of duplicate Angular decorators in local compilation diagnostics (#54139)" (#54264)
This reverts commit 4b1d948b36.

PR Close #54264
2024-02-05 18:18:47 +00:00
Jessica Janiuk bd43aa39a8 Revert "fix(compiler-cli): allow custom/duplicate decorators for @Injectable classes in local compilation mode (#54139)" (#54264)
This reverts commit a592904c69.

PR Close #54264
2024-02-05 18:18:47 +00:00
Jessica Janiuk a2af706855 Revert "fix(compiler-cli): forbid custom/duplicate decorator when option forbidOrphanComponents is set (#54139)" (#54264)
This reverts commit 96bcf4fb12.

PR Close #54264
2024-02-05 18:18:47 +00:00
Jason Warner d339941a0d docs: add Jason Warner to GDE resources (#54237)
PR Close #54237
2024-02-05 16:40:57 +00:00
Andrew Kushnir 1090570781 refactor(core): avoid reusing argument name as a local const (#54239)
This refactoring renames a local variable to make sure we do not reuse an argument name, which can lead to confusion and bugs.

PR Close #54239
2024-02-05 15:15:17 +00:00
Andrew Kushnir 90fb623614 refactor(core): create pending task while defer block loading is in progress (#54239)
This commit updates the logic of defer blocks to create an internal pending task to indicate that an application is not yet stable. This change would be helpful for zoneless applications.

PR Close #54239
2024-02-05 15:15:17 +00:00
Matthieu Riegler f5e5543732 docs: remove an outdated comment. (#54243)
Note: We still expect `ngOnChanges` to not be supported in future signal components.

PR Close #54243
2024-02-05 15:09:40 +00:00
Paul Gschwendtner 8ac4f7d4ef refactor: support multiple acceptance spec files with JIT transforms (#54253)
Updates the acceptance authoring test compiler targets to support
multiple spec files. This will be useful for output, model, inputs
and queries.

PR Close #54253
2024-02-05 15:09:00 +00:00
Paul Gschwendtner 6cb47a7c9d test: verify output() in signals integration test (#54217)
Adds `output()` to the signal inputs integration test to verify
full integration with the Angular CLI. In the future we may
consider renaming the test to something less specific to signal inputs,
but for now this serves the purpose and `output()` is a closely related
part to signal-based inputs.

it doesn't warrant creating another new integration test, as those are
quite expensive to maintain and run.

PR Close #54217
2024-02-05 15:08:35 +00:00
Paul Gschwendtner efcec0a290 refactor(core): improve type safety for listener instruction (#54217)
The `listener` instruction currently always assumes RxJS subscribables,
and verifies this via `isSubscribable`. The type narrowing is not
ignored and the type remains `any` given the `ngDevMode` check.

This commit improves type safety, and actually switches to a dedicated
interface for "output subscribable" values. This is needed because
`Subscribable` from `RxJS` is typed to expect an observer in object
literal form- which is not correct and doesn't apply to `EventEmitter`
and matches the form of `.subscribe` we are using in the `listener`
instruction.

PR Close #54217
2024-02-05 15:08:35 +00:00
Paul Gschwendtner 02fdd8d6ee test: add tests to verify language-service supports output() function (#54217)
Adds unit tests to verify that the language service supports
the `output()` function with completions, and definition jumping.

PR Close #54217
2024-02-05 15:08:35 +00:00
Paul Gschwendtner ee635f9aa6 test: add language-service test for type definition of signal inputs (#54217)
Adds an extra unit test for the language-service to verify that type
definitions for signal-based inputs can be resolved.

PR Close #54217
2024-02-05 15:08:35 +00:00
Paul Gschwendtner b285b1402c refactor(compiler-cli): introduce JIT transform for new output() initializer API (#54217)
Similar to `input()`, initializer-based `output()`'s need to be
transformed in JIT to be annotated with an `@Output()` decorator.

This is necessary so that Angular can statically collect all defined
outputs without instantiating the class (which would not be possible
upon directive definition computation).

This commit introduces a transform next to the input transform that
automatically runs with the Angular CLI and `ng test`.

PR Close #54217
2024-02-05 15:08:35 +00:00
Paul Gschwendtner 55040fb80b test: add type check diagnostic tests for output() API (#54217)
Adds type check diagnostic tests for the `output()` API. This
is necessary because we are maintaining a separate emitter
for `output()` as with the current design (still discussed - but this is
a starting foundation).

Note: `OutputEmitter` currently does not publicly expose `.subscribe`,
while the testing infrastructure exposes it for now. That is because we
are still discussing this before making changes in the TCB to account
for the case where `.subscribe` might be `@internal` ultimately.

PR Close #54217
2024-02-05 15:08:35 +00:00
Paul Gschwendtner 0e9e401ca1 test: generalize type check scenario testing helpers (#54217)
Generalizes the type check table scenario testing infrastructure
so that it can also be used for testing outputs in a table-scheme
without a lot of TS code repetition.

PR Close #54217
2024-02-05 15:08:34 +00:00
Paul Gschwendtner aa4157cc54 test: add ngtsc compiler test for output() (#54217)
Adds an ngtsc diagnostic and compilation output test for `output()`. The
test will verify certain recognition restrictions and ensures that
diagnostics are raised, in addition to proper full compilation output
being generated (aside from the compliance tests verifying output more
closely).

PR Close #54217
2024-02-05 15:08:34 +00:00
Paul Gschwendtner 65de61ba0d test: add compliance output tests for output() (#54217)
Adds compliance output tests for `output()` to verify that
we are emitting proper full compilation output, as well as proper
partial compilation output that can be linked to match the full output.

PR Close #54217
2024-02-05 15:08:34 +00:00
Paul Gschwendtner c05e1042b4 refactor(core): introduce output() signature and runtime code (#54217)
This commit introduces the `output()` function and corresponding
runtime code.

In practice, `output()` will defer to `EventEmitter` as outlined in the
RFC, but we are considering limiting the type to a minimal version that
is not coupled with RxJS, less complex, and also has better type safety
around emitting of values.

E.g. currently `EventEmitter.emit` can always be called without
any value, even though the output may be typed to always pass around
values of type `T`. This could cause subtle and confusing bugs.

PR Close #54217
2024-02-05 15:08:34 +00:00
Paul Gschwendtner f7da77b90d refactor(compiler-cli): detect output() function (#54217)
As we are introducing the new `output()` function as an inituive
alternative to `@Output()` that matches with signal-based inputs,
this commit prepares the compiler to detect such initializer-based
outputs.

PR Close #54217
2024-02-05 15:08:34 +00:00
Payam Valadkhan 96bcf4fb12 fix(compiler-cli): forbid custom/duplicate decorator when option forbidOrphanComponents is set (#54139)
The deps tracker which is responsible to track orphan components does not work for classes mutated by custom decorator. Some work needed to make this happen (tracked in b/320536434). As a result, with option `forbidOrphanComponents` being true the deps tracker will falsely report any component as orphan if it or its NgModule have custom/duplicate decorators. So it is unsafe to use this option in the presence of custom/duplicate decorator and we disable it until it is made compatible. Note that applying custom/duplicate decorators to `@Injectable` classes is ok since these classes never make it into the deps tracker. So we excempt them.

PR Close #54139
2024-02-05 15:07:40 +00:00
Payam Valadkhan a592904c69 fix(compiler-cli): allow custom/duplicate decorators for @Injectable classes in local compilation mode (#54139)
Custom/duplicate decorators break the deps tracker in local mode. But deps tracker only deals with non-injectable classes. So applying custom/duplicate decorators to `@Injectable` only classes does not disturb deps tracker and local compilation in general. There are also ~ 100 such cases in g3 which cannot be cleaned up.

PR Close #54139
2024-02-05 15:07:40 +00:00
Payam Valadkhan 4b1d948b36 fix(compiler-cli): consider the case of duplicate Angular decorators in local compilation diagnostics (#54139)
For cases like this:

```
@Component({...})
@Component({...})
export class SomeComp {
}
```

The `DecoratorHandler.detect` apparantly matches only one of the `@Component` decorator, leaving the other undetected which will be transformed by TS decorator helper and that breaks local compilation runtimes. But the error message only mentioned "custom" decorator, while in this case it is a "duplicate Angular" decorator. The respective error message is updated thus.

PR Close #54139
2024-02-05 15:07:40 +00:00
László Czöndör 3b1926acdb docs: fix typo in inject-based DI tutorial (#54245)
PR Close #54245
2024-02-05 15:06:11 +00:00
Nigro Simone 350081d445 refactor(docs): fix typo (#54247)
PR Close #54247
2024-02-05 15:05:36 +00:00
Angular Robot 2ab536ee3e docs: update Angular CLI help [main] (#54223)
Updated Angular CLI help contents.

PR Close #54223
2024-02-02 22:01:16 +00:00
Dylan Hunn f600f0fb27 refactor(compiler): Show an error when a property binding duplicates an i18n attribute (#54063)
Consider the following very quirky Angular template, which has both an i18n attribute binding and a property binding to `in`:
```
<cmp [in]="foo" in="bar" i18n-in />
```

What would you expect the above template to do? `TemplateDefinitionBuilder` will emit the following Ivy instructions:
```
// Element constant attributes
consts: () => {
    __i18nMsg__('bar', [], {}, {})
    return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
    if (rf & 1) {
        // Create mode
        i0.ɵɵelement(0, "cmp", 0);
    }
}
```

This makes some sense -- we create a single element, and attach an i18n message to the `in` attribute. But is this actually correct? Notice that the property binding is completely missing!

Indeed, Template Pipeline actually produces this code:
```
// Element constant attributes
consts: () => {
    __i18nMsg__('bar', [], {}, {})
    return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
    if (rf & 1) {
        // Create mode
        i0.ɵɵelement(0, "cmp", 0);
    } else if (rf & 2) {
        // Update mode
        i0.ɵɵproperty("in", ctx.foo);
    }
}
```

Aha! There's the property binding! Arguably, this is a bug in `TemplateDefinitionBuilder`, but after some discussion on Slack, we have decided to ban this practice in a future Angular version.

For now, we allow Template Pipeline to have slightly different output, but print an error to warn the user of the issue.

PR Close #54063
2024-02-02 20:52:39 +00:00
Dylan Hunn 8d230e1259 refactor(compiler): Fix a source maps i18n test for Template Pipeline (#54063)
TemplateDefinitionBuilder and Template Pipeline choose different const array orders, which is fine. Update the tests to reflect that.

PR Close #54063
2024-02-02 20:52:39 +00:00
Andrew Scott 74aa8a3888 test(core): ExpressionChanged... error does not happen with signals (#54206)
This test ensures that the `ExpressionChanged...` error does not happen
when signals are updated in a view that is attached to `ApplicationRef`
but was already checked. This was fixed in 432afd1ef4
which actually consequently fixes it for regular `markForCheck` as well.

PR Close #54206
2024-02-02 14:51:46 +00:00
Kristiyan Kostadinov fc5fe3e8e9 build: rework signals acceptance tests build setup (#54213)
* Renames the `input_signals` directory to `signals` so it can be reused for other tests.
* Reworks the build file to allow multiple test files.

PR Close #54213
2024-02-02 14:51:18 +00:00
mooyil bdf6927125 docs: remove outdated info about ng serve (#53890)
PR Close #53890
2024-02-01 23:00:18 +00:00
Thabo 32d0742348 docs: fix typo in router.md (#54194)
Correct spelling mistake

PR Close #54194
2024-02-01 22:31:48 +00:00
Andrew Scott 3cf612c857 fix(core): update imports to be compatible with rxjs 6 (#54193)
Peer dependency range allows for rxjs 6. We cannot use features only
available in rxjs 7 unless that changes.

fixes #54192

PR Close #54193
2024-02-01 20:48:19 +00:00
Samuel Marks 908baecf1e [aio/src/styles/custom-themes/{dark,light}-theme.scss] Change theme definitions to resolve warning "Angular Material themes should be created from a map" (#53717)
PR Close #53717
2024-02-01 20:18:42 +00:00
Lars Gyrup Brink Nielsen 0e150c4ae9 docs: correct TypeScript version range for 17.0.x (#53213)
PR Close #53213
2024-02-01 20:07:32 +00:00
Mateusz Daniluk de777afbc5 refactor: standardize doctype declaration to <!DOCTYPE html> (#51052)
This commit standardizes the doctype declaration across all HTML files in the project to use `<!DOCTYPE html>`

PR Close #51052
2024-02-01 19:29:46 +00:00
Matthieu Riegler 7b2b0f40e2 refactor(core): Guard assertion with ngDevMode (#53764)
`assertDefined` is always guarded elsewhere

PR Close #53764
2024-02-01 19:28:08 +00:00
Matthieu Riegler bc81440b25 docs(docs-infra): Remove the edit button from AIO (#54204)
As a move to reduce PRs toward AIO we drop the edit button and recommend users to use ADEV instead and make suggestions there.

PR Close #54204
2024-02-01 18:54:55 +00:00
Jessica Janiuk 5d98a023bc ci: Add framework team to adev approvers (#54082)
This adds the entire framework team to the adev approvers list.

PR Close #54082
2024-02-01 17:44:59 +00:00
Angular Robot 36a9bf3d6a build: update actions/checkout action to v4 (#54183)
See associated pull request for more information.

PR Close #54183
2024-02-01 16:02:47 +00:00
Paul Gschwendtner d74ee6e343 refactor(compiler-cli): group initializer-API based transforms into single transform (#54200)
Instead of maintaining individual transforms for `input`, `output`,
`model` etc. we are grouping them directly and the first one matching,
will execute.

This reduces needed traversal through AST and also makes it a little
more clean to write new initializer API metadata transforms.

Note: The Angular JIT transform is now also moving from `tooling.ts`
directly into `/transformers` for more local placement of transformer
logic.

PR Close #54200
2024-02-01 15:58:50 +00:00
Kristiyan Kostadinov d89d5230a7 refactor(compiler-cli): allow signal input transform to be reused (#54200)
Splits up the signal input transform so that it can be reused for other signal-based properties.

PR Close #54200
2024-02-01 15:58:50 +00:00
Kristiyan Kostadinov 50b22a4260 refactor(core): move input signals into own directory (#54200)
Moves the signal input code into its own directory to avoid too many files in the `authoring` root once model inputs are introduced.

PR Close #54200
2024-02-01 15:58:50 +00:00
Kristiyan Kostadinov 95dcf5fafa fix(compiler-cli): handle default imports in defer blocks (#53695)
Fixes that `@defer` blocks weren't recognizing default imports and generating the proper code for them. Default symbols need to be accessed through the `default` property in the `import` statement, rather than by their name.

PR Close #53695
2024-02-01 15:58:21 +00:00
Ezéchiel Amen AGBLA ebbacb9d45 docs: more readable standalone importing component example (#54196)
PR Close #54196
2024-02-01 15:57:51 +00:00
Kristiyan Kostadinov 3b892e98b0 refactor(compiler): update ordering in template pipeline (#54154)
Updates the instruction ordering logic in the template pipeline.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov ec8e8ab5d5 refactor(compiler): maintain order between two-way and one-way properties (#54154)
One of the earlier commits separated one-way and two-way bindings which ended up breaking some internal targets, because it changed the assignment order. These changes bring back the old order.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov cbe6e1ffcf refactor(compiler): allow some invalid expressions in two-way bindings that previously worked by accident (#54154)
In one of the earlier commits, the logic that appends `=$event` before parsing two-way bindings was removed and some validation was added to prevent unassignable expressions from being used. This ended up being problematic, because previously the parser was incorrectly allowing some invalid expressions which users came to depend on. For example, it transformed `[(value)]="a && a.b"` to `a && (a.b = $event)`.

These changes add some special cases for the common breakages that came up during the TGP.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov cbdfc88b24 refactor(compiler): implement new two-way listener shape in pipeline (#54154)
Implements the new shape of two-way listener instructions in the template pipeline.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov 4babc47b31 refactor(compiler): update two-way listener emit in definition builder (#54154)
Updates the template definition builder to emit the new format for the listener side of two-way bindings.

```js
// Before
listener("ngModelChange", function($event) {
  return ctx.name = $event;
});

// After
ɵɵtwoWayListener("ngModelChange", function($event) {
  ɵɵtwoWayBindingSet(ctx.name, $event) || (ctx.name = $event);
  return $event;
});
```

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov a436e2d5ea refactor(compiler): preserve expression in two-way listeners (#54154)
Currently the listener side two-way listeners are parsed by appending `=$event` to the raw expression. This is problematic, because:
1. It can interfere with other expressions (see #37809).
2. It can lead to confusing error messages because users will see code that they didn't write.
3. It doesn't allow us to further manipulate the expression.

These changes remove the logic that appends `=$event` to resolve the issue. There's also some new logic that checks the expression after it has been parsed to ensure that the result is an assignable expression.

Subsequent commits will update the code that emits the expression to add back the `$event` assignment where it's needed.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov e7a75d3ec2 refactor(core): introduce two-way listener instructions (#54154)
Adds the following new instructions:
* `twoWayBindingSet` - used to assign values inside of the listener side of a two-way binding. Currently a noop, but will come into play later.
* `twoWayListener` - used to bind a two-way listener. Currently calls directly into `listener`, but it may be useful in the future.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov a22d765cca refactor(compiler): update access of members in expression parser (#54154)
Currently all the members of `_ParseAST` are public, even though they're all used only within the class. This change marks them as private so that it's explicit which ones are intended to be used outside the class.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov ea7d1b363f refactor(compiler): implement two-way property instruction (#54154)
Reworks the compiler so that it generates a `twoWayProperty` instruction, instead of `property`, for the property side of a two-way binding. Currently the new instruction passes through to `property`, but it'll have some two-way-binding-specific logic in subsequent PRs.

PR Close #54154
2024-02-01 14:39:32 +00:00
Joey Perrott 70d0fb088e refactor(docs-infra): migrate to using docs- prefix for class names rather than adev- for shared pieces (#54188)
Updates to later version of shared docs with prefix renamed.

PR Close #54188
2024-01-31 21:49:23 +00:00
Andrew Scott 432afd1ef4 fix(core): afterRender hooks should allow updating state (#54074)
It was always the intent to have `afterRender` hooks allow updating
state, as long as those state updates specifically mark views for
(re)check. This commit delivers that behavior. Developers can now use
`afterRender` hooks to perform further updates within the same change
detection cycle rather than needing to defer this work to another round
(i.e. `queueMicrotask(() => <<updateState>>)`). This is an important
change to support migrating from the `queueMicrotask`-style deferred
updates, which are not entirely compatible with zoneless or event `NgZone` run
coalescing.

When using a microtask to update state after a render, it
doesn't work with coalescing because the render may not have happened
yet (coalescing and zoneless use `requestAnimationFrame` while the
default for `NgZone` is effectively a microtask-based change detection
scheduler). Second, when using a `microtask` _during_ change detection to defer
updates to the next cycle, this can cause updates to be split across
multiple frames with run coalescing and with zoneless (again, because of
`requestAnimationFrame`/`macrotask` change detection scheduling).

PR Close #54074
2024-01-31 20:19:06 +00:00
Andrew Scott 33e5abd4f9 refactor(core): only run checkNoChanges once per tick (#54074)
This change updates the `checkNoChanges` pass to only run once after
both view refresh and `afterRender` hooks execute rather than both
before and after the hooks. The original motivation was to specifically
ensure that the application was in a "clean state" before running the
`afterRender` hooks and ensure that `afterRender` hooks don't "fix"
`ExpressionChanged...` errors. This, however, adds to the complexity and
cost of running change detection in dev mode. Instead, the
`checkNoChanges` pass runs once we have done all render-related work and
want to ensure that the application state has been synced to the DOM
(without additional changes).

PR Close #54074
2024-01-31 20:19:06 +00:00
Andrew Scott ecaf7ceae0 refactor(core): Do not run afterRender hooks if there is an error (#54074)
Errors during change detection are terminal and we do not generally
attempt to continue processing or recover after one occurs. This helps clean
up the `tick` implementation with respect to running `afterRender` hooks.

PR Close #54074
2024-01-31 20:19:06 +00:00
Angular Robot 989d496708 build: update cross-repo angular dependencies (#54178)
See associated pull request for more information.

PR Close #54178
2024-01-31 20:13:06 +00:00
Angular Robot 0a67085289 build: update actions/cache action to v4 (#54179)
See associated pull request for more information.

PR Close #54179
2024-01-31 19:45:54 +00:00
Jessica Janiuk 2d20c4a25b release: cut the v17.2.0-next.1 release 2024-01-31 11:29:36 -08:00
Jessica Janiuk 0465a4c5d0 docs: release notes for the v17.1.2 release 2024-01-31 11:07:39 -08:00
Ivan Zlatanov 4f7edaa478 refactor(router): RouterLink read urlTree only once (#53817)
In RouterLink, urlTree is created every time we access it, so when used we should read it only once.

PR Close #53817
2024-01-31 17:37:12 +00:00
Angular Robot 441a23cb8b build: update actions/cache digest to e12d46a (#54176)
See associated pull request for more information.

PR Close #54176
2024-01-31 17:36:28 +00:00
Angular Robot 4b11e0c15d build: update actions/checkout digest to f43a0e5 (#54177)
See associated pull request for more information.

PR Close #54177
2024-01-31 17:35:59 +00:00
Angular Robot f5ede2ab63 build: update slackapi/slack-github-action digest to 2a8087d (#52000)
See associated pull request for more information.

PR Close #52000
2024-01-31 16:47:31 +00:00
narendherraj 318a181d8e docs: fix link missing to lazy loading module (#54113)
author narendherraj <narendherraj@gmail.com> 1706354106 +0530
committer narendherraj <narendherraj@gmail.com> 1706718969 +0530

docs: fix link missing to lazy loading module

docs: fix link missing to lazy loading module

docs: fix link missing lazy loading module updated

PR Close #54113
2024-01-31 16:45:51 +00:00
Angular Robot 1a918b397e build: update io_bazel_rules_sass digest to d970cb5 (#52388)
See associated pull request for more information.

PR Close #52388
2024-01-31 16:45:07 +00:00
Matthieu Riegler 122213d37d fix(common): The date pipe should return ISO format for week and week-year as intended in the unit test. (#53879)
ISO 8601 defines
* Monday as the first day of the week.
* week 01 is the week with the first Thursday

Therefore:
Sunday Dec 31st 2023 is the last day of the last week of the year : W52 2023.

PR Close #53879
2024-01-31 16:41:10 +00:00
Alejandro a297012839 docs(docs-infra): add tab titles to home, playground and tutorial (#53026)
PR Close #53026
2024-01-31 16:30:49 +00:00
Paweł Kubiak 2e2e8aad9b test(docs-infra): unit tests in the reference pages (#53529)
Implementation of additional unit tests for `Reference` pages in `adev`.

PR Close #53529
2024-01-31 16:13:31 +00:00
Jared Bada 34feb4f32d docs(docs-infra): @input getter setter syntax change (#51023)
PR Close #51023
2024-01-31 16:04:04 +00:00
kabrunko-dev b02cf14525 fix(docs-infra): sort api reference items (#54116)
Sort correctly items from angular.dev api reference secondary navigation menu

PR Close #54116
2024-01-31 15:44:23 +00:00
Elias b9aa25ed23 docs: Fix minor grammar mistake (#54094)
PR Close #54094
2024-01-31 15:34:26 +00:00
vatsa03 d8f417bf10 docs(core): fix example sections (#54121)
PR Close #54121
2024-01-31 15:22:30 +00:00
Matthieu Riegler 4a44f73288 docs: Update docs about equality. (#54158)
Since v17, `ngSwitch` uses a strict equality.

Fixes #54156

PR Close #54158
2024-01-31 15:07:52 +00:00
arturovt 260d3ed0d9 fix(zone.js): patch Response methods returned by fetch (#50653)
This commit updates the implementation of the `fetch` patch and additionally
patches `Response` methods which return promises. These are `arrayBuffer`, `blob`,
`formData`, `json` and `text`. This fixes the issue when zone becomes stable too early
before all of the `fetch` tasks complete. Given the following code:
```ts
appRef.isStable.subscribe(console.log);
fetch(...).then(response => response.json()).then(console.log);
```
The `isStable` observer would log `false, true, false, true`. This was happening because
`json()` was returning a native promise (and not a `ZoneAwarePromise`). But calling `then`
on the native promise returns a `ZoneAwarePromise` which notifies Angular about the task
being scheduled and forces to re-calculate the `isStable` state.

Issue: #50327

PR Close #50653
2024-01-31 14:57:25 +00:00
arturovt f87f058a69 fix(zone.js): add __Zone_ignore_on_properties to ZoneGlobalConfigurations (#50737)
This commit updates the signature of the `ZoneGlobalConfigurations` interface and adds
missing `__Zone_ignore_on_properties` property, which may be setup to ignore specific `on`
properties from being patched.

PR Close #50737
2024-01-31 14:56:57 +00:00
Matthieu Riegler d6e4931c68 refactor(router): remove duplicate helper methods (#53762)
`isNavigationCancelingError` & `isRedirectingNavigationCancelingError` had duplicate implementations. This commit also cleans-up those functions.

PR Close #53762
2024-01-31 14:56:24 +00:00
Matthieu Riegler e67b9a46f6 refactor(forms): Provide RadioControlRegistry in root. (#54130)
The `RadioControlRegistry` was only provided in a module, providedIn: 'root' fixes that issue.

Fixes #54117

Co-authored-by: sr5434 <118690585+sr5434@users.noreply.github.com>

PR Close #54130
2024-01-31 14:55:56 +00:00
ahmadhakeem18 6ec2f07f5d docs: focus on the respective card of the current active line while scrolling (#53733)
make the active cards have the focus while scrolling like their
respective lines in the scroll service

PR Close #53733
2024-01-30 21:27:55 +00:00
Joey Perrott c4b880a025 refactor: migrate docs, examples, private, service worker and upgrade to prettier formatting (#54163)
Migrate formatting to prettier for docs, examples, private, service worker and upgrade from clang-format

PR Close #54163
2024-01-30 20:08:40 +00:00
Matthieu Riegler b560e02cdf refactor(devtools): Add hydration informations (#53910)
This commit adds hydration informations to the devtools.
* List of hydrated/hydrated components
* Shows hydration overlays
* Shows hydration errors for NG0500, 501 & 502

PR Close #53910
2024-01-30 20:03:14 +00:00
Mahdi Lazraq 274a489bb5 docs: fix path to housing location css file in lesson 03 (#54106)
PR Close #54106
2024-01-30 17:50:11 +00:00
Joey Perrott 0460a9dfaf refactor: migrate common to prettier formatting (#54150)
Migrate formatting to prettier for common from clang-format

PR Close #54150
2024-01-30 16:08:07 +00:00
kabrunko-dev f3567bbc26 refactor(common): simplify i18n plural and select pipe metadata (#53939)
Remove pure property from pipe decorator

PR Close #53939
2024-01-30 15:06:24 +00:00
kabrunko-dev 3c881acc5d refactor(common): simplify date pipe metadata (#53939)
Remove pure property from date pipe decorator

PR Close #53939
2024-01-30 15:06:24 +00:00
Payam Valadkhan 64fa5715c6 fix(compiler-cli): generating extra imports in local compilation mode when cycle is introduced (#53543)
At the moment the extra import generation in local compilation mode fails if these extra imports produce a cycle. To handle this, the cycle handling strategy is updated for local compilation, and following the behaviour in the full compilation mode, the compiler does not generate extra import if it leads to cycle and instead leave things to the runtime.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan 7e861c640e feat(compiler-cli): generate extra imports for component local dependencies in local mode (#53543)
With option `generateExtraImportsInLocalMode` set, in local mode the compiler generates extra imports for each component local dependencies. Here local dependencies means all component's dependencies within the same compilation unit.

To achieve this, the compiler performs a "local version" of its regular static analysis to find each component's deps, and these deps are used to generate extra side effect imports.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan f6e9dbbe73 refactor(compiler-cli): run resolve phase fully for components in local mode when generateExtraImportsInLocalMode is set (#53543)
In this commit the resolve method for components is run fully when the option `generateExtraImportsInLocalMode` is set. This is because we need local component depedencies in order to generate extra imports causing by them. This requires cutting some resolve phase logics that are unnecessary in local mode, such as diagnostics.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan 6a136d1ab3 refactor(compiler-cli): run register phase in local compilation mode (#53543)
When option `generateExtraImportsInLocalMode` is set, we need to compute component local depednecies in order to generate extra imports related to them. At the same time running the register phase in general is harmless in local compilation. So we run it anyway.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan 3263df23f2 feat(compiler-cli): generate global imports in local compilation mode (#53543)
With option `generateExtraImportsInLocalMode` set in local compilation mode, the compiler generates extra side effect imports using this rule: any external module from which an identifier is imported into an NgModule will be added as side effect import to every file in the compilation unit. To illustrate this better assume the compilation unit has source files `a.ts` and `b.ts`, and:

```
// a.ts
import {SomeExternalStuff} from 'path/to/some_where';
import {SomeExternalStuff2} from 'path/to/some_where2';

...

@NgModule({imports: [SomeExternalStuff]})

```

then the extra import `import "path/to/some_where"` will be added to both `a.js` and `b.js`. Note that this is not the case for `import "path/to/some_where2"` though, since the symbol `SomeExternalStuff2` is not imported into any NgModule.

The math behind this mechanism is, in local compilation mode we cannot resolve component external dependencies fully. For example if a component in `a.ts` uses an external component defined in an external file `some_external_comp.ts` then we can generate the import to this file in `a.js`. Instead, we want to generate an import to a file that "gurantees" that `a.js` is placed after `some_external_comp.js` in the bundle. Now since the component in  `some_external_comp.ts` is used in `a.ts`, then there must be a chain of imports starting from the NgModule that declares the component in `a.ts` to the component in `some_external_comp.ts`. This chain means some file in the same compilation unit as `a.ts` should import some external NgModule which includes `some_external_comp.ts` in its transitive closure and import it to some NgModule. So by adding this import to `a.js` we ensure that the bundling will have the right order.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan 5feed80523 refactor(bazel): make option generateExtraImportsInLocalMode configurable (#53543)
This is to allow testing this option using bazel

PR Close #53543
2024-01-30 15:05:42 +00:00
Payam Valadkhan 8c36f2d6f1 refactor(compiler-cli): ability to generate side effect imports (#53543)
As the first step,  the import manager's `generateSideEffectImport` method is implemented to enable it to store info for side effect imports. Next, the helper `addImports` is modified to be able to generate correct statement for side effect imports.

These changes will be tested in the subsequent commits when these tools are used to generate an actual extra import for the generated file.

PR Close #53543
2024-01-30 15:05:42 +00:00
Payam Valadkhan fc55de1416 refactor(compiler-cli): incorporate LocalCompilationExtraImportsTracker in the compilation workflow (#53543)
This commit includes a skeleton of how the tool `LocalCompilationExtraImportsTracker` is used in the overall compilation workflow end-to-end.

First of all, a new option `generateExtraImportsInLocalMode` is added, whose presence will make `LocalCompilationExtraImportsTracker` part of the compilation process. When this option is set an instance of `LocalCompilationExtraImportsTracker` is created within the NgCompiler. Then it is passed to the Ivy transformer and plumbed all the way down and the extra imports registered in it are added to the `ImportManager` instances before the imports are added from `ImportManager` to the generated file. This required adding a new method `generateSideEffectImport` to the `ImportManager`, which is an empty method and will be implemented in the subsequent commits.

This commit expected to make no change in the compilation behavior as the methods are not implemented yet.

PR Close #53543
2024-01-30 15:05:42 +00:00
Payam Valadkhan ac3c484bb1 refactor(compiler-cli): add API for extra import tracker (#53543)
The tracker is responsible for registering the extra imports during the analysis and resolve compiler phases, and later to be used by the transformer to get a list of extra imports to be generated for each source file.

This commit only contains the API, and the actual implementation for each method will be done in subsequent commits where an application of that method is available and so tests can be written for the implementation.

PR Close #53543
2024-01-30 15:05:42 +00:00
Andrew Scott 15c48113c2 refactor(router): Update integration tests to cover navigation and history API (#53799)
This commit updates the router integration tests to cover both the
classic History and the new Navigation API. There is more work to be
done here, but this commit works to prove the efficacy of the
`FakeNavigation` implementation.

PR Close #53799
2024-01-30 15:04:02 +00:00
Dylan Hunn 7b4d275f49 fix(compiler): Fix the template pipeline option (#54148)
The `useTemplatePipeline` option was not properly threaded through the component handler.

PR Close #54148
2024-01-29 21:12:32 +00:00
Andrew Scott 3ca34e606d refactor(core): Update ComponentFixture behavior when using zoneless scheduler (#54024)
When the zoneless scheduler is provided, we want to update the behavior
of `ComponentFixture` to address common issues and painpoints in testing.
Developers should never have to call `detectChanges` on a fixture
manually. Instead of calling `detectChanges` after performing an
action that updates state and requies a template refresh, developers
should wait for change detection to run because the update needs to also have
notified the scheduler. If this was not the case, the component would
not work correctly in the application. Calling `detectChanges` to force
an update could hide real bugs.

This commit also updates the zoneless tests to uses `ComponentFixture`
instead of manually attaching to the `ApplicationRef` and rewriting a
lot of the helpers (`getDebugNode`, `isStable` as a value, `whenStable` as a
Promise).

PR Close #54024
2024-01-29 20:21:47 +00:00
Mark Thompson 098543f1d8 docs: Update component-overview.md (#52282)
Refined the text a bit
PR Close #52282
2024-01-29 19:30:59 +00:00
Renan Ferro e86a13674f docs: add new component imports documentation structure (#52282)
PR Close #52282
2024-01-29 19:30:59 +00:00
Jesse Zomer c55018724a docs: fix shareReplay refcount default (#54145)
according to the official rxjs docs the refcount default is false. See https://rxjs.dev/api/operators/shareReplay

Co-authored-by: Andrew Scott <atscott01@gmail.com>

PR Close #54145
2024-01-29 19:30:33 +00:00
therealdennis08 9571287299 docs: correct grammar error on start page (#53993)
Fixed grammatical error

PR Close #53993
2024-01-29 16:41:29 +00:00
Alex Castle f5c520b836 feat(common): add placeholder to NgOptimizedImage (#53783)
Add a automatic placeholder implementation supporting loader-based and data URL placeholders

PR Close #53783
2024-01-29 16:00:38 +00:00
Ido Strauss f3a2b49f82 docs: update TypeScript version support details for Angular v15 and v16 (#54131)
Clarify the range of TypeScript versions supported in Angular v15 and v16 upgrade guides. The previous documentation's phrasing led to potential misunderstandings, as it suggested broader compatibility than actually supported. This change prevents errors by explicitly stating the maximum TypeScript version for each Angular version, ensuring developers have clear guidance during upgrades.

PR Close #54131
2024-01-29 15:57:01 +00:00
Swami 45288f7815 docs: update input/output guide links (#54135)
PR Close #54135
2024-01-29 15:43:05 +00:00
Kristiyan Kostadinov 28ad6fc4ad fix(migrations): error in standalone migration when non-array value is used as declarations in TestBed (#54122)
Adds some logic to skip over `TestBed.configureTestingModule` calls where the `declarations` aren't initialized to an array. We can't migrate these cases, because test migrations don't have access to the Angular compiler. Previously the migration would throw a runtime error.

PR Close #54122
2024-01-29 15:40:05 +00:00
Santosh Yadav d9a84705c9 docs: add link for control flow migration (#53375)
PR Close #53375
2024-01-29 15:39:05 +00:00
Dwouglas Mhagnum c213a4e15a InMemoryBackendConfigArgs.passThruUnknownUrl: fix tsdoc (#52273)
PR Close #52273
2024-01-26 20:39:38 +00:00
Matt Ezell aef7b2c74e docs: Corrected link for defer related blocks (#52704)
PR Close #52704
2024-01-26 20:38:36 +00:00
Muhammad Ahsan Ayaz 52e8f364ed docs(changelog): release notes, fix the typos etc (#52628)
fixed the typos in a few places
added a missing backtick
removed an unnecessary bullet point

PR Close #52628
2024-01-26 20:38:05 +00:00
Wojciech b0632bd703 docs: Update update-to-version-16.md (#51857)
Fix example for required inputs that leads to TS2564 error - property has no initializer

PR Close #51857
2024-01-26 19:13:24 +00:00
Matthieu Riegler 7800a3c9f5 refactor(core): remove InjectionToken descriptions in optimized builds. (#53747)
We started guarding the `InjectionToken` descriptions with `ngDevMode`. Let's generalize that accross the FW.

PR Close #53747
2024-01-26 19:12:41 +00:00
Payam Valadkhan 0970129e20 fix(compiler-cli): show proper error for custom decorators in local compilation mode (#53983)
At the moment local compilation mode does not support custom decorators, and it leads to unhandled errors. In this change a compile time diagnostic is produced in local mode for custom decorators. This is a temporary solution since there are few custom decorators are in use in g3. Custom decorators will be eventually supported in local mode.

PR Close #53983
2024-01-26 19:11:34 +00:00
Paul Gschwendtner 23eeea5bd7 ci: adding devversion to reviewers for compiler/core (#54053)
I've been working on framework parts and compiler since pre-Ivy, and
helped with Ivy, runtime and compiler. Adding myself as a reviewer to
ease future work and to help with review load.

PR Close #54053
2024-01-26 19:10:56 +00:00
Paul Gschwendtner fcea8c1c5d feat(docs-infra): show overloads of methods in API overview (#54053)
This enables us to show overloads of methods in the API overview. This
is useful for e.g. showing the various signatures of the signal input
function, or for signal-based queris.

There seems to be some issues with the length of the `InputFunction`
overloads. There is some line wrapping that doesn't make it _super_
readable but this is an unrelated problem to this change, but rather
a question of UI / API representation in the angular.io site.

PR Close #54053
2024-01-26 19:10:56 +00:00
Paul Gschwendtner 8ba4db2627 refactor(core): avoid clang-format obfuscating InputFunction.required (#54053)
clang-format seems to have problems with the call signature for
`input.required`. This commit works around the formatting issues that
obfuscate the signature. Users will actually see similar output when
they are looking for the `input` function definition of `@angular/core`.

PR Close #54053
2024-01-26 19:10:56 +00:00
Paul Gschwendtner fe4343cf13 refactor(compiler): extract call and construct signatures of interfaces (#54053)
This adds initial support for extracting and rendering call and construct
signatures of classes, like within the new `InputFunction` for signal
inputs.

For now, signatures are a rare occasion and represented as class member
entries. In the future we might consider exposing this via its own entry
type, and field on the class/interface entry.

PR Close #54053
2024-01-26 19:10:56 +00:00
Paul Gschwendtner 58b8a232d6 fix(compiler-cli): support jumping to definitions of signal-based inputs (#54053)
This fixes the definitions for signal-based inputs in the language
service and type checking symbol builder.

Signal inputs emit a slightly different output. The output works well
for comppletion and was designed to affect language service minimally.
Turns out there is a small adjustment needed for the definition symbols.

PR Close #54053
2024-01-26 19:10:56 +00:00
Paul Gschwendtner b78042f3a5 refactor(core): separate InputSignal and InputSignalWithTransform (#54053)
This commit separates `InputSignal` for input signals with transforms.
The reason being that most of the time, signal inputs are not using
transforms and the generics are rather confusing.

Especially for users with inferred types displayed in their IDEs, the
input signal types are seemingly complex, even if no transform is used.

For this reason, we are introducing a new type called
`InputSignalWithTransform`. This type will be used for inputs with
transforms, while non-transform inputs just use `InputSignal`.

A notable fact is that `InputSignal` extends `InputSignalWithTransform`,
with the "identity transform". i.e. there is no transform. This allows
us to share the code for input signals. In practice, we don't expect
users to pass around `InputSignal`'s anyway.

PR Close #54053
2024-01-26 19:10:56 +00:00
Matthieu Riegler d38238e478 docs: remove mention of providedIn module. This feature has been deprecated. (#54072)
PR Close #54072
2024-01-26 19:09:28 +00:00
fhoekstra 16fbe85702 docs(router): fix variable reference in text (#54099)
PR Close #54099
2024-01-26 19:02:42 +00:00
iliasaddab 4105ab51a5 docs: update i18n-common-merge.md (#52400)
correct spelling

PR Close #52400
2024-01-26 17:38:09 +00:00
Matthieu Riegler 1a2b5691e1 docs: add 2 new diagnostics created recently. (#52329)
PR Close #52329
2024-01-26 17:28:01 +00:00
Matthieu Riegler 8a1f1c075a refactor(platform-browser): remove non necessary factories (#52439)
Let's keep the code a simple as necessary

PR Close #52439
2024-01-26 17:26:51 +00:00
Matthieu Riegler 983968dc68 refactor(platform-browser): remove the depency on window for the AngularProfiler. (#52440)
`performance` and `console` are both available on NodeJS, we can replace `window` with `globalThis`.

PR Close #52440
2024-01-26 17:24:40 +00:00
Matthieu Riegler 89ab1c18a1 refactor(common): Use Nullish coalescing assignment when possible. (#53931)
Inspired by #53923, lets simplify code when possible.

PR Close #53931
2024-01-26 16:58:36 +00:00
Angular Robot 6946316350 docs: update events (#53654)
Generated `events.json` with the latest events retrieved from the Firebase DB.

Closes #53229

PR Close #53654
2024-01-26 16:58:07 +00:00
Shuaib hasan akib 271755d0e4 docs(docs-infra): cleanup repeated scss from typography (#51579)
PR Close #51579
2024-01-26 16:03:43 +00:00
Sylvain DEDIEU 1c49160129 docs(docs-infra): add if cases in templates to avoid internal marked parameters or methods to appear in the documentation (#52020)
Fix case of not wanted internal properties displayed in the documentation by adding if blocks in the concerned templates. So if the option is marked as internal the template won't create an entry in the documentation table for the concerned property of method

Fixes #52018

PR Close #52020
2024-01-26 15:47:15 +00:00
Chellappan 989394db90 refactor(forms): Specify Provider type for DEFAULT_VALUE_ACCESSOR (#54029)
Change from `any` to `Provider` type for enhanced type safety and clarity

PR Close #54029
2024-01-26 15:46:31 +00:00
Ezéchiel Amen AGBLA 768b927f9a docs: remove link (#54090)
PR Close #54090
2024-01-26 15:46:00 +00:00
cexbrayat 037b79b72e fix(core): change defer block fixture default behavior to playthrough (#54088)
This is a followup to #53956

The default behavior needs to be changed in `TestBedCompiler` as well to have an effect.

PR Close #54088
2024-01-26 15:44:40 +00:00
Magda98 c3b0095965 docs(docs-infra): move comma in Angular Language Service section (#53759)
PR Close #53759
2024-01-25 23:48:56 +00:00
jivanf b9547a98f6 docs: Use correct service name in hierarchical dependency injection guide (#53723)
This commit replaces `TitleService` with `TiresService` in the specialized providers scenario described in the guide.
PR Close #53723
2024-01-25 23:47:01 +00:00
Antoine PARIZE 863c12aa89 docs: testing-components-basics.md and components-basics.md links to css selector documentation are dead (#53586)
docs: testing-components-basics.md and components-basics.md links to css selector documentation are dead

As MDN's documentation link to the "css selector" topic is dead, this commit makes the angular documentation use the new valid link.

PR Close #53586
2024-01-25 23:34:03 +00:00
oliv37 c634405a52 docs: fix add builder from package (#53154)
PR Close #53154
2024-01-25 23:31:01 +00:00
pBouillon 89abbaac7f docs: fix reference to forwardRef in ForwardRefFn JSdoc (#53556)
PR Close #53556
2024-01-25 23:16:46 +00:00
lsst25 fa0f44da7e docs(docs-infra): close tag in the example of Composing Components tutorial (#52923)
PR Close #52923
2024-01-25 23:04:47 +00:00
Ross MacPhee 2a4d8aa070 docs: fix nonsensical injection provider docs (#53456)
PR Close #53456
2024-01-25 23:02:46 +00:00
nickolashkraus f034d29023 docs: With >>> with (#53472)
PR Close #53472
2024-01-25 22:58:34 +00:00
Srinath Vayalpati 3db755d411 docs: fix router api url link (#53398)
PR Close #53398
2024-01-25 22:58:09 +00:00
Andrea Canciani ecbb47b208 refactor: fix a number of typos throughout the codebase (#52826)
Fix several typos, mostly in the `adev` site.

PR Close #52826
2024-01-25 22:54:59 +00:00
Sai Kumar Kola dfc6c8d0c7 fix: cta clickability issue in adev homepage. (#52905)
PR Close #52905
2024-01-25 22:48:47 +00:00
Aditya Kumar c9c22fa059 docs: Fix open link in new tab (#53647)
Signed-off-by: Aditya Kumar <aditya.kumar60@infosys.com>

PR Close #53647
2024-01-25 22:40:50 +00:00
louay.meskini 96bee52b28 docs: Fix links for NgZone (#53667)
PR Close #53667
2024-01-25 22:38:51 +00:00
jase 4bb1c8fe58 docs: fix http handler usage on interceptor example (#53772)
PR Close #53772
2024-01-25 22:38:18 +00:00
Trung Vo 3e2cd83e65 docs: add Trung Vo to GDE resources (#53599)
PR Close #53599
2024-01-25 22:29:26 +00:00
Aditya Kumar ec526ca77a docs: Fix router api url link on tutorial page (#53416)
Signed-off-by: Aditya Kumar <aditya.kumar60@infosys.com>

PR Close #53416
2024-01-25 22:27:11 +00:00
Ezéchiel Amen AGBLA 9f18227f3a docs: bad redirection in core Injector page for providers and injection token links (#52775)
PR Close #52775
2024-01-25 21:34:35 +00:00
Gleb28 001c30defd docs: removed repeated words "when" (#53828)
Fixes #53827

PR Close #53828
2024-01-25 21:31:33 +00:00
Sylvain DEDIEU 9bb1884304 docs: change the file of the provideHttpClient standalone example to match cli generated project (#52806)
The "Providing HttpClient through dependency injection" documentation now shows that in case of a standalone boostraped app, the provideHttpClient is to include in the app.config.ts file.

Also updated the http setup server communication example to align the new doc (adev) with the old one (aio).

PR Close #52806
2024-01-25 21:24:58 +00:00
Sasidharan SD c8d1b11cec docs: fix invalid file replacement configuration (#52802)
PR Close #52802
2024-01-25 21:22:44 +00:00
Aditya Kumar d404fe87e8 docs: Fix minor grammatical fixes in the documentations (#53418)
Signed-off-by: Aditya Kumar <aditya.kumar60@infosys.com>

PR Close #53418
2024-01-25 21:21:59 +00:00
Nelson Gutierrez ef8c68bd22 docs: add correct language for syntax highlighting on new docs (#52712)
PR Close #52712
2024-01-25 21:19:29 +00:00
Nelson Gutierrez 8c65376324 docs: add correct syntax highlighting type in event binding documentation (#52712)
PR Close #52712
2024-01-25 21:19:29 +00:00
ilir.beqiri 35ec260029 docs: fix type at change detection with pipes section (#53940)
Fix a typo of word 'heroes' at docs guide for change detection with pure pipes

PR Close #53940
2024-01-25 20:46:18 +00:00
Kristiyan Kostadinov c637dfa092 refactor(core): signals toString improvements (#54079)
Follow-up to #54002 that:
* Remove the `toString` implementation from the `primitives`.
* Guards the `toString` with `ngDevMode` and prints out the value.

PR Close #54079
2024-01-25 20:45:02 +00:00
Jessica Janiuk a6dad59536 ci: update adev approvers list (#54081)
This temporarily updates the adev approvers list before we decide how we will handle adev content reviews going forward.

PR Close #54081
2024-01-25 20:40:08 +00:00
Ben Hong d5c0743380 ci: add ben to reviewers for adev files (#54078)
For ADEV changes going forward, Ben will be helping the team to review all PRs associated with this project.

PR Close #54078
2024-01-25 20:18:51 +00:00
Angular Robot 58d4abcb22 docs: update Angular CLI help [main] (#54075)
Updated Angular CLI help contents.

PR Close #54075
2024-01-25 18:03:27 +00:00
vladboisa 8da67ae217 docs: fix & update MDN Shadow API link examples (#54040)
PR Close #54040
2024-01-25 18:02:58 +00:00
Ben Hong c4853e952d docs: add documentation and script for local docs dev environment (#54038)
PR Close #54038
2024-01-25 18:02:27 +00:00
d-codez fab1590731 docs: correct grammar in event handling documentation (#54009)
PR Close #54009
2024-01-25 18:01:50 +00:00
Kristiyan Kostadinov 656bc282e3 fix(core): add toString implementation to signals (#54002)
Since signals are function, currently stringifying them reveals the implementation of the function. This can lead to confusion since it contains internal implementation details. These changes add static `toString` function to address the issue.

**Note:** it's tempting to have `toString` output the actual value of the signal, but that would encourage users not to call the function which will be problematic in the long run. That's why these changes are using a static string instead.

PR Close #54002
2024-01-25 17:11:30 +00:00
arturovt 75aeae42b7 fix(animations): cleanup DOM elements when root view is removed with async animations (#53033)
Currently, when using `provideAnimationsAsync`, Angular uses `AnimationRenderer`
as the renderer. When the root view is removed, the `AnimationRenderer` defers the actual
work to the `TransitionAnimationEngine` to do this, and the `TransitionAnimationEngine`
doesn't actually remove the DOM node, but just calls `markElementAsRemoved()`.

The actual DOM node is not removed until `TransitionAnimationEngine` "flushes".

Unfortunately, though, that "flush" will never happen, since the root view is being
destroyed and there will be no more flushes.

This commit adds `flush()` call when the root view is being destroyed.

PR Close #53033
2024-01-25 16:32:57 +00:00
Kristiyan Kostadinov 93188cb439 refactor(compiler): distinguish two-way bindings in the AST (#54065)
During the template parsing stage two-way bindings are split up into a property and event binding. All the downstream code treats these binding the same as their one-way equivalents. For some future work we'll have to distinguish between the two so these changes update the `BoundElementProperty.type` and `ParsedEvent.type` to include a `TwoWay` type. All existing call-sites have been updated to treat `TwoWay` the same as `Property`/`Regular`, but more specialized logic will be added in the future.

PR Close #54065
2024-01-25 16:31:57 +00:00
Dylan Hunn c3bb00a2eb refactor(compiler): Fix defer deps fn duplicate names in Template Pipeline (#54060)
Previously, defer deps fns names were only prefixed with the component name, meaning that distinct deps fns in the same component would produce a name collision. Now, we take into account the entire template function name when naming inner deps fns.

PR Close #54060
2024-01-25 16:31:01 +00:00
Diego Julião bd9c2c5b3f docs: remove ngx-deploy-npm from deployers table (#53999)
PR Close #53999
2024-01-25 16:07:40 +00:00
Pawel Kozlowski c04312860b refactor(core): introduce instructions for view queries as signals (#54017)
This commit adds new instructions to support view queries as signals.

PR Close #54017
2024-01-24 18:39:51 -05:00
Pawel Kozlowski 3e67b271ad refactor(core): introduce onDirty notification on QueryList (#54017)
This refactoring expands the QueryList such that we can add onDirty
callback to be invoked when a given query gets marked as dirty during
view insertion / removal. This mechanism is needed for signal-based
queries.

PR Close #54017
2024-01-24 18:39:51 -05:00
Pawel Kozlowski 73fec9ddbf refactor(core): extract more query logic from instructions (#54017)
This is a refactor commit that moves more query construction / refresh
logic from the body of instructions into dedicated functions. This is
in preparation for the signal-based query instructions.

PR Close #54017
2024-01-24 18:39:51 -05:00
Andrew Scott 308d83c312 refactor(core): race rAF and setTimeout in zoneless scheduler (#54023)
Update zoneless scheduler to run change detection after the first of
either `requestAnimationFrame` or `setTimeout` callbacks execute.

PR Close #54023
2024-01-24 18:39:15 -05:00
Jan Olaf Krems c7df61fbc2 refactor(core): Allow mutation instead of reassignment of ngDevMode (#53862)
In some bundling scenarios, there may be local references to `ngDevMode` that need to be kept in sync with the global variable. This becomes hard to impossible if the global is reassigned. This allows setting the global to an empty object instead of `true` and preserve identity during `initNgDevMode`.
PR Close #53862
2024-01-24 18:38:50 -05:00
Andrew Scott eddf5dae5e fix(compiler): Update type check block to fix control flow source mappings (#53980)
The source mappings and types for various pieces of the control flow
were not quite right and prevented the language service from providing
accurate information.

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

PR Close #53980
2024-01-24 18:37:58 -05:00
Dylan Hunn 47e6e84101 feat(compiler): Add a TSConfig option useTemplatePipeline (#54057)
The Template Pipeline is a brand new backend for the Angular compiler, replacing `TemplateDefinitionBuilder`. It generates the Ivy instructions corresponding to an input template (or host binding). The Template Pipeline has an all-new design based on an intermediate representation compiled over many phases, which will allow us to experiment with compiler changes more easily in the future.

With this commit, the template pipeline can now be enabled in any project via the `useTemplatePipeline` TSConfig option. However, it is still disabled by default.

PR Close #54057
2024-01-24 18:36:23 -05:00
Dylan Hunn 0f5f45c0fa refactor(compiler): Support externally provided defer deps fns (#54043)
In #53591, Andrew added local compliation support for defer blocks. However, this requires the ability to emit pre-generated static defer deps functions. We now also support that feature in Template Pipeline.

PR Close #54043
2024-01-24 18:35:24 -05:00
Alex Rickabaugh fad1354d50 release: cut the v17.2.0-next.0 release 2024-01-24 13:00:51 -08:00
nikvarma 9e10af45c5 docs: typo Chat to chart fix (#53892)
PR Close #53892
2024-01-24 21:23:51 +01:00
Pawel Kozlowski a2a0b33c13 docs: release notes for the v17.1.1 release (#54056)
PR Close #54056
2024-01-24 20:35:15 +01:00
Paul Gschwendtner 77516450c8 refactor(compiler): support JIT for signal-based queries (#54019)
Similar to signal-based inputs, we support signal-based queries in JIT
by expecting a decorator to be added. This is a consequence of the
design, given that JIT requires query declaration information before
the class is initialized- but ironically there is no way to collect this
information without instantiating the class.

A JIT transform in the Angular CLI will automatically generate these
decorators for testing.

PR Close #54019
2024-01-24 16:13:31 +01:00
Paul Gschwendtner 17a47c4c54 refactor(compiler-cli): additional diagnostics for signal-based queries (#54019)
This commit introduces three additional diagnostics for queries:

- If a query (either using decorator or signal-based) is declared on a
  static class member, a diagnostic is raised.
- If a signal-based query is mixed with a query decorator, a diagnostic
  is raised. Similar to signal inputs.
- If a singal-based query is also declared in the directive/component
  class decorator metadata, a diagnostic is raised.

PR Close #54019
2024-01-24 16:13:31 +01:00
Paul Gschwendtner a7017a0471 refactor(core): improve safety of input/query initializer API detection (#54019)
Due to some refactorings, we were only checking the function name
and whether it originates from an import. We should also verify the
module. This seems like logic we lost in the refactorings.

PR Close #54019
2024-01-24 16:13:31 +01:00
Paul Gschwendtner 3b6f636edf refactor(compiler-cli): collapse multiple query advance statements (#54019)
Collapses multiple sibling query advance statements into single
query advance invocations. This will help reducing generated code
for directives/components with many queries.

PR Close #54019
2024-01-24 16:13:31 +01:00
Paul Gschwendtner 998af3276f refactor(compiler-cli): move more query generation logic to dedicated file (#54019)
Without any modifications, this commit moves more of the the query
generation logic into its dedicated file.

PR Close #54019
2024-01-24 16:13:31 +01:00
Max 09f94234ee docs: fix typo in Custom directives section (#54044)
There was a grammatically incorrect sentence in the What is Angular page, Custom directives section. This change makes it more correct.
PR Close #54044
2024-01-24 15:32:22 +01:00
Paul Gschwendtner 25f91e38b2 build: ensure zone.js typing test is hermetic (#54048)
Currently the ZoneJS typing tests executes outside of Bazel, as a legacy
artifact of the monorepo merging (as it seems - not ideal at all).

Looks like this test relies on its own node modules, that were NOT
locked using a yarn lock file. This commit adds one, and specifically
locks it to a `@types/node` version that does not include the most
recent patch release (which seemingly introduced a breaking change)
that causes issues with TypeScript's lib checking.

Whenever we perform lock file maintenance in the future, we have the
following options:

- Consider disabling lib checking via `skipLibCheck` for this test. This
  may be acceptable.
- Continue locking the node version,
- Waiting for chokidar to comply with the new signature
- Waiting for the breaking change to be rolled back.

Culprit change:
https://github.com/DefinitelyTyped/DefinitelyTyped/pull/68300

PR Close #54048
2024-01-24 14:57:05 +01:00
Andrew Scott bc85551bfc fix(router): revert commit that replaced last helper with native Array.at(-1) (#54021)
While `Array.at` is technically supported in all browsers we officially
support, the change was needlessly breaking without any real benefit.

PR Close #54021
2024-01-24 10:54:52 +01:00
Andrew Kushnir aeaec8629c refactor(compiler-cli): rephrase an error message related to @defer and local compilation (#54030)
This commit updates the error message to cover cases when imported symbols have eager references inside of a file.

PR Close #54030
2024-01-24 10:08:50 +01:00
1339 changed files with 73333 additions and 48440 deletions
+4 -1
View File
@@ -1,5 +1,5 @@
# Enable debugging tests with --config=debug
test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results
test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results --spawn_strategy=local
# Do not attempt to de-flake locally.
# On CI we might set this to `3` to run with deflaking.
@@ -177,6 +177,9 @@ test:saucelabs --flaky_test_attempts=1
# --ng_perf will ask the Ivy compiler to produce performance results for each build.
build --flag_alias=ng_perf=//packages/compiler-cli:ng_perf
# --adev_fast will run adev build/serve in a faster mode, skipping things like prerendering
# for local development.
build --flag_alias=fast_adev=//adev:fast_build_mode
####################################################
# User bazel configuration
+1 -1
View File
@@ -4,7 +4,7 @@ description: 'Installs the dependencies using Yarn'
runs:
using: 'composite'
steps:
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # 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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
run: yarn bazel build --config=aio_local_deps //adev:build
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@c83e99a12397014162531ca125c94549db55dd84
with:
workflow-artifact-name: 'adev-preview'
pull-number: '${{github.event.pull_request.number}}'
+2 -2
View File
@@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with:
token: '${{secrets.GITHUB_TOKEN}}'
@@ -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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@c83e99a12397014162531ca125c94549db55dd84
with:
github-token: '${{secrets.GITHUB_TOKEN}}'
workflow-artifact-name: 'adev-preview'
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: ./.github/actions/yarn-install
- uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
with:
bazelrc: ./.bazelrc.user
@@ -34,7 +34,7 @@ jobs:
# the number of concurrent actions is determined based on the host resources.
- run: bazel build //aio:build --jobs=32 --announce_rc --verbose_failures
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@c83e99a12397014162531ca125c94549db55dd84
with:
workflow-artifact-name: 'aio'
pull-number: '${{github.event.pull_request.number}}'
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
npx -y firebase-tools@latest target:clear --project ${{env.PREVIEW_PROJECT}} hosting aio
npx -y firebase-tools@latest target:apply --project ${{env.PREVIEW_PROJECT}} hosting aio ${{env.PREVIEW_SITE}}
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@c83e99a12397014162531ca125c94549db55dd84
with:
github-token: '${{secrets.GITHUB_TOKEN}}'
workflow-artifact-name: 'aio'
@@ -16,6 +16,6 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
persist-credentials: false
- uses: angular/dev-infra/github-actions/branch-manager@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/branch-manager@c83e99a12397014162531ca125c94549db55dd84
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
with:
bazelrc: ./.bazelrc.user
+2 -2
View File
@@ -23,7 +23,7 @@ jobs:
SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
# Checking out the pull request commit is intended here as we need to run the changed code tests.
@@ -31,7 +31,7 @@ jobs:
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Starting Saucelabs tunnel service
run: ./tools/saucelabs/sauce-service.sh run &
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
+32 -30
View File
@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
@@ -60,13 +60,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Run unit tests
@@ -78,13 +78,13 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules
run: yarn install --frozen-lockfile --network-timeout 100000
- name: Run CI tests for framework
@@ -94,15 +94,15 @@ jobs:
runs-on: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules for aio
run: yarn install --cwd aio --frozen-lockfile
- name: Run AIO tests with upstream packages
@@ -115,11 +115,11 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Build adev to ensure it continues to work
@@ -130,15 +130,15 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules
run: yarn install --cwd aio --frozen-lockfile
- name: Run AIO tests with local packages
@@ -153,15 +153,15 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules for aio
run: yarn install --cwd aio --frozen-lockfile
- name: Set the stable branch environment variable
@@ -184,7 +184,7 @@ jobs:
run: yarn --cwd aio deploy-production
- name: Notify about failed deployment
if: ${{ failure() }}
uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v=v1.24.0
uses: slackapi/slack-github-action@2a8087d4af6f83146a87539a70defe909fe6dbe6 # v=v1.24.0
with:
channel-id: 'C07DT5M6V,CKV1F72BG'
slack-message: 'Deploy to aio job failed for ${{ github.base_ref }} branch failed on build ${{ github.event.after }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
@@ -197,13 +197,13 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules
run: yarn install --frozen-lockfile
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
@@ -215,7 +215,7 @@ jobs:
labels: ubuntu-latest-4core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
@@ -223,9 +223,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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules
run: yarn install --frozen-lockfile
- run: |
@@ -235,9 +235,11 @@ jobs:
//packages/zone.js/test/closure:closure_js \
- run: |
rm -Rf packages/zone.js/build
rm -Rf packages/zone.js/test/extra/*.umd.js
mkdir -p packages/zone.js/build/
mkdir -p packages/zone.js/build/test/
mkdir -p packages/zone.js/test/
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
@@ -262,7 +264,7 @@ jobs:
JOBS: 2
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
# Checking out the pull request commit is intended here as we need to run the changed code tests.
@@ -270,9 +272,9 @@ jobs:
- name: Install node modules
run: yarn install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Set up Sauce Tunnel Daemon
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
env:
+2 -2
View File
@@ -13,13 +13,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/commit-message-based-labels@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/commit-message-based-labels@c83e99a12397014162531ca125c94549db55dd84
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
post_approval_changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/post-approval-changes@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/post-approval-changes@c83e99a12397014162531ca125c94549db55dd84
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
-19
View File
@@ -1,19 +0,0 @@
name: Feature request triage bot
on:
schedule:
# Run at 14:00 every day
- cron: '0 14 * * *'
# Declare default permissions as read only.
permissions:
contents: read
jobs:
feature_triage:
if: github.repository == 'angular/angular'
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/feature-request@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: angular/dev-infra/github-actions/google-internal-tests@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/google-internal-tests@c83e99a12397014162531ca125c94549db55dd84
with:
run-tests-guide-url: http://go/angular-g3sync-start
github-token: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
status:
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/unified-status-check@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
- uses: angular/dev-infra/github-actions/unified-status-check@c83e99a12397014162531ca125c94549db55dd84
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+4 -4
View File
@@ -22,15 +22,15 @@ jobs:
version: ['https://next.angular.io/', 'https://angular.io/']
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
./aio/node_modules
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/setup@c83e99a12397014162531ca125c94549db55dd84
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/bazel/configure-remote@c83e99a12397014162531ca125c94549db55dd84
- name: Install node modules in aio
run: yarn install --frozen-lockfile --cwd aio
- name: Run basic e2e and deployment config tests.
@@ -44,7 +44,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c83e99a12397014162531ca125c94549db55dd84
with:
cache-node-modules: true
node-module-directories: |
+2 -2
View File
@@ -39,7 +39,7 @@ jobs:
# Upload the results as artifacts.
- name: 'Upload artifact'
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.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@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
uses: github/codeql-action/upload-sarif@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
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@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/create-pr-for-changes@c83e99a12397014162531ca125c94549db55dd84
with:
branch-prefix: update-cli-help
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
- name: Generate `events.json`
run: node aio/scripts/generate-events/index.mjs --ignore-invalid-dates
- name: Create a PR (if necessary)
uses: angular/dev-infra/github-actions/create-pr-for-changes@ae9155d1083fd8390e98bfe09a5ccf89f0375b52
uses: angular/dev-infra/github-actions/create-pr-for-changes@c83e99a12397014162531ca125c94549db55dd84
with:
branch-prefix: docs-update-events
pr-title: 'docs: update events'
-3
View File
@@ -1,6 +1,3 @@
#!/bin/sh
. "$(dirname $0)/_/husky.sh"
set +e
yarn -s ng-dev commit-message pre-commit-validate --file $1 2>/dev/null
+1 -4
View File
@@ -1,11 +1,8 @@
#!/bin/sh
. "$(dirname $0)/_/husky.sh"
set +e
yarn -s ng-dev format staged 2>/dev/null
if [ $? -ne 0 ]; then
echo "WARNING: failed to run file formatting (ng-dev format staged)"
fi
exit 0;
-3
View File
@@ -1,6 +1,3 @@
#!/bin/sh
. "$(dirname $0)/_/husky.sh"
set +e
yarn -s ng-dev commit-message restore-commit-message-draft $1 $2 2>/dev/null
+21
View File
@@ -14,8 +14,22 @@ export const format: FormatConfig = {
'packages/animations/**/*.{js,ts}',
'packages/bazel/**/*.{js,ts}',
'packages/benchpress/**/*.{js,ts}',
'packages/common/**/*.{js,ts}',
'packages/docs/**/*.{js,ts}',
'packages/elements/**/*.{js,ts}',
'packages/examples/**/*.{js,ts}',
'packages/misc/**/*.{js,ts}',
'packages/private/**/*.{js,ts}',
'packages/router/**/*.{js,ts}',
'packages/service-worker/**/*.{js,ts}',
'packages/upgrade/**/*.{js,ts}',
// Do not format d.ts files as they are generated
'!**/*.d.ts',
// Both third_party and .yarn are directories containing copied code which should
// not be modified.
'!third_party/**',
'!.yarn/**',
],
},
'clang-format': {
@@ -51,8 +65,15 @@ export const format: FormatConfig = {
'!packages/animations/**/*.{js,ts}',
'!packages/bazel/**/*.{js,ts}',
'!packages/benchpress/**/*.{js,ts}',
'!packages/common/**/*.{js,ts}',
'!packages/docs/**/*.{js,ts}',
'!packages/elements/**/*.{js,ts}',
'!packages/examples/**/*.{js,ts}',
'!packages/misc/**/*.{js,ts}',
'!packages/private/**/*.{js,ts}',
'!packages/router/**/*.{js,ts}',
'!packages/service-worker/**/*.{js,ts}',
'!packages/upgrade/**/*.{js,ts}',
],
},
'buildifier': true,
+8 -1
View File
@@ -1,5 +1,12 @@
{
"syncedFilePatterns": ["LICENSE", "modules/benchmarks/**", "packages/**"],
"syncedFilePatterns": [
"LICENSE",
"modules/benchmarks/**",
"packages/**"
],
"separateFilePatterns": [
"packages/core/primitives/**"
],
"alwaysExternalFilePatterns": [
"packages/*",
"packages/bazel/*",
+5
View File
@@ -17,4 +17,9 @@ export const pullRequest: PullRequestConfig = {
// the `bazel` package is not considered part of the public API so that features
// can land in patch branches.
targetLabelExemptScopes: ['dev-infra', 'docs-infra', 'bazel'],
// enables specific validations during the pull request merge process
validators: {
assertEnforceTested: true,
assertIsolatedSeparateFiles: true,
},
};
+1 -1
View File
@@ -1 +1 @@
18.13.0
18.18.2
+1
View File
@@ -2,6 +2,7 @@
"printWidth": 100,
"tabWidth": 2,
"tabs": false,
"embeddedLanguageFormatting": "off",
"singleQuote": true,
"semicolon": true,
"quoteProps": "preserve",
+16 -2
View File
@@ -166,8 +166,9 @@ groups:
- AndrewKushnir
- atscott
- crisbeto
- JoostK
- devversion
- dylhunn
- JoostK
# =========================================================
# Framework: Migrations
@@ -321,7 +322,9 @@ groups:
'aio/content/guide/providers.md',
'aio/content/examples/providers/**/{*,.*}',
'aio/content/images/guide/providers/**/{*,.*}',
'aio/content/guide/signal-queries.md',
'aio/content/guide/singleton-services.md',
'aio/content/guide/signal-inputs.md',
'aio/content/guide/sharing-ngmodules.md',
'aio/content/guide/standalone-components.md',
'aio/content/guide/standalone-migration.md',
@@ -344,6 +347,7 @@ groups:
'aio/content/guide/defer.md',
'aio/content/guide/signals.md',
'aio/content/guide/control_flow.md',
'aio/content/guide/model-inputs.md',
'aio/content/examples/injection-token/**/{*,.*}',
])
reviewers:
@@ -352,6 +356,7 @@ groups:
- AndrewKushnir
- atscott
- crisbeto
- devversion
- dylhunn
- jessicajaniuk
- pkozlowski-opensource
@@ -934,6 +939,7 @@ groups:
'aio/content/guide/update-to-version-14.md',
'aio/content/guide/update-to-version-15.md',
'aio/content/guide/update-to-version-16.md',
'aio/content/guide/update-to-version-17.md',
])
reviewers:
users:
@@ -1069,9 +1075,17 @@ groups:
])
reviewers:
users:
- twerske
- josephperrott
- jelbourn
- bencodezen
- jessicajaniuk
- dylhunn
- AndrewKushnir
- alxhub
- crisbeto
- atscott
- pkozlowski-opensource
- ~jeanmeche
# =========================================================
# Docs-infra
+255 -68
View File
@@ -1,3 +1,191 @@
<a name="17.2.4"></a>
# 17.2.4 (2024-03-06)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [917b9bdd2e](https://github.com/angular/angular/commit/917b9bdd2eec9cd6395adb0cbde979490bcc3a88) | fix | unwrap expressions with type parameters in query read property ([#54647](https://github.com/angular/angular/pull/54647)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [586cc24a10](https://github.com/angular/angular/commit/586cc24a102d51e7c42ecc839124353afe459073) | fix | apply TestBed provider overrides to `@defer` dependencies ([#54667](https://github.com/angular/angular/pull/54667)) |
| [b558a01c84](https://github.com/angular/angular/commit/b558a01c84a1fe4f9e047e92d99d69f02f2ccc4f) | fix | generic inference for signal inputs may break with `--strictFunctionTypes` ([#54652](https://github.com/angular/angular/pull/54652)) |
| [443e5f1591](https://github.com/angular/angular/commit/443e5f1591896909eab6ad157bb4b5db50a49f26) | fix | return a readonly signal on `asReadonly`. ([#54719](https://github.com/angular/angular/pull/54719)) |
| [ffbafc7d4a](https://github.com/angular/angular/commit/ffbafc7d4a3c61226cb5c524b3ff42ed4f9f1d76) | fix | untrack various core operations ([#54614](https://github.com/angular/angular/pull/54614)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.2.3"></a>
# 17.2.3 (2024-02-27)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [1a526f2881](https://github.com/angular/angular/commit/1a526f28814429c05b003edbe40500b7069e1404) | perf | `AsyncPipe` should not call `markForCheck` on subscription ([#54554](https://github.com/angular/angular/pull/54554)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [2aefed8763](https://github.com/angular/angular/commit/2aefed87632293c5570e17653a7d270162ea35c3) | fix | catch function instance properties in interpolated signal diagnostic ([#54325](https://github.com/angular/angular/pull/54325)) |
| [48aec63ee4](https://github.com/angular/angular/commit/48aec63ee48fe9d20c1f1565b044ec359100736d) | fix | identify aliased initializer functions ([#54480](https://github.com/angular/angular/pull/54480)) |
| [daf7c611b2](https://github.com/angular/angular/commit/daf7c611b23797ba2dba24e20e26c344902e7bc7) | fix | identify aliased initializer functions ([#54609](https://github.com/angular/angular/pull/54609)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [57123524a2](https://github.com/angular/angular/commit/57123524a2e1481987eaf239d2ae7f1216291864) | fix | collect providers from NgModules while rendering `@defer` block ([#52881](https://github.com/angular/angular/pull/52881)) |
| [79a32816dc](https://github.com/angular/angular/commit/79a32816dcb57e9b02ba6e18261c6dccd14b0b23) | fix | fix typo in injectors.svg file ([#54596](https://github.com/angular/angular/pull/54596)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [dbe673b027](https://github.com/angular/angular/commit/dbe673b02751b8bf12f6f6f79b843dd268d965e1) | fix | resolve infinite loop for a single line element with a long tag name and angle bracket on a new line ([#54588](https://github.com/angular/angular/pull/54588)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.2.2"></a>
# 17.2.2 (2024-02-21)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [d34e3298db](https://github.com/angular/angular/commit/d34e3298db2da9d3aa8f8e2c49e1d1aed849e7d2) | fix | image placeholder not removed in OnPush component ([#54515](https://github.com/angular/angular/pull/54515)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [6447c0eecc](https://github.com/angular/angular/commit/6447c0eecc15800417bb5bde2d273865c559b7d4) | fix | adding the inert property to the "SCHEMA" array ([#53148](https://github.com/angular/angular/pull/53148)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [0a3edfb543](https://github.com/angular/angular/commit/0a3edfb5433e1b67f37d7b3f69a5c77b48eedce6) | fix | correctly detect deferred dependencies across scoped nodes ([#54499](https://github.com/angular/angular/pull/54499)) |
| [790f4f7c26](https://github.com/angular/angular/commit/790f4f7c26474af2b1d81a4f3c761047bf920edf) | fix | use correct symbol name for default imported symbols in defer blocks ([#54495](https://github.com/angular/angular/pull/54495)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [3bd5860c74](https://github.com/angular/angular/commit/3bd5860c749517c4d35850703c53a768138b7bde) | fix | properly execute content queries for root components ([#54457](https://github.com/angular/angular/pull/54457)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [bb57d34110](https://github.com/angular/angular/commit/bb57d34110ea8796f5c5f522b98dadf078e8ad8a) | fix | Fix cf migration regular expression to include underscores ([#54533](https://github.com/angular/angular/pull/54533)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [3e31f1a34e](https://github.com/angular/angular/commit/3e31f1a34ee97a802a4032cd9e7816d683a51d5e) | fix | Clear internal transition when navigation finalizes ([#54261](https://github.com/angular/angular/pull/54261)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.2.1"></a>
# 17.2.1 (2024-02-14)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [7234824228](https://github.com/angular/angular/commit/7234824228df11249a5ebe01a6dee381be74e02e) | fix | fix broken version detection condition ([#54443](https://github.com/angular/angular/pull/54443)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.2.0"></a>
# 17.2.0 (2024-02-14)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [03c3b3eb79](https://github.com/angular/angular/commit/03c3b3eb79ec061b0031d6ad7ba386d185c87d8d) | feat | add Netlify image loader ([#54311](https://github.com/angular/angular/pull/54311)) |
| [f5c520b836](https://github.com/angular/angular/commit/f5c520b836c4545c7043649f28b3a0369c168747) | feat | add placeholder to NgOptimizedImage ([#53783](https://github.com/angular/angular/pull/53783)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [47e6e84101](https://github.com/angular/angular/commit/47e6e841016abfca0c1aa84051d82a04b3027617) | feat | Add a TSConfig option `useTemplatePipeline` ([#54057](https://github.com/angular/angular/pull/54057)) |
| [66e940aebf](https://github.com/angular/angular/commit/66e940aebfd5a93944860a4e0dbd14e1072f80f2) | feat | scope selectors in @starting-style ([#53943](https://github.com/angular/angular/pull/53943)) |
| [7b4d275f49](https://github.com/angular/angular/commit/7b4d275f494a64c38b61cea7045ba8b6e8447b78) | fix | Fix the template pipeline option ([#54148](https://github.com/angular/angular/pull/54148)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [7e861c640e](https://github.com/angular/angular/commit/7e861c640edf90c5f8d4f7e091861d3d98cd49c0) | feat | generate extra imports for component local dependencies in local mode ([#53543](https://github.com/angular/angular/pull/53543)) |
| [3263df23f2](https://github.com/angular/angular/commit/3263df23f2f4da722ef2c1a1dacfb0866498dd60) | feat | generate global imports in local compilation mode ([#53543](https://github.com/angular/angular/pull/53543)) |
| [b774e22d8e](https://github.com/angular/angular/commit/b774e22d8e384f43e9cd8f5c55475d06e7f66988) | feat | make it configurable to generate alias reexports ([#53937](https://github.com/angular/angular/pull/53937)) |
| [3e1384048e](https://github.com/angular/angular/commit/3e1384048eb76c92532ae19aa2883318121c00e8) | feat | support host directives for local compilation mode ([#53877](https://github.com/angular/angular/pull/53877)) |
| [a592904c69](https://github.com/angular/angular/commit/a592904c691844d2c1aed00bd914edabef49f9b1) | fix | allow custom/duplicate decorators for `@Injectable` classes in local compilation mode ([#54139](https://github.com/angular/angular/pull/54139)) |
| [4b1d948b36](https://github.com/angular/angular/commit/4b1d948b36285ec6d80dbe93e0b92133f9d4be94) | fix | consider the case of duplicate Angular decorators in local compilation diagnostics ([#54139](https://github.com/angular/angular/pull/54139)) |
| [96bcf4fb12](https://github.com/angular/angular/commit/96bcf4fb1208d1f073784a2cde4a03553e905807) | fix | forbid custom/duplicate decorator when option `forbidOrphanComponents` is set ([#54139](https://github.com/angular/angular/pull/54139)) |
| [64fa5715c6](https://github.com/angular/angular/commit/64fa5715c696101fba0b4f8623eaec0eadc5b159) | fix | generating extra imports in local compilation mode when cycle is introduced ([#53543](https://github.com/angular/angular/pull/53543)) |
| [6c8b09468a](https://github.com/angular/angular/commit/6c8b09468a05a80cba3960861f0ab8d3bae80415) | fix | highlight the unresolved element in the @Component.styles array for the error LOCAL_COMPILATION_UNRESOLVED_CONST ([#54230](https://github.com/angular/angular/pull/54230)) |
| [0970129e20](https://github.com/angular/angular/commit/0970129e20f77dc309f2b4f76f961b310124778c) | fix | show proper error for custom decorators in local compilation mode ([#53983](https://github.com/angular/angular/pull/53983)) |
| [f39cb06418](https://github.com/angular/angular/commit/f39cb064183d984254bdf4e41b61d3dc9379738a) | fix | show specific error for unresolved @Directive.exportAs in local compilation mode ([#54230](https://github.com/angular/angular/pull/54230)) |
| [f3851b5945](https://github.com/angular/angular/commit/f3851b59459a1d9c214ace3db5a716d51c1f93c7) | fix | show specific error for unresolved @HostBinding's argument in local compilation mode ([#54230](https://github.com/angular/angular/pull/54230)) |
| [39ddd884e8](https://github.com/angular/angular/commit/39ddd884e826cc0be63fd0f7d7de20d642877ef9) | fix | show specific error for unresolved @HostListener's event name in local compilation mode ([#54230](https://github.com/angular/angular/pull/54230)) |
| [5d633240fd](https://github.com/angular/angular/commit/5d633240fd5927c4318a9240e60c3a30b2333cee) | fix | show the correct message for the error LOCAL_COMPILATION_UNRESOLVED_CONST when an unresolved symbol used for @Component.styles ([#54230](https://github.com/angular/angular/pull/54230)) |
| [58b8a232d6](https://github.com/angular/angular/commit/58b8a232d64f5fe3207c90c8145cab36e7e192c2) | fix | support jumping to definitions of signal-based inputs ([#54053](https://github.com/angular/angular/pull/54053)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [702ab28b4c](https://github.com/angular/angular/commit/702ab28b4c07a903c403a20af2ca287348b6afd0) | feat | add support for model inputs ([#54252](https://github.com/angular/angular/pull/54252)) |
| [e95ef2cbc6](https://github.com/angular/angular/commit/e95ef2cbc6f850d8fe96218b74cff76cea947674) | feat | expose queries as signals ([#54283](https://github.com/angular/angular/pull/54283)) |
| [656bc282e3](https://github.com/angular/angular/commit/656bc282e345c5e37a9189a0a4daa631e02c31bf) | fix | add toString implementation to signals ([#54002](https://github.com/angular/angular/pull/54002)) |
| [62b87b4551](https://github.com/angular/angular/commit/62b87b4551d77815f58af152d1921de3733621ba) | fix | do not crash for signal query that does not have any matches ([#54353](https://github.com/angular/angular/pull/54353)) |
| [4b96f370ee](https://github.com/angular/angular/commit/4b96f370eea08d2531cc54f65a651f94b504692d) | fix | expose model signal subcribe for type checking purposes ([#54357](https://github.com/angular/angular/pull/54357)) |
| [744cb1e561](https://github.com/angular/angular/commit/744cb1e561d9b0cbffd20ad612d5ea9e2cf6b2e7) | fix | return the same children query results if there are no changes ([#54392](https://github.com/angular/angular/pull/54392)) |
| [6d00115bf4](https://github.com/angular/angular/commit/6d00115bf45731b80178e11921df6ec1dc89efaf) | fix | show placeholder block on the server with immediate trigger ([#54394](https://github.com/angular/angular/pull/54394)) |
### http
| Commit | Type | Description |
| -- | -- | -- |
| [1c536250b6](https://github.com/angular/angular/commit/1c536250b6112c67a68159de50c4afe0dbc440f8) | fix | Use string body to generate transfer cache key. ([#54379](https://github.com/angular/angular/pull/54379)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.3"></a>
# 17.1.3 (2024-02-08)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [bc4a6a9715](https://github.com/angular/angular/commit/bc4a6a9715547881ed8e65169a5aaebfd3188a7f) | fix | do not error due to multiple components named equally ([#54273](https://github.com/angular/angular/pull/54273)) |
| [a997e08c6f](https://github.com/angular/angular/commit/a997e08c6f5c5321e5d18f3368ff0886fa133d59) | fix | handle default imports in defer blocks ([#53695](https://github.com/angular/angular/pull/53695)) |
| [63a9027720](https://github.com/angular/angular/commit/63a9027720611002c6ee3b443a11e9feff213059) | fix | interpolatedSignalNotInvoked diagnostic for model signals ([#54338](https://github.com/angular/angular/pull/54338)) |
| [40e1edc977](https://github.com/angular/angular/commit/40e1edc977fbe398adc535167f8ede2db8985656) | fix | properly catch fatal diagnostics in type checking ([#54309](https://github.com/angular/angular/pull/54309)) |
| [9f6605d11b](https://github.com/angular/angular/commit/9f6605d11b7ee75f289b5a2ed69e201d65b038d8) | fix | support jumping to definitions of signal-based inputs ([#54233](https://github.com/angular/angular/pull/54233)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [7df133dcc2](https://github.com/angular/angular/commit/7df133dcc243cd6b0f779fa35de7f916e6938301) | fix | `afterRender` hooks should allow updating state ([#54074](https://github.com/angular/angular/pull/54074)) |
| [744e20641a](https://github.com/angular/angular/commit/744e20641a21d18c324bd9c157c8912d38741826) | fix | Fix possible infinite loop with `markForCheck` by partially reverting [#54074](https://github.com/angular/angular/pull/54074) ([#54329](https://github.com/angular/angular/pull/54329)) |
| [0fb114274c](https://github.com/angular/angular/commit/0fb114274cead9f317a2fc902cc3a3f6b046e708) | fix | update imports to be compatible with rxjs 6 ([#54193](https://github.com/angular/angular/pull/54193)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [238f2a8bc9](https://github.com/angular/angular/commit/238f2a8bc9c46b0d08aff163349ecc1493441a69) | fix | Clear internal transition when navigation finalizes ([#54261](https://github.com/angular/angular/pull/54261)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.2"></a>
# 17.1.2 (2024-01-31)
###
| Commit | Type | Description |
| -- | -- | -- |
| [ccddacf11d](https://github.com/angular/angular/commit/ccddacf11deaebeda12e1bdb6e93ec401397d352) | fix | cta clickability issue in adev homepage. ([#52905](https://github.com/angular/angular/pull/52905)) |
### animations
| Commit | Type | Description |
| -- | -- | -- |
| [98d545fafa](https://github.com/angular/angular/commit/98d545fafa7fc3b1fb3ae049ce655e33ef9bd423) | fix | cleanup DOM elements when root view is removed with async animations ([#53033](https://github.com/angular/angular/pull/53033)) |
### common
| Commit | Type | Description |
| -- | -- | -- |
| [cdc5e39532](https://github.com/angular/angular/commit/cdc5e3953237a192beafd6330f9d9e36ede34f2c) | fix | The date pipe should return ISO format for week and week-year as intended in the unit test. ([#53879](https://github.com/angular/angular/pull/53879)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [f12b01ec88](https://github.com/angular/angular/commit/f12b01ec88eaf18041c2e46335428627aa0d7744) | fix | Update type check block to fix control flow source mappings ([#53980](https://github.com/angular/angular/pull/53980)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [c477e876e3](https://github.com/angular/angular/commit/c477e876e39495b855b096440d53cf1dd1ad33c6) | fix | change defer block fixture default behavior to playthrough ([#54088](https://github.com/angular/angular/pull/54088)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [8264382a6b](https://github.com/angular/angular/commit/8264382a6bf389fb3fca75fa2d6c0a2aa5a1e42f) | fix | error in standalone migration when non-array value is used as declarations in TestBed ([#54122](https://github.com/angular/angular/pull/54122)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.1"></a>
# 17.1.1 (2024-01-24)
### router
| Commit | Type | Description |
| -- | -- | -- |
| [f222bee8fa](https://github.com/angular/angular/commit/f222bee8fa037f437761e5f7f127f22f280e9154) | fix | revert commit that replaced `last` helper with native `Array.at(-1)` ([#54021](https://github.com/angular/angular/pull/54021)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.0"></a>
# 17.1.0 (2024-01-17)
### compiler
@@ -324,47 +512,46 @@ Live long and prosper 🖖🏻
[Blog post "Angular v17 is now available"](http://goo.gle/angular-v17).
## Breaking Changes
###
###
- Node.js v16 support has been removed and the minimum support version has been bumped to 18.13.0.
Node.js v16 is planned to be End-of-Life on 2023-09-11. Angular will stop supporting Node.js v16 in Angular v17. For Node.js release schedule details, please see: https://github.com/nodejs/release#release-schedule
### common
-
- the NgSwitch directive now defaults to the === equality operator,
migrating from the previously used ==. NgSwitch expressions and / or
migrating from the previously used == operator. NgSwitch expressions and / or
individual condition values need adjusting to this stricter equality
check. The added warning message should help pinpointing NgSwitch
usages where adjustements are needed.
check. The added warning message should help pin-pointing NgSwitch
usages where adjustments are needed.
### core
- Angular now required `zone.js` version `~0.14.0`
- Angular now requires `zone.js` version `~0.14.0`
- Versions of TypeScript older than 5.2 are no longer supported.
- The `mutate` method was removed from the `WritableSignal` interface and completely
dropped from the public API surface. As an alternative please use the update method and
dropped from the public API surface. As an alternative, please use the `update` method and
make immutable changes to the object.
Example before:
```typescript
items.mutate(itemsArray => itemsArray.push(newItem));
```
Example after:
```typescript
items.update(itemsArray => [itemsArray, …newItem]);
```
- The `mutate` method was removed from the `WritableSignal` interface and completely
dropped from the public API surface. As an alternative please use the update method and
make immutable changes to the object.
Example before:
```typescript
items.mutate(itemsArray => itemsArray.push(newItem));
```
Example after:
```typescript
items.update(itemsArray => [itemsArray, …newItem]);
```
@@ -380,7 +567,7 @@ Live long and prosper 🖖🏻
`detectChanges` on that component's `ChangeDetectorRef`.
### platform-browser
- `REMOVE_STYLES_ON_COMPONENT_DESTROY` default value is now `true`. This causes CSS of components to be removed from the DOM when destroyed. You retain the previous behaviour by providing the `REMOVE_STYLES_ON_COMPONENT_DESTROY` injection token.
```ts
import {REMOVE_STYLES_ON_COMPONENT_DESTROY} from '@angular/platform-browser';
...
@@ -403,13 +590,13 @@ Live long and prosper 🖖🏻
This should instead be configured through the provideRouter or RouterModule.forRoot APIs.
- The following Router properties have been removed from
the public API:
- canceledNavigationResolution
- paramsInheritanceStrategy
- titleStrategy
- urlUpdateStrategy
- malformedUriErrorHandler
These should instead be configured through the `provideRouter` or
`RouterModule.forRoot` APIs.
- The `setupTestingRouter` function has been removed. Use
@@ -420,7 +607,7 @@ Live long and prosper 🖖🏻
handled in the `UrlSerializer.parse` method.
### zone.js
- Deep and legacy `dist/` imports like `zone.js/bundles/zone-testing.js` and `zone.js/dist/zone` are no longer allowed. `zone-testing-bundle` and `zone-testing-node-bundle` are also no longer part of the package.
The proper way to import `zone.js` and `zone.js/testing` is:
```js
import 'zone.js';
@@ -431,21 +618,21 @@ Live long and prosper 🖖🏻
- The `AnimationDriver.NOOP` symbol is deprecated, use `NoopAnimationDriver` instead.
### core
- `ChangeDetectorRef.checkNoChanges` is deprecated.
Test code should use `ComponentFixture` instead of `ChangeDetectorRef`.
Application code should not call `ChangeDetectorRef.checkNoChanges` directly.
- Swapping out the context object for `EmbeddedViewRef`
is no longer supported. Support for this was introduced with v12.0.0, but
this pattern is rarely used. There is no replacement, but you can use
simple assignments in most cases, or `Object.assign , or alternatively
simple assignments in most cases, or `Object.assign` , or alternatively
still replace the full object by using a `Proxy` (see `NgTemplateOutlet`
as an example).
Also adds a warning if the deprecated
- NgProbeToken
The `NgProbeToken` is not used internally since the transition from View Engine to Ivy. The token has no utility and can be removed from applications and libraries.
###
###
| Commit | Type | Description |
| -- | -- | -- |
| [59aa0634f4](https://github.com/angular/angular/commit/59aa0634f4d4694203f2a69c40017fe5a3962514) | build | remove support for Node.js v16 ([#51755](https://github.com/angular/angular/pull/51755)) |
@@ -1059,7 +1246,7 @@ Live long and prosper 🖖🏻
[Blog post "Angular v16 is now available"](https://goo.gle/angular-v16).
## Breaking Changes
###
###
- Angular Compatibility Compiler (ngcc) has been removed and as a result Angular View Engine libraries will no longer work
- Deprecated `EventManager` method `addGlobalEventListener` has been removed as it is not used by Ivy.
### bazel
@@ -1082,14 +1269,14 @@ Live long and prosper 🖖🏻
The ideal fix would be to update the code to instead be compatible with
`MockPlatformLocation` instead.
- If the 'ngTemplateOutletContext' is different from the context, it will result in a compile-time error.
Before the change, the following template was compiling:
```typescript
interface MyContext {
$implicit: string;
}
@Component({
standalone: true,
imports: [NgTemplateOutlet],
@@ -1107,7 +1294,7 @@ Live long and prosper 🖖🏻
}
```
However, it does not compile now because the 'xxx' property does not exist in 'MyContext', resulting in the error: 'Type '{ $implicit: string; xxx: string; }' is not assignable to type 'MyContext'.'
The solution is either:
- add the 'xxx' property to 'MyContext' with the correct type or
- add '$any(...)' inside the template to make the error disappear. However, adding '$any(...)' does not correct the error but only preserves the previous behavior of the code.
@@ -1126,7 +1313,7 @@ Live long and prosper 🖖🏻
value differs from the previous call to `setInput`.
- `RendererType2.styles` no longer accepts a nested arrays.
- The `APP_ID` token value is no longer randomly generated. If you are bootstrapping multiple application on the same page you will need to set to provide the `APP_ID` yourself.
```ts
bootstrapApplication(ComponentA, {
providers: [
@@ -1137,21 +1324,21 @@ Live long and prosper 🖖🏻
```
- The `ReflectiveInjector` and related symbols were removed. Please update the code to avoid references to the `ReflectiveInjector` symbol. Use `Injector.create` as a replacement to create an injector instead.
- Node.js v14 support has been removed
Node.js v14 is planned to be End-of-Life on 2023-04-30. Angular will stop supporting Node.js v14 in Angular v16. Angular v16 will continue to officially support Node.js versions v16 and v18.
### platform-browser
- The deprecated `BrowserTransferStateModule` was removed, since it's no longer needed. The `TransferState` class can be injected without providing the module. The `BrowserTransferStateModule` was empty starting from v14 and you can just remove the reference to that module from your applications.
### platform-server
- Users that are using SSR with JIT mode will now need to add `import to @angular/compiler` before bootstrapping the application.
**NOTE:** this does not effect users using the Angular CLI.
- `renderApplication` method no longer accepts a root component as first argument. Instead, provide a bootstrapping function that returns a `Promise<ApplicationRef>`.
Before
```ts
const output: string = await renderApplication(RootComponent, options);
```
Now
```ts
const bootstrap = () => bootstrapApplication(RootComponent, appConfig);
@@ -1186,14 +1373,14 @@ Live long and prosper 🖖🏻
## Deprecations
### core
- `makeStateKey`, `StateKey` and `TransferState` exports have been moved from `@angular/platform-browser` to `@angular/core`. Please update the imports.
```diff
- import {makeStateKey, StateKey, TransferState} from '@angular/platform-browser';
+ import {makeStateKey, StateKey, TransferState} from '@angular/core';
```
- `EnvironmentInjector.runInContext` is now deprecated, with
`runInInjectionContext` functioning as a direct replacement:
```typescript
// Previous method version (deprecated):
envInjector.runInContext(fn);
@@ -1206,7 +1393,7 @@ Live long and prosper 🖖🏻
### platform-browser
- `BrowserModule.withServerTransition` has been deprecated. `APP_ID` should be used instead to set the application ID.
NB: Unless, you render multiple Angular applications on the same page, setting an application ID is not necessary.
Before:
```ts
imports: [
@@ -1214,7 +1401,7 @@ Live long and prosper 🖖🏻
...
]
```
After:
```ts
imports: [
@@ -1226,7 +1413,7 @@ Live long and prosper 🖖🏻
- `ApplicationConfig` has moved, please import `ApplicationConfig` from `@angular/core` instead.
### platform-server
- `PlatformConfig.baseUrl` and `PlatformConfig.useAbsoluteUrl` platform-server config options are deprecated as these were not used.
###
###
| Commit | Type | Description |
| -- | -- | -- |
| [48aa96ea13](https://github.com/angular/angular/commit/48aa96ea13ebfadf2f6b13516c7702dae740a7be) | refactor | remove Angular Compatibility Compiler (ngcc) ([#49101](https://github.com/angular/angular/pull/49101)) |
@@ -1535,11 +1722,11 @@ Alan Agius, Andrew Kushnir, Aristeidis Bampakos, Craig Spence, Doug Parker, Ivá
<a name="15.2.0"></a>
# 15.2.0 (2023-02-22)
## Deprecations
###
###
- Class and `InjectionToken` guards and resolvers are
deprecated. Instead, write guards as plain JavaScript functions and
inject dependencies with `inject` from `@angular/core`.
###
###
| Commit | Type | Description |
| -- | -- | -- |
| [926c35f4ac](https://github.com/angular/angular/commit/926c35f4ac70f5e4d142e545d6d056dd67aac97b) | docs | Deprecate class and InjectionToken and resolvers ([#47924](https://github.com/angular/angular/pull/47924)) |
@@ -1704,21 +1891,21 @@ Alan Agius, Alex Rickabaugh, Andrew Scott, Aristeidis Bampakos, Bob Watson, Jens
- CanLoad guards in the Router are deprecated. Use CanMatch
instead.
- router writable properties
The following strategies are meant to be configured by registering the
application strategy in DI via the `providers` in the root `NgModule` or
`bootstrapApplication`:
* `routeReuseStrategy`
* `titleStrategy`
* `urlHandlingStrategy`
The following options are meant to be configured using the options
available in `RouterModule.forRoot` or `provideRouter`.
* `onSameUrlNavigation`
* `paramsInheritanceStrategy`
* `urlUpdateStrategy`
* `canceledNavigationResolution`
The following options are available in `RouterModule.forRoot` but not
available in `provideRouter`:
* `malformedUriErrorHandler` - This was found to not be used anywhere
@@ -1913,23 +2100,23 @@ Andrew Kushnir
- Keyframes names are now prefixed with the component's "scope name".
For example, the following keyframes rule in a component definition,
whose "scope name" is host-my-cmp:
@keyframes foo { ... }
will become:
@keyframes host-my-cmp_foo { ... }
Any TypeScript/JavaScript code which relied on the names of keyframes rules
will no longer match.
The recommended solutions in this case are to either:
- change the component's view encapsulation to the `None` or `ShadowDom`
- define keyframes rules in global stylesheets (e.g styles.css)
- define keyframes rules programmatically in code.
### compiler-cli
- Invalid constructors for DI may now report compilation errors
When a class inherits its constructor from a base class, the compiler may now
report an error when that constructor cannot be used for DI purposes. This may
either be because the base class is missing an Angular decorator such as
@@ -1938,7 +2125,7 @@ Andrew Kushnir
These situations used to behave unexpectedly at runtime, where the class may be
constructed without any of its constructor parameters, so this is now reported
as an error during compilation.
Any new errors that may be reported because of this change can be resolved either
by decorating the base class from which the constructor is inherited, or by adding
an explicit constructor to the class for which the error is reported.
@@ -1972,16 +2159,16 @@ Andrew Kushnir
### core
- - The ability to pass an `NgModule` to the `providedIn` option for
`@Injectable` and `InjectionToken` is now deprecated.
`providedIn: NgModule` was intended to be a tree-shakable alternative to
NgModule providers. It does not have wide usage, and in most cases is used
incorrectly, in circumstances where `providedIn: 'root'` should be
preferred. If providers should truly be scoped to a specific NgModule, use
`NgModule.providers` instead.
- The ability to set `providedIn: 'any'` for an `@Injectable` or
`InjectionToken` is now deprecated.
`providedIn: 'any'` is an option with confusing semantics and is almost
never used apart from a handful of esoteric cases internal to the framework.
- The bit field signature of `Injector.get()` has been deprecated, in favor of the new options object.
@@ -2584,16 +2771,16 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
- Keyframes names are now prefixed with the component's "scope name".
For example, the following keyframes rule in a component definition,
whose "scope name" is host-my-cmp:
@keyframes foo { ... }
will become:
@keyframes host-my-cmp_foo { ... }
Any TypeScript/JavaScript code which relied on the names of keyframes rules
will no longer match.
The recommended solutions in this case are to either:
- change the component's view encapsulation to the `None` or `ShadowDom`
- define keyframes rules in global stylesheets (e.g styles.css)
@@ -2603,23 +2790,23 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
- Support for Node.js v12 has been removed as it will become EOL on 2022-04-30. Please use Node.js v14.15 or later.
- TypeScript versions older than 4.6 are no longer supported.
- Forms [email] input coercion
Forms [email] input value will be considered as true if it is defined with any value rather
than false and 'false'.
- Since Ivy, TestBed doesn't use AOT summaries. The `aotSummaries` fields in TestBed APIs were present, but unused. The fields were deprecated in previous major version and in v14 those fields are removed. The `aotSummaries` fields were completely unused, so you can just drop them from the TestBed APIs usage.
### forms
- Forms classes accept a generic.
Forms model classes now accept a generic type parameter. Untyped versions of these classes are available to opt-out of the new, stricter behavior.
- objects with a length key set to zero will no longer validate as empty.
This is technically a breaking change, since objects with a key `length` and value `0` will no longer validate as empty. This is a very minor change, and any reliance on this behavior is probably a bug anyway.
### http
- Queries including + will now actually query for + instead of space.
Most workarounds involving custom codecs will be unaffected.
Possible server-side workarounds will need to be undone.
- JSONP will throw an error when headers are set on a reques
JSONP does not support headers being set on requests. Before when
a request was sent to a JSONP backend that had headers set the headers
were ignored. The JSONP backend will now throw an error if it
@@ -2630,7 +2817,7 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
- This change may cause a breaking change in unit tests that are implicitly depending on a specific
number and sequence of change detections in order for their assertions to pass.
- This may break invalid calls to `TransferState` methods.
This tightens parameter types of `TransferState` usage, and is a minor breaking change which may reveal existing problematic calls.
### router
- The type of `Route.pathMatch` is now stricter. Places that use
@@ -2652,7 +2839,7 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
actually gets set to something completely different. It's set to the
current internal `UrlTree` of the Router at the time navigation
occurs.
With this change, there is no exact replacement for the old value of
`initialUrl` because it was never intended to be exposed.
`Router.url` is likely the best replacement for this.
@@ -2676,7 +2863,7 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
returned by other guards: only the first value is used.
### zone.js
- in TaskTrackingZoneSpec track a periodic task until it is cancelled
The breaking change is scoped only to the plugin
`zone.js/plugins/task-tracking`. If you used `TaskTrackingZoneSpec` and
checked the pending macroTasks e.g. using `(this.ngZone as any)._inner
@@ -2685,7 +2872,7 @@ Adrien Crivelli, Alan Agius, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Dyla
previously the `setInterval` macrotask was no longer tracked after its
callback was executed for the first time. Now it's tracked until
the task is explicitly cancelled, e.g with `clearInterval(id)`.
## Deprecations
### common
- The `ngModuleFactory` input of the `NgComponentOutlet` directive is deprecated in favor of a newly added `ngModule` input. The `ngModule` input accepts references to the NgModule class directly, without the need to resolve module factory first.
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2023 Google LLC. https://angular.io/license
Copyright (c) 2010-2024 Google LLC. https://angular.io/license
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+19
View File
@@ -61,6 +61,25 @@ Get started with Angular, learn the fundamentals and explore advanced topics on
- [Lazy Loading][lazyloading]
- [Animations][animations]
### Local Development
To contribute to Angular docs, you can setup a local environment with the following commands:
```bash
# Clone Angular repo
git clone https://github.com/angular/angular.git
# Navigate to project directory
cd angular
# Install dependencies
yarn
# Build and run local dev server
# Note: Initial build will take some time
yarn docs
```
## Development Setup
### Prerequisites
+14 -4
View File
@@ -64,7 +64,17 @@ load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
nodejs_register_toolchains(
name = "nodejs",
node_version = "18.13.0",
node_repositories = {
"18.18.2-darwin_arm64": ("node-v18.18.2-darwin-arm64.tar.gz", "node-v18.18.2-darwin-arm64", "9f982cc91b28778dd8638e4f94563b0c2a1da7aba62beb72bd427721035ab553"),
"18.18.2-darwin_amd64": ("node-v18.18.2-darwin-x64.tar.gz", "node-v18.18.2-darwin-x64", "5bb8da908ed590e256a69bf2862238c8a67bc4600119f2f7721ca18a7c810c0f"),
"18.18.2-linux_arm64": ("node-v18.18.2-linux-arm64.tar.xz", "node-v18.18.2-linux-arm64", "2e630e18548627f61eaf573233da7949dc0a1df5eef3f486fa9820c5f6c121aa"),
"18.18.2-linux_ppc64le": ("node-v18.18.2-linux-ppc64le.tar.xz", "node-v18.18.2-linux-ppc64le", "b0adff5cf5938266b711d6c724fb134d802e0dee40b3a3f73d162de1b3d11880"),
"18.18.2-linux_s390x": ("node-v18.18.2-linux-s390x.tar.xz", "node-v18.18.2-linux-s390x", "c70ec2074b5e2b42c55bb4b8105418b67bf8a61c500d9376a07430dfcc341fdb"),
"18.18.2-linux_amd64": ("node-v18.18.2-linux-x64.tar.xz", "node-v18.18.2-linux-x64", "75aba25ae76999309fc6c598efe56ce53fbfc221381a44a840864276264ab8ac"),
"18.18.2-windows_amd64": ("node-v18.18.2-win-x64.zip", "node-v18.18.2-win-x64", "3bb0e51e579a41a22b3bf6cb2f3e79c03801aa17acbe0ca00fc555d1282e7acd"),
},
# We need at least Node 18.17 due to some transitive dependencies.
node_version = "18.18.2",
)
# Download npm dependencies.
@@ -196,10 +206,10 @@ cldr_xml_data_repository(
# sass rules
http_archive(
name = "io_bazel_rules_sass",
sha256 = "7a90567717c3417a23ff4b21963a698a6e9aa669ac9e682121ea33f218a2816a",
strip_prefix = "rules_sass-425ecafa8268bc013d684216363fe75bc802323e",
sha256 = "974f5e14c54d300ca63a67910ebfcea6d838d8811fefc61184f2872107152705",
strip_prefix = "rules_sass-888dd9c02709e228b60a8b3e51e2b16b2ca5279d",
urls = [
"https://github.com/bazelbuild/rules_sass/archive/425ecafa8268bc013d684216363fe75bc802323e.zip",
"https://github.com/bazelbuild/rules_sass/archive/888dd9c02709e228b60a8b3e51e2b16b2ca5279d.zip",
],
)
+26 -1
View File
@@ -1,4 +1,5 @@
load("//:packages.bzl", "link_packages")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
load("@npm//@angular-devkit/architect-cli:index.bzl", "architect", "architect_test")
@@ -96,12 +97,36 @@ copy_to_bin(
srcs = APPLICATION_FILES,
)
bool_flag(
name = "fast_build_mode",
build_setting_default = False,
)
config_setting(
name = "fast",
flag_values = {
":fast_build_mode": "true",
},
)
config_setting(
name = "full",
flag_values = {
":fast_build_mode": "false",
},
)
config_based_architect_flags = select({
":fast": ["--no-prerender"],
":full": ["--prerender"],
})
architect(
name = "build",
args = [
"angular-dev:build",
"--output-path=build",
],
] + config_based_architect_flags,
chdir = "$(RULEDIR)",
data = APPLICATION_DEPS + [
":application_files_bin",
-1
View File
@@ -26,7 +26,6 @@
"index": "src/index.html",
"browser": "src/main.ts",
"server": "src/main.server.ts",
"prerender": true,
"polyfills": ["src/polyfills.ts", "zone.js"],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
-135
View File
@@ -1,135 +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 {input, confirm} from '@inquirer/prompts';
import {existsSync} from 'fs';
import {copyFile, mkdir, writeFile} from 'fs/promises';
import {dirname, join} from 'path';
import {fileURLToPath} from 'url';
import {copyFolder} from './utils/fs.mjs';
const EXAMPLES_BASE = join(
dirname(fileURLToPath(import.meta.url)),
'../../src/content/examples',
);
const STACKBLITZ_TEMPLATE = join(
dirname(fileURLToPath(import.meta.url)),
'../../src/content/stackblitz-template',
);
const MAIN_TS_FILENAME = 'main.ts';
const STACKBLITZ_CONFIG_FILENAME = 'stackblitz.json';
createExample();
async function createExample(): Promise<void> {
console.info('Create example');
const name = await input({message: 'What is the example name?'});
const description = await input({message: 'Could you provide the description of the example?'});
const tags: string[] = [];
let addMoreTags = true;
while (addMoreTags) {
const tag = await input({message: 'Could you provide the tag of the example?'});
if (!!tag) {
tags.push(tag);
}
console.info();
addMoreTags = await confirm({message: 'Would you like to add another tag?', default: true});
}
const shouldCopySrcAppFolderFromTemplate = await confirm({
message: 'Would you like to copy /src/app/**.* from template?',
default: true,
});
const shouldCopyMainTsFromTemplate = await confirm({
message: 'Would you like to copy /src/main.ts from template?',
default: false,
});
const examplePath = join(EXAMPLES_BASE, name);
await createEmptyExample(examplePath, name, description, tags);
await copyFilesFromTemplate(
examplePath,
shouldCopySrcAppFolderFromTemplate,
shouldCopyMainTsFromTemplate,
);
}
/**
* Create the directory and marker files for the new example.
*/
async function createEmptyExample(
examplePath: string,
exampleName: string,
description: string,
tags: string[],
): Promise<void> {
validateExampleName(exampleName);
await ensureExamplePath(examplePath);
await writeStackBlitzFile(examplePath, description, tags);
}
function validateExampleName(exampleName: string): void {
if (/\s/.test(exampleName)) {
throw new Error(`Unable to create example. The example name contains spaces: '${exampleName}'`);
}
}
/**
* Ensure that the new example directory exists.
*/
async function ensureExamplePath(examplePath: string): Promise<void> {
if (existsSync(examplePath)) {
throw new Error(
`Unable to create example. The path to the new example already exists: ${examplePath}`,
);
}
await mkdir(examplePath);
}
/**
* Write the `stackblitz.json` file into the new example.
*/
async function writeStackBlitzFile(
examplePath: string,
description: string,
tags: string[],
): Promise<void> {
const config = {
description,
ignore: ['**/*.d.ts', '**/*.js', '**/*.[1,2].*'],
tags,
};
await writeFile(
join(examplePath, STACKBLITZ_CONFIG_FILENAME),
JSON.stringify(config, null, 2) + '\n',
);
}
async function copyFilesFromTemplate(
examplePath: string,
shouldCopySrcAppFolderFromTemplate: boolean,
shouldCopyMainTsFromTemplate: boolean,
): Promise<void> {
if (shouldCopySrcAppFolderFromTemplate) {
const appTemplateFolderPath = join(STACKBLITZ_TEMPLATE, 'src/app');
const exampleAppFolderPath = join(examplePath, 'src/app');
await copyFolder(appTemplateFolderPath, exampleAppFolderPath);
}
if (shouldCopyMainTsFromTemplate) {
const mainTsTemplatePath = join(STACKBLITZ_TEMPLATE, 'src', MAIN_TS_FILENAME);
const exampleMainTsPath = join(examplePath, 'src', MAIN_TS_FILENAME);
await copyFile(mainTsTemplatePath, exampleMainTsPath);
}
}
@@ -1,158 +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 ts from 'typescript';
import * as fs from 'fs';
import {dirname, join, relative} from 'path';
import {fileURLToPath} from 'url';
import {readFile, writeFile} from 'fs/promises';
const TYPESCRIPT_EXTENSION = '.ts';
const SKIP_FILES_WITH_EXTENSIONS = ['.e2e-spec.ts', '.spec.ts', '.po.ts'];
const EXAMPLES_PATH = `../../content/examples`;
interface File {
path: string;
content: string;
}
interface AnalyzedFiles {
path: string;
componentNames: string[];
}
/** Absolute disk path to the project directory. */
const examplesDir = join(
dirname(fileURLToPath(import.meta.url)),
'../../src/content/examples',
);
const projectDir = join(dirname(fileURLToPath(import.meta.url)), '../../src');
const previewsComponentMapFileName = 'previews.ts';
main();
async function main() {
const files = await retrieveAllTypescriptFiles(
examplesDir,
(path) => !SKIP_FILES_WITH_EXTENSIONS.some((extensionToSkip) => path.endsWith(extensionToSkip)),
);
const filesWithComponent = files
.map((file) => ({
componentNames: analyzeFile(file),
path: file.path,
}))
.filter((result) => result.componentNames.length > 0);
const previewsComponentMap = generatePreviewsComponentMap(filesWithComponent);
fs.mkdirSync(join(projectDir, 'assets/previews'), {recursive: true});
await writeFile(
join(projectDir, 'assets/previews', previewsComponentMapFileName),
previewsComponentMap,
);
}
/** Recursively search the provided directory for all typescript files and asynchronously load them. */
function retrieveAllTypescriptFiles(
baseDir: string,
predicateFn: (path: string) => boolean,
): Promise<File[]> {
const typescriptFiles: Promise<File>[] = [];
const checkFilesInDirectory = (dir: string) => {
const files = fs.readdirSync(dir, {withFileTypes: true});
for (const file of files) {
const fullPathToFile = join(dir, file.name);
const relativeFilePath = relative(baseDir, fullPathToFile);
if (
file.isFile() &&
file.name.endsWith(TYPESCRIPT_EXTENSION) &&
predicateFn(relativeFilePath)
) {
typescriptFiles.push(
readFile(fullPathToFile, {encoding: 'utf-8'}).then((fileContent) => {
return {
path: relativeFilePath,
content: fileContent,
};
}),
);
} else if (file.isDirectory()) {
checkFilesInDirectory(fullPathToFile);
}
}
};
checkFilesInDirectory(baseDir);
return Promise.all(typescriptFiles);
}
/** Returns list of the `Standalone` @Component class names for given file */
function analyzeFile(file: File): string[] {
const componentClassNames: string[] = [];
const sourceFile = ts.createSourceFile(file.path, file.content, ts.ScriptTarget.Latest, false);
const visitNode = (node: ts.Node): void => {
if (ts.isClassDeclaration(node)) {
const decorators = ts.getDecorators(node);
const componentName = node.name ? node.name.text : null;
if (decorators && decorators.length) {
for (const decorator of decorators) {
const call = decorator.expression;
if (
ts.isCallExpression(call) &&
ts.isIdentifier(call.expression) &&
call.expression.text === 'Component' &&
call.arguments.length > 0 &&
ts.isObjectLiteralExpression(call.arguments[0])
) {
const hasStandaloneProperty = call.arguments[0].properties.some(
(property) =>
property.name &&
ts.isIdentifier(property.name) &&
property.name.text === 'standalone',
);
if (hasStandaloneProperty && componentName) {
componentClassNames.push(componentName);
}
}
}
}
}
ts.forEachChild(node, visitNode);
};
visitNode(sourceFile);
return componentClassNames;
}
function generatePreviewsComponentMap(data: AnalyzedFiles[]): string {
let result = '';
for (const fileData of data) {
for (const componentName of fileData.componentNames) {
const key = `${fileData.path}${
fileData.componentNames.length > 1 ? '_' + componentName : ''
}`.replace(/\\/g, '/');
result += `['${key}']: () => import('${EXAMPLES_PATH}/${fileData.path
.replace(/\\/g, '/')
.replace('.ts', '')}').then(c => c.${componentName}),\n`;
}
}
return fs
.readFileSync('scripts/examples/previews-components.template', 'utf8')
.replace(/\${previewsComponents}/g, result);
}
@@ -1,23 +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
*/
/**
******************************************************************************
* DO NOT MANUALLY EDIT THIS FILE. THIS FILE IS AUTOMATICALLY GENERATED.
******************************************************************************
*/
import {Type} from '@angular/core';
/**
* Map of the previews components, values are functions which returns the promise of the component type, which will be displayed as preview in the ExampleViewer component.
* Keys has to be equal to paths written down in the docs markdown files.
*/
export const PREVIEWS_COMPONENTS_MAP: Record<string, () => Promise<Type<unknown>>> = {
${previewsComponents}
};
@@ -1,221 +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 {dirname, join} from 'path';
import {readFile, writeFile} from 'fs/promises';
import {
ASSETS_EXAMPLE_PATH,
CSS_TS_COPYRIGHT,
EXAMPLES_PATH,
HTML_COPYRIGHT,
STACKBLITZ_TEMPLATE_PATH,
STACKBLITZ_CONFIG_FILENAME,
TEMPORARY_EXAMPLES_PATH,
EXCLUDE_FILES_FOR_STACKBLITZ,
} from './utils/examples-constants.mjs';
import {copyFolder, createFolder, removeFolder} from './utils/fs.mjs';
import jsdom from 'jsdom';
import {glob} from 'glob';
import {regionParser} from './../../prerender/markdown-pipeline/regions/region-parser.mjs';
interface StackblitzConfig {
ignore: string[];
file: string;
tags: string[];
description: string;
}
export async function generateStackblitzExample(
exampleFolderName: string,
primaryFilePath: string,
title: string,
) {
const exampleDir = join(EXAMPLES_PATH, exampleFolderName);
const temporaryExampleDir = join(TEMPORARY_EXAMPLES_PATH, exampleFolderName);
const config = await readFile(join(exampleDir, STACKBLITZ_CONFIG_FILENAME), 'utf-8');
const stackblitzConfig: StackblitzConfig = JSON.parse(config);
primaryFilePath = join(...primaryFilePath.split('/'));
await createFolder(temporaryExampleDir);
await combineTemplateWithExample(exampleDir, temporaryExampleDir);
await generateStackblitzHtml(
temporaryExampleDir,
stackblitzConfig,
exampleFolderName,
primaryFilePath,
title,
);
await removeFolder(temporaryExampleDir);
}
async function combineTemplateWithExample(
exampleDir: string,
temporaryExampleDir: string,
): Promise<void> {
// Copy template files to TEMP folder
await copyFolder(STACKBLITZ_TEMPLATE_PATH, temporaryExampleDir);
// Copy example files to TEMP folder
await copyFolder(exampleDir, temporaryExampleDir);
}
async function generateStackblitzHtml(
temporaryExampleDir: string,
stackBlitzConfig: StackblitzConfig,
exampleFolderName: string,
primaryFilePath: string,
title: string,
): Promise<void> {
const defaultIncludes = [
'**/*.ts',
'**/*.js',
'**/*.css',
'**/*.html',
'**/*.md',
'**/*.json',
'**/*.svg',
];
const exampleFilePaths = await glob(defaultIncludes, {
cwd: temporaryExampleDir,
nodir: true,
dot: true,
ignore: stackBlitzConfig.ignore,
});
const postData = await createPostData(
temporaryExampleDir,
stackBlitzConfig,
exampleFilePaths,
title,
);
const primaryFile = getPrimaryFile(primaryFilePath ?? stackBlitzConfig.file, exampleFilePaths);
const html = createStackblitzHtml(postData, primaryFile);
const stackblitzHtmlPath = join(
join(ASSETS_EXAMPLE_PATH, exampleFolderName),
`${primaryFile}.html`,
);
await createFolder(dirname(stackblitzHtmlPath));
await writeFile(stackblitzHtmlPath, html, 'utf-8');
}
function getPrimaryFile(primaryFilePath: string, exampleFilePaths: string[]): string {
if (primaryFilePath) {
if (!exampleFilePaths.some((filePath) => filePath === primaryFilePath)) {
throw new Error(`The specified primary file (${primaryFilePath}) does not exist!`);
}
return primaryFilePath;
} else {
const defaultPrimaryFilePaths = [
'src/app/app.component.html',
'src/app/app.component.ts',
'src/app/main.ts',
];
const primaryFile = defaultPrimaryFilePaths.find((path) =>
exampleFilePaths.some((filePath) => filePath === path),
);
if (!primaryFile) {
throw new Error(
`None of the default primary files (${defaultPrimaryFilePaths.join(', ')}) exists.`,
);
}
return primaryFile;
}
}
async function createPostData(
exampleDir: string,
config: StackblitzConfig,
exampleFilePaths: string[],
title: string,
): Promise<Record<string, string>> {
const postData: Record<string, string> = {};
for (const filePath of exampleFilePaths) {
if (EXCLUDE_FILES_FOR_STACKBLITZ.some((excludedFile) => filePath.endsWith(excludedFile))) {
continue;
}
let content = await readFile(join(exampleDir, filePath), 'utf-8');
content = appendCopyright(filePath, content);
content = extractRegions(filePath, content);
postData[`project[files][${filePath}]`] = content;
}
const tags = ['angular', 'example', ...(config.tags || [])];
tags.forEach((tag, index) => (postData[`project[tags][${index}]`] = tag));
postData['project[description]'] = `Angular Example - ${config.description}`;
postData['project[template]'] = 'node';
postData['project[title]'] = title ?? 'Angular Example';
return postData;
}
function createStackblitzHtml(postData: Record<string, string>, primaryFile: string): string {
const baseHtml = createBaseStackblitzHtml(primaryFile);
const doc = new jsdom.JSDOM(baseHtml).window.document;
const form = doc.querySelector('form');
for (const [key, value] of Object.entries(postData)) {
const element = htmlToElement(doc, `<input type="hidden" name="${key}">`);
if (element && form) {
element.setAttribute('value', value as string);
form.appendChild(element);
}
}
return doc.documentElement.outerHTML;
}
function createBaseStackblitzHtml(primaryFile: string) {
const file = `?file=${primaryFile}`;
const action = `https://stackblitz.com/run${file}`;
return `
<!DOCTYPE html><html lang="en"><body>
<form id="mainForm" method="post" action="${action}" target="_self"></form>
<script>
var embedded = 'ctl=1';
var isEmbedded = window.location.search.indexOf(embedded) > -1;
if (isEmbedded) {
var form = document.getElementById('mainForm');
var action = form.action;
var actionHasParams = action.indexOf('?') > -1;
var symbol = actionHasParams ? '&' : '?'
form.action = form.action + symbol + embedded;
}
document.getElementById("mainForm").submit();
</script>
</body></html>
`.trim();
}
function appendCopyright(filename: string, content: string): string {
if (filename.endsWith('.html')) {
return `${HTML_COPYRIGHT}${content}`;
} else if (filename.endsWith('.ts') || filename.endsWith('.css')) {
return `${CSS_TS_COPYRIGHT}${content}`;
}
return content;
}
function htmlToElement(document: Document, html: string) {
const div = document.createElement('div');
div.innerHTML = html;
return div.firstElementChild;
}
function extractRegions(path: string, contents: string): string {
const regionParserResult = regionParser(contents, path);
return regionParserResult.contents;
}
-8
View File
@@ -1,8 +0,0 @@
{
"extends": "../../tsconfig.json",
"ts-node": {
"compilerOptions": {
"module": "es2020"
}
}
}
@@ -1,55 +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 {dirname, join} from 'path';
import {fileURLToPath} from 'url';
const BASE = dirname(fileURLToPath(import.meta.url));
// Directory paths
export const ASSETS_EXAMPLE_PATH = join(
BASE,
'../../../src/assets/content/examples',
);
export const EXAMPLES_PATH = join(BASE, '../../../src/content/examples');
export const STACKBLITZ_TEMPLATE_PATH = join(
BASE,
'../../../src/content/stackblitz-template',
);
export const TEMPORARY_EXAMPLES_PATH = join(fileURLToPath(import.meta.url), '../../../../TEMP');
// Extensions
export const TEST_FILES_EXTENSION_SUFFIX = '.spec.ts';
export const TEST_FILES_E2E_EXTENSION_SUFFIX = '.e2e-spec.ts';
// Filename
// TODO: BUILD.bazel and example-config will be deprecated when migration to standalone examples will be done.
export const BUILD_BAZEL_FILENAME = 'BUILD.bazel';
export const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
export const STACKBLITZ_CONFIG_FILENAME = 'stackblitz.json';
// Copyright
const PAD = '\n\n';
const COPYRIGHT =
'@license\n' +
'Copyright Google LLC All Rights Reserved.\n' +
'\n' +
'Use of this source code is governed by an MIT-style license that can be\n' +
'found in the LICENSE file at https://angular.dev/license\n';
export const CSS_TS_COPYRIGHT = `/*\n${COPYRIGHT}\n*/${PAD}`;
export const HTML_COPYRIGHT = `<!-- \n${COPYRIGHT}\n-->${PAD}`;
// Exclude
export const EXCLUDE_FILES_FOR_STACKBLITZ = [
STACKBLITZ_CONFIG_FILENAME,
BUILD_BAZEL_FILENAME,
EXAMPLE_CONFIG_FILENAME,
TEST_FILES_EXTENSION_SUFFIX,
TEST_FILES_E2E_EXTENSION_SUFFIX,
];
-77
View File
@@ -1,77 +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 {Dirent, existsSync, readdirSync} from 'fs';
import {copyFile, mkdir, readFile, readdir, rm, stat} from 'fs/promises';
import {join, relative} from 'path';
export async function copyFolder(source: string, destination: string) {
if (!existsSync(destination)) {
await mkdir(destination, {recursive: true});
}
const files = await readdir(source);
for (const file of files) {
const sourcePath = join(source, file);
const destPath = join(destination, file);
const stats = await stat(sourcePath);
const isDirectory = await stats.isDirectory();
if (isDirectory) {
await copyFolder(sourcePath, destPath);
} else {
await copyFile(sourcePath, destPath);
}
}
}
/** Recursively search the provided directory for all files which satisfy predicate and asynchronously load them. */
export function retrieveFiles(
baseDir: string,
predicate?: (file: Dirent) => boolean,
): Promise<{path: string; content: string}[]> {
const filesWithContent: Promise<{path: string; content: string}>[] = [];
const checkFilesInDirectory = (dir: string) => {
const files = readdirSync(dir, {withFileTypes: true});
for (const file of files) {
const fullPathToFile = join(dir, file.name);
if (file.isFile() && (predicate ? predicate(file) : true)) {
filesWithContent.push(
readFile(fullPathToFile, {encoding: 'utf-8'}).then((fileContent) => {
return {
path: relative(baseDir, fullPathToFile),
content: fileContent,
};
}),
);
} else if (file.isDirectory()) {
checkFilesInDirectory(fullPathToFile);
}
}
};
checkFilesInDirectory(baseDir);
return Promise.all(filesWithContent);
}
export async function createFolder(path: string): Promise<void> {
if (!existsSync(path)) {
await mkdir(path, {recursive: true});
}
}
export async function removeFolder(path: string): Promise<void> {
if (existsSync(path)) {
await rm(path, {recursive: true});
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
@if (displaySecondaryNav()) {
<adev-secondary-navigation />
}
<div class="adev-app-main-content">
<div class="docs-app-main-content">
<!--
Avoid rendering cookies popup on the server,
since there is no benefit of doing this and
+3 -3
View File
@@ -12,9 +12,9 @@
flex-direction: column;
}
// If navs are open, render a blurry background over content
&:has(.adev-nav-secondary--open),
&:has(.docs-nav-secondary--open),
&:has(.adev-nav-primary--open) {
.adev-app-main-content {
.docs-app-main-content {
&::after {
visibility: visible;
opacity: 1;
@@ -54,7 +54,7 @@
}
}
.adev-app-main-content {
.docs-app-main-content {
display: flex;
flex-direction: column;
min-height: 100vh;
@@ -116,7 +116,7 @@
</div>
</div>
<p class="docs-license">
Super-powered by Google ©2010-2023. Code licensed under an
Super-powered by Google ©2010-2024. 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>
@@ -59,7 +59,7 @@
</div>
<nav
class="adev-nav-primary adev-scroll-hide"
class="adev-nav-primary docs-scroll-hide"
[class.adev-nav-primary--open]="isMobileNavigationOpened()"
>
<button
@@ -126,7 +126,7 @@
</a>
<!-- Version picker for v18+ -->
<!-- <div class="adev-nav-item">
<div class="adev-nav-item">
<button
type="button"
aria-label="Select Angular version"
@@ -166,7 +166,7 @@
}
</ul>
</ng-template>
</div> -->
</div>
</li>
<!-- Search -->
@@ -6,9 +6,10 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
import {ProgressBarComponent} from './progress-bar.component';
import {PROGRESS_BAR_DELAY, ProgressBarComponent} from './progress-bar.component';
import {RouterTestingHarness, RouterTestingModule} from '@angular/router/testing';
describe('ProgressBarComponent', () => {
let component: ProgressBarComponent;
@@ -16,7 +17,7 @@ describe('ProgressBarComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ProgressBarComponent],
imports: [ProgressBarComponent, RouterTestingModule],
}).compileComponents();
fixture = TestBed.createComponent(ProgressBarComponent);
@@ -24,7 +25,13 @@ describe('ProgressBarComponent', () => {
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should call progressBar.complete() on route change', fakeAsync(async () => {
const progressBarCompleteSpy = spyOn(component.progressBar, 'complete');
const harness = await RouterTestingHarness.create();
await harness.navigateByUrl('/');
tick(PROGRESS_BAR_DELAY);
expect(progressBarCompleteSpy).toHaveBeenCalled();
}));
});
@@ -27,7 +27,7 @@ import {
import {filter, map, switchMap, take} from 'rxjs/operators';
/** Time to wait after navigation starts before showing the progress bar. This delay allows a small amount of time to skip showing the progress bar when a navigation is effectively immediate. 30ms is approximately the amount of time we can wait before a delay is perceptible.*/
const PROGRESS_BAR_DELAY = 30;
export const PROGRESS_BAR_DELAY = 30;
@Component({
selector: 'adev-progress-bar',
@@ -1,5 +1,5 @@
<div [attr.id]="SECONDARY_NAV_ID" class="adev-secondary-nav-mask" [class.adev-nav-secondary--open]="isSecondaryNavVisible()" (docsClickOutside)="close()" [docsClickOutsideIgnore]="[PRIMARY_NAV_ID]">
<div class="adev-nav-secondary adev-scroll-track-transparent" [style.transform]="translateX()" [style.transition]="transition">
<div [attr.id]="SECONDARY_NAV_ID" class="adev-secondary-nav-mask" [class.docs-nav-secondary--open]="isSecondaryNavVisible()" (docsClickOutside)="close()" [docsClickOutsideIgnore]="[PRIMARY_NAV_ID]">
<div class="docs-nav-secondary docs-scroll-track-transparent" [style.transform]="translateX()" [style.transition]="transition">
<!-- Secondary Nav -->
@if (navigationItems && navigationItems.length > 0) {
<docs-navigation-list
@@ -18,7 +18,7 @@
transform: translateX(0);
z-index: 99;
transition: transform 0.3s ease;
&:has(.adev-nav-secondary--open) {
&:has(.docs-nav-secondary--open) {
transform: translateX(82px);
transition: transform 0.3s ease-in 0.3s;
}
@@ -46,7 +46,7 @@
@include mq.for-tablet-landscape-down {
transform: translateX(-100%);
&.adev-nav-secondary--open {
&.docs-nav-secondary--open {
transform: translateX(0);
}
}
@@ -56,7 +56,7 @@
// exit immediately
transition: transform 0.45s ease-in;
&.adev-nav-secondary--open {
&.docs-nav-secondary--open {
transform: translateX(0);
// enter delayed
transition: transform 0.45s ease-out 0.2s;
@@ -64,8 +64,8 @@
}
}
// seconday nav - translated on x to display levels
.adev-nav-secondary {
// secondary nav - translated on x to display levels
.docs-nav-secondary {
display: flex;
flex-direction: row;
max-width: var(--secondary-nav-width);
@@ -45,7 +45,7 @@ export class CustomErrorHandler implements ErrorHandler {
openErrorSnackBar(): void {
this.snackBar
.openFromComponent(ErrorSnackBar, {
panelClass: 'adev-invert-mode',
panelClass: 'docs-invert-mode',
data: {
message: `Our docs have been updated, reload the page to see the latest.`,
actionText: `Reload`,
@@ -19,7 +19,7 @@ export interface ErrorSnackBarData {
template: `
{{ message }}
<button
class="adev-primary-btn"
class="docs-primary-btn"
type="button"
matSnackBarAction
[attr.text]="actionText"
@@ -14,8 +14,8 @@ import {Subject} from 'rxjs';
// Keep these constants in sync with the code in index.html
export const THEME_PREFERENCE_LOCAL_STORAGE_KEY = 'themePreference';
export const DARK_MODE_CLASS_NAME = 'adev-dark-mode';
export const LIGHT_MODE_CLASS_NAME = 'adev-light-mode';
export const DARK_MODE_CLASS_NAME = 'docs-dark-mode';
export const LIGHT_MODE_CLASS_NAME = 'docs-light-mode';
export const PREFERS_COLOR_SCHEME_DARK = '(prefers-color-scheme: dark)';
export type Theme = 'dark' | 'light' | 'auto';
@@ -38,13 +38,13 @@ export class ThemeManager {
}
this.loadThemePreference();
this.watchPreferedColorScheme();
this.watchPreferredColorScheme();
}
setTheme(theme: Theme): void {
this.theme.set(theme);
this.setThemeInLocalStorage();
this.setThemeBodyClasses(theme === 'auto' ? preferedScheme() : theme);
this.setThemeBodyClasses(theme === 'auto' ? preferredScheme() : theme);
}
// 1. Read theme preferences stored in localStorage
@@ -54,7 +54,7 @@ export class ThemeManager {
const useTheme = savedUserPreference ?? 'auto';
this.theme.set(useTheme);
this.setThemeBodyClasses(useTheme === 'auto' ? preferedScheme() : useTheme);
this.setThemeBodyClasses(useTheme === 'auto' ? preferredScheme() : useTheme);
}
// Set theme classes on the body element
@@ -81,14 +81,14 @@ export class ThemeManager {
}
}
private watchPreferedColorScheme() {
private watchPreferredColorScheme() {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {
const preferedScheme = event.matches ? 'dark' : 'light';
this.setThemeBodyClasses(preferedScheme);
const preferredScheme = event.matches ? 'dark' : 'light';
this.setThemeBodyClasses(preferredScheme);
});
}
}
function preferedScheme(): 'dark' | 'light' {
function preferredScheme(): 'dark' | 'light' {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
@@ -10,22 +10,70 @@ import {Injectable, VERSION, computed, signal} from '@angular/core';
// TODO(josephperrott): extract this out of the file into a managed location.
const VERSIONS_CONFIG = {
currentVersion: "stable",
historicalVersionsLinkPattern: "https://v{{version}}.angular.dev",
currentVersion: 'stable',
historicalVersionsLinkPattern: 'https://v{{version}}.angular.dev',
mainVersions: [
{
version: "stable",
url: "https://angular.dev"
version: 'stable',
url: 'https://angular.dev',
},
{
version: "rc",
url: "https://rc.angular.dev"
version: 'v16',
url: 'https://v16.angular.io/docs',
},
{
version: "next",
url: "https://next.angular.dev"
}
]
version: 'v15',
url: 'https://v15.angular.io/docs',
},
{
version: 'v14',
url: 'https://v14.angular.io/docs',
},
{
version: 'v13',
url: 'https://v13.angular.io/docs',
},
{
version: 'v12',
url: 'https://v12.angular.io/docs',
},
{
version: 'v11',
url: 'https://v11.angular.io/docs',
},
{
version: 'v10',
url: 'https://v10.angular.io/docs',
},
{
version: 'v9',
url: 'https://v9.angular.io/docs',
},
{
version: 'v8',
url: 'https://v8.angular.io/docs',
},
{
version: 'v7',
url: 'https://v7.angular.io/docs',
},
{
version: 'v6',
url: 'https://v6.angular.io/docs',
},
{
version: 'v5',
url: 'https://v5.angular.io/docs',
},
{
version: 'v4',
url: 'https://v4.angular.io/docs',
},
{
version: 'v2',
url: 'https://v2.angular.io/docs',
},
],
};
export interface Version {
+207
View File
@@ -0,0 +1,207 @@
# EmbeddedEditor components, services and functionality
- [Scenarios](#scenarios)
- [Loading a project](#loading-a-project)
- [Updating the code](#updating-the-code)
- [Creating a new file](#creating-a-new-file)
- [Deleting a file](#deleting-a-file)
- [Switching a project](#switching-a-project)
- [Components and services](#components-and-services)
- [EmbeddedEditor](#EmbeddedEditor)
- [CodeEditor](#CodeEditor)
- [CodeMirrorEditor](#CodeMirrorEditor)
- [TypeScript Web Worker](#typescript-web-worker)
- [Preview](#Preview)
- [Terminal](#Terminal)
- [InteractiveTerminal](#InteractiveTerminal)
- [Console](#Console)
- [NodeRuntimeSandbox](#NodeRuntimeSandbox)
- [NodeRuntimeState](#NodeRuntimeState)
- [EmbeddedTutorialManager](#EmbeddedTutorialManager)
- [EditorUiState](#EditorUiState)
- [DownloadManager](#DownloadManager)
- [AlertManager](#AlertManager)
- [TypingsLoader](#TypingsLoader)
## External libraries
- [WebContainers API](https://webcontainers.io/)
- [CodeMirror](https://codemirror.net/)
- [@typescript/vfs](https://www.npmjs.com/package/@typescript/vfs)
- [Xterm.js](https://xtermjs.org/)
## Notes
- See [scripts/tutorials/README.md](/scripts/tutorials/README.md) for more information about the tutorials script.
- See [adev/src/content/tutorials/README.md](/adev/src/content/tutorials/README.md) for more information about the tutorials content.
---
## Scenarios
### Loading a project
1. The page responsible for the embedded editor lazy loads the [`EmbeddedEditor`](./embedded-editor.component.ts) component and the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts), then triggers the initialization of all components and services. The embedded editor is available in the following pages:
- homepage: https://angular.dev
- playground: https://angular.dev/playground
- tutorial pages: https://angular.dev/tutorials
2. The project assets are fetched by the [`EmbeddedTutorialManager`](./embedded-tutorial-manager.service.ts). Meanwhile:
- The code editor is initialized
- The code editor initializes the TypeScript Web Worker, which initializes the "default file system map" using TypeScript's CDN.
- The WebContainer is initialized
- The terminal is initialized
3. The tutorial source code is mounted in the `WebContainer`'s filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts)
4. The tutorial project dependencies are installed by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
5. The development server is started by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts) and the types are loaded by the [`TypingsLoader`](./typings-loader.service.ts) service.
6. The preview is loaded with the URL provided by the WebContainer API after the development server is started.
7. The project is ready.
### Updating the code
1. The user update the code in the code editor.
2. The code editor state is updated on real time, without debouncing so that the user can see the changes in the code editor and CodeMirror can handle the changes accordingly.
3. At the same time, the changes are sent to the TypeScript web worker to provide diagnostics, autocomplete and type features as soon as possible.
4. The code changes are debounced to be written in the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
5. After the debounce time is reached, the code changes are written in the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts), then the user can see the changes in the preview.
### Creating a new file
1. The user clicks on the new file button.
2. The new file tab is opened.
3. The user types the new file name.
4. If the file name is valid, the file is created in the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
- `..` is disallowed in the file name to prevent users to create files outside the `src` directory.
5. The file is added to the TypeScript virtual file system, allowing the TypeScript web worker to provide diagnostics, autocomplete and type features for the new file. Also, exports from the new file are available in other files.
6. The new file is added as the last tab in the code editor and the new file can be edited.
Note: If the new file name matches a file that already exists but is hidden in the code editor, the content for that file will show up in the created file. An example for a file that always exists is `index.html`.
### Deleting a file
1. The user clicks on the delete file button.
2. The file is deleted from the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
3. The file is removed from the TypeScript virtual file system.
4. The file is removed from the code editor tabs.
Note: Some files can't be deleted to prevent users to break the app, being `src/main.ts`and `src/index.html`
### Switching a project
The embedded editor considers a project change when the embedded editor was already initialized and the user changes the page in the following scenarios:
- Navigating through tutorial steps
- Going from the homepage after the embedded editor is initialized to the playground
- Going from a tutorial page to the playground
- Going from a tutorial page to the homepage
- Going from the playground to the homepage
When a project change is detected, the [`EmbeddedTutorialManager`](./embedded-tutorial-manager.service.ts) emits the `tutorialChanged` observable, which is listened in multiple sub-components and services, then each component/service performs the necessary operations to switch the project.
The following steps are executed on project change:
1. The new project files are fetched by the [`EmbeddedTutorialManager`](./embedded-tutorial-manager.service.ts).
2. The new project files are mounted in the WebContainer filesystem.
3. The TypeScript virtual filesystem is updated with the new files and contents.
4. The previous project and new project files are compared.
1. Files that are not available in the new project are deleted from the WebContainer filesystem.
2. Files that have the same path and name have their content replaced on the previous step when the files are mounted.
5. The previous project dependencies are compared with the new project dependencies.
1. If there are differences, a `npm install` is triggered, hiding the preview and going to the install loading step.
2. If there are no differences, the project is ready.
6. Some states are resetted, for example the "reveal answer" state if the previous project was in the "reveal answer" state.
## Components and services
### [`EmbeddedEditor`](./embedded-editor.component.ts)
The embedded editor is the parent component that holds all the components and services that compose the embedded editor.
#### [`CodeEditor`](./code-editor/code-editor.component.ts)
The component that holds the code editor view and the code editor state.
##### [`CodeMirrorEditor`](./code-editor/code-mirror-editor.service.ts)
[CodeMirror](https://codemirror.net/) is the library used to handle the code editor.
The `CodeMirrorEditor` service manages the CodeMirror instance and all the interactions with the library used to handle the code editor.
- handle the file edits and the CodeMirror view and state
- handle the current project files in the code editor
- handle the file creations and deletions
- handle the file changes
- handle all the CodeMirror specific events and extensions
###### [TypeScript Web Worker](./code-editor/workers/typescript-vfs.worker.ts)
The TypeScript features are provided by the TypeScript web worker, that is initialized by the `CodeMirrorEditor` service.
The TypeScript web worker uses `@typescript/vfs` and the TypeScript language service to provide diagnostics, autocomplete and type features.
#### [`Preview`](./preview/preview.component.ts)
The preview component manages the `iframe` responsible for displaying the tutorial project preview, with the URL provided by the WebContainer API after the development server is started.
While the project is being initialized, the preview displays the loading state.
#### [`Terminal`](./terminal/terminal.component.ts)
[Xterm.js](https://xtermjs.org/) is the library used to handle the terminals.
The terminal component handles the Xterm.js instance for the console and for the interactive terminal.
##### [`InteractiveTerminal`](./terminal/interactive-terminal.ts)
The interactive terminal is the terminal where the user can interact with the terminal and run commands, supporting only commands for the Angular CLI.
##### Console
The console displays the output for `npm install` and `ng serve`.
#### [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts)
Responsible for managing the WebContainer instance and all communication with its API. This service handles:
- the WebContainer instance
- all Node.js scripts
- the WebContainer filesystem, mounting the tutorial project files, writing new content, deleting and creating files.
- the terminal session, reading and processing user inputs.
- the tutorial project dependencies, installing the dependencies.
- the processes running inside the WebContainer, being the npm scripts to install the dependencies, run the development server and the user inputs for the `ng` CLI.
##### [`NodeRuntimeState`](./node-runtime-state.service.ts)
Manages the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts) loading and error state.
#### [`EmbeddedTutorialManager`](./embedded-tutorial-manager.service.ts)
Manages the tutorial assets, being responsible for fetching the tutorial source code and metadata.
The source code is mounted in the WebContainer filesystem by the [`NodeRuntimeSandbox`](./node-runtime-sandbox.service.ts).
The metadata is used to manage the project, handle the project changes and the user interactivity with the app.
This service also handles the reveal answer and reset reveal answer feature.
#### [`EditorUiState`](./editor-ui-state.service.ts)
Manages the editor UI state, being responsible for handling the user interactions with the editor tabs, switching between the preview, the terminal and the console.
#### [`DownloadManager`](./download-manager.service.ts)
Responsible for handling the download button in the embedded editor, fetching the tutorial project files and generating a zip file with the project content.
#### [`AlertManager`](./alert-manager.service.ts)
Manage the alerts displayed in the embedded editor, being the out of memory alert when multiple tabs are opened, and unsupported enviroments alerts.
#### [`TypingsLoader`](./typings-loader.service.ts)
Manages the types definitions for the code editor.
+1 -1
View File
@@ -95,7 +95,7 @@ export class AlertManager {
}
this.snackBar.openFromComponent(ErrorSnackBar, {
panelClass: 'adev-invert-mode',
panelClass: 'docs-invert-mode',
data: {
message,
actionText: 'I understand',
@@ -1,5 +1,5 @@
<!-- Code Editor Tabs -->
<div class="adev-code-editor-tabs">
<div class="docs-code-editor-tabs">
<div class="adev-tabs-and-plus">
<mat-tab-group animationDuration="0ms" mat-stretch-tabs="false">
<!--
@@ -13,7 +13,7 @@
{{ file.filename.replace('src/', '') }}
@if (tab.isActive && canDeleteFile(file.filename)) {
<button
class="adev-delete-file"
class="docs-delete-file"
aria-label="Delete file"
(click)="deleteFile(file.filename)"
>
@@ -65,7 +65,7 @@
position: relative;
}
.adev-code-editor-tabs {
.docs-code-editor-tabs {
display: flex;
background: var(--octonary-contrast);
border-block-end: 1px solid var(--senary-contrast);
@@ -79,7 +79,7 @@
}
.adev-add-file,
.adev-delete-file {
.docs-delete-file {
docs-icon {
color: var(--gray-400);
transition: color 0.3s ease;
@@ -92,7 +92,7 @@
}
}
.adev-delete-file {
.docs-delete-file {
padding-inline-start: 0.1rem;
padding-inline-end: 0;
margin-block-start: 0.2rem;
@@ -66,7 +66,7 @@ export const getTooltipExtension = (
dom: tooltip,
// Note: force the tooltip to scroll to the top on mount and on position change
// because depending on the position of the mouse and the siez of the tooltip content,
// because depending on the position of the mouse and the size of the tooltip content,
// the tooltip might render with its initial scroll position on the bottom
mount: (_) => forceTooltipScrollTop(),
positioned: (_) => forceTooltipScrollTop(),
@@ -92,7 +92,7 @@ function forceTooltipScrollTop() {
function getMarkedHtmlFromString(content: string): HTMLDivElement {
const wrapper = document.createElement('div');
wrapper.innerHTML = marked(content);
wrapper.innerHTML = marked(content) as string;
return wrapper;
}
@@ -137,7 +137,7 @@ function getTagsHtml(tags: JSDocTagInfo[]): HTMLDivElement {
}
}
tagsWrapper.innerHTML = marked(contentString);
tagsWrapper.innerHTML = marked(contentString) as string;
return tagsWrapper;
}
@@ -1,5 +1,5 @@
<div class="adev-editor-container" #editorContainer>
<as-split class="adev-editor" [direction]="splitDirection" restrictMove="true" gutterSize="5">
<as-split class="docs-editor" [direction]="splitDirection" restrictMove="true" gutterSize="5">
<as-split-area class="adev-left-side" [size]="50">
<!-- Code Editor -->
@if (!displayOnlyTerminal()) {
@@ -16,9 +16,9 @@
</as-split-area>
<as-split-area [size]="50">
<!-- Preview, Termnial & Console -->
<!-- Preview, Terminal & Console -->
@if (!displayOnlyTerminal()) {
<as-split class="adev-right-side" direction="vertical" restrictMove="true" gutterSize="5">
<as-split class="docs-right-side" direction="vertical" restrictMove="true" gutterSize="5">
<!-- Preview Section: for larger screens -->
@if (!displayPreviewInMatTabGroup()) {
<as-split-area [size]="50" [order]="1">
@@ -34,9 +34,9 @@
</as-split-area>
}
<as-split-area class="adev-editor-tabs-and-refresh" [size]="50" [order]="2">
<as-split-area class="docs-editor-tabs-and-refresh" [size]="50" [order]="2">
<!-- Container to hide preview, console and footer when only the interactive terminal is used -->
<mat-tab-group class="adev-editor-tabs" animationDuration="0ms" mat-stretch-tabs="false">
<mat-tab-group class="docs-editor-tabs" animationDuration="0ms" mat-stretch-tabs="false">
@if (displayPreviewInMatTabGroup()) {
<mat-tab label="Preview">
<docs-tutorial-preview />
@@ -32,7 +32,7 @@ $width-breakpoint: 950px;
}
// If files are displayed, shpare the space
&:has(.adev-editor-tabs) {
&:has(.docs-editor-tabs) {
.adev-tutorial-code-editor {
display: block;
box-sizing: border-box;
@@ -56,7 +56,7 @@ $width-breakpoint: 950px;
height: 100%;
}
.adev-right-side {
.docs-right-side {
height: 100%;
// prevent border flicker when resizing editor
@@ -71,7 +71,7 @@ $width-breakpoint: 950px;
}
}
.adev-editor-tabs-and-refresh {
.docs-editor-tabs-and-refresh {
position: relative;
height: 100%;
@@ -81,7 +81,7 @@ $width-breakpoint: 950px;
}
// preview, terminal, console side/container of the embedded editor
.adev-editor-tabs {
.docs-editor-tabs {
height: 100%;
display: block;
}
@@ -145,7 +145,9 @@ $width-breakpoint: 950px;
display: flex;
align-items: center;
background-color: var(--octonary-contrast);
transition: background-color 0.3s ease, border-color 0.3s ease;
transition:
background-color 0.3s ease,
border-color 0.3s ease;
i {
color: var(--bright-blue);
@@ -192,3 +194,11 @@ $width-breakpoint: 950px;
padding: 1.5rem;
}
}
::ng-deep mat-tab-group {
.mat-mdc-tab-body-wrapper,
.mat-mdc-tab-body,
.mat-mdc-tab-body-content {
display: contents;
}
}
@@ -26,7 +26,7 @@ export const DEV_SERVER_READY_MSG = 'Watch mode enabled. Watching for file chang
export const OUT_OF_MEMORY_MSG = 'Out of memory';
const enum PROCESS_EXIT_CODE {
SUCCESS = 0, // process exited succesfully
SUCCESS = 0, // process exited successfully
ERROR = 10, // process exited with error
SIGTERM = 143, // 143 = gracefully terminated by SIGTERM, e.g. Ctrl + C
}
@@ -73,7 +73,7 @@ export class NodeRuntimeSandbox {
}
async init(): Promise<void> {
// Note: the error state can already be set when loading the NodeRuntimeSanbox
// Note: the error state can already be set when loading the NodeRuntimeSandbox
// in an unsupported environment.
if (this.nodeRuntimeState.error()) {
return;
@@ -155,7 +155,7 @@ export class NodeRuntimeSandbox {
* Initialize the WebContainer for an Angular project
*/
private async initProject(): Promise<void> {
// prevent re-initializion
// prevent re-initialization
if (this._isProjectInitialized()) return;
// clean up the sandbox if it was initialized before so that the CLI can
@@ -230,7 +230,7 @@ export class NodeRuntimeSandbox {
* Initialize the WebContainer for the Angular CLI
*/
private async initAngularCli() {
// prevent re-initializion
// prevent re-initialization
if (this._isAngularCliInitialized()) return;
// clean up the sandbox if a project was initialized before so the CLI can
@@ -292,7 +292,7 @@ export class NodeRuntimeSandbox {
const terminal = this.terminalHandler.interactiveTerminalInstance;
// use WebContainer spawn directly so that the proccess isn't killed on
// use WebContainer spawn directly so that the process isn't killed on
// cleanup
const shellProcess = await webContainer.spawn('bash');
@@ -516,10 +516,10 @@ export class NodeRuntimeSandbox {
/**
* Kill existing processes and remove files from the WebContainer
* when switching tutorials that have diferent requirements
* when switching tutorials that have different requirements
*/
private async cleanup() {
// await the proccess to be killed before removing the files because
// await the process to be killed before removing the files because
// a process can create files during the promise
await this.killExistingProcesses();
await this.removeFiles();
@@ -1,4 +1,4 @@
<div class="adev-preview-error adev-light-mode adev-mini-scroll-track">
<div class="adev-preview-error docs-light-mode docs-mini-scroll-track">
@switch (true) {
@case (error()?.type === ErrorType.UNSUPPORTED_BROWSER_ENVIRONMENT) {
@if(isIos) {
@@ -1,7 +1,7 @@
:host {
display: block;
.adev-dark-mode & {
.docs-dark-mode & {
.adev-embedded-editor-preview-container {
background: var(--gray-100);
}
@@ -80,7 +80,7 @@ export class TypingsLoader {
.readFile(`./node_modules/${library}/package.json`, 'utf-8')
.catch((error) => {
// Note: "ENOENT" errors occurs:
// - While reseting the NodeRuntimeSandbox.
// - While resetting the NodeRuntimeSandbox.
// - When the library is not a dependency in the project, its package.json won't exist.
//
// In both cases we ignore the error to continue the process.
+1 -1
View File
@@ -14,7 +14,7 @@ import {ActivatedRoute} from '@angular/router';
import {map} from 'rxjs/operators';
@Component({
selector: 'adev-docs',
selector: 'docs-docs',
standalone: true,
imports: [CommonModule, DocViewer],
styleUrls: ['./docs.component.scss'],
@@ -8,13 +8,6 @@
</p>
<p class="adev-banner-cta">Read about our beta launch</p>
</a>
<a href="https://goo.gle/angular-event" class="adev-banner" target="_blank">
<p>
<code>ng update</code>
to Angular v17 on November 8th!
</p>
<p class="adev-banner-cta">Learn more</p>
</a>
</div>
</div>
<div class="adev-canvas"></div>
@@ -88,6 +81,6 @@
</div>
<div class="adev-arrow"></div>
<a routerLink="{{ctaLink}}" class="adev-cta">
<button class="adev-primary-btn" [attr.text]="'Learn Angular'" aria-label="Learn Angular">Learn Angular</button>
<button class="docs-primary-btn" [attr.text]="'Learn Angular'" aria-label="Learn Angular">Learn Angular</button>
</a>
</div>
@@ -4,7 +4,7 @@
width: 100%;
// While editor is loading, display an svg of the editor
.adev-dark-mode & {
.docs-dark-mode & {
.adev-editor-scroll-container img {
content: url('../../../assets/images/editor-dark-horizontal.svg');
@include mq.for-tablet-down {
@@ -12,7 +12,7 @@
}
}
}
.adev-light-mode & {
.docs-light-mode & {
.adev-editor-scroll-container img {
content: url('../../../assets/images/editor-light-horizontal.svg');
@include mq.for-tablet-down {
@@ -142,7 +142,8 @@
display: inline-block;
padding: 7px;
opacity: 0;
transition: opacity 0.5s linear;
visibility: hidden;
transition: opacity 0.5s linear, visibility 0.5s linear;
button {
font-size: 1rem;
@@ -307,6 +308,7 @@
.adev-cta,
.adev-arrow {
opacity: 1;
visibility: visible;
}
}
@@ -9,6 +9,7 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import ApiItemLabel from './api-item-label.component';
import {ApiItemType} from '../interfaces/api-item-type';
describe('ApiItemLabel', () => {
let component: ApiItemLabel;
@@ -23,7 +24,32 @@ describe('ApiItemLabel', () => {
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
it('should by default display short label for Class', () => {
component.type = ApiItemType.CLASS;
fixture.detectChanges();
const label = fixture.nativeElement.innerText;
expect(label).toBe('C');
});
it('should display full label for Class when labelMode equals full', () => {
component.type = ApiItemType.CLASS;
component.mode = 'full';
fixture.detectChanges();
const label = fixture.nativeElement.innerText;
expect(label).toBe('Class');
});
it('should display short label for Class when labelMode equals short', () => {
component.type = ApiItemType.CLASS;
component.mode = 'short';
fixture.detectChanges();
const label = fixture.nativeElement.innerText;
expect(label).toBe('C');
});
});
@@ -11,7 +11,7 @@ import {ApiItemType} from '../interfaces/api-item-type';
import {ApiLabel} from '../pipes/api-label.pipe';
@Component({
selector: 'adev-api-item-label',
selector: 'docs-api-item-label',
standalone: true,
templateUrl: './api-item-label.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -9,16 +9,16 @@
@for (apiItem of group.items; track apiItem.url) {
<li [class.adev-api-items-section-item-deprecated]="apiItem.isDeprecated">
<a [routerLink]="'/' + apiItem.url" class="adev-api-items-section-item" [attr.aria-describedby]="apiItem.isDeprecated ? 'deprecated-description' : null">
<adev-api-item-label
<docs-api-item-label
[type]="apiItem.itemType"
mode="short"
class="adev-api-item-label"
class="docs-api-item-label"
aria-hidden="true"
/>
<span class="adev-item-title">{{ apiItem.title }}</span>
</a>
@if (apiItem.isDeprecated) {
<span class="adev-deprecated">
<span class="docs-deprecated">
&lt;!&gt;
</span>
}
@@ -91,7 +91,7 @@
gap: 1em;
}
.adev-deprecated {
.docs-deprecated {
font-family: var(--code-font);
background-color: var(--senary-contrast);
color: var(--tertiary-contrast);
@@ -13,17 +13,44 @@ import {ApiItemsGroup} from '../interfaces/api-items-group';
import {ApiReferenceManager} from '../api-reference-list/api-reference-manager.service';
import {ApiItemType} from '../interfaces/api-item-type';
import {RouterTestingModule} from '@angular/router/testing';
import {By} from '@angular/platform-browser';
describe('ApiItemsSection', () => {
let component: ApiItemsSection;
let fixture: ComponentFixture<ApiItemsSection>;
let apiReferenceManagerSpy: jasmine.SpyObj<ApiReferenceManager>;
const fakeGroup: ApiItemsGroup = {
const fakeFeaturedGroup: ApiItemsGroup = {
title: 'Featured',
isFeatured: true,
items: [
{title: 'Fake Title', itemType: ApiItemType.CLASS, url: 'api/fakeTitle', isFeatured: true},
{
title: 'Fake Featured Title',
itemType: ApiItemType.CLASS,
url: 'api/fakeFeaturedTitle',
isFeatured: true,
},
{
title: 'Fake Deprecated Title',
itemType: ApiItemType.CONST,
url: 'api/fakeDeprecatedTitle',
isFeatured: false,
isDeprecated: true,
},
{
title: 'Fake Standard Title',
itemType: ApiItemType.DIRECTIVE,
url: 'api/fakeTitle',
isFeatured: false,
},
],
};
const fakeGroup: ApiItemsGroup = {
title: 'Example group',
isFeatured: false,
items: [
{title: 'Fake Title', itemType: ApiItemType.CONST, url: 'api/fakeTitle', isFeatured: false},
],
};
@@ -34,12 +61,60 @@ describe('ApiItemsSection', () => {
});
fixture = TestBed.createComponent(ApiItemsSection);
component = fixture.componentInstance;
});
it('should render star icon for featured group', () => {
component.group = fakeFeaturedGroup;
fixture.detectChanges();
const starIcon = fixture.debugElement.query(By.css('.adev-api-items-section-header docs-icon'));
expect(starIcon).toBeTruthy();
});
it('should not render star icon for standard group', () => {
component.group = fakeGroup;
fixture.detectChanges();
const starIcon = fixture.debugElement.query(By.css('.adev-api-items-section-header docs-icon'));
expect(starIcon).toBeFalsy();
});
it('should create', () => {
expect(component).toBeTruthy();
it('should render list of all APIs of provided group', () => {
component.group = fakeFeaturedGroup;
fixture.detectChanges();
const apis = fixture.debugElement.queryAll(By.css('.adev-api-items-section-grid li'));
expect(apis.length).toBe(3);
});
it('should display deprecated icon for deprecated API', () => {
component.group = fakeFeaturedGroup;
fixture.detectChanges();
const deprecatedApiIcons = fixture.debugElement.queryAll(
By.css('.adev-api-items-section-grid li .docs-deprecated'),
);
const deprecatedApiTitle = deprecatedApiIcons[0].parent?.query(By.css('.adev-item-title'));
expect(deprecatedApiIcons.length).toBe(1);
expect(deprecatedApiIcons[0]).toBeTruthy();
expect(deprecatedApiTitle?.nativeElement.innerText).toBe('Fake Deprecated Title');
});
it('should display star icon for featured API', () => {
component.group = fakeFeaturedGroup;
fixture.detectChanges();
const featuredApiIcons = fixture.debugElement.queryAll(
By.css('.adev-api-items-section-grid li .adev-api-items-section-item-featured'),
);
const featuredApiTitle = featuredApiIcons[0].parent?.query(By.css('.adev-item-title'));
expect(featuredApiIcons.length).toBe(1);
expect(featuredApiIcons[0]).toBeTruthy();
expect(featuredApiTitle?.nativeElement.innerText).toBe('Fake Featured Title');
});
});
@@ -1,7 +1,7 @@
<div class="adev-header-and-tabs adev-scroll-track-transparent">
<docs-viewer [docContent]="headerInnerHtml()" class="adev-reference-header"></docs-viewer>
<div class="adev-header-and-tabs docs-scroll-track-transparent">
<docs-viewer [docContent]="headerInnerHtml()" class="docs-reference-header"></docs-viewer>
<mat-tab-group class="adev-reference-tabs" animationDuration="0ms" mat-stretch-tabs="false" [selectedIndex]="selectedTabIndex()">
<mat-tab-group class="docs-reference-tabs" animationDuration="0ms" mat-stretch-tabs="false" [selectedIndex]="selectedTabIndex()">
@for (tab of tabs(); track tab) {
<mat-tab [label]="tab.title">
<div class="adev-reference-tab-body">
@@ -14,7 +14,7 @@
@if (canDisplayCards() && membersMarginTopInPx() > 0) {
<docs-viewer
class="adev-reference-members-container"
class="docs-reference-members-container"
[docContent]="membersInnerHtml()"
[style.marginTop.px]="membersMarginTopInPx()"
(contentLoaded)="membersCardsLoaded()">
@@ -38,7 +38,7 @@
@include mq.for-desktop-up {
// this section should only be independently scrollable if
// the API tab is active & the screen is wide enough
&:has(.adev-reference-api-tab),
&:has(.docs-reference-api-tab),
&.adev-cli-content {
position: sticky;
top: 0;
@@ -48,10 +48,11 @@
overflow-y: scroll;
width: 50%;
}
&:has(.adev-reference-api-tab) {
&:has(.docs-reference-api-tab) {
width: 60%;
}
&:not(.adev-reference-api-tab) {
&:not(:has(.docs-reference-api-tab)) {
width: 100%;
max-width: var(--page-width);
}
}
@@ -73,7 +74,7 @@
}
}
.adev-reference-header {
.docs-reference-header {
> p {
color: var(--secondary-contrast);
margin-block-start: 0;
@@ -94,15 +95,18 @@
}
}
.adev-reference-api-tab {
.docs-reference-api-tab {
display: flex;
gap: 1.81rem;
align-items: flex-start;
margin-bottom: 1px;
@include mq.for-desktop-down {
flex-direction: column;
}
& > .docs-code {
box-sizing: border-box;
width: 100%;
max-height: 93vh;
overflow: hidden;
@@ -155,7 +159,7 @@
margin-block-start: 2.5rem;
}
.adev-reference-members-container {
.docs-reference-members-container {
width: 40%;
padding: 0 var(--layout-padding) 1rem 0;
box-sizing: border-box;
@@ -172,7 +176,7 @@
}
// Sidebar
.adev-reference-members {
.docs-reference-members {
display: flex;
flex-direction: column;
gap: 20px;
@@ -182,7 +186,7 @@
}
}
.adev-reference-title {
.docs-reference-title {
display: flex;
flex-wrap: wrap;
align-items: center;
@@ -217,7 +221,7 @@
gap: 0.5rem;
}
.adev-reference-category {
.docs-reference-category {
color: var(--gray-400);
font-size: 0.875rem;
font-weight: 500;
@@ -225,7 +229,7 @@
letter-spacing: -0.00875rem;
}
.adev-reference-member-card {
.docs-reference-member-card {
border: 1px solid var(--senary-contrast);
border-radius: 0.25rem;
position: relative;
@@ -248,7 +252,7 @@
}
}
&:has(.adev-reference-card-body) {
&:has(.docs-reference-card-body) {
header {
border-radius: 0.25rem 0.25rem 0 0;
border-bottom: 1px solid var(--senary-contrast);
@@ -266,7 +270,7 @@
transition: background-color 0.3s ease, border 0.3s ease;
// h3 + code || # of overloads
.adev-reference-header {
.docs-reference-header {
display: flex;
align-items: center;
justify-content: space-between;
@@ -299,7 +303,7 @@
}
}
.adev-reference-card-body {
.docs-reference-card-body {
padding: 0.25rem 1.25rem;
background: var(--septenary-contrast);
transition: background-color 0.3s ease;
@@ -316,14 +320,14 @@
}
// when it's not the only card...
.adev-reference-card-item:has(~ .adev-reference-card-item) {
.docs-reference-card-item:has(~ .docs-reference-card-item) {
border: 1px solid var(--senary-contrast);
margin-block: 1rem;
border-radius: 0.25rem;
padding-inline: 1rem;
}
// & the last card
.adev-reference-card-item:last-child {
.docs-reference-card-item:last-child {
&:not(:first-of-type) {
border: 1px solid var(--senary-contrast);
margin-block: 1rem;
@@ -332,7 +336,7 @@
}
}
.adev-reference-card-item {
.docs-reference-card-item {
span {
display: inline-block;
font-size: 0.875rem;
@@ -342,31 +346,31 @@
}
}
.adev-function-definition {
.docs-function-definition {
&:has(*) {
border-block-end: 1px solid var(--senary-contrast);
}
}
.adev-param-group {
.docs-param-group {
margin-block-start: 1rem;
}
// If it's the only param group...
.adev-param-group:not(:has(~ .adev-param-group)) {
.docs-param-group:not(:has(~ .docs-param-group)) {
margin-block: 1rem;
}
.adev-return-type {
.docs-return-type {
padding-block: 1rem;
// & does not follow a function definition
&:not(.adev-function-definition + .adev-return-type) {
&:not(.docs-function-definition + .docs-return-type) {
border-block-start: 1px solid var(--senary-contrast);
}
}
.adev-param-keyword {
.docs-param-keyword {
color: var(--primary-contrast);
font-family: var(--code-font);
margin-inline-end: 0.5rem;
@@ -381,7 +385,7 @@
}
}
.adev-deprecated {
.docs-deprecated {
color: var(--page-background);
background-color: var(--quaternary-contrast);
width: max-content;
@@ -391,11 +395,11 @@
}
// deprecated markers beside header
.adev-reference-header ~ .adev-deprecated {
.docs-reference-header ~ .docs-deprecated {
margin-block-start: 0.5rem;
}
.adev-parameter-description {
.docs-parameter-description {
p:first-child {
margin-block-start: 0;
}
@@ -17,22 +17,25 @@ import {provideRouter} from '@angular/router';
import {RouterTestingHarness, RouterTestingModule} from '@angular/router/testing';
import ApiReferenceDetailsPage from './api-reference-details-page.component';
import {By} from '@angular/platform-browser';
describe('ApiReferenceDetailsPage', () => {
let component: ApiReferenceDetailsPage;
let loader: HarnessLoader;
let harness: RouterTestingHarness;
let fakeApiReferenceScrollHandler = {
setupListeners: () => {},
membersMarginTopInPx: signal(0),
membersMarginTopInPx: signal(10),
updateMembersMarginTop: () => {},
};
const SAMPLE_CONTENT_WITH_TABS = `<div class="adev-reference-tabs">
<div data-tab="API" class="adev-reference-tab"></div>
<div data-tab="Description" class="adev-reference-tab"></div>
<div data-tab="Examples" class="adev-reference-tab"></div>
<div data-tab="Usage Notes" class="adev-reference-tab"></div>
const SAMPLE_CONTENT_WITH_TABS = `<div class="docs-reference-tabs">
<div data-tab="API" data-tab-url="api" class="adev-reference-tab"></div>
<div data-tab="Description" data-tab-url="description" class="adev-reference-tab"></div>
<div data-tab="Examples" data-tab-url="examples" class="adev-reference-tab"></div>
<div data-tab="Usage Notes" data-tab-url="usage-notes" class="adev-reference-tab"></div>
<div class="docs-reference-members-container"></div>
</div>`;
beforeEach(async () => {
@@ -54,7 +57,7 @@ describe('ApiReferenceDetailsPage', () => {
],
});
TestBed.overrideProvider(ReferenceScrollHandler, {useValue: fakeApiReferenceScrollHandler});
const harness = await RouterTestingHarness.create();
harness = await RouterTestingHarness.create();
const {fixture} = harness;
component = await harness.navigateByUrl('/', ApiReferenceDetailsPage);
loader = TestbedHarnessEnvironment.loader(fixture);
@@ -72,4 +75,32 @@ describe('ApiReferenceDetailsPage', () => {
expect(tabs.length).toBe(4);
}));
it('should display members cards when API tab is active', waitForAsync(async () => {
const matTabGroup = await loader.getHarness(MatTabGroupHarness);
const tabs = await matTabGroup.getTabs();
let membersCard = harness.fixture.debugElement.query(
By.css('.docs-reference-members-container'),
);
expect(membersCard).toBeTruthy();
await matTabGroup.selectTab({label: await tabs[1].getLabel()});
membersCard = harness.fixture.debugElement.query(By.css('.docs-reference-members-container'));
expect(membersCard).toBeFalsy();
await matTabGroup.selectTab({label: await tabs[0].getLabel()});
membersCard = harness.fixture.debugElement.query(By.css('.docs-reference-members-container'));
expect(membersCard).toBeTruthy();
}));
it('should setup scroll listeners when API members are loaded', () => {
const setupListenersSpy = spyOn(fakeApiReferenceScrollHandler, 'setupListeners');
component.membersCardsLoaded();
expect(setupListenersSpy).toHaveBeenCalled();
});
});
@@ -27,7 +27,7 @@
[class.adev-reference-list-legend-item-active]="type() === itemType"
(click)="filterByItemType(itemType)"
>
<adev-api-item-label [type]="itemType" mode="short" class="adev-api-item-label" />
<docs-api-item-label [type]="itemType" mode="short" class="docs-api-item-label" />
<span>{{ itemType | adevApiLabel : 'full' }}</span>
</li>
}
@@ -40,5 +40,5 @@
<adev-api-items-section [group]="group" />
}
<span id="deprecated-description" class="adev-deprecated-description">Deprecated</span>
<span id="deprecated-description" class="docs-deprecated-description">Deprecated</span>
</div>
@@ -96,6 +96,6 @@
}
.adev-deprecated-description {
.docs-deprecated-description {
display: none;
}
@@ -8,7 +8,7 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import ApiReferenceList from './api-reference-list.component';
import ApiReferenceList, {ALL_STATUSES_KEY} from './api-reference-list.component';
import {RouterTestingModule} from '@angular/router/testing';
import {ApiReferenceManager} from './api-reference-manager.service';
import {signal} from '@angular/core';
@@ -95,4 +95,20 @@ describe('ApiReferenceList', () => {
expect(component.filteredGroups()![0].items).toEqual([fakeItem2]);
});
it('should set selected type when provided type is different than selected', () => {
component.filterByItemType(ApiItemType.BLOCK);
expect(component.type()).toBe(ApiItemType.BLOCK);
});
it('should reset selected type when provided type is equal to selected', () => {
component.filterByItemType(ApiItemType.BLOCK);
expect(component.type()).toBe(ApiItemType.BLOCK);
component.filterByItemType(ApiItemType.BLOCK);
expect(component.type()).toBe(ALL_STATUSES_KEY);
});
});
@@ -1,4 +1,4 @@
<div class="adev-header-and-tabs adev-cli-content adev-scroll-track-transparent">
<div class="adev-header-and-tabs adev-cli-content docs-scroll-track-transparent">
<docs-viewer [docContent]="mainContentInnerHtml()" />
</div>
@@ -47,7 +47,7 @@
}
}
.adev-reference-type-and-default {
.docs-reference-type-and-default {
width: 4.375rem;
flex-shrink: 0;
span {
@@ -6,16 +6,18 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {TestBed} from '@angular/core/testing';
import CliReferenceDetailsPage from './cli-reference-details-page.component';
import {RouterTestingModule} from '@angular/router/testing';
import {RouterTestingHarness, RouterTestingModule} from '@angular/router/testing';
import {signal} from '@angular/core';
import {ReferenceScrollHandler} from '../services/reference-scroll-handler.service';
import {provideRouter} from '@angular/router';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
describe('CliReferenceDetailsPage', () => {
let component: CliReferenceDetailsPage;
let fixture: ComponentFixture<CliReferenceDetailsPage>;
let harness: RouterTestingHarness;
let fakeApiReferenceScrollHandler = {
setupListeners: () => {},
@@ -23,18 +25,42 @@ describe('CliReferenceDetailsPage', () => {
updateMembersMarginTop: () => {},
};
const SAMPLE_CONTENT = `
<div class="cli">
<div class="docs-reference-cli-content">First column content</div>
<div class="docs-reference-members-container">Members content</div>
</div>
`;
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [CliReferenceDetailsPage, RouterTestingModule],
providers: [
provideRouter([
{
path: '**',
component: CliReferenceDetailsPage,
data: {
'docContent': {
id: 'id',
contents: SAMPLE_CONTENT,
},
},
},
]),
],
});
TestBed.overrideProvider(ReferenceScrollHandler, {useValue: fakeApiReferenceScrollHandler});
fixture = TestBed.createComponent(CliReferenceDetailsPage);
component = fixture.componentInstance;
harness = await RouterTestingHarness.create();
const {fixture} = harness;
component = await harness.navigateByUrl('/', CliReferenceDetailsPage);
TestbedHarnessEnvironment.loader(fixture);
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
it('should set content on init', () => {
expect(component.mainContentInnerHtml()).toBe('First column content');
expect(component.cardsInnerHtml()).toBe('Members content');
});
});
@@ -22,7 +22,7 @@ import {map} from 'rxjs/operators';
import {ReferenceScrollHandler} from '../services/reference-scroll-handler.service';
import {API_REFERENCE_DETAILS_PAGE_MEMBERS_CLASS_NAME} from '../constants/api-reference-prerender.constants';
export const CLI_MAIN_CONTENT_SELECTOR = '.adev-reference-cli-content';
export const CLI_MAIN_CONTENT_SELECTOR = '.docs-reference-cli-content';
export const CLI_TOC = '.adev-reference-cli-toc';
@Component({
@@ -7,15 +7,15 @@
*/
export const API_REFERENCE_DETAILS_PAGE_CONTENT_CLASS_NAME = '.adev-reference-content';
export const API_REFERENCE_DETAILS_PAGE_HEADER_CLASS_NAME = '.adev-reference-header';
export const API_REFERENCE_DETAILS_PAGE_MEMBERS_CLASS_NAME = '.adev-reference-members-container';
export const API_REFERENCE_DETAILS_PAGE_HEADER_CLASS_NAME = '.docs-reference-header';
export const API_REFERENCE_DETAILS_PAGE_MEMBERS_CLASS_NAME = '.docs-reference-members-container';
export const API_REFERENCE_TAB_BODY_CLASS_NAME = '.adev-reference-tab-body';
export const API_REFERENCE_TAB_ATTRIBUTE = 'data-tab';
export const API_REFERENCE_TAB_URL_ATTRIBUTE = 'data-tab-url';
export const API_REFERENCE_TAB_API_LABEL = 'API';
export const API_REFERENCE_TAB_QUERY_PARAM = 'tab';
export const API_TAB_CLASS_NAME = '.adev-reference-api-tab';
export const API_REFERENCE_MEMBER_CARD_CLASS_NAME = '.adev-reference-member-card';
export const API_TAB_CLASS_NAME = '.docs-reference-api-tab';
export const API_REFERENCE_MEMBER_CARD_CLASS_NAME = '.docs-reference-member-card';
export const API_TAB_ACTIVE_CODE_LINE = 'hljs-ln-line-highlighted';
export const HIGHLIGHT_JS_CODE_LINE_CLASS_NAME = 'hljs-ln-line';
export const MEMBER_ID_ATTRIBUTE = 'member-id';
@@ -56,10 +56,12 @@ export function getApiNavigationItems(): NavigationItem[] {
const packageNavigationItem: NavigationItem = {
label: packageNameWithoutPrefix,
children: packageApis.map((api) => ({
path: getApiUrl(packageNameWithoutPrefix, api.name),
label: api.name,
})),
children: packageApis
.map((api) => ({
path: getApiUrl(packageNameWithoutPrefix, api.name),
label: api.name,
}))
.sort((a, b) => a.label.localeCompare(b.label)),
};
apiNavigationItems.push(packageNavigationItem);
@@ -6,11 +6,23 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {ApiItemType} from '../interfaces/api-item-type';
import {ApiLabel} from './api-label.pipe';
describe('ApiLabel', () => {
it('create an instance', () => {
const pipe = new ApiLabel();
expect(pipe).toBeTruthy();
let pipe: ApiLabel;
beforeEach(() => {
pipe = new ApiLabel();
});
it(`should return short label when labelType equals short`, () => {
const result = pipe.transform(ApiItemType.CLASS, 'short');
expect(result).toBe('C');
});
it(`should return short label when labelType equals short`, () => {
const result = pipe.transform(ApiItemType.CLASS, 'full');
expect(result).toBe('Class');
});
});
@@ -160,6 +160,9 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
for (const line of Array.from(activeLines)) {
line.classList.remove(API_TAB_ACTIVE_CODE_LINE);
}
this.getAllMemberCards().forEach((card) => {
card.blur();
});
} else {
const lines = this.document.querySelectorAll<HTMLButtonElement>(
`button[${MEMBER_ID_ATTRIBUTE}="${currentActiveMemberId}"]`,
@@ -167,6 +170,7 @@ export class ReferenceScrollHandler implements OnDestroy, ReferenceScrollHandler
for (const line of Array.from(lines)) {
line.classList.add(API_TAB_ACTIVE_CODE_LINE);
}
this.document.getElementById(`${currentActiveMemberId}`)?.focus();
}
}
@@ -1,6 +1,6 @@
@use '@angular/docs/styles/media-queries' as mq;
// horizozntal tutorial nav bar
// horizontal tutorial nav bar
.adev-tutorial-nav-container {
position: sticky;
top: 0;
@@ -21,7 +21,7 @@
transition: background-color 0.3s ease;
container: nav-container / inline-size;
&:has(.adev-reveal-answer-button) {
&:has(.docs-reveal-answer-button) {
@container tutorial-content (max-width: 430px) {
padding-block-end: calc(1.5rem + 85px);
}
@@ -115,7 +115,7 @@
}
}
.adev-reveal-answer-button {
.docs-reveal-answer-button {
height: 2.875rem;
width: 120px;
}
@@ -3,7 +3,7 @@
@if (shouldRenderContent()) {
<div
#content
class="adev-tutorial-content"
class="docs-tutorial-content"
[class.adev-nav-open]="showNavigationDropdown()"
>
<!-- Tutorial Nav: Current Tutorial Title and Nav Buttons -->
@@ -30,7 +30,7 @@
@if (shouldRenderEmbeddedEditor()) {
<div
#editor
class="adev-tutorial-editor"
class="docs-tutorial-editor"
[class.adev-split-tutorial]="shouldRenderContent()"
>
@if (embeddedEditorComponent) {
@@ -59,7 +59,7 @@
#revealAnswerButton
(click)="answerRevealed() ? handleResetAnswer() : handleRevealAnswer()"
[disabled]="!canRevealAnswer()"
class="adev-reveal-answer-button adev-reveal-desktop-button adev-primary-btn"
class="docs-reveal-answer-button adev-reveal-desktop-button docs-primary-btn"
[attr.text]="answerRevealed() ? 'Reset' : 'Reveal Answer'"
[attr.aria-label]="answerRevealed() ? 'Reset' : 'Reveal Answer'"
[class.adev-reset-answer-button]="answerRevealed()"
@@ -74,7 +74,7 @@
[download]="stepName() + '.zip'"
[href]="localTutorialZipUrl()"
>
<button class="adev-download-button adev-primary-btn">
<button class="adev-download-button docs-primary-btn">
<docs-icon>download</docs-icon>
</button>
</a>
@@ -83,26 +83,26 @@
<div class="adev-nav-arrows">
@if (previousStepPath) {
<a [routerLink]="previousStepPath">
<button class="adev-primary-btn">
<button class="docs-primary-btn">
<docs-icon>chevron_left</docs-icon>
</button>
</a>
}
@if (!previousStepPath) {
<button class="adev-primary-btn" disabled>
<button class="docs-primary-btn" disabled>
<docs-icon>chevron_left</docs-icon>
</button>
}
@if (nextStepPath) {
<a [routerLink]="nextStepPath">
<button class="adev-primary-btn">
<button class="docs-primary-btn">
<docs-icon>chevron_right</docs-icon>
</button>
</a>
}
@if (!nextStepPath) {
<button class="adev-primary-btn" disabled>
<button class="docs-primary-btn" disabled>
<docs-icon>chevron_right</docs-icon>
</button>
}
@@ -115,7 +115,7 @@
#revealAnswerButton
(click)="answerRevealed() ? handleResetAnswer() : handleRevealAnswer()"
[disabled]="!canRevealAnswer()"
class="adev-reveal-answer-button adev-reveal-mobile-button adev-primary-btn"
class="docs-reveal-answer-button adev-reveal-mobile-button docs-primary-btn"
[attr.text]="answerRevealed() ? 'Reset' : 'Reveal Answer'"
[attr.aria-label]="answerRevealed() ? 'Reset' : 'Reveal Answer'"
[class.adev-reset-answer-button]="answerRevealed()"
@@ -36,8 +36,8 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
}
// if there is an embedded editor in view, apply column width
&:has(.adev-tutorial-editor) {
.adev-tutorial-content {
&:has(.docs-tutorial-editor) {
.docs-tutorial-content {
width: $column-width;
@include mq.for-tablet-landscape-down {
@@ -50,7 +50,7 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
// if tutorial nav exists, size editor to fit vertically within viewport on mobile
@include mq.for-tablet-landscape-down {
&:has(.adev-tutorial-nav-container) {
.adev-tutorial-editor {
.docs-tutorial-editor {
height: calc(100vh - 200px);
}
}
@@ -58,7 +58,7 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
@include mq.for-phone-only {
&:has(.adev-tutorial-nav-container) {
.adev-tutorial-editor {
.docs-tutorial-editor {
// account for reveal answer button height when on smaller screens
height: calc(100vh - 200px);
}
@@ -66,7 +66,7 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
}
}
.adev-tutorial-content {
.docs-tutorial-content {
max-width: var(--page-width);
min-width: 300px;
width: 100%;
@@ -127,7 +127,7 @@ $column-width: calc(50% - #{$resizer-width} - var(--layout-padding));
}
}
.adev-tutorial-editor {
.docs-tutorial-editor {
position: sticky;
top: 0;
width: 100%;
+2 -1
View File
@@ -125,6 +125,7 @@ export const routes: Route[] = [
{
path: '',
loadComponent: () => import('./features/home/home.component'),
data: {label: 'Home'}
},
{
path: PagePrefix.DOCS,
@@ -141,7 +142,7 @@ export const routes: Route[] = [
{
path: PagePrefix.PLAYGROUND,
loadComponent: () => import('./features/playground/playground.component'),
data: {...commonTutorialRouteData},
data: {...commonTutorialRouteData, label: 'Playground'},
},
...SUB_NAVIGATION_ROUTES,
...API_REFERENCE_ROUTES,
+192 -166
View File
@@ -157,6 +157,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/components/advanced-configuration',
contentPath: 'guide/components/advanced-configuration',
},
{
label: 'Custom Elements',
path: 'guide/elements',
contentPath: 'guide/elements',
},
],
},
{
@@ -218,9 +223,39 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'guide/templates/control-flow',
},
{
label: 'Deferrable views',
path: 'guide/defer',
contentPath: 'guide/defer',
label: 'Pipes',
children: [
{
label: 'Overview',
path: 'guide/pipes',
contentPath: 'guide/pipes/overview',
},
{
label: 'Using a pipe in a template',
path: 'guide/pipes/template',
contentPath: 'guide/pipes/template',
},
{
label: 'Custom pipes',
path: 'guide/pipes/transform-data',
contentPath: 'guide/pipes/transform-data',
},
{
label: 'Pipe precedence in expressions',
path: 'guide/pipes/precedence',
contentPath: 'guide/pipes/precedence',
},
{
label: 'Change detection with pipes',
path: 'guide/pipes/change-detection',
contentPath: 'guide/pipes/change-detection',
},
{
label: 'Unwrapping data from an observable',
path: 'guide/pipes/unwrapping-data-observables',
contentPath: 'guide/pipes/unwrapping-data-observables',
},
],
},
{
label: 'Template reference variables',
@@ -317,70 +352,20 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'guide/signals/rxjs-interop',
contentPath: 'guide/signals/rxjs-interop',
},
],
},
{
label: 'NgModule',
children: [
{
label: 'Overview',
path: 'guide/ngmodules',
contentPath: 'guide/ngmodules/overview',
label: 'Inputs as signals',
path: 'guide/signals/inputs',
contentPath: 'guide/signals/inputs',
},
{
label: 'JS Modules vs NgModules',
path: 'guide/ngmodules/vs-jsmodule',
contentPath: 'guide/ngmodules/vs-jsmodule',
label: 'Model inputs',
path: 'guide/signals/model',
contentPath: 'guide/signals/model',
},
{
label: 'Launching your app with a root module',
path: 'guide/ngmodules/bootstrapping',
contentPath: 'guide/ngmodules/bootstrapping',
},
{
label: 'Sharing NgModules',
path: 'guide/ngmodules/sharing',
contentPath: 'guide/ngmodules/sharing',
},
{
label: 'Frequently used NgModules',
path: 'guide/ngmodules/frequent',
contentPath: 'guide/ngmodules/frequent',
},
{
label: 'Feature modules',
path: 'guide/ngmodules/feature-modules',
contentPath: 'guide/ngmodules/feature-modules',
},
{
label: 'Types of feature modules',
path: 'guide/ngmodules/module-types',
contentPath: 'guide/ngmodules/module-types',
},
{
label: 'Providing dependencies',
path: 'guide/ngmodules/providers',
contentPath: 'guide/ngmodules/providers',
},
{
label: 'Singleton services',
path: 'guide/ngmodules/singleton-services',
contentPath: 'guide/ngmodules/singleton-services',
},
{
label: 'Lazy-loading feature modules',
path: 'guide/ngmodules/lazy-loading',
contentPath: 'guide/ngmodules/lazy-loading',
},
{
label: 'NgModule API',
path: 'guide/ngmodules/api',
contentPath: 'guide/ngmodules/api',
},
{
label: 'NgModule FAQs',
path: 'guide/ngmodules/faq',
contentPath: 'guide/ngmodules/faq',
label: 'Queries as signals',
path: 'guide/signals/queries',
contentPath: 'guide/signals/queries',
},
],
},
@@ -450,29 +435,64 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
],
},
{
label: 'Server-side Rendering',
path: 'guide/ssr',
contentPath: 'guide/ssr',
label: 'HTTP Client',
children: [
{
label: 'Overview',
path: 'guide/http',
contentPath: 'guide/http/overview',
},
{
label: 'Setting up HttpClient',
path: 'guide/http/setup',
contentPath: 'guide/http/setup',
},
{
label: 'Making requests',
path: 'guide/http/making-requests',
contentPath: 'guide/http/making-requests',
},
{
label: 'Intercepting requests and responses',
path: 'guide/http/interceptors',
contentPath: 'guide/http/interceptors',
},
{
label: 'Testing',
path: 'guide/http/testing',
contentPath: 'guide/http/testing',
},
],
},
{
label: 'Build-time prerendering',
path: 'guide/prerendering',
contentPath: 'guide/prerendering',
},
{
label: 'Hydration',
path: 'guide/hydration',
contentPath: 'guide/hydration',
},
{
label: 'Deferrable views',
path: 'guide/defer',
contentPath: 'guide/defer',
},
{
label: 'Image Optimization',
path: 'guide/image-optimization',
contentPath: 'guide/image-optimization',
label: 'Performance',
children: [
{
label: 'Deferrable views',
path: 'guide/defer',
contentPath: 'guide/defer',
},
{
label: 'Image Optimization',
path: 'guide/image-optimization',
contentPath: 'guide/image-optimization',
},
{
label: 'Server-side Rendering',
path: 'guide/ssr',
contentPath: 'guide/ssr',
},
{
label: 'Build-time prerendering',
path: 'guide/prerendering',
contentPath: 'guide/prerendering',
},
{
label: 'Hydration',
path: 'guide/hydration',
contentPath: 'guide/hydration',
},
],
},
{
label: 'Testing',
@@ -584,81 +604,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
{
label: 'Security',
path: 'guide/security',
contentPath: 'guide/security',
},
{
label: 'Pipes',
children: [
{
label: 'Overview',
path: 'guide/pipes',
contentPath: 'guide/pipes/overview',
},
{
label: 'Using a pipe in a template',
path: 'guide/pipes/template',
contentPath: 'guide/pipes/template',
},
{
label: 'Custom pipes',
path: 'guide/pipes/transform-data',
contentPath: 'guide/pipes/transform-data',
},
{
label: 'Pipe precedence in expressions',
path: 'guide/pipes/precedence',
contentPath: 'guide/pipes/precedence',
},
{
label: 'Change detection with pipes',
path: 'guide/pipes/change-detection',
contentPath: 'guide/pipes/change-detection',
},
{
label: 'Unwrapping data from an observable',
path: 'guide/pipes/unwrapping-data-observables',
contentPath: 'guide/pipes/unwrapping-data-observables',
},
],
},
{
label: 'Http Client',
children: [
{
label: 'Overview',
path: 'guide/http',
contentPath: 'guide/http/overview',
},
{
label: 'Setting up HttpClient',
path: 'guide/http/setup',
contentPath: 'guide/http/setup',
},
{
label: 'Making requests',
path: 'guide/http/making-requests',
contentPath: 'guide/http/making-requests',
},
{
label: 'Intercepting requests and responses',
path: 'guide/http/interceptors',
contentPath: 'guide/http/interceptors',
},
{
label: 'Security',
path: 'guide/http/security',
contentPath: 'guide/http/security',
},
{
label: 'Testing',
path: 'guide/http/testing',
contentPath: 'guide/http/testing',
},
],
},
{
label: 'Animations',
children: [
@@ -689,11 +634,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
{
label: 'Custom Elements',
path: 'guide/elements',
contentPath: 'guide/elements',
},
],
},
{
@@ -825,9 +765,9 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'best-practices/style-guide',
},
{
label: 'Keeping up-to-date',
path: 'update',
contentPath: 'best-practices/update',
label: 'Security',
path: 'best-practices/security',
contentPath: 'guide/security', // Have not refactored due to build issues
},
{
label: 'Accessibility',
@@ -859,6 +799,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
},
],
},
{
label: 'Keeping up-to-date',
path: 'update',
contentPath: 'best-practices/update',
},
],
},
{
@@ -943,6 +888,7 @@ export const TUTORIALS_SUB_NAVIGATION_DATA: NavigationItem[] = [
{
path: DefaultPage.TUTORIALS,
contentPath: 'tutorials/home',
label: 'Tutorials',
},
];
@@ -1336,6 +1282,86 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
path: 'reference/migrations/typed-forms',
contentPath: 'reference/migrations/typed-forms',
},
{
label: 'Control Flow Syntax',
path: 'reference/migrations/control-flow',
contentPath: 'reference/migrations/control-flow',
},
],
},
{
label: 'Concepts',
children: [
{
label: 'Overview',
path: 'reference/concepts',
contentPath: 'reference/concepts/overview',
},
{
label: 'NgModule',
children: [
{
label: 'Overview',
path: 'guide/ngmodules',
contentPath: 'guide/ngmodules/overview',
},
{
label: 'JS Modules vs NgModules',
path: 'guide/ngmodules/vs-jsmodule',
contentPath: 'guide/ngmodules/vs-jsmodule',
},
{
label: 'Launching your app with a root module',
path: 'guide/ngmodules/bootstrapping',
contentPath: 'guide/ngmodules/bootstrapping',
},
{
label: 'Sharing NgModules',
path: 'guide/ngmodules/sharing',
contentPath: 'guide/ngmodules/sharing',
},
{
label: 'Frequently used NgModules',
path: 'guide/ngmodules/frequent',
contentPath: 'guide/ngmodules/frequent',
},
{
label: 'Feature modules',
path: 'guide/ngmodules/feature-modules',
contentPath: 'guide/ngmodules/feature-modules',
},
{
label: 'Types of feature modules',
path: 'guide/ngmodules/module-types',
contentPath: 'guide/ngmodules/module-types',
},
{
label: 'Providing dependencies',
path: 'guide/ngmodules/providers',
contentPath: 'guide/ngmodules/providers',
},
{
label: 'Singleton services',
path: 'guide/ngmodules/singleton-services',
contentPath: 'guide/ngmodules/singleton-services',
},
{
label: 'Lazy-loading feature modules',
path: 'guide/ngmodules/lazy-loading',
contentPath: 'guide/ngmodules/lazy-loading',
},
{
label: 'NgModule API',
path: 'guide/ngmodules/api',
contentPath: 'guide/ngmodules/api',
},
{
label: 'NgModule FAQs',
path: 'guide/ngmodules/faq',
contentPath: 'guide/ngmodules/faq',
},
],
},
],
},
];
+4
View File
@@ -26,6 +26,7 @@ copy_to_directory(
"//adev/src/content/introduction",
"//adev/src/content/introduction/essentials",
"//adev/src/content/reference",
"//adev/src/content/reference/concepts",
"//adev/src/content/reference/configs",
"//adev/src/content/reference/errors",
"//adev/src/content/reference/extended-diagnostics",
@@ -65,10 +66,13 @@ copy_to_directory(
"//packages/upgrade:upgrade_docs",
"//packages/upgrade/static:upgrade_static_docs",
"//packages/upgrade/static/testing:upgrade_static_testing_docs",
"//tools/manual_api_docs/blocks:blocks_docs",
"//tools/manual_api_docs/elements:elements_docs",
],
replace_prefixes = {
"adev/src/content": "",
"packages/**/": "api/",
"tools/**/": "api/",
},
)
+1 -1
View File
@@ -4,7 +4,7 @@
viewBox="0 0 157 288"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="adev-directives-svg"
class="docs-directives-svg"
>
<g style="mix-blend-mode: multiply;">
<path

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

+1 -1
View File
@@ -4,7 +4,7 @@
viewBox="0 0 433 182"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="adev-roadmap-svg"
class="docs-roadmap-svg"
>
<path
d="M26.0339 81.4492H316.739L406.475 153.601H114.71L26.0339 81.4492Z"

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

+1 -1
View File
@@ -4,7 +4,7 @@
viewBox="0 0 297 205"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="adev-what-is-angular-svg"
class="docs-what-is-angular-svg"
>
<g style="mix-blend-mode: multiply;">
<path

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@@ -19,7 +19,7 @@ In the image above, there is a series of change detection calls triggered by eve
## Run tasks outside `NgZone`
In such cases, you can instruct Angular to avoid calling change detection for tasks scheduled by a given piece of code using [NgZone](/guide/zone).
In such cases, you can instruct Angular to avoid calling change detection for tasks scheduled by a given piece of code using [NgZone](/api/core/NgZone).
<docs-code header="Run outside of the Zone" language='ts' linenums>
import { Component, NgZone, OnInit } from '@angular/core';
+1 -1
View File
@@ -43,7 +43,7 @@ It also includes troubleshooting information and any recommended manual changes
For simple updates, the CLI command [`ng update`](cli/update) is all you need.
Without additional arguments, [`ng update`](cli/update) lists the updates that are available to you and provides recommended steps to update your application to the most current version.
[Angular Versioning and Releases](reference/releases#versioning "Angular Release Practices, Versioning") describes the level of change that you can expect based a release's version number.
[Angular Versioning and Releases](reference/releases#versioning "Angular Release Practices, Versioning") describes the level of change that you can expect based on a release's version number.
It also describes supported update paths.
## Resource summary
@@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
@@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
@@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
@@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

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