Close#40387
Currently zone.js patches `setTimeout` and keeps a `tasksByHandleId` map to keep `timerId` <-> `ZoneTask`
relationship. This is needed so that when `clearTimeout(timerId)` is called, zone.js can find the associated
`ZoneTask`. Now zone.js set the `tasksByHandleId` map in the `scheduleTask` function, but if the `setTimeout`
is running in the `FakeAsyncZoneSpec` or any other `ZoneSpec` with `onScheduleTask` hooks. The `scheduleTask`
in `timer` patch may not be invoked.
For example:
```
fakeAsync(() => {
setTimeout(() => {});
tick();
});
```
In this case, the `timerId` kept in the `tasksByHandleId` map is not cleared.
This is because the `FakeAsyncZoneSpec` in the `onScheduleTask` hook looks like this.
```
onScheduleTask(delegate, ..., task) {
fakeAsyncScheduler.setTimeout(task);
return task;
}
```
Because `FakeAsyncZoneSpec` handles the task itself and it doesn't call `parentDelegate.onScheduleTask`,
therefore the default `scheduleTask` in the `timer` patch is not invoked.
In this commit, the cleanup logic is moved from `scheduleTask` to `setTimeout` patch entry to
avoid the memory leak.
PR Close#40586
This commit adds the missing `min` and `max` validators.
BREAKING CHANGE:
Previously `min` and `max` attributes defined on the `<input type="number">`
were ignored by Forms module. Now presence of these attributes would
trigger min/max validation logic (in case `formControl`, `formControlName`
or `ngModel` directives are also present on a given input) and
corresponding form control status would reflect that.
Fixes#16352
PR Close#39063
No longer emits to `Router.events` after the router has been destroyed. Also
returns a resolved promise to the navigation methods.
Fixes#40502.
PR Close#40638
Two motivations behind this change:
1. We would like to expose the types of the Language Service to external
users (like the VSCode extension) via the npm package, on the top
level of the package
2. We would like the View Engine and Ivy LS to share a common interface
(notably after the inclusion of `getTcb`, the Ivy LS upholds a
strict superset of `ts.LanguageService`; previously both VE and Ivy
LS were aligned on `ts.LanguageService`.)
To this end, this commit refactors the exports on the toplevel of the
`language-service/` package to just be types common to both the VE and
Ivy language services. The VE and Ivy build targets then import and use
these types accordingly, and the expectation is that an external user
will just import the relevant typings from the toplevel package without
diving into either the VE or Ivy sources.
Follow up on #40607
PR Close#40621
This commit updates `AbstractControlStatus` directive code to remove duplicated logic in getters and replaces
that logic with a new function that accepts an argument.
PR Close#40651
The `AsyncPipe.transform<T>(emitter)` method must infer the `T`
type from the `emitter` parameter. Since we changed the `AsyncPipe`
to expect a `Subscribable<T>` rather than `Observable<T>` the
`EventEmitter.subscribe()` method needs to have a tighter signature.
Otherwise TypeScript struggles to infer the type and ends up making
it `unknown`.
Fixes#40637
PR Close#40644
The `TemplateTypeChecker.overrideComponentTemplate` operation was originally
conceived as a "fast path" for the Language Service to react to a template
change without needing to go through a full incremental compilation step. It
served this purpose until the previous commit, which switches the LS to use
the new resource-only incremental change operation provided by `NgCompiler`.
`overrideComponentTemplate` is now no longer utilized, and is known to have
several hard-to-overcome issues that prevent it from being useful in any
other situations. As such, this commit removes it entirely.
PR Close#40585
This commit changes the Language Service's "compiler factory" mechanism to
leverage the new resource-only update path for `NgCompiler`. When an
incoming change only affects a resource file like a component template or
stylesheet, going through the new API allows the Language Service to avoid
unnecessary incremental steps of the `NgCompiler` and return answers more
efficiently.
PR Close#40585
This commit removes some styles for the `.heading` CSS class which do
not have any effect (either because they are overridden in other rules
or because they do not make any difference).
NOTE:
The `.heading` class is kept in the HTML to make it easier to associate
the `.heading-children` element with its corresponding `.heading`
parent.
PR Close#40427
This commit simplifies the styling of the "collapsed/expanded" icons in
sidenav nav-items with children by consolidating the CSS rules in one
block (instead of having duplicate blocks for different levels).
PR Close#40427
This commit fixes the layout and appearance of the cards shown in the
docs introduction page (`/docs`) in the following ways:
- Center the cards.
- Ensure two cards are shown per line (instead of 3 one the first line
and 1 on the second).
- Adjust their widths to ensure their content fits well in them
(given that the cards have a fixed height).
- Use more engaging styles to better indicate that the cards are
clickable (as discussed [here][1]).
[1]: https://github.com/angular/angular/pull/40427#discussion_r560688953
PR Close#40427
This commit cleans up the styles in `_card.scss` by:
- Fixing incosistenct indentation/newlines.
- Removing rules for unused selectors.
- Removing unnecessary styles.
PR Close#40427
This commit changes the layout of the main content to improve
legibility, especially on wider screens:
- Limit main content width to 50em (800px by default).
- Center main content on the page.
Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>
PR Close#40427
This commit includes some general improvements to heading styles
(font-weight, margin/padding). It also adds a horizontal separator above
`<h2>` headings to segment important sections more easily.
(As a consequence, we can remove several `<hr />` elements right before
`<h2>` headings.)
Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>
PR Close#40427
This commit improves the padding nav-menus and nav-items in the sidenav.
It also ensures that all nav-items have the same height, regardless of
their level and of whether they have children or not.
Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>
PR Close#40427
Previously, we used a box-shadow to indicate that the sidenav is
separate from the main content.
This commits updates the sidenav styling to remove the shadow and give
it a slightly different background color instead.
Co-authored-by: Stefanie Fluin <sjtrimble@gmail.com>
PR Close#40427
Normally the template parsing operation normalizes all template line endings
to '\n' only. This normalization operation causes source mapping errors when
the original template uses '\r\n' line endings.
The compiler already parses templates again to create a "diagnostic"
template AST with accurate source maps, to avoid other parsing issues that
affect source map accuracy. This commit configures this diagnostic parse to
also preserve line endings.
PR Close#40597
In b6cd38ff05 we fixed the DatePipe so
that when it parsed date strings that looked like `YYYY-MM` it created a UTC
date that was not affected by the local timezone of the JavaScript engine.
This commit does the same for date strings of the form `YYYY`.
(Note that the previous commit, mentioned above, attempted to fix this case
too but the test was not actually checking the correct input string.)
Fixes#33944
PR Close#40620
PR Close#40629
In 2aba8b0 we fixed the DatePipe so that when it parsed date strings
that looked like `YYYY-MM-DD` it created a UTC date that was not
affected by the local timezone of the JavaScript engine.
This commit does the same for date strings of the form `YYYY-MM`
and `YYYY`.
Fixes#33944
PR Close#40620
fix https://github.com/angular/components/issues/21674
When setting `ngZoneRunCoalescing` to true, `onStable` is not emitted correctly.
The reason is before this commit, the code looks like this
```
// Application code call `ngZone.run()`
ngZone.run(() => {}); // step 1
// Inside NgZone, in the OnInvoke hook, NgZone try to delay the checkStable()
function delayChangeDetectionForEvents(zone: NgZonePrivate) {
if (zone.lastRequestAnimationFrameId !== -1) { // step 9
return;
}
zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(global, () => { // step 2
if (!zone.fakeTopEventTask) {
zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', () => {
zone.lastRequestAnimationFrameId = -1; // step 3
updateMicroTaskStatus(zone); // step 4
checkStable(zone); // step 6
}, undefined, () => {}, () => {});
}
zone.fakeTopEventTask.invoke();
});
updateMicroTaskStatus(zone);
}
function updateMicroTaskStatus(zone: NgZonePrivate, ignoreCheckRAFId = false) {
if (zone._hasPendingMicrotasks ||
((zone.shouldCoalesceEventChangeDetection || zone.shouldCoalesceRunChangeDetection) &&
zone.lastRequestAnimationFrameId !== -1)) { // step 5
zone.hasPendingMicrotasks = true;
} else {
zone.hasPendingMicrotasks = false;
}
}
function checkStable(zone: NgZonePrivate) {
if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) { // step 7
try {
zone._nesting++;
zone.onMicrotaskEmpty.emit(null);
...
}
// application ref subscribe onMicroTaskEmpty
ngZone.onMicroTaskEmpty.subscribe(() => {
ngZone.run(() => { // step 8
tick();
});
});
```
And the process is:
1. step 1: application call ngZone.run()
2. step 2: NgZone delay the checkStable() call in a requestAnimationFrame, and also set
zone.lastRequestAnimationFrameId
3. step 3: Inside the requestAnimationFrame callback, reset zone.lastRequestAnimationFrameId first
4. step 4: update microTask status
5, step 5: if zone.lastRequestAnimationFrameId is -1, that means no microTask pending.
6. step 6: checkStable and trigger onMicrotaskEmpty emitter.
7. step 7: ApplicationRef subscribed onMicrotaskEmpty, so it will call another `ngZone.run()` to process
tick()
8. step 8: And this new `ngZone.run()` will try to check `zone.lastRequestAnimationFrameId` in `step 9`
when trying to delay the checkStable(), and since the zone.lastRequestAnimationFrameId is already reset
to -1 in step 3, so this ngZone.run() will run into step 2 again.
9. And become a infinite loop..., so onStable is never emit
In this commit, the `zone.lastRequestAnimationFrameId` reset is moved after `checkStable()` call.
PR Close#40540
They aim to improve code readability.
Since they are defined by `const enum` they have zero runtime performance impact
over just using constant literals.
Fixes#23543
PR Close#23548
When parsing interpolations, if we encounter an empty interpolation
(`{{}}`), the current code uses a "pretend" value of `$implicit` for the
name as if the interplotion were really `{{$implicit}}`. This is
problematic because the spans are then incorrect downstream since they
are based off of the `$implicit` text.
This commit changes the interpretation of empty interpolations so that
the text is simply an empty string.
Fixes https://github.com/angular/vscode-ng-language-service/issues/1077
Fixes https://github.com/angular/vscode-ng-language-service/issues/1078
PR Close#40583
Previously, we could not use `npm_package.pack` for building the Zone.js
package due to a bug in Windows. This bug has been fixed in version
2.3.0 of `bazelbuild/rules_nodejs`.
Now that we have updated `bazelbuild/rules_nodejs` to version 2.3.3
(in #40581) we can replace `npm pack` with `npm_package.pack`.
PR Close#40592