Compare commits

...

225 Commits

Author SHA1 Message Date
Matthieu Riegler 9c486c9682 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:21 -08:00
Joey Perrott 3fe21333ce 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:39 -08:00
Lukas Matta 97e8265570 docs: fix typo (#54403)
PR Close #54403
2024-02-13 11:51:55 -08:00
Kristiyan Kostadinov da93046920 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:40 -08:00
arturovt 017825b0f4 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:56 -08:00
Joey Perrott 58365e04a2 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:07 -08:00
Hakeem 2435291dda docs(docs-infra): change deprecated modules' headers' style in the hover state (#54337)
PR Close #54337
2024-02-09 14:58:55 +00:00
Joey Perrott 5cb44aa2fd 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
Matthieu Riegler 375e60610e 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 ca39926de2 refactor: migrate router to prettier formatting (#54319)
Migrate formatting to prettier for router from clang-format

PR Close #54319
2024-02-08 19:12:05 +00:00
Jessica Janiuk dd8490f384 release: cut the v17.1.3 release 2024-02-08 10:16:37 -08:00
Kristiyan Kostadinov 2e9a21a6ad Revert "fix(compiler-cli): interpolatedSignalNotInvoked diagnostic for model signals (#54338)" (#54346)
This reverts commit 63a9027720.

PR Close #54346
2024-02-08 18:01:48 +00:00
Andrew Scott 744e20641a 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:21 +00:00
cexbrayat 63a9027720 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:22 +00:00
Kristiyan Kostadinov ef55d48dee 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:55 +00:00
Kristiyan Kostadinov 8d4b4ff7bf 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:26 +00:00
Ben Hong 2e3fa28b93 docs: enable version picker (#54161)
PR Close #54161
2024-02-07 22:21:07 +00:00
Paul Gschwendtner eeaec924ef 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:23 +00:00
Paul Gschwendtner 40e1edc977 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:22 +00:00
cexbrayat 4482cbd22c 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:14 +00:00
Jessica Janiuk d695398414 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
Angular Robot f3f1f85bed 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
Joey Perrott c6896a30c0 docs: remove v17 banner from adev (#54287)
PR Close #54287
2024-02-06 21:06:24 +00:00
Alejandro Cuba Ruiz db78666196 docs: add alejandrocuba.jpg file to images/bios/ (#53842)
PR Close #53842
2024-02-06 20:34:02 +00:00
Alejandro Cuba Ruiz e847487d4f docs: add alejandrocuba to GDE resources (#53842)
PR Close #53842
2024-02-06 20:34:02 +00:00
Andrew Scott 238f2a8bc9 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 2de7679b0b build: update dependency husky to v9 (#54289)
See associated pull request for more information.

PR Close #54289
2024-02-06 19:34:47 +00:00
Angular Robot 06391d1eb8 build: update dependency jasmine-core to v5 (#54290)
See associated pull request for more information.

PR Close #54290
2024-02-06 19:30:08 +00:00
Joey Perrott 0cd9538f24 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:48 +00:00
Angular Robot 241858d20b build: update dependency @octokit/graphql to v7 (#53554)
See associated pull request for more information.

PR Close #53554
2024-02-06 18:24:05 +00:00
ilir.beqiri f303838d95 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:12 +00:00
Paul Gschwendtner bc4a6a9715 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 429700590c 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 ca459177d6 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
Jason Warner 04a1d50bc8 docs: add Jason Warner to GDE resources (#54237)
PR Close #54237
2024-02-05 16:40:58 +00:00
Andrew Kushnir fc4d8bb78c 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 756aa8f600 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 4586d2341d 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:41 +00:00
Paul Gschwendtner f466c89d1f ci: adding devversion to reviewers for compiler/core (#54233)
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 #54233
2024-02-05 15:06:50 +00:00
Paul Gschwendtner 8876283f47 feat(docs-infra): show overloads of methods in API overview (#54233)
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 #54233
2024-02-05 15:06:50 +00:00
Paul Gschwendtner e74ea10f5d refactor(core): avoid clang-format obfuscating InputFunction.required (#54233)
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 #54233
2024-02-05 15:06:50 +00:00
Paul Gschwendtner b74c02a6b8 refactor(compiler): extract call and construct signatures of interfaces (#54233)
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 #54233
2024-02-05 15:06:49 +00:00
Paul Gschwendtner 9f6605d11b fix(compiler-cli): support jumping to definitions of signal-based inputs (#54233)
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 #54233
2024-02-05 15:06:49 +00:00
Paul Gschwendtner a42f0ba65e refactor(core): separate InputSignal and InputSignalWithTransform (#54233)
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 #54233
2024-02-05 15:06:49 +00:00
László Czöndör ea2fd1b66a docs: fix typo in inject-based DI tutorial (#54245)
PR Close #54245
2024-02-05 15:06:12 +00:00
Nigro Simone a6f09adb55 refactor(docs): fix typo (#54247)
PR Close #54247
2024-02-05 15:05:37 +00:00
Dylan Hunn 47c712e51e 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:40 +00:00
Dylan Hunn 6f637718d1 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:40 +00:00
Andrew Scott 54deaae3ba 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
mooyil cd88f1486e docs: remove outdated info about ng serve (#53890)
PR Close #53890
2024-02-01 23:00:18 +00:00
Thabo 37a6da30ca docs: fix typo in router.md (#54194)
Correct spelling mistake

PR Close #54194
2024-02-01 22:31:49 +00:00
Jessica Janiuk afc72b06fe ci: fix size tracking for aio (#54207)
ups the size for the dark-theme

PR Close #54207
2024-02-01 21:51:39 +00:00
Andrew Scott 0fb114274c 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 86086169e7 [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:43 +00:00
Lars Gyrup Brink Nielsen 99a0b90073 docs: correct TypeScript version range for 17.0.x (#53213)
PR Close #53213
2024-02-01 20:07:32 +00:00
Mateusz Daniluk 52a31d0ed8 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 4b6deb5ac2 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 f933a38e3d 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:56 +00:00
Jessica Janiuk 46a2c5f8cc 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:45:00 +00:00
Angular Robot 9e3d54cf2d build: update actions/checkout action to v4 (#54183)
See associated pull request for more information.

PR Close #54183
2024-02-01 16:02:48 +00:00
Kristiyan Kostadinov a997e08c6f 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:22 +00:00
Ezéchiel Amen AGBLA 7d59eb0a96 docs: more readable standalone importing component example (#54196)
PR Close #54196
2024-02-01 15:57:51 +00:00
Joey Perrott 924a2768df refactor(docs-infra): migrate to using docs- prefix for class names rather than adev- for shared pieces (#54189)
Updates to later version of shared docs with prefix renamed.

PR Close #54189
2024-01-31 21:49:49 +00:00
Andrew Scott 7df133dcc2 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:07 +00:00
Andrew Scott 2a0ac20824 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:07 +00:00
Andrew Scott 67eb402024 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:07 +00:00
Angular Robot 4883ae686c 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 57cb448de5 release: cut the v17.1.2 release 2024-01-31 11:04:26 -08:00
Ivan Zlatanov 0bd668c943 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 2c0bb7fb0e 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 735cdf3761 build: update actions/checkout digest to f43a0e5 (#54177)
See associated pull request for more information.

PR Close #54177
2024-01-31 17:36:00 +00:00
Angular Robot 948fb5f937 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:32 +00:00
narendherraj 9f1a5fa5da 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 cab06bd125 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 cdc5e39532 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 ed8e7c727b 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 e08cc50f3c 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 ca7456e722 docs(docs-infra): @input getter setter syntax change (#51023)
PR Close #51023
2024-01-31 16:04:04 +00:00
kabrunko-dev b353ad5bac 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 bd6d18b977 docs: Fix minor grammar mistake (#54094)
PR Close #54094
2024-01-31 15:34:27 +00:00
vatsa03 3b218a72ce docs(core): fix example sections (#54121)
PR Close #54121
2024-01-31 15:22:30 +00:00
Matthieu Riegler 4367c44f7f 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 b69bf37841 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:26 +00:00
arturovt 05a05b628b 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 c21f41d6d4 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:25 +00:00
Matthieu Riegler 413db303f4 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:57 +00:00
ahmadhakeem18 752ebd62c9 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 7001b5d633 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 fccf375df1 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:15 +00:00
Mahdi Lazraq 8d85de7fe1 docs: fix path to housing location css file in lesson 03 (#54106)
PR Close #54106
2024-01-30 17:50:12 +00:00
Joey Perrott 4c2b0d94e2 refactor: migrate common to prettier formatting (#54159)
Migrate formatting to prettier for common from clang-format

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

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

PR Close #53939
2024-01-30 15:06:25 +00:00
Andrew Scott c5a0e909ac 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:48 +00:00
Mark Thompson d07ce6156e docs: Update component-overview.md (#52282)
Refined the text a bit
PR Close #52282
2024-01-29 19:30:59 +00:00
Renan Ferro e3b874b4fb docs: add new component imports documentation structure (#52282)
PR Close #52282
2024-01-29 19:30:59 +00:00
Jesse Zomer 1ac37f932f 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:34 +00:00
therealdennis08 8650f0dee2 docs: correct grammar error on start page (#53993)
Fixed grammatical error

PR Close #53993
2024-01-29 16:41:29 +00:00
Ido Strauss 030d77010d 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 96ca49d145 docs: update input/output guide links (#54135)
PR Close #54135
2024-01-29 15:43:05 +00:00
Kristiyan Kostadinov 8264382a6b 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 f5a5215166 docs: add link for control flow migration (#53375)
PR Close #53375
2024-01-29 15:39:06 +00:00
Dwouglas Mhagnum 5cd00f167c InMemoryBackendConfigArgs.passThruUnknownUrl: fix tsdoc (#52273)
PR Close #52273
2024-01-26 20:39:38 +00:00
Matt Ezell 22f89c0a2d docs: Corrected link for defer related blocks (#52704)
PR Close #52704
2024-01-26 20:38:37 +00:00
Muhammad Ahsan Ayaz c442912532 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 9f9dd901ae 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 30e42df518 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
Matthieu Riegler 566499af1d docs: remove mention of providedIn module. This feature has been deprecated. (#54072)
PR Close #54072
2024-01-26 19:09:28 +00:00
fhoekstra 4a5f37d216 docs(router): fix variable reference in text (#54099)
PR Close #54099
2024-01-26 19:02:42 +00:00
iliasaddab 74567f1c8a docs: update i18n-common-merge.md (#52400)
correct spelling

PR Close #52400
2024-01-26 17:38:09 +00:00
Matthieu Riegler 64399b26c0 docs: add 2 new diagnostics created recently. (#52329)
PR Close #52329
2024-01-26 17:28:01 +00:00
Matthieu Riegler 1b296dbb80 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:52 +00:00
Matthieu Riegler cddc426e18 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 8109013b0f 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 f25d7e880f 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 f240c70971 docs(docs-infra): cleanup repeated scss from typography (#51579)
PR Close #51579
2024-01-26 16:03:43 +00:00
Sylvain DEDIEU 0172477ff2 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:16 +00:00
Chellappan 0702d4a560 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 798aee7a83 docs: remove link (#54090)
PR Close #54090
2024-01-26 15:46:01 +00:00
cexbrayat c477e876e3 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 ecd0daf8fd docs(docs-infra): move comma in Angular Language Service section (#53759)
PR Close #53759
2024-01-25 23:48:57 +00:00
jivanf 6eca767811 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 d8d6478d0e 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 0c4d7e061e docs: fix add builder from package (#53154)
PR Close #53154
2024-01-25 23:31:01 +00:00
pBouillon 293dc3b046 docs: fix reference to forwardRef in ForwardRefFn JSdoc (#53556)
PR Close #53556
2024-01-25 23:16:46 +00:00
lsst25 8dca5a11f5 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 45fca0bc95 docs: fix nonsensical injection provider docs (#53456)
PR Close #53456
2024-01-25 23:02:46 +00:00
nickolashkraus 85819b9cdb docs: With >>> with (#53472)
PR Close #53472
2024-01-25 22:58:34 +00:00
Srinath Vayalpati 87378a773d docs: fix router api url link (#53398)
PR Close #53398
2024-01-25 22:58:09 +00:00
Andrea Canciani 96dd0c715e 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:55:00 +00:00
Sai Kumar Kola ccddacf11d fix: cta clickability issue in adev homepage. (#52905)
PR Close #52905
2024-01-25 22:48:47 +00:00
Aditya Kumar b216e76838 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 0d31904a96 docs: Fix links for NgZone (#53667)
PR Close #53667
2024-01-25 22:38:51 +00:00
jase aa3df2a7d4 docs: fix http handler usage on interceptor example (#53772)
PR Close #53772
2024-01-25 22:38:19 +00:00
Trung Vo 50b7901169 docs: add Trung Vo to GDE resources (#53599)
PR Close #53599
2024-01-25 22:29:26 +00:00
Aditya Kumar 1439f059a3 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 ac211d46b0 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 356984d9ba docs: removed repeated words "when" (#53828)
Fixes #53827

PR Close #53828
2024-01-25 21:31:33 +00:00
Sylvain DEDIEU 7ac94dd664 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:59 +00:00
Sasidharan SD 49aff2726f docs: fix invalid file replacement configuration (#52802)
PR Close #52802
2024-01-25 21:22:44 +00:00
Aditya Kumar 6c14c9324f 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 c0c7216c5f docs: add correct language for syntax highlighting on new docs (#52712)
PR Close #52712
2024-01-25 21:19:29 +00:00
Nelson Gutierrez 25e4f04d9f docs: add correct syntax highlighting type in event binding documentation (#52712)
PR Close #52712
2024-01-25 21:19:29 +00:00
ilir.beqiri 259707e31c 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:19 +00:00
Jessica Janiuk d17ba9bc87 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:09 +00:00
Ben Hong a4923f1f17 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
vladboisa e603450592 docs: fix & update MDN Shadow API link examples (#54040)
PR Close #54040
2024-01-25 18:02:58 +00:00
Ben Hong c6861eefa4 docs: add documentation and script for local docs dev environment (#54038)
PR Close #54038
2024-01-25 18:02:28 +00:00
d-codez 910742389f docs: correct grammar in event handling documentation (#54009)
PR Close #54009
2024-01-25 18:01:51 +00:00
arturovt 98d545fafa 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 7786e35faa 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 49101330f8 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 4507704a7e docs: remove ngx-deploy-npm from deployers table (#53999)
PR Close #53999
2024-01-25 16:07:40 +00:00
Andrew Scott 854b839531 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 89f7b00e59 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:51 -05:00
Andrew Scott f12b01ec88 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 0c8aaf082e 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
nikvarma a4f024fb07 docs: typo Chat to chart fix (#53892)
PR Close #53892
2024-01-24 21:23:52 +01:00
Pawel Kozlowski e2e0f08d99 release: cut the v17.1.1 release 2024-01-24 19:31:20 +01:00
Max e194fbfbaa 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 8ad1ee764b 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 f222bee8fa 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:55 +01:00
Alan Agius 9a9a00e0f9 docs: update docs to reflect changes in Angular CLI version 17.1 (#53949)
This changes include mentioning the experimental application builder migration and changes to the `outputPath` and `optimization` option.

PR Close #53949
2024-01-23 18:56:19 +01:00
Younes Jaaidi 5f9cac037b test(core): fix test with false-negative risk (#54025)
change assertion to handle the case where the function doesn't throw

PR Close #54025
2024-01-23 16:58:57 +01:00
Dylan Hunn 9778326f10 refactor(compiler): ICUs should roll up to the root i18n block for application (#54026)
Previously, if an ICU was inside a nested i18n root, it would use the nested root to calculate whether it should be applied. Now, we use the root i18n block.

PR Close #54026
2024-01-23 15:09:37 +01:00
Aristeidis Bampakos fac5a7cf4e docs: update Aristeidis Bampakos bio (#51779)
PR Close #51779
2024-01-23 10:22:23 +01:00
Matthieu Riegler ae145d19c6 refactor(devtools): migrate to standalone (#53998)
Migrated with the schematics and cleanup by hand.

PR Close #53998
2024-01-23 09:53:24 +01:00
Matthieu Riegler 30b6d34a49 refactor(devtools): remove date utility. (#53997)
We can use the `toIsoString()` function instead !

PR Close #53997
2024-01-23 09:52:14 +01:00
Srinath Vayalpati 3e0b7c1bdc docs: fixed req.method in http client testing (#53395)
PR Close #53395
2024-01-23 09:51:00 +01:00
ilir.beqiri a58a35dfe4 docs: fix typo at component template metadata property (#54015)
Rename the component metadata property, templateUrl to template in the reactive forms tutorial step

PR Close #54015
2024-01-23 09:47:43 +01:00
Matthieu Riegler a7c9fbb087 docs: update version compatibility table for aio & adev (#54008)
PR Close #54008
2024-01-23 09:46:57 +01:00
divyasudagoni 20811aad27 docs: move import statement of ngmodule from standalone component to module code #53952 (#54016)
PR Close #54016
2024-01-22 19:43:37 +01:00
Joey Perrott df453c3549 refactor: migrate bazel, benchpress, elements and misc to prettier formatting (#53995)
Migrate formatting to prettier for bazel, benchpress, elements and misc from clang-format

PR Close #53995
2024-01-22 09:07:16 +01:00
Joey Perrott 1f6c96a1dc refactor: migrate animations to prettier formatting (#53977)
Migrate formatting to prettier for animations from clang-format

PR Close #53977
2024-01-19 20:08:58 +01:00
Joey Perrott 656549d88a refactor(devtools): migrate devtools to prettier formatting (#53945)
Migrate formatting to prettier for devtools from clang-format

PR Close #53945
2024-01-19 19:09:54 +01:00
Tomasz Ducin c0f0baac58 refactor(devtools): improving type safety (#53436)
This PR reduces the number of unnecessary `any` occurrences in devtools packages.

PR Close #53436
2024-01-19 17:35:26 +01:00
Paul d38aa4f103 docs: update start-data.md (#52577)
PR Close #52577
2024-01-19 17:34:45 +01:00
Matthieu Riegler 7397b6648a build: Adding myself for devtools approval (#53989)
This to help Alex with the reviewing of devtools PRs.

PR Close #53989
2024-01-19 17:33:21 +01:00
Paul Gschwendtner 0fe9331958 build: update g3 sync config to match internal one (#53987)
There were some changes to the Copybara config that should
be reflected here as well.

PR Close #53987
2024-01-19 17:18:11 +01:00
Andrew Scott 7620f506c0 refactor(core): node removal notifies scheduler only when animations are enabled (#53857)
Node removal is immediate and does not require change detection to run
when animations are not provided. This refactor makes the animation
engine notify the scheduler rather than doing it on all node removals.

PR Close #53857
2024-01-19 10:28:25 +01:00
Joey Perrott 62ad2f0c71 refactor: migrate scripts to prettier formatting (#53976)
Migrate formatting to prettier for scripts from clang-format

PR Close #53976
2024-01-19 10:22:07 +01:00
Jessica Janiuk 424a26b3c7 docs: updates defer guide to reflect updated default defer block test behavior (#53975)
This updates the deferrable view guide to specify playthrough as the default with examples of configuring to manual.

PR Close #53975
2024-01-19 10:16:36 +01:00
Joey Perrott 18bd1a5ccb build: update version of @angular/docs (#53974)
Update docs to later version

PR Close #53974
2024-01-18 18:49:58 +01:00
Joey Perrott 8922a11693 ci: provide proper location for artifacts to allow for firebase to find the artifacts for deployment (#53960)
Move the artifacts during deployment into adev/ so that its at the same level as the firebase.json file.

PR Close #53960
2024-01-18 18:08:30 +01:00
Ankita Sood 4e0341050b docs: add ankita (#52319)
add Ankita as GDE in contributors.json

PR Close #52319
2024-01-18 14:28:35 +01:00
lilbeqiri 0616dc2839 build(devtools): prevent underscores from being added at build time (#53921)
Add the keepNames config property to esbuild in order to prevent prepending of underscores to the class names.

PR Close #53921
2024-01-18 10:22:13 +01:00
Sasidharan SD dc228c6fc1 docs: fix broken code example (#53531)
PR Close #53531
2024-01-18 10:16:20 +01:00
Sasidharan SD b1a7249c24 docs: fix spelling errors in tutorials steps (#53840)
PR Close #53840
2024-01-18 10:14:48 +01:00
Matthieu Riegler 9ff4893bc0 refactor(devtools): Add support for signals. (#53269)
The devtools now support signals.
Writable signals of primitives are editable.
Object Signal and other non-writable signals (like computed) are not editable.

Co-authored-by: Tomasz Ducin <tomasz.ducin@gmail.com>

PR Close #53269
2024-01-17 16:47:17 -08:00
Matthieu Riegler 025f7af694 refactor(compiler): remove mentions of unused compiler options. (#53746)
Those options where removed in #49672.

PR Close #53746
2024-01-17 16:41:35 -08:00
macvag 1c4a99a6d1 docs: fix broken hyperlink in tutorials first app search (#53816)
PR Close #53816
2024-01-17 16:40:06 -08:00
Dylan Hunn 51d53fc728 release: cut the v17.1.0 release 2024-01-17 14:45:22 -08:00
Dylan Hunn be882c3efb Revert "refactor(core): improve forwardRef typings (#53880)"
This reverts commit af6f6e6448.
2024-01-17 13:57:11 -08:00
cexbrayat 18fa6d7556 refactor(compiler-cli): interpolatedSignalNotInvoked diagnostic for input signals (#53883)
This updates the extended diagnotic to handle input signals as well.

PR Close #53883
2024-01-17 11:36:43 -08:00
Matthieu Riegler bb8a5a4c70 refactor(router): Use Nullish coalescing assignment when possible. (#53930)
Inspired by #53923, lets simplify code when possible.

PR Close #53930
2024-01-17 11:36:13 -08:00
Joey Perrott 9c00506a26 ci: use ng-dev-previews project for previews (#53958)
Rather than use the actual adev site, we should be using the ng-dev-preview site

PR Close #53958
2024-01-17 11:19:29 -08:00
Andrew Kushnir 79e8539ce2 refactor(compiler): extra diagnostics for @defer in local compilation mode (#53899)
This commit adds extra logic to produce a diagnostic in case `@Component.deferredImports` contain types from imports that also bring eager symbols. This would result in retaining a regular import and generating a dynamic import, which would not allow to defer-load dependencies.

PR Close #53899
2024-01-17 10:46:15 -08:00
Jessica Janiuk 6f79507ea7 fix(core): Change defer block fixture default behavior to playthrough (#53956)
This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: #53686

PR Close #53956
2024-01-17 10:45:42 -08:00
Joey Perrott 6616019735 refactor: migrate modules to prettier formatting (#53954)
Migrate formatting to prettier for modules directory from clang-format

PR Close #53954
2024-01-17 09:42:01 -08:00
Matthieu Riegler 4d4858fa28 docs: add platform-browser/animations/async entry to AIO (#53914)
fixes #53912

PR Close #53914
2024-01-17 09:14:44 -08:00
Joey Perrott 538fe47d9d ci: use the config from adev for adev previews (#53955)
Properly use the adev firebase config.

PR Close #53955
2024-01-17 09:13:44 -08:00
Andrew Kushnir b07c549802 refactor(compiler): enable register and resolve phases for local compilation (#53901)
This commit update the logic to enable `register` and `resolve` phases for local compilation. Those phases will be useful for local compilation in certain cases (will be used in followup PRs).

PR Close #53901
2024-01-17 09:03:57 -08:00
Joey Perrott 6f6ad0279b ci: set up previews of adev (#53941)
Set up preview actions to allow for a preview of the adev site to be deployed for a PR with the `adev: preview` label.

PR Close #53941
2024-01-16 19:18:33 -08:00
Joey Perrott d08f91f861 ci: run adev tests on CI (#53941)
Run tests in adev for CI

PR Close #53941
2024-01-16 19:18:32 -08:00
Joey Perrott 28aa7b3188 refactor: migrate tools to prettier formatting (#53947)
Migrate formatting to prettier for tools directory from clang-format

PR Close #53947
2024-01-16 19:17:51 -08:00
AleksanderBodurri 6ac0a68d73 docs(devtools): update development docs (#53948)
These docs are out of date with how we currently build devtools in dev mode and as a browser extension. This commit brings these docs up to date.

PR Close #53948
2024-01-16 19:17:20 -08:00
AleksanderBodurri ea19bff302 docs(devtools): remove devtools/CONTRIBUTING.md (#53948)
This is an artifact left over form the repo merge. There is already an existing CONTRIBUTING.md for this repo

PR Close #53948
2024-01-16 19:17:20 -08:00
Pawel Kozlowski 1112e9196a refactor(core): re-organize queries code (#53922)
This commit splits the query implementation and instructions
into a separate files. This is a pattern frequently used by
other functional areas of the framework and is a preparation for
introducing queries-as-signals where we are going to see more
instructions delegating to the same core functionality.

PR Close #53922
2024-01-16 16:00:36 -08:00
Ilija Leko 0d8a5c4665 docs: fix-build-path-in-http-server-command (#53226)
PR Close #53226
2024-01-16 09:37:12 -08:00
Paul Gschwendtner 76ceebad04 fix(compiler-cli): do not throw fatal error if extended type check fails (#53896)
Currently when the extended type check fails due to an import reference
that cannot be generated, the fatal diagnostic is not caught and
not properly exposed as a `ts.Diagnostic` that can be gracefully
handled. This is inconsistent to non-extended type checking diagnostics.

This is problematic because Angular CLI applications currently fail in
obscure ways because:

- the CLI does not expect `getDiagnosticsForFile` to actually throw
  runtime errors.
- the CLI does not seem to properly print these errors given the
  parallel workers and build excection, and those errors are
  especially hard to debug because there is no `stack` for
  `FatalDiagnosticError`'s.

Example: `MyDir` is not exported and the type check block cannot reference it.

PR Close #53896
2024-01-16 09:36:36 -08:00
Joey Perrott 99c2d76651 build(docs-infra): enable prerendering for adev (#53871)
Enable the prerender option for adev's angular.json file.

PR Close #53871
2024-01-16 09:35:46 -08:00
Sasidharan SD 246cb9c381 docs: remove repeated sentence (#53853)
PR Close #53853
2024-01-12 10:26:33 -08:00
Pawel Kozlowski d7c75c6edb refactor(core): improve forwardRef typings (#53880)
This commit improves the forwardRef typings for better
type safety and inference.

PR Close #53880
2024-01-12 10:26:02 -08:00
Andrew Scott 0daca457bb fix(core): TestBed should still use the microtask queue to schedule effects (#53843)
Prior to this commit, `TestBed` would require tests call `flushEffects`
or `fixture.detectChanges` in order to execute effects. In general, we
want to discourage authoring tests like this because it makes the timing
of change detection and effects differ from what happens in the
application. Instead, developers should perform actions and `await` (or
`flush`/`tick` when using `fakeAsync`) some `Promise` so that Angular
can react to the changes in the same way that it does in the
application.

Note that this still _allows_ developers to flush effects synchronously
with `flushEffects` and `detectChanges` but also enables the <action>,
`await` pattern described above.

PR Close #53843
2024-01-11 12:05:58 -08:00
Andrew Kushnir 12f9ed01cc refactor(compiler-cli): add tests for defer blocks and local compilation (#53591)
This commit adds tests to cover local compilation support for `@defer` blocks.

PR Close #53591
2024-01-10 15:29:00 -08:00
Andrew Kushnir 69713413f7 refactor(compiler): update TemplateDefinitionBuilder to support local compilation (#53591)
This commit updates the logic of the `TemplateDefinitionBuilder` to support local compilation and generate a single dependency function for all explicitly deferred deps within a component.

PR Close #53591
2024-01-10 15:28:59 -08:00
Andrew Kushnir 43d6816f9e refactor(compiler-cli): add checks to prevent same deps in imports and deferredImports (#53591)
This commit updates the typechecker logic to prevent same deps in `imports` and `deferredImports`.

PR Close #53591
2024-01-10 15:28:59 -08:00
Andrew Kushnir 4c4fea1304 refactor(compiler): add support for internal deferredImports field (#53591)
This commit updates the logic to add support for internal `deferredImports` field in compiler.

PR Close #53591
2024-01-10 15:28:59 -08:00
Andrew Kushnir c6df89c827 refactor(compiler-cli): update DeferredSymbolTracker to use explicit deps config (#53591)
This commit updates the `DeferredSymbolTracker` class to take info account the `onlyExplicitDeferDependencyImports` flag. The `DeferredSymbolTracker` class also exposes a new API to register import declarations as explicitly deferred, which will be used in followup commits.

PR Close #53591
2024-01-10 15:28:59 -08:00
Andrew Kushnir 9cae9b4a8c refactor(compiler-cli): add an internal config to enforce explicit deps in @defer for local compilation mode (#53591)
This commit adds an internal config option to enforce explicit deps in `@defer` for local compilation mode.

PR Close #53591
2024-01-10 15:28:59 -08:00
Andrew Kushnir 29b959ce31 refactor(compiler): add an internal API to check is an element is inside a defer block (#53591)
This commit updates the logic to expose an internal API on the `R3BoundTarget` to check if an element belongs to any defer block.

PR Close #53591
2024-01-10 15:28:59 -08:00
Andrew Kushnir a24b24e8a4 refactor(compiler-cli): store full Pipe metadata in typechecking code (#53591)
This commit updates typechecker to store full Pipe metadata in internal data strctures, so that this information is available to more places in the code, which will be updated in a followup commit.

PR Close #53591
2024-01-10 15:28:59 -08:00
Andrew Kushnir f51c008744 refactor(compiler-cli): extract various logic into separate functions (#53591)
This commit updates a few places to extract the logic into a separate functions which will be reused in a few places in followup commits.

PR Close #53591
2024-01-10 15:28:59 -08:00
Joey Perrott 3dedd6a07a build: set up adev testing (#53854)
Set up testing for the adev directory

PR Close #53854
2024-01-10 15:22:37 -08:00
Andrew Scott 881376eb42 release: cut the v17.1.0-rc.0 release 2024-01-10 14:25:36 -08:00
1500 changed files with 71324 additions and 56571 deletions
+3
View File
@@ -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/
+38
View File
@@ -0,0 +1,38 @@
# This workflow builds the previews for pull requests when a certain label is applied.
# The actual deployment happens as part of a dedicated second workflow to avoid security
# issues where the building would otherwise occur in an authorized context where secrets
# could be leaked. More details can be found here:
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
name: Build adev for preview deployment
on:
pull_request:
types: [synchronize, labeled]
permissions: read-all
jobs:
adev-build:
runs-on: ubuntu-latest
if: |
(github.event.action == 'labeled' && github.event.label.name == 'adev: preview') ||
(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@e52eb8237f2ed71195f87ce8046467a176568e58
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@e52eb8237f2ed71195f87ce8046467a176568e58
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@e52eb8237f2ed71195f87ce8046467a176568e58
- 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@73777547f819464aa5f48071b966eed34fd2c402
with:
workflow-artifact-name: 'adev-preview'
pull-number: '${{github.event.pull_request.number}}'
artifact-build-revision: '${{github.event.pull_request.head.sha}}'
deploy-directory: './dist/bin/adev/build/browser'
+50
View File
@@ -0,0 +1,50 @@
# This workflow runs whenever the ADEV build workflow has completed. Deployment happens
# as part of a dedicated second workflow to avoid security issues where the building would
# otherwise occur in an authorized context where secrets could be leaked.
#
# More details can be found here:
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
name: Deploying adev preview to Firebase
on:
workflow_run:
workflows: ['Build adev for preview deployment']
types: [completed]
permissions:
# Needed in order to be able to comment on the pull request.
pull-requests: write
# Needed in order to checkout the repository
contents: read
# Needed in order to retrieve the artifacts from the previous job
actions: read
env:
PREVIEW_PROJECT: ng-dev-previews
PREVIEW_SITE: ng-dev-previews-fw
jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with:
token: '${{secrets.GITHUB_TOKEN}}'
- name: Configure Firebase deploy target
working-directory: ./
run: |
# We can use `npx` as the Firebase deploy actions uses it too.
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@73777547f819464aa5f48071b966eed34fd2c402
with:
github-token: '${{secrets.GITHUB_TOKEN}}'
workflow-artifact-name: 'adev-preview'
firebase-config-dir: './adev'
firebase-public-dir: './adev/build/browser'
firebase-project-id: '${{env.PREVIEW_PROJECT}}'
firebase-service-key: '${{secrets.FIREBASE_PREVIEW_SERVICE_TOKEN}}'
+5 -3
View File
@@ -123,7 +123,7 @@ jobs:
- 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
run: yarn bazel test --config=aio_local_deps //adev:test
aio-local:
runs-on:
@@ -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 }}'
@@ -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/
-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
+44 -1
View File
@@ -5,7 +5,32 @@ import {FormatConfig} from '@angular/ng-dev';
*/
export const format: FormatConfig = {
'prettier': {
'matchers': ['**/*.{yaml,yml}'],
'matchers': [
'**/*.{yaml,yml}',
'devtools/**/*.{js,ts}',
'tools/**/*.{js,ts}',
'modules/**/*.{js,ts}',
'scripts/**/*.{js,ts}',
'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': {
'matchers': [
@@ -31,6 +56,24 @@ export const format: FormatConfig = {
'!packages/common/src/i18n/currencies.ts',
// Temporarily disable formatting for adev
'!adev/**',
// Migrated to prettier
'!devtools/**/*.{js,ts}',
'!tools/**/*.{js,ts}',
'!modules/**/*.{js,ts}',
'!scripts/**/*.{js,ts}',
'!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,
-2
View File
@@ -31,8 +31,6 @@
"packages/http/**",
"**/.gitignore",
"**/.gitkeep",
"**/yarn.lock",
"**/package.json",
"**/third_party/**",
"**/tsconfig-build.json",
"**/tsconfig-tsec.json",
+1
View File
@@ -2,6 +2,7 @@
"printWidth": 100,
"tabWidth": 2,
"tabs": false,
"embeddedLanguageFormatting": "off",
"singleQuote": true,
"semicolon": true,
"quoteProps": "preserve",
+13 -2
View File
@@ -166,8 +166,9 @@ groups:
- AndrewKushnir
- atscott
- crisbeto
- JoostK
- devversion
- dylhunn
- JoostK
# =========================================================
# Framework: Migrations
@@ -352,6 +353,7 @@ groups:
- AndrewKushnir
- atscott
- crisbeto
- devversion
- dylhunn
- jessicajaniuk
- pkozlowski-opensource
@@ -1069,9 +1071,16 @@ groups:
])
reviewers:
users:
- twerske
- josephperrott
- jelbourn
- bencodezen
- jessicajaniuk
- dylhunn
- AndrewKushnir
- alxhub
- crisbeto
- atscott
- pkozlowski-opensource
# =========================================================
# Docs-infra
@@ -1150,6 +1159,7 @@ groups:
- josephperrott
- mgechev
- twerske
- ~jeanmeche
# =========================================================
# Dev-infra
@@ -1394,6 +1404,7 @@ groups:
- devversion # Paul Gschwendtner
- dgp1130 # Doug Parker
- dylhunn # Dylan Hunn
- jeanmeche # Matthieu Riegler
- jelbourn # Jeremy Elbourn
- jessicajaniuk # Jessica Janiuk
- JiaLiPassion # Jia Li
+105 -205
View File
@@ -1,3 +1,102 @@
<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
| Commit | Type | Description |
| -- | -- | -- |
| [79ff91a813](https://github.com/angular/angular/commit/79ff91a813e544929cb5eb5f9aab762a9f3d0435) | fix | allow TS jsDocParsingMode host option to be programmatically set ([#53126](https://github.com/angular/angular/pull/53126)) |
| [5613051a8b](https://github.com/angular/angular/commit/5613051a8bd2626ae347292807b2bf21085c4c02) | fix | allow TS jsDocParsingMode host option to be programmatically set again ([#53292](https://github.com/angular/angular/pull/53292)) |
| [df8a825910](https://github.com/angular/angular/commit/df8a825910951bebf34a4eede42f3ce5cd3e6fb7) | fix | project empty block root node ([#53620](https://github.com/angular/angular/pull/53620)) |
| [478d622265](https://github.com/angular/angular/commit/478d6222650884478314985e3d5132587c4f670c) | fix | project empty block root node in template pipeline ([#53620](https://github.com/angular/angular/pull/53620)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [abdc7e4578](https://github.com/angular/angular/commit/abdc7e45786667e4283912024a641975f1917d97) | feat | support type-checking for generic signal inputs ([#53521](https://github.com/angular/angular/pull/53521)) |
| [e620b3a724](https://github.com/angular/angular/commit/e620b3a724cb615af24b7779c0ab492d24efb8cc) | fix | add compiler option to disable control flow content projection diagnostic ([#53311](https://github.com/angular/angular/pull/53311)) |
| [4c1d69e288](https://github.com/angular/angular/commit/4c1d69e2880f22745c820eee630d10071e4fa86b) | fix | add diagnostic for control flow that prevents content projection ([#53190](https://github.com/angular/angular/pull/53190)) |
| [76ceebad04](https://github.com/angular/angular/commit/76ceebad047f62972654a8c934c77d8d02d9fa14) | fix | do not throw fatal error if extended type check fails ([#53896](https://github.com/angular/angular/pull/53896)) |
| [1a6eaa0fea](https://github.com/angular/angular/commit/1a6eaa0fea1024b919e17ac9d2e8c07df7916de8) | fix | input transform in local compilation mode ([#53645](https://github.com/angular/angular/pull/53645)) |
| [56a76d73e0](https://github.com/angular/angular/commit/56a76d73e037aeea1975808d5c51608fd23d4fa6) | fix | modify `getConstructorDependencies` helper to work with reflection host after the previous change ([#52215](https://github.com/angular/angular/pull/52215)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [863be4b698](https://github.com/angular/angular/commit/863be4b6981dc60ca0610b0e61d2ba1f5759e2a3) | feat | expose new `input` API for signal-based inputs ([#53872](https://github.com/angular/angular/pull/53872)) |
| [94096c6ede](https://github.com/angular/angular/commit/94096c6ede67436a349ae07901f2bb418bf9f461) | feat | support TypeScript 5.3 ([#52572](https://github.com/angular/angular/pull/52572)) |
| [69b384c0d1](https://github.com/angular/angular/commit/69b384c0d16f631741339d8757c32ef08260cfce) | fix | `SignalNode` reactive node incorrectly exposing unset field ([#53571](https://github.com/angular/angular/pull/53571)) |
| [6f79507ea7](https://github.com/angular/angular/commit/6f79507ea7f272d8d09250e222ca831f407867d8) | fix | Change defer block fixture default behavior to playthrough ([#53956](https://github.com/angular/angular/pull/53956)) |
| [32f908ab70](https://github.com/angular/angular/commit/32f908ab70f1b9ed3f92df1cae05ddde68932404) | fix | do not accidentally inherit input transforms when overridden ([#53571](https://github.com/angular/angular/pull/53571)) |
| [bdd61c768a](https://github.com/angular/angular/commit/bdd61c768a28b56c68634b99c036986499829f45) | fix | replace assertion with more intentional error ([#52234](https://github.com/angular/angular/pull/52234)) |
| [0daca457bb](https://github.com/angular/angular/commit/0daca457bb5bb6ffe14b7037264f8497eb5b3daf) | fix | TestBed should still use the microtask queue to schedule effects ([#53843](https://github.com/angular/angular/pull/53843)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [5c1d441029](https://github.com/angular/angular/commit/5c1d4410298e20cb03d7a1ddf7931538b6a181b4) | feat | Add info property to `NavigationExtras` ([#53303](https://github.com/angular/angular/pull/53303)) |
| [50d7916278](https://github.com/angular/angular/commit/50d79162785bb8d3e158a7a4a3733f4c75d3b127) | feat | Add router configuration to resolve navigation promise on error ([#48910](https://github.com/angular/angular/pull/48910)) |
| [a5a9b408e2](https://github.com/angular/angular/commit/a5a9b408e2eb64dcf1d3ca16da4897649dd2fc34) | feat | Add transient info to RouterLink input ([#53784](https://github.com/angular/angular/pull/53784)) |
| [726530a9af](https://github.com/angular/angular/commit/726530a9af9c8daf7295cc3548f24e70f380d70e) | feat | Allow `onSameUrlNavigation: 'ignore'` in `navigateByUrl` ([#52265](https://github.com/angular/angular/pull/52265)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.0.9"></a>
# 17.0.9 (2024-01-10)
### common
@@ -30,36 +129,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.0-next.5"></a>
# 17.1.0-next.5 (2023-12-21)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [3a689c2050](https://github.com/angular/angular/commit/3a689c20509ed5972b3831988fc0014d293d0cc3) | fix | correctly intercept index in loop tracking function ([#53604](https://github.com/angular/angular/pull/53604)) |
| [df8a825910](https://github.com/angular/angular/commit/df8a825910951bebf34a4eede42f3ce5cd3e6fb7) | fix | project empty block root node ([#53620](https://github.com/angular/angular/pull/53620)) |
| [478d622265](https://github.com/angular/angular/commit/478d6222650884478314985e3d5132587c4f670c) | fix | project empty block root node in template pipeline ([#53620](https://github.com/angular/angular/pull/53620)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [aecb675fa5](https://github.com/angular/angular/commit/aecb675fa5059e510e0223e00fa114d92e799b04) | fix | avoid repeated work when parsing version ([#53598](https://github.com/angular/angular/pull/53598)) |
| [872e7f25fe](https://github.com/angular/angular/commit/872e7f25fea8a01f980e4e406ad382a9e187ce5c) | fix | tree shake version class ([#53598](https://github.com/angular/angular/pull/53598)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [d49333edc3](https://github.com/angular/angular/commit/d49333edc3fe170c57d953aa2d8df58d0db379e0) | fix | cf migration - detect and error when result is invalid i18n nesting ([#53638](https://github.com/angular/angular/pull/53638)) ([#53639](https://github.com/angular/angular/pull/53639)) |
| [8e2178792d](https://github.com/angular/angular/commit/8e2178792d474e84817c27851cd6b9600deb15b5) | fix | cf migration - ensure full check runs for all imports ([#53637](https://github.com/angular/angular/pull/53637)) |
| [22b95de9bc](https://github.com/angular/angular/commit/22b95de9bcb92267b8f848a1aafa71af70d5577b) | fix | cf migration - fix bug in attribute formatting ([#53636](https://github.com/angular/angular/pull/53636)) |
| [b40bb22a66](https://github.com/angular/angular/commit/b40bb22a66a3c2ae478778f3ef0be0ce971a1b2c) | fix | cf migration - improve import declaration handling ([#53622](https://github.com/angular/angular/pull/53622)) |
| [8bf752539f](https://github.com/angular/angular/commit/8bf752539f6b4b5955e3d61a76423910af55181b) | fix | cf migration - preserve indentation on attribute strings ([#53625](https://github.com/angular/angular/pull/53625)) |
| [7bb312fcf6](https://github.com/angular/angular/commit/7bb312fcf612c57d6606ae14f21707f10d8ff9ce) | fix | cf migration - stop removing empty newlines from i18n blocks ([#53578](https://github.com/angular/angular/pull/53578)) |
| [db6b4a6bc4](https://github.com/angular/angular/commit/db6b4a6bc479b0fac0a4a99e1a202c38d1ea8944) | fix | Fix cf migration bug with parsing for loop conditions properly ([#53558](https://github.com/angular/angular/pull/53558)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [502f300757](https://github.com/angular/angular/commit/502f3007575a5445c2876c92548415cb003582b1) | fix | Should not freeze original object used for route data ([#53635](https://github.com/angular/angular/pull/53635)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.0.8"></a>
# 17.0.8 (2023-12-21)
### compiler
@@ -89,45 +158,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.0-next.4"></a>
# 17.1.0-next.4 (2023-12-13)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [b98d8f79ed](https://github.com/angular/angular/commit/b98d8f79ed4979fb91661dbdfb6266a917b41474) | fix | handle ambient types in input transform function ([#51474](https://github.com/angular/angular/pull/51474)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [9e5456912a](https://github.com/angular/angular/commit/9e5456912a699315f1f5e8458d35df946c01dc12) | fix | generate less type checking code in for loops ([#53515](https://github.com/angular/angular/pull/53515)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [2565121851](https://github.com/angular/angular/commit/25651218512becb3a491b1c94d643a5066a6d3cb) | fix | Avoid refreshing a host view twice when using transplanted views ([#53021](https://github.com/angular/angular/pull/53021)) |
| [629343f247](https://github.com/angular/angular/commit/629343f24741760e76d98ea1005debaf4775bfc7) | fix | Multiple subscribers to ApplicationRef.isStable should all see values ([#53541](https://github.com/angular/angular/pull/53541)) |
| [42f4f70e97](https://github.com/angular/angular/commit/42f4f70e97b47f7ffcf15e8af2c1a3fa3f393903) | fix | remove signal equality check short-circuit ([#53446](https://github.com/angular/angular/pull/53446)) |
| [f35adcb9b2](https://github.com/angular/angular/commit/f35adcb9b255741515d54bbce694f4cd34aac249) | fix | update feature usage marker ([#53542](https://github.com/angular/angular/pull/53542)) |
| [1fc5442947](https://github.com/angular/angular/commit/1fc5442947b07be7c11fe7c79b9e69f9458c8108) | perf | avoid changes Observable creation on QueryList ([#53498](https://github.com/angular/angular/pull/53498)) |
| [e3a6bf9b6c](https://github.com/angular/angular/commit/e3a6bf9b6c3bef03df9bfc8f05b817bc875cbad6) | perf | optimize memory allocation when reconcilling lists ([#52245](https://github.com/angular/angular/pull/52245)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [a02767956a](https://github.com/angular/angular/commit/a02767956a00e0b44b690411f01584f6660c83ea) | fix | CF Migration - ensure bound ngIfElse cases ignore line breaks ([#53435](https://github.com/angular/angular/pull/53435)) |
| [6aa1bb78e8](https://github.com/angular/angular/commit/6aa1bb78e8b9ca866b3c2d84f4005a0e67f2b6bc) | fix | cf migration - undo changes when html fails to parse post migration ([#53530](https://github.com/angular/angular/pull/53530)) |
| [cc02852ac4](https://github.com/angular/angular/commit/cc02852ac44bfea13e8b9d5768694a094fc2c4b5) | fix | CF migration only remove newlines of changed template content ([#53508](https://github.com/angular/angular/pull/53508)) |
| [ce1076785c](https://github.com/angular/angular/commit/ce1076785c98ecc9660637cafa4a62a63be8d315) | fix | cf migration validate structure of ngswitch before migrating ([#53530](https://github.com/angular/angular/pull/53530)) |
| [1f5c8bf116](https://github.com/angular/angular/commit/1f5c8bf116783c25234ab7fa301a0be842e58007) | fix | ensure we do not overwrite prior template replacements in migration ([#53393](https://github.com/angular/angular/pull/53393)) |
| [79f791543b](https://github.com/angular/angular/commit/79f791543b607eea1bb6a28b9c744760ba4fd028) | fix | fix cf migration import removal when errors occur ([#53502](https://github.com/angular/angular/pull/53502)) |
### platform-browser
| Commit | Type | Description |
| -- | -- | -- |
| [fdb9cb7a5b](https://github.com/angular/angular/commit/fdb9cb7a5be4695abaa60efc89ecd50ddb9e9e6e) | fix | Get correct base path when using "." as base href when serving from the file:// protocol. ([#53547](https://github.com/angular/angular/pull/53547)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [48c5041687](https://github.com/angular/angular/commit/48c50416872313f23d2759232c990cf8d2de6996) | fix | provide more actionable error message when route is not matched in production mode ([#53523](https://github.com/angular/angular/pull/53523)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.0.7"></a>
# 17.0.7 (2023-12-13)
### compiler
@@ -167,47 +197,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.0-next.3"></a>
# 17.1.0-next.3 (2023-12-06)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [5613051a8b](https://github.com/angular/angular/commit/5613051a8bd2626ae347292807b2bf21085c4c02) | fix | allow TS jsDocParsingMode host option to be programmatically set again ([#53292](https://github.com/angular/angular/pull/53292)) |
| [77ac4cd324](https://github.com/angular/angular/commit/77ac4cd32491d0c994cb4ea50372601c955cec3d) | fix | generate proper code for nullish coalescing in styling host bindings ([#53305](https://github.com/angular/angular/pull/53305)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [e620b3a724](https://github.com/angular/angular/commit/e620b3a724cb615af24b7779c0ab492d24efb8cc) | fix | add compiler option to disable control flow content projection diagnostic ([#53311](https://github.com/angular/angular/pull/53311)) |
| [d7a83f9521](https://github.com/angular/angular/commit/d7a83f95213cdd5d3ceefbc95fa1190856b0198c) | fix | avoid conflicts with built-in global variables in for loop blocks ([#53319](https://github.com/angular/angular/pull/53319)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [77939a3bd3](https://github.com/angular/angular/commit/77939a3bd39073d07e24797a4632ec2d2a6b92e0) | fix | cleanup signal consumers for all views ([#53351](https://github.com/angular/angular/pull/53351)) |
| [899f6c4a12](https://github.com/angular/angular/commit/899f6c4a12127f87aeedf47ee128ce949ebe717c) | fix | handle hydration of multiple nodes projected in a single slot ([#53270](https://github.com/angular/angular/pull/53270)) |
| [4b23221b4e](https://github.com/angular/angular/commit/4b23221b4e5f8be7bcffc8ace255143653550d3d) | fix | support hydration for cases when content is re-projected using ng-template ([#53304](https://github.com/angular/angular/pull/53304)) |
| [82609d471c](https://github.com/angular/angular/commit/82609d471c9802b847a5654918eca1ba3ebb29b3) | fix | support swapping hydrated views in `@for` loops ([#53274](https://github.com/angular/angular/pull/53274)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [1c1e8c477b](https://github.com/angular/angular/commit/1c1e8c477b8d5c8deecf05744bd1d5f7c86d2e14) | fix | CF migration - ensure NgIfElse attributes are properly removed ([#53298](https://github.com/angular/angular/pull/53298)) |
| [2998d482dd](https://github.com/angular/angular/commit/2998d482dd3f1f5ff7f08260c3947ded74dac126) | fix | CF Migration - Fix case of aliases on i18n ng-templates preventing removal ([#53299](https://github.com/angular/angular/pull/53299)) |
| [aad5e5bd0e](https://github.com/angular/angular/commit/aad5e5bd0e7f6581f51fc3a23c98a7f11219a8f8) | fix | CF Migration add support for ngIf with just a then ([#53297](https://github.com/angular/angular/pull/53297)) |
| [6f75471307](https://github.com/angular/angular/commit/6f75471307a9458d0cffd0ee2bbf4190640c3c3a) | fix | CF Migration fix missing alias for bound ngifs ([#53296](https://github.com/angular/angular/pull/53296)) |
| [2a5a8f6f05](https://github.com/angular/angular/commit/2a5a8f6f052961c010a68a05d868f50220f2fcf2) | fix | Change CF Migration ng-template placeholder generation and handling ([#53394](https://github.com/angular/angular/pull/53394)) |
| [03e2f1bb25](https://github.com/angular/angular/commit/03e2f1bb25693d1a5f4e53fc4f4cd1937cf6bda1) | fix | fix regexp for else and then in cf migration ([#53257](https://github.com/angular/angular/pull/53257)) |
| [f4a96a9160](https://github.com/angular/angular/commit/f4a96a9160927903c38e172f6375c4bc5f8e0905) | fix | handle aliases on bound ngIf migrations ([#53261](https://github.com/angular/angular/pull/53261)) |
| [5a0ed28c9d](https://github.com/angular/angular/commit/5a0ed28c9d3f1c7507feee482e37c3346d52b033) | fix | handle nested ng-template replacement safely in CF migration ([#53368](https://github.com/angular/angular/pull/53368)) |
| [01b18a4248](https://github.com/angular/angular/commit/01b18a4248f068df33c0ca8a2d62ef2fc69f941c) | fix | handle templates outside of component in cf migration ([#53368](https://github.com/angular/angular/pull/53368)) |
| [9834fd2738](https://github.com/angular/angular/commit/9834fd27387ed5edc65bed56aa003fc45d250420) | fix | remove setting that removes comments in CF migration ([#53350](https://github.com/angular/angular/pull/53350)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [5c1d441029](https://github.com/angular/angular/commit/5c1d4410298e20cb03d7a1ddf7931538b6a181b4) | feat | Add info property to `NavigationExtras` ([#53303](https://github.com/angular/angular/pull/53303)) |
| [50d7916278](https://github.com/angular/angular/commit/50d79162785bb8d3e158a7a4a3733f4c75d3b127) | feat | Add router configuration to resolve navigation promise on error ([#48910](https://github.com/angular/angular/pull/48910)) |
| [1940280d27](https://github.com/angular/angular/commit/1940280d27bb3ece585d6345dbd742d208f46912) | fix | Ensure canMatch guards run on wildcard routes ([#53239](https://github.com/angular/angular/pull/53239)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.0.6"></a>
# 17.0.6 (2023-12-06)
### compiler
@@ -247,43 +236,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.0-next.2"></a>
# 17.1.0-next.2 (2023-11-29)
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [79ff91a813](https://github.com/angular/angular/commit/79ff91a813e544929cb5eb5f9aab762a9f3d0435) | fix | allow TS jsDocParsingMode host option to be programmatically set ([#53126](https://github.com/angular/angular/pull/53126)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [4c1d69e288](https://github.com/angular/angular/commit/4c1d69e2880f22745c820eee630d10071e4fa86b) | fix | add diagnostic for control flow that prevents content projection ([#53190](https://github.com/angular/angular/pull/53190)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [58cf389d80](https://github.com/angular/angular/commit/58cf389d8095dd522a998b6b9a7d7b8da1656644) | fix | avoid stale provider info when TestBed.overrideProvider is used ([#52918](https://github.com/angular/angular/pull/52918)) |
| [c7c7ea9813](https://github.com/angular/angular/commit/c7c7ea9813f6dcf91c096bb37d36bfe0c715a04f) | fix | inherit host directives ([#52992](https://github.com/angular/angular/pull/52992)) |
| [b35c6731e5](https://github.com/angular/angular/commit/b35c6731e51de9c33707010fc780cbaa559be6c3) | fix | Reattached views that are dirty from a signal update should refresh ([#53001](https://github.com/angular/angular/pull/53001)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [dbca1c9d61](https://github.com/angular/angular/commit/dbca1c9d618be4d195d779ef80606c6d22f7c977) | fix | Add ngForTemplate support to control flow migration ([#53076](https://github.com/angular/angular/pull/53076)) |
| [53912fdf74](https://github.com/angular/angular/commit/53912fdf74e1224f95edc3dd550c51451e613c44) | fix | allows colons in ngIf else cases to migrate ([#53076](https://github.com/angular/angular/pull/53076)) |
| [fadfee4324](https://github.com/angular/angular/commit/fadfee43247acec7e450d5cc929a0a6780a54bd1) | fix | cf migration fix migrating empty switch default ([#53237](https://github.com/angular/angular/pull/53237)) |
| [b2aeaf5d97](https://github.com/angular/angular/commit/b2aeaf5d97327842a5bb657e9f02bb4f1358304b) | fix | CF migration log warning when collection aliasing detected in `@for` ([#53238](https://github.com/angular/angular/pull/53238)) |
| [c6326289f8](https://github.com/angular/angular/commit/c6326289f87089b3415ba0f3e371206b8a396b66) | fix | cf migration removes unnecessary bound ngifelse attribute ([#53236](https://github.com/angular/angular/pull/53236)) |
| [e6f10e81d2](https://github.com/angular/angular/commit/e6f10e81d2486b5cc1f468777b7e1057d3f09dc5) | fix | control flow migration formatting fixes ([#53076](https://github.com/angular/angular/pull/53076)) |
| [6291c8db09](https://github.com/angular/angular/commit/6291c8db092c0ab67f6789cc03c19dfa0bdc251d) | fix | fix off by one issue with template removal in CF migration ([#53255](https://github.com/angular/angular/pull/53255)) |
| [f1b7d40057](https://github.com/angular/angular/commit/f1b7d400575a6a02a2fc2b642c2b8c15cca9b3c4) | fix | fixes CF migration i18n ng-template offsets ([#53212](https://github.com/angular/angular/pull/53212)) |
| [a738b48717](https://github.com/angular/angular/commit/a738b48717e16613b34c3e50480cd49f2a31858f) | fix | fixes control flow migration common module removal ([#53076](https://github.com/angular/angular/pull/53076)) |
| [a3599515bb](https://github.com/angular/angular/commit/a3599515bb2513fbcb2899284c7f6b4bc021ddaf) | fix | properly handle ngIfThen cases in CF migration ([#53256](https://github.com/angular/angular/pull/53256)) |
| [8a52674faa](https://github.com/angular/angular/commit/8a52674faacefd4042726383fdf0aed59a04fb7e) | fix | Update CF migration to skip templates with duplicate ng-template names ([#53204](https://github.com/angular/angular/pull/53204)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [29e0834c4d](https://github.com/angular/angular/commit/29e0834c4deecfa8bf384b5e4359796c8123afcd) | fix | Resolvers in different parts of the route tree should be able to execute together ([#52934](https://github.com/angular/angular/pull/52934)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.0.5"></a>
# 17.0.5 (2023-11-29)
### core
@@ -313,39 +265,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.0-next.1"></a>
# 17.1.0-next.1 (2023-11-20)
### common
| Commit | Type | Description |
| -- | -- | -- |
| [29c5416d14](https://github.com/angular/angular/commit/29c5416d14638a05a894269aa5dbe67e98754418) | fix | remove `load` on image once it fails to load ([#52990](https://github.com/angular/angular/pull/52990)) |
| [7affa57754](https://github.com/angular/angular/commit/7affa5775427e92ef6e949c879765b7c8aa172da) | fix | scan images once page is loaded ([#52991](https://github.com/angular/angular/pull/52991)) |
### compiler
| Commit | Type | Description |
| -- | -- | -- |
| [ec2d6e7b9c](https://github.com/angular/angular/commit/ec2d6e7b9c2b386247d1320ee89f8e3ac5e5a0dd) | fix | changed after checked error in for loops ([#52935](https://github.com/angular/angular/pull/52935)) |
| [406049b95e](https://github.com/angular/angular/commit/406049b95e5234f17a7a18839ac848640f53fdde) | fix | generate i18n instructions for blocks ([#52958](https://github.com/angular/angular/pull/52958)) |
| [d9d566d315](https://github.com/angular/angular/commit/d9d566d31540582d73201675d0b8ed901261669e) | fix | nested for loops incorrectly calculating computed variables ([#52931](https://github.com/angular/angular/pull/52931)) |
| [5fb707f81a](https://github.com/angular/angular/commit/5fb707f81aee43751e61d2ed0861afc9b85bc85a) | fix | produce placeholder for blocks in i18n bundles ([#52958](https://github.com/angular/angular/pull/52958)) |
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [b4d022e230](https://github.com/angular/angular/commit/b4d022e230ca141b12437949d11dc384bfe5c082) | fix | add diagnostic for control flow that prevents content projection ([#52726](https://github.com/angular/angular/pull/52726)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [ed0fbd4071](https://github.com/angular/angular/commit/ed0fbd4071339b1af22d82bac07d51c6c41790cd) | fix | cleanup loading promise when no dependencies are defined ([#53031](https://github.com/angular/angular/pull/53031)) |
| [1ce31d819b](https://github.com/angular/angular/commit/1ce31d819b2e4f4425a41f07167a6edce98e77e1) | fix | handle local refs when `getDeferBlocks` is invoked in tests ([#52973](https://github.com/angular/angular/pull/52973)) |
### migrations
| Commit | Type | Description |
| -- | -- | -- |
| [e33f6e0f1a](https://github.com/angular/angular/commit/e33f6e0f1a483cad908fa6d7376d62332797499c) | fix | control flow migration fails for async pipe with unboxing of observable ([#52756](https://github.com/angular/angular/pull/52756)) ([#52972](https://github.com/angular/angular/pull/52972)) |
| [5564d020cd](https://github.com/angular/angular/commit/5564d020cdcea8273b65cf69c45c3f935195af66) | fix | Fixes control flow migration if then else case ([#53006](https://github.com/angular/angular/pull/53006)) |
| [28f6cbf9c9](https://github.com/angular/angular/commit/28f6cbf9c91f957b4926fe34610387e1f1919d4f) | fix | fixes migrations of nested switches in control flow ([#53010](https://github.com/angular/angular/pull/53010)) |
| [e090b48bf8](https://github.com/angular/angular/commit/e090b48bf8534761d46523be57a7889a325bcdec) | fix | tweaks to formatting in control flow migration ([#53058](https://github.com/angular/angular/pull/53058)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.0.4"></a>
# 17.0.4 (2023-11-20)
### common
@@ -379,24 +298,6 @@
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.1.0-next.0"></a>
# 17.1.0-next.0 (2023-11-15)
### compiler-cli
| Commit | Type | Description |
| -- | -- | -- |
| [56a76d73e0](https://github.com/angular/angular/commit/56a76d73e037aeea1975808d5c51608fd23d4fa6) | fix | modify `getConstructorDependencies` helper to work with reflection host after the previous change ([#52215](https://github.com/angular/angular/pull/52215)) |
### core
| Commit | Type | Description |
| -- | -- | -- |
| [94096c6ede](https://github.com/angular/angular/commit/94096c6ede67436a349ae07901f2bb418bf9f461) | feat | support TypeScript 5.3 ([#52572](https://github.com/angular/angular/pull/52572)) |
| [bdd61c768a](https://github.com/angular/angular/commit/bdd61c768a28b56c68634b99c036986499829f45) | fix | replace assertion with more intentional error ([#52234](https://github.com/angular/angular/pull/52234)) |
### router
| Commit | Type | Description |
| -- | -- | -- |
| [726530a9af](https://github.com/angular/angular/commit/726530a9af9c8daf7295cc3548f24e70f380d70e) | feat | Allow `onSameUrlNavigation: 'ignore'` in `navigateByUrl` ([#52265](https://github.com/angular/angular/pull/52265)) |
<!-- CHANGELOG SPLIT MARKER -->
<a name="17.0.3"></a>
# 17.0.3 (2023-11-15)
### animations
@@ -489,17 +390,16 @@ Live long and prosper 🖖🏻
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:
@@ -597,7 +497,7 @@ Live long and prosper 🖖🏻
- 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).
+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
+3 -3
View File
@@ -196,10 +196,10 @@ cldr_xml_data_repository(
# sass rules
http_archive(
name = "io_bazel_rules_sass",
sha256 = "7a90567717c3417a23ff4b21963a698a6e9aa669ac9e682121ea33f218a2816a",
strip_prefix = "rules_sass-425ecafa8268bc013d684216363fe75bc802323e",
sha256 = "386ef2b97bd4342e45db450ce7eb5acb343d22f7580c0bbae89186dc009fa14e",
strip_prefix = "rules_sass-d970cb53ad159e7fd1d3a99a00a530cc2c83eff9",
urls = [
"https://github.com/bazelbuild/rules_sass/archive/425ecafa8268bc013d684216363fe75bc802323e.zip",
"https://github.com/bazelbuild/rules_sass/archive/d970cb53ad159e7fd1d3a99a00a530cc2c83eff9.zip",
],
)
+66 -3
View File
@@ -1,6 +1,7 @@
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")
load("@npm//@angular-devkit/architect-cli:index.bzl", "architect", "architect_test")
package(default_visibility = ["//visibility:public"])
@@ -21,6 +22,13 @@ APPLICATION_FILES = [
],
)
TEST_FILES = APPLICATION_FILES + [
"karma.conf.js",
"tsconfig.spec.json",
] + glob(
["**/*.spec.ts"],
)
APPLICATION_DEPS = link_packages([
"@npm//@angular-devkit/build-angular",
"@npm//@angular/animations",
@@ -69,17 +77,56 @@ APPLICATION_DEPS = link_packages([
"@npm//angular-split",
])
TEST_DEPS = APPLICATION_DEPS + link_packages([
"@npm//@angular/platform-browser-dynamic",
"@npm//@angular/build-tooling/bazel/browsers/chromium",
"@npm//@types/jasmine",
"@npm//@types/node",
"@npm//assert",
"@npm//jasmine",
"@npm//jasmine-core",
"@npm//karma-chrome-launcher",
"@npm//karma-coverage",
"@npm//karma-jasmine",
"@npm//karma-jasmine-html-reporter",
"//aio/tools:windows-chromium-path",
])
copy_to_bin(
name = "application_files_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-app",
],
"--output-path=build",
] + config_based_architect_flags,
chdir = "$(RULEDIR)",
data = APPLICATION_DEPS + [
":application_files_bin",
@@ -100,3 +147,19 @@ architect(
":application_files_bin",
],
)
architect_test(
name = "test",
args = [
"angular-dev:test",
"--no-watch",
],
chdir = package_name(),
data = TEST_DEPS + TEST_FILES,
env = {
"CHROME_BIN": "../$(CHROMIUM)",
},
toolchains = [
"@npm//@angular/build-tooling/bazel/browsers/chromium:toolchain_alias",
],
)
+1 -2
View File
@@ -26,8 +26,6 @@
"index": "src/index.html",
"browser": "src/main.ts",
"server": "src/main.server.ts",
// TODO(josephperrott): enabled prerender
"prerender": false,
"polyfills": ["src/polyfills.ts", "zone.js"],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
@@ -89,6 +87,7 @@
"polyfills": ["zone.js", "zone.js/testing"],
"tsConfig": "tsconfig.spec.json",
"include": ["src/app"],
"karmaConfig": "karma.conf.js",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["@angular/docs/styles/global-styles.scss"],
+73
View File
@@ -0,0 +1,73 @@
{
"hosting": {
"target": "angular-docs",
"public": "./build/browser",
"ignore": ["**/.*"],
"headers": [
{
"source": "assets/tutorials/common/*.jpg",
"headers": [
{
"key": "Cross-Origin-Resource-Policy",
"value": "cross-origin"
},
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
},
{
"source": "*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)",
"headers": [
{
"key": "Cache-Control",
"value": "public,max-age=31536000,immutable"
},
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
},
{
"source": "/[0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].js",
"headers": [
{
"key": "Cross-Origin-Embedder-Policy",
"value": "require-corp"
}
]
},
{
"source": "/@(ngsw-worker.js|ngsw.json)",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache"
}
]
},
{
"source": "/**",
"headers": [
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
},
{
"key": "Cross-Origin-Embedder-Policy",
"value": "require-corp"
}
]
}
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
+74
View File
@@ -0,0 +1,74 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
const {getAdjustedChromeBinPathForWindows} = require('../aio/tools/windows-chromium-path');
process.env.CHROME_BIN = getAdjustedChromeBinPathForWindows();
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma'),
{'reporter:jasmine-seed': ['type', JasmineSeedReporter]},
],
proxies: {
'/dummy/image': 'src/assets/images/logos/angular/angular.png',
},
client: {
clearContext: false, // leave Jasmine Spec Runner output visible in browser
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
random: true,
seed: '',
},
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/site'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
],
},
reporters: ['progress', 'kjhtml', 'jasmine-seed'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
customLaunchers: {
ChromeHeadlessNoSandbox: {
base: 'ChromeHeadless',
// See /integration/README.md#browser-tests for more info on these args
flags: ['--no-sandbox', '--headless', '--disable-gpu', '--disable-dev-shm-usage', '--hide-scrollbars', '--mute-audio'],
},
},
browsers: ['ChromeHeadlessNoSandbox'],
browserNoActivityTimeout: 60000,
singleRun: false,
restartOnFileChange: true,
});
};
// Helpers
function JasmineSeedReporter(baseReporterDecorator) {
baseReporterDecorator(this);
this.onBrowserComplete = (browser, result) => {
const seed = result.order && result.order.random && result.order.seed;
if (seed) this.write(`${browser}: Randomized with seed ${seed}.\n`);
};
this.onRunComplete = () => undefined;
}
+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;
@@ -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);
@@ -7,7 +7,7 @@
*/
import {Injector} from '@angular/core';
import {WINDOW} from '@angular/docs';
import {ENVIRONMENT, WINDOW} from '@angular/docs';
import {AnalyticsService} from './analytics.service';
describe('AnalyticsService', () => {
@@ -36,6 +36,7 @@ describe('AnalyticsService', () => {
injector = Injector.create({
providers: [
{provide: ENVIRONMENT, useValue: {}},
{provide: AnalyticsService, deps: [WINDOW]},
{provide: WINDOW, useFactory: () => mockWindow, deps: []},
],
@@ -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 {
+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;
@@ -19,7 +19,7 @@ import {EmbeddedTutorialManager} from '../embedded-tutorial-manager.service';
import {CodeEditor, REQUIRED_FILES} from './code-editor.component';
import {CodeMirrorEditor} from './code-mirror-editor.service';
import {FakeChangeDetectorRef} from '../../../../../shared/src/lib/utils/test-utils.spec';
import {FakeChangeDetectorRef} from '@angular/docs/testing';
import {TutorialType} from '@angular/docs';
const files = [
@@ -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;
}
@@ -8,16 +8,9 @@
import {TestBed} from '@angular/core/testing';
import type {FileSystemTree} from '@webcontainer/api';
import type {
TutorialConfig,
TutorialMetadata,
} from '@angular/docs';
import {
TUTORIALS_COMMON_DIRECTORY,
TUTORIALS_METADATA_WEB_PATH,
TUTORIALS_SOURCE_CODE_WEB_PATH,
TutorialType,
} from '@angular/docs';
import type {TutorialConfig, TutorialMetadata} from '@angular/docs';
import {TUTORIALS_ASSETS_WEB_PATH} from '../editor/constants';
import {TutorialType} from '@angular/docs';
import {EmbeddedTutorialManager} from './embedded-tutorial-manager.service';
describe('EmbeddedTutorialManager', () => {
@@ -252,13 +245,7 @@ describe('EmbeddedTutorialManager', () => {
},
},
};
const commonSourceCode: FileSystemTree = {
'common.ts': {
file: {
contents: 'code',
},
},
};
const metadata: TutorialMetadata = {
tutorialFiles: {'app.js': ''},
openFiles: ['app.js'],
@@ -271,14 +258,13 @@ describe('EmbeddedTutorialManager', () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock.and.returnValues(
Promise.resolve(new Response(JSON.stringify(commonSourceCode))),
Promise.resolve(new Response(JSON.stringify(tutorialSourceCode))),
Promise.resolve(new Response(JSON.stringify(metadata))),
);
await service.fetchAndSetTutorialFiles(tutorial);
expect(fetchMock).toHaveBeenCalledTimes(3);
expect(fetchMock).toHaveBeenCalledTimes(2);
expect(service.tutorialId()).toEqual(tutorial);
expect(service.tutorialFilesystemTree()).toEqual(tutorialSourceCode);
@@ -289,8 +275,6 @@ describe('EmbeddedTutorialManager', () => {
expect(service.type()).toEqual(metadata.type);
expect(service.commonFilesystemTree()).toEqual(commonSourceCode);
expect(service.hiddenFiles()).toEqual(metadata.hiddenFiles);
expect(service.answerFiles()).toEqual(metadata.answerFiles!);
});
@@ -299,15 +283,11 @@ describe('EmbeddedTutorialManager', () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/source-code.json`)
.and.returnValues(Promise.resolve(new Response(null, {status: 404})));
fetchMock
.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/metadata.json`)
.and.returnValues(Promise.resolve(new Response(null, {status: 404})));
await expectAsync(service.fetchAndSetTutorialFiles(tutorial)).toBeRejectedWithError(
@@ -315,38 +295,15 @@ describe('EmbeddedTutorialManager', () => {
);
});
it('should throw an error if the tutorial common project cannot be fetched', async () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.and.returnValues(Promise.resolve(new Response(null, {status: 404})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
await expectAsync(service.fetchAndSetTutorialFiles(tutorial)).toBeRejectedWithError(
'Missing source code for tutorial common',
);
});
it('should not set shouldReinstallDependencies if project did not change', async () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/source-code.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`).and.returnValues(
fetchMock.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/metadata.json`).and.returnValues(
Promise.resolve(
new Response(
JSON.stringify({
@@ -368,15 +325,12 @@ describe('EmbeddedTutorialManager', () => {
it('should trigger shouldReInstallDependencies if new metadata has different dependencies', async () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/source-code.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`).and.returnValues(
fetchMock.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/metadata.json`).and.returnValues(
Promise.resolve(
new Response(
JSON.stringify({
@@ -404,14 +358,10 @@ describe('EmbeddedTutorialManager', () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/source-code.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`).and.returnValues(
fetchMock.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/metadata.json`).and.returnValues(
Promise.resolve(
new Response(
JSON.stringify({
@@ -437,14 +387,10 @@ describe('EmbeddedTutorialManager', () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/source-code.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`).and.returnValues(
fetchMock.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/metadata.json`).and.returnValues(
Promise.resolve(
new Response(
JSON.stringify({
@@ -472,16 +418,12 @@ describe('EmbeddedTutorialManager', () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/source-code.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
const allFiles = ['file1.ts', 'file2.ts'];
fetchMock.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`).and.returnValues(
fetchMock.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/metadata.json`).and.returnValues(
Promise.resolve(
new Response(
JSON.stringify({
@@ -507,16 +449,12 @@ describe('EmbeddedTutorialManager', () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/source-code.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
const allFiles = ['file1.ts', 'file2.ts'];
fetchMock.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`).and.returnValues(
fetchMock.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/metadata.json`).and.returnValues(
Promise.resolve(
new Response(
JSON.stringify({
@@ -539,16 +477,12 @@ describe('EmbeddedTutorialManager', () => {
const fetchMock = spyOn(window, 'fetch');
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${TUTORIALS_COMMON_DIRECTORY}.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
fetchMock
.withArgs(`${TUTORIALS_SOURCE_CODE_WEB_PATH}/${tutorial}.json`)
.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/source-code.json`)
.and.returnValues(Promise.resolve(new Response('{}', {status: 200})));
const allFiles = ['file1.ts', 'file2.ts'];
fetchMock.withArgs(`${TUTORIALS_METADATA_WEB_PATH}/${tutorial}.json`).and.returnValues(
fetchMock.withArgs(`${TUTORIALS_ASSETS_WEB_PATH}/${tutorial}/metadata.json`).and.returnValues(
Promise.resolve(
new Response(
JSON.stringify({
@@ -15,7 +15,7 @@ import {TutorialType} from '@angular/docs';
import {
FakeWebContainer,
FakeWebContainerProcess,
} from '../../../../shared/src/lib/utils/test-utils.spec';
} from '@angular/docs/testing';
import {AlertManager} from './alert-manager.service';
import {EmbeddedTutorialManager} from './embedded-tutorial-manager.service';
import {LoadingStep} from './enums/loading-steps';
@@ -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);
}
@@ -11,7 +11,8 @@ import {By} from '@angular/platform-browser';
import {Terminal} from './terminal.component';
import {TerminalHandler, TerminalType} from './terminal-handler.service';
import {FakeEventTarget, WINDOW} from '@angular/docs';
import {WINDOW} from '@angular/docs';
import {FakeEventTarget} from '@angular/docs/testing';
describe('Terminal', () => {
let component: Terminal;
@@ -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,10 @@
overflow-y: scroll;
width: 50%;
}
&:has(.adev-reference-api-tab) {
&:has(.docs-reference-api-tab) {
width: 60%;
}
&:not(.adev-reference-api-tab) {
&:not(.docs-reference-api-tab) {
max-width: var(--page-width);
}
}
@@ -73,7 +73,7 @@
}
}
.adev-reference-header {
.docs-reference-header {
> p {
color: var(--secondary-contrast);
margin-block-start: 0;
@@ -94,7 +94,7 @@
}
}
.adev-reference-api-tab {
.docs-reference-api-tab {
display: flex;
gap: 1.81rem;
align-items: flex-start;
@@ -155,7 +155,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 +172,7 @@
}
// Sidebar
.adev-reference-members {
.docs-reference-members {
display: flex;
flex-direction: column;
gap: 20px;
@@ -182,7 +182,7 @@
}
}
.adev-reference-title {
.docs-reference-title {
display: flex;
flex-wrap: wrap;
align-items: center;
@@ -217,7 +217,7 @@
gap: 0.5rem;
}
.adev-reference-category {
.docs-reference-category {
color: var(--gray-400);
font-size: 0.875rem;
font-weight: 500;
@@ -225,7 +225,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 +248,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 +266,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 +299,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 +316,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 +332,7 @@
}
}
.adev-reference-card-item {
.docs-reference-card-item {
span {
display: inline-block;
font-size: 0.875rem;
@@ -342,31 +342,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 +381,7 @@
}
}
.adev-deprecated {
.docs-deprecated {
color: var(--page-background);
background-color: var(--quaternary-contrast);
width: max-content;
@@ -391,11 +391,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%;
@@ -19,7 +19,7 @@ import {
EmbeddedEditor,
EmbeddedTutorialManager,
NodeRuntimeSandbox
} from '@angular/docs';
} from '../../editor';
import {mockAsyncProvider} from '../../core/services/inject-async';
import Tutorial from './tutorial.component';
+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,
+6
View File
@@ -943,6 +943,7 @@ export const TUTORIALS_SUB_NAVIGATION_DATA: NavigationItem[] = [
{
path: DefaultPage.TUTORIALS,
contentPath: 'tutorials/home',
label: 'Tutorials'
},
];
@@ -1336,6 +1337,11 @@ 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',
},
],
},
];
+3
View File
@@ -65,10 +65,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
@@ -78,7 +78,7 @@ For example, imagine the following scenario:
1. After some time, a new version of the application is deployed to the server.
This newer version includes the files `index.html`, `main.<main-hash-2>.js` and `lazy-chunk.<lazy-hash-2>.js`.
IMPORANT: The hashes are different now, because the content of the files changed. The old version is no longer available on the server.
IMPORTANT: The hashes are different now, because the content of the files changed. The old version is no longer available on the server.
1. In the meantime, the user's browser decides to evict `lazy-chunk.<lazy-hash-1>.js` from its cache.
Browsers might decide to evict specific (or all) resources from a cache in order to reclaim disk space.
@@ -110,7 +110,7 @@ Make a change to the application, and watch the service worker install the updat
<docs-code language="shell">
ng build
npx http-server -p 8080 -c-1 dist/
npx http-server -p 8080 -c-1 dist/&lt;project-name&gt;/browser
</docs-code>
@@ -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">
@@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
@@ -3,6 +3,7 @@ import { Architect } from '@angular-devkit/architect';
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
import { schema } from '@angular-devkit/core';
import { promises as fs } from 'fs';
import { join } from 'path';
describe('Copy File Builder', () => {
let architect: Architect;
@@ -19,7 +20,7 @@ describe('Copy File Builder', () => {
// This will either take a Node package name, or a path to the directory
// for the package.json file.
await architectHost.addBuilderFromPackage('..');
await architectHost.addBuilderFromPackage(join(__dirname, '..'));
});
it('can copy files', async () => {
@@ -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,13 +0,0 @@
// #docregion
import { Injectable } from '@angular/core';
import { HeroModule } from './hero.module';
import { HEROES } from './mock-heroes';
@Injectable({
// we declare that this service should be created
// by any injector that includes HeroModule.
providedIn: HeroModule,
})
export class HeroService {
getHeroes() { return HEROES; }
}
@@ -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,6 +1,6 @@
import { AppPage } from './app.po';
describe('forms-overvoew App', () => {
describe('forms-overview App', () => {
let page: AppPage;
beforeEach(() => {
@@ -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">
@@ -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